This commit is contained in:
ywb
2026-05-20 22:15:03 +08:00
parent a5be69bfaa
commit a5aaddc4fc
3 changed files with 155 additions and 23 deletions
+75 -9
View File
@@ -9,7 +9,8 @@ createApp({
missionConfig: { rows: 3, cols: 3, grid: [], machines: [] },
selectedMachine: null,
sequence: [],
poseForm: { name: '', photo_type: 'front', description: '' },
poseForm: {},
newPoseForm: {},
// 地图
mapForm: { map_dir: '/home/elephant/agv_pro_ros2/src/agv_pro_navigation2/map/', map_file: 'map.yaml' },
mapMsg: '',
@@ -45,6 +46,7 @@ createApp({
agvMoveInterval: null,
agvCameraUrl: API + '/api/camera/refresh',
agvCameraTimer: null,
armCameraTimer: null,
// 机型展开
expandedModelId: null,
showAddModelModal: false,
@@ -61,6 +63,11 @@ createApp({
this.refreshAngles()
this.loadQrConfigs()
this.nav2Timer = setInterval(this.refreshNavStatus, 3000)
// 机械臂摄像头自动刷新(每2秒)
this.armCameraUrl = API + '/api/camera/arm_refresh?t=' + Date.now()
this.armCameraTimer = setInterval(() => {
this.armCameraUrl = API + '/api/camera/arm_refresh?t=' + Date.now()
}, 2000)
},
computed: {
hasQr() {
@@ -90,6 +97,7 @@ createApp({
beforeUnmount() {
Object.values(this.jogIntervals).forEach(i => clearInterval(i))
if (this.agvCameraTimer) clearInterval(this.agvCameraTimer)
if (this.armCameraTimer) { clearInterval(this.armCameraTimer); this.armCameraTimer = null }
if (this.nav2Timer) clearInterval(this.nav2Timer)
},
methods: {
@@ -280,30 +288,88 @@ createApp({
await this.loadAllModels()
},
// === 姿态管理(属于机型)===
async addPose(modelId) {
const form = this.poseForm[modelId]
if (!form) return
async addPose(modelId, type, name) {
if (!name) name = '姿态' + (((this.getModel(modelId)?.poses?.length) || 0) + 1)
await fetch(API + '/api/models/poses/add', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model_id: modelId,
name: form.name || '姿态' + ((this.getModel(modelId)?.poses?.length || 0) + 1),
photo_type: form.photo_type,
name: name,
photo_type: type || 'front',
arm_angles: this.currentAngles,
speed: 500,
description: form.description || ''
description: ''
})
})
await this.loadAllModels()
form.name = ''
form.description = ''
const key = modelId + '_' + (type || 'front')
if (this.newPoseForm[key] !== undefined) this.newPoseForm[key] = ''
},
async deletePose(modelId, poseId) {
if (!confirm('确定删除该姿态?')) return
await fetch(API + '/api/models/' + modelId + '/poses/' + poseId, { method: 'DELETE' })
await this.loadAllModels()
},
async refreshPoseAngles(modelId, poseId) {
if (!this.armConnected) { alert('机械臂未连接'); return }
try {
const res = await fetch(API + '/api/arm/get_angles')
const data = await res.json()
if (data.ok && data.angles) {
const model = this.getModel(modelId)
if (model && model.poses) {
const pose = model.poses.find(p => p.id === poseId)
if (pose) {
// Update local immediately for reactive UI
pose.arm_angles = [...data.angles]
// Persist to backend
await fetch(API + '/api/models/' + modelId + '/poses/' + poseId, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ arm_angles: data.angles })
})
await this.loadAllModels()
}
}
}
} catch (e) { alert('刷新角度失败: ' + e.message) }
},
async applyPoseAngles(modelId, poseId) {
const model = this.getModel(modelId)
if (!model || !model.poses) return
const pose = model.poses.find(p => p.id === poseId)
if (!pose || !pose.arm_angles) { alert('无效的姿态数据'); return }
try {
const res = await fetch(API + '/api/arm/set_angles', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ angles: pose.arm_angles, speed: 50 })
})
const data = await res.json()
if (data.ok) { alert('姿态已应用到机械臂') }
else { alert('应用失败: ' + (data.error || '未知错误')) }
} catch (e) { alert('应用姿态失败: ' + e.message) }
},
adjustPoseAngle(modelId, poseId, jointIdx, delta) {
const model = this.getModel(modelId)
if (!model || !model.poses) return
const pose = model.poses.find(p => p.id === poseId)
if (!pose) return
if (!pose.arm_angles) pose.arm_angles = [0,0,0,0,0,0]
if (!pose.arm_angles[jointIdx]) pose.arm_angles[jointIdx] = 0
pose.arm_angles[jointIdx] = Math.round((pose.arm_angles[jointIdx] + delta) * 10) / 10
this.setAngle(jointIdx, pose.arm_angles[jointIdx])
},
async updatePoseAngleAndMove(modelId, poseId, jointIdx, value) {
const model = this.getModel(modelId)
if (!model || !model.poses) return
const pose = model.poses.find(p => p.id === poseId)
if (!pose) return
if (!pose.arm_angles) pose.arm_angles = [0,0,0,0,0,0]
pose.arm_angles[jointIdx] = parseFloat(value) || 0
await this.setAngle(jointIdx, pose.arm_angles[jointIdx])
},
getModel(id) {
return this.models.find(m => m.id === id)
},