From 001ac86310d22c1b30de040c7d2f1f6a631ad717 Mon Sep 17 00:00:00 2001 From: lixiaolong <702156524@qq.com> Date: Thu, 20 Nov 2025 16:04:46 +0800 Subject: [PATCH] =?UTF-8?q?feat:=E4=BF=AE=E6=94=B9=E6=9C=BA=E6=A2=B0?= =?UTF-8?q?=E8=87=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/api/device/arm.js | 18 + src/assets/images/arm.png | Bin 0 -> 34989 bytes .../components/MechanicalArm/index.vue | 318 +++++++++--------- 3 files changed, 182 insertions(+), 154 deletions(-) create mode 100644 src/api/device/arm.js create mode 100644 src/assets/images/arm.png diff --git a/src/api/device/arm.js b/src/api/device/arm.js new file mode 100644 index 0000000..00e859c --- /dev/null +++ b/src/api/device/arm.js @@ -0,0 +1,18 @@ +import request from '@/utils/request' +// 移动机械臂 +export function moveJ(data) { + return request({ + url: '/api/humanoid/moveJ', + method: 'post', + data: data + }) +} + +// 获取机械臂状态 +export function status(data) { + return request({ + url: '/api/humanoid/status', + method: 'post', + data: data + }) +} \ No newline at end of file diff --git a/src/assets/images/arm.png b/src/assets/images/arm.png new file mode 100644 index 0000000000000000000000000000000000000000..6b38d40a398c34cde7349efbdb4e32e18d08eff8 GIT binary patch literal 34989 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 -import { reactive, toRefs, onMounted, onUnmounted, watch, computed } from "vue"; +import { reactive, toRefs, onMounted, onUnmounted, watch, computed, ref } from "vue"; import { useRoute } from "vue-router"; import dayjs from "dayjs"; -import { deviceTeach, deviceUpdateProfile } from "@/api/device/register.js"; +import { deviceTeach } from "@/api/device/register.js"; import { formatNumber } from "@/views/device/register/components/index.js"; import { convertNumbersToStringAndRemoveNulls } from "@/utils/fn.js"; +import { + moveJ, + status +} from '@/api/device/arm'; const data = reactive({ form: { @@ -18,6 +22,7 @@ const data = reactive({ joint4: 0.000012, joint5: 0.000012, joint6: 0.000012, + joint7: 0.000012, x: 11, y: 11, z: 11, @@ -51,10 +56,33 @@ const data = reactive({ ], time: dayjs().format("YYYY-MM-DD HH:mm:ss"), }); - +const terminalId = ref('25449ff3fcc7b27da5f69462c5efcec2'); +const deviceId = ref('spk1'); const { form, time, zeroPos, initPos, armList } = toRefs(data); - const route = useRoute(); +const coordinateSystem = ref(null); // 用于获取容器元素 +const buttonPositions = ref([]); // 存储按钮的动态位置 + +// 调整后的原始坐标(基于默认图片尺寸 1025x817px) +const initialPositions = [ + { target: "z_plus", x: 500, y: 80, label: "Z+" }, + { target: "rz_plus", x: 675, y: 124, label: "RZ+" }, + { target: "x_plus", x: 796, y: 245, label: "X+" }, + { target: "ry_plus", x: 840, y: 410, label: "RY+" }, + { target: "y_minus", x: 796, y: 570, label: "Y-" }, + { target: "ry_minus", x: 675, y: 696, label: "RY-" }, + { target: "z_minus", x: 500, y: 745, label: "Z-" }, + { target: "rx_minus", x: 345, y: 696, label: "RX-" }, + { target: "x_minus", x: 206, y: 570, label: "X-" }, + { target: "rx_plus", x: 180, y: 410, label: "RX+" }, + { target: "y_plus", x: 204, y: 245, label: "Y+" }, + { target: "rz_minus", x: 345, y: 124, label: "RZ-" }, +]; + +// 默认图片尺寸 +const ORIGINAL_IMAGE_WIDTH = 1025; +const ORIGINAL_IMAGE_HEIGHT = 817; + let timer = null; onUnmounted(() => { @@ -74,8 +102,46 @@ const getDeviceInfo = () => { }); }; +const updateButtonPositions = () => { + if (coordinateSystem.value) { + const { width, height } = coordinateSystem.value.getBoundingClientRect(); + // 计算图片的实际显示尺寸(考虑 background-size: contain) + const imageAspectRatio = ORIGINAL_IMAGE_WIDTH / ORIGINAL_IMAGE_HEIGHT; // 1025 / 817 ≈ 1.255 + const containerAspectRatio = width / height; + + let imageWidth, imageHeight, offsetX, offsetY; + if (containerAspectRatio > imageAspectRatio) { + // 容器较宽,高度限制图片大小,上下有留白 + imageHeight = height; + imageWidth = height * imageAspectRatio; + offsetX = (width - imageWidth) / 2; // 水平居中 + offsetY = 0; // 顶部对齐 + } else { + // 容器较窄,宽度限制图片大小,左右有留白 + imageWidth = width; + imageHeight = width / imageAspectRatio; + offsetX = 0; // 左对齐 + offsetY = (height - imageHeight) / 2; // 垂直居中 + } + + // 计算缩放比例(基于图片实际显示尺寸) + const scaleX = imageWidth / ORIGINAL_IMAGE_WIDTH; + const scaleY = imageHeight / ORIGINAL_IMAGE_HEIGHT; + + // 更新按钮位置 + buttonPositions.value = initialPositions.map((pos) => ({ + ...pos, + left: pos.x * scaleX + offsetX, // 按比例缩放 x 坐标并加上水平偏移 + top: pos.y * scaleY + offsetY, // 按比例缩放 y 坐标并加上垂直偏移 + })); + } +}; + onMounted(() => { getDeviceInfo(); + // 初始计算按钮位置 + updateButtonPositions(); + // 添加按钮事件监听 const posControls = document.querySelectorAll(".pos-btn"); posControls.forEach((item) => { item.addEventListener('click', (e) => { @@ -86,13 +152,59 @@ onMounted(() => { form.value[pos] += delta * (data.speed / 100); }); }); + // 监听窗口大小变化,更新按钮位置 + window.addEventListener('resize', updateButtonPositions); +}); + +onUnmounted(() => { + window.removeEventListener('resize', updateButtonPositions); }); watch(() => JSON.parse(JSON.stringify(form.value)), (newData) => { const dataToSend = convertNumbersToStringAndRemoveNulls(newData); - deviceUpdateProfile({ idDeDeviceRegistration: devId.value, ...dataToSend }).then((res) => { - console.log(res); - }); + moveJ({ + "deviceId": deviceId.value, + "terminalId": terminalId.value, + "acc": 0.8, + "vel": 0.8, + "cmds": [ + { + "jointName": "R_SHOULDER_P", + "rad": dataToSend.joint1, + "vel": 1.0 + }, + { + "jointName": "R_SHOULDER_R", + "rad": dataToSend.joint2, + "vel": 1.0 + }, + { + "jointName": "R_SHOULDER_Y", + "rad": dataToSend.joint3, + "vel": 1.0 + }, + { + "jointName": "R_ELBOW_R", + "rad": dataToSend.joint4, + "vel": 1.0 + }, + { + "jointName": "R_WRIST_P", + "rad": dataToSend.joint5, + "vel": 1.0 + }, + { + "jointName": "R_WRIST_Y", + "rad": dataToSend.joint6, + "vel": 1.0 + }, + { + "jointName": "R_WRIST_R", + "rad": dataToSend.joint7, + "vel": 1.0 + } + ] + }) }); const devId = computed(() => { @@ -131,88 +243,21 @@ const handleResets = (type) => {
-
+
姿态与位置控制
-
-
-
- X: {{ form.x.toFixed(6) }} m - - -
-
- Y: {{ form.y.toFixed(6) }} m - - -
-
- Z: {{ form.z.toFixed(6) }} m - - -
-
- RX: {{ form.rx.toFixed(6) }} deg - - -
-
- RY: {{ form.ry.toFixed(6) }} deg - - -
-
- RZ: {{ form.rz.toFixed(6) }} deg - - -
+
+
+
-
- - - - X - - - -X - - - Y - - - -Y - - - Z - - - -Z - -
关节控制 (deg)
@@ -241,6 +286,10 @@ const handleResets = (type) => { 关节6
+
+ 关节7 + +
关节步进 @@ -305,81 +354,42 @@ const handleResets = (type) => { .left { display: flex; flex-direction: column; - - .control-buttons { - margin-bottom: 20px; - - .axis-controls { - justify-content: space-around; - flex-wrap: wrap; - gap: 10px; - - .axis-group { - display: flex; - align-items: center; - gap: 5px; - min-width: 150px; - - span { - width: 80px; - text-align: center; - user-select: none; - } - - button { - width: 30px; - height: 30px; - background: #4076ff; - color: white; - border: none; - cursor: pointer; - font-size: 16px; - border-radius: 4px; - display: flex; - align-items: center; - justify-content: center; - } - - .rotation svg { - transform-origin: center; - } - - .turn-up { - transform: rotate(0deg); - } - - .turn-bottom { - transform: rotate(180deg); - } - - .turn-left { - transform: rotate(-90deg); - } - - .turn-right { - transform: rotate(90deg); - } - - .turn-lb { - transform: rotate(-135deg); - } - - .turn-rb { - transform: rotate(135deg); - } - } - } - } + position: relative; .coordinate-system { flex: 1; display: flex; justify-content: center; align-items: center; + position: relative; + background-color: #FFF; + background-image: url('@/assets/images/arm.png'); + background-size: contain; + background-position: center; + background-repeat: no-repeat; - .coordinate-svg { - background: #f5f7fa; - border-radius: 4px; + .control-buttons { + position: absolute; + width: 100%; + height: 100%; + top: 0; + left: 0; + + .pos-btn { + position: absolute; + width: 40px; + height: 40px; + background: #4076ff; + color: white; + border: none; + cursor: pointer; + font-size: 16px; + border-radius: 4px; + display: flex; + align-items: center; + justify-content: center; + transform: translate(-50%, -50%); /* 按钮中心对齐坐标 */ + } } } }