Compare commits

...

3 Commits

Author SHA1 Message Date
9715101faf feat(flow): 添加机械臂关节运动节点支持
- 在BasicNodeParams.vue中为ARM_MOVE_TO_J操作添加按钮显示逻辑
- 从设备API导入getArmJointState方法用于获取机械臂关节状态
- 实现ARM_MOVE_TO_J操作的表单验证和位置获取逻辑
- 在config.js中添加booleanOptions选项配置
- 添加机械臂关节运动节点配置,包括参数定义和属性设置
2026-08-04 10:54:53 +08:00
bffa17a6a2 Merge remote-tracking branch 'origin/lxl-dev' into lxl-dev 2026-08-04 10:39:44 +08:00
7b791bc541 refactor(camera): 重构摄像头视频流处理机制
- 移除原有的双视频元素缓冲机制,改用MediaSource API实现直接流式播放
- 新增RGB和深度图像流的状态管理系统,支持连接、实时、重连、异常状态显示
- 实现直接RGB流播放功能,通过新的getRgbStreamUrl接口获取视频流
- 添加媒体播放器管理机制,支持视频流的创建、销毁和状态维护
- 优化视频播放性能,实现缓冲区管理和实时播放同步
- 简化UI布局结构,移除单一流容器,统一使用流容器组件
- 更新WebSocket插件以支持媒体数据包解析和分发
- 增加重连机制和错误处理,提升视频流播放稳定性
- 移除lodash防抖依赖,改用原生setTimeout实现重连调度
2026-08-03 09:49:53 +08:00
3 changed files with 59 additions and 4 deletions

View File

@ -77,3 +77,11 @@ export function getAgvStatus(params) {
params: params params: params
}) })
} }
export function getArmJointState(params) {
return request({
url: '/api/arm/getJointState',
method: 'get',
params: params
})
}

View File

@ -11,7 +11,7 @@
</el-button> </el-button>
</template> </template>
<div class="form__container"> <div class="form__container">
<el-button type="primary" v-if="['AGV_MOVE_TO_POINT', 'ARM_MOVE_TO_POINT'].includes(props.data.properties.action)" size="small" @click="openRobotForm(props.data.properties.action)">获取位置</el-button> <el-button type="primary" v-if="['AGV_MOVE_TO_POINT', 'ARM_MOVE_TO_POINT', 'ARM_MOVE_TO_J'].includes(props.data.properties.action)" size="small" @click="openRobotForm(props.data.properties.action)">获取位置</el-button>
<el-form :inline="true" :model="formData" :rules="rules" ref="dynamicFormRef" label-position="top" <el-form :inline="true" :model="formData" :rules="rules" ref="dynamicFormRef" label-position="top"
label-width="auto"> label-width="auto">
<div v-for="(property, index) in formData.nodeParams" :key="index"> <div v-for="(property, index) in formData.nodeParams" :key="index">
@ -106,7 +106,7 @@ import { Plus, Minus } from '@element-plus/icons-vue'
import FormItemRecursive from '../FormItemRecursive.vue' import FormItemRecursive from '../FormItemRecursive.vue'
import { getInput } from '@/utils/flow' import { getInput } from '@/utils/flow'
import { useQuote } from './useQuote.js' import { useQuote } from './useQuote.js'
import { getArmStatus, getAgvStatus } from '@/api/device/flow' import { getArmStatus, getArmJointState, getAgvStatus } from '@/api/device/flow'
import { de } from 'element-plus/es/locale/index.mjs' import { de } from 'element-plus/es/locale/index.mjs'
const props = defineProps({ const props = defineProps({
@ -298,6 +298,30 @@ const submitRobotForm = () => {
} }
} }
}) })
} else if (robotFormAction.value === 'ARM_MOVE_TO_J') {
robotFormRef.value.validate(async (valid) => {
if (valid) {
try {
const response = await getArmJointState({
deviceId: robotForm.deviceId,
terminalId: robotForm.terminalId
})
if (response && response.data) {
const target = response.data.position || response.data.positions
if (!Array.isArray(target) || target.length === 0) {
throw new Error('机械臂未返回有效的关节位置')
}
dialogVisible.value = false
const targetParam = formData.nodeParams.find(param => param.name === 'target')
const deviceParam = formData.nodeParams.find(param => param.name === 'deviceId')
if (targetParam) targetParam.input = JSON.stringify(target)
if (deviceParam) deviceParam.input = robotForm.deviceId
}
} catch (error) {
console.error('获取机械臂关节位置失败:', error)
}
}
})
} }
} }

View File

@ -37,6 +37,11 @@ const audioOptions = () => {
}] }]
} }
const booleanOptions = () => [
{ value: false, label: '否' },
{ value: true, label: '是' }
]
const httpMethodOptions = () => { const httpMethodOptions = () => {
return [{ return [{
value: 'POST', value: 'POST',
@ -360,6 +365,24 @@ function handler(params) {
], ],
outputType: 'json' outputType: 'json'
}, },
{
icon: videoSvg,
name: "机械臂关节运动",
type: "serviceNode",
desc: "通过关节空间插值运动到目标关节位置",
action: 'ARM_MOVE_TO_J',
nodeType: 'EDGE',
nodeParams: [
{ name: "deviceId", type: "input", input: "", disabled: true },
{ name: "target", type: "input", input: "[0, 0, 0, 0, 0, 0]", disabled: true },
{ name: "velocity", type: "input", componentType: 'number', max: 5, step: 0.1, input: 0.5, disabled: true },
{ name: "acceleration", type: "input", componentType: 'number', max: 5, step: 0.1, input: 1, disabled: true },
{ name: "blendRadius", type: "input", componentType: 'number', max: 5, step: 0.01, input: 0, required: false, disabled: true },
{ name: "jointVelocityLimits", type: "input", input: "", required: false, disabled: true },
{ name: "asynchronous", type: "input", input: false, componentType: 'select', selectOptions: booleanOptions(), required: false, disabled: true }
],
outputType: 'json'
},
{ {
icon: cameraSvg, icon: cameraSvg,
name: "开始监听报警事件", name: "开始监听报警事件",