机型配置
This commit is contained in:
@@ -209,48 +209,6 @@
|
|||||||
"poses": []
|
"poses": []
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
|
||||||
"id": "m_3_4",
|
|
||||||
"row": 3,
|
|
||||||
"col": 4,
|
|
||||||
"front": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
"back": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "m_3_3",
|
|
||||||
"row": 3,
|
|
||||||
"col": 3,
|
|
||||||
"front": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
},
|
|
||||||
"back": {
|
|
||||||
"coords": [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
],
|
|
||||||
"poses": []
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"id": "m_0_1",
|
"id": "m_0_1",
|
||||||
"row": 0,
|
"row": 0,
|
||||||
@@ -334,5 +292,215 @@
|
|||||||
],
|
],
|
||||||
"poses": []
|
"poses": []
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_0_3",
|
||||||
|
"row": 0,
|
||||||
|
"col": 3,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_0_4",
|
||||||
|
"row": 0,
|
||||||
|
"col": 4,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_0_5",
|
||||||
|
"row": 0,
|
||||||
|
"col": 5,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_1_3",
|
||||||
|
"row": 1,
|
||||||
|
"col": 3,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_1_5",
|
||||||
|
"row": 1,
|
||||||
|
"col": 5,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_1_4",
|
||||||
|
"row": 1,
|
||||||
|
"col": 4,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_2_3",
|
||||||
|
"row": 2,
|
||||||
|
"col": 3,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_2_1",
|
||||||
|
"row": 2,
|
||||||
|
"col": 1,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_2_4",
|
||||||
|
"row": 2,
|
||||||
|
"col": 4,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "m_2_5",
|
||||||
|
"row": 2,
|
||||||
|
"col": 5,
|
||||||
|
"front": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
},
|
||||||
|
"back": {
|
||||||
|
"coords": [
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0
|
||||||
|
],
|
||||||
|
"poses": []
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"rows": 2,
|
"rows": 4,
|
||||||
"cols": 2,
|
"cols": 6,
|
||||||
"grid": [],
|
"grid": [],
|
||||||
"positions": [
|
"positions": [
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ const app = createApp({
|
|||||||
models: [],
|
models: [],
|
||||||
selectedModelId: null,
|
selectedModelId: null,
|
||||||
newModelName: '',
|
newModelName: '',
|
||||||
|
newModelId: null,
|
||||||
newModelDesc: '',
|
newModelDesc: '',
|
||||||
newModelNotes: '',
|
newModelNotes: '',
|
||||||
newPoseForm: {}, // 机型配置:新建姿态的表单
|
newPoseForm: {}, // 机型配置:新建姿态的表单
|
||||||
@@ -211,6 +212,7 @@ const app = createApp({
|
|||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
name: this.newModelName || '型号_' + (this.models.length + 1),
|
name: this.newModelName || '型号_' + (this.models.length + 1),
|
||||||
|
id: this.newModelId,
|
||||||
description: this.newModelDesc || '',
|
description: this.newModelDesc || '',
|
||||||
notes: this.newModelNotes || '',
|
notes: this.newModelNotes || '',
|
||||||
serial_prefix: this.newModelSerial || ''
|
serial_prefix: this.newModelSerial || ''
|
||||||
@@ -831,6 +833,101 @@ const app = createApp({
|
|||||||
onPreviewError(e) {
|
onPreviewError(e) {
|
||||||
e.target.style.display = 'none'
|
e.target.style.display = 'none'
|
||||||
},
|
},
|
||||||
|
// === 姿态角度控制(机型配置 Tab) ===
|
||||||
|
async refreshPoseAngles(modelId, poseId) {
|
||||||
|
// 获取当前机械臂角度,填入姿态,保存到后端
|
||||||
|
if (!this.armConnected) {
|
||||||
|
alert('机械臂未连接')
|
||||||
|
return
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
var res = await fetch(API + '/api/arm/get_angles')
|
||||||
|
var data = await res.json()
|
||||||
|
if (data.ok && data.angles) {
|
||||||
|
// Find the pose and update
|
||||||
|
var model = this.models.find(m => m.id === modelId)
|
||||||
|
if (model) {
|
||||||
|
var pose = model.poses.find(p => p.id === poseId)
|
||||||
|
if (pose) {
|
||||||
|
pose.arm_angles = [...data.angles]
|
||||||
|
// Save to backend
|
||||||
|
await fetch(API + '/api/models/' + modelId + '/poses/' + poseId, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ arm_angles: pose.arm_angles })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error('refreshPoseAngles error:', e)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async applyPoseAngles(modelId, poseId) {
|
||||||
|
// 调整机械臂到姿态的角度
|
||||||
|
var model = this.models.find(m => m.id === modelId)
|
||||||
|
if (model) {
|
||||||
|
var pose = model.poses.find(p => p.id === poseId)
|
||||||
|
if (pose && pose.arm_angles) {
|
||||||
|
try {
|
||||||
|
await fetch(API + '/api/arm/set_angles', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ angles: pose.arm_angles, speed: 500 })
|
||||||
|
})
|
||||||
|
} catch (e) {
|
||||||
|
console.error('applyPoseAngles error:', e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async adjustPoseAngle(modelId, poseId, jointIndex, delta) {
|
||||||
|
// 微调姿态角度,并实时调整机械臂
|
||||||
|
var model = this.models.find(m => m.id === modelId)
|
||||||
|
if (model) {
|
||||||
|
var pose = model.poses.find(p => p.id === poseId)
|
||||||
|
if (pose) {
|
||||||
|
if (!pose.arm_angles) pose.arm_angles = [0, 0, 0, 0, 0, 0]
|
||||||
|
pose.arm_angles[jointIndex] = (pose.arm_angles[jointIndex] || 0) + delta
|
||||||
|
// Save to backend
|
||||||
|
await fetch(API + '/api/models/' + modelId + '/poses/' + poseId, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ arm_angles: pose.arm_angles })
|
||||||
|
})
|
||||||
|
// Move arm
|
||||||
|
await fetch(API + '/api/arm/set_angle', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ joint: 'J' + (jointIndex + 1), angle: pose.arm_angles[jointIndex] })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async updatePoseAngleAndMove(modelId, poseId, jointIndex, value) {
|
||||||
|
// 更新姿态角度(输入框),并实时调整机械臂
|
||||||
|
var model = this.models.find(m => m.id === modelId)
|
||||||
|
if (model) {
|
||||||
|
var pose = model.poses.find(p => p.id === poseId)
|
||||||
|
if (pose) {
|
||||||
|
if (!pose.arm_angles) pose.arm_angles = [0, 0, 0, 0, 0, 0]
|
||||||
|
pose.arm_angles[jointIndex] = parseFloat(value) || 0
|
||||||
|
// Save to backend
|
||||||
|
await fetch(API + '/api/models/' + modelId + '/poses/' + poseId, {
|
||||||
|
method: 'PUT',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ arm_angles: pose.arm_angles })
|
||||||
|
})
|
||||||
|
// Move arm
|
||||||
|
await fetch(API + '/api/arm/set_angle', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({ joint: 'J' + (jointIndex + 1), angle: pose.arm_angles[jointIndex] })
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// === AGV 控制 ===
|
// === AGV 控制 ===
|
||||||
async refreshAgvPosition() {
|
async refreshAgvPosition() {
|
||||||
if (!this.agvConnected) return
|
if (!this.agvConnected) return
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
<title>设置 - AGV 拍摄系统</title>
|
<title>设置 - AGV 拍摄系统</title>
|
||||||
<link rel="stylesheet" href="/static/css/style.css?v=20260514l">
|
<link rel="stylesheet" href="/static/css/style.css?v=20260514m">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id="app">
|
<div id="app">
|
||||||
@@ -78,6 +78,10 @@
|
|||||||
<label>机型名称</label>
|
<label>机型名称</label>
|
||||||
<input type="text" v-model="newModelName" placeholder="例如:SMT-A" style="width:100%;padding:8px;border:1px solid #2a3441;border-radius:4px">
|
<input type="text" v-model="newModelName" placeholder="例如:SMT-A" style="width:100%;padding:8px;border:1px solid #2a3441;border-radius:4px">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="form-group" style="flex:1">
|
||||||
|
<label>机型ID(数值)</label>
|
||||||
|
<input type="number" v-model.number="newModelId" placeholder="例如:100" style="width:100%;padding:8px;border:1px solid #2a3441;border-radius:4px">
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row">
|
<div class="form-row">
|
||||||
<div class="form-group" style="flex:1">
|
<div class="form-group" style="flex:1">
|
||||||
@@ -121,14 +125,20 @@
|
|||||||
<button class="btn btn-danger btn-small" @click="deletePose(m.id, pose.id)">删除</button>
|
<button class="btn btn-danger btn-small" @click="deletePose(m.id, pose.id)">删除</button>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;gap:8px;flex-wrap:wrap">
|
<div style="display:flex;gap:8px;flex-wrap:wrap">
|
||||||
<div v-for="j in 6" :key="j" style="display:flex;align-items:center;gap:4px">
|
<div v-for="j in 6" :key="j" style="display:flex;align-items:center;gap:4px">
|
||||||
<span style="font-size:12px;color:#9aa0a6">J{% raw %}{ j }{% endraw %}</span>
|
<span style="font-size:12px;color:#9aa0a6">J{% raw %}{ j }{% endraw %}</span>
|
||||||
<input type="number" step="0.1"
|
<button class="btn btn-small" @click="adjustPoseAngle(m.id, pose.id, j-1, -0.5)" style="width:24px;height:24px;padding:0;font-size:12px">-</button>
|
||||||
|
<input type="number" step="0.5"
|
||||||
:value="pose.arm_angles && pose.arm_angles[j-1] !== undefined ? pose.arm_angles[j-1] : 0"
|
:value="pose.arm_angles && pose.arm_angles[j-1] !== undefined ? pose.arm_angles[j-1] : 0"
|
||||||
@change="updatePoseAngle(m.id, pose.id, j-1, $event.target.value)"
|
@change="updatePoseAngleAndMove(m.id, pose.id, j-1, $event.target.value)"
|
||||||
style="width:70px;padding:4px;border:1px solid #2a3441;border-radius:4px">
|
style="width:70px;padding:4px;border:1px solid #2a3441;border-radius:4px">
|
||||||
|
<button class="btn btn-small" @click="adjustPoseAngle(m.id, pose.id, j-1, 0.5)" style="width:24px;height:24px;padding:0;font-size:12px">+</button>
|
||||||
<span style="font-size:11px;color:#999">°</span>
|
<span style="font-size:11px;color:#999">°</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="margin-top:8px;display:flex;gap:8px">
|
||||||
|
<button class="btn btn-secondary btn-small" @click="refreshPoseAngles(m.id, pose.id)">🔄 刷新角度</button>
|
||||||
|
<button class="btn btn-primary btn-small" @click="applyPoseAngles(m.id, pose.id)">✅ 应用角度</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 添加正面姿态 -->
|
<!-- 添加正面姿态 -->
|
||||||
@@ -163,14 +173,20 @@
|
|||||||
<button class="btn btn-danger btn-small" @click="deletePose(m.id, pose.id)">删除</button>
|
<button class="btn btn-danger btn-small" @click="deletePose(m.id, pose.id)">删除</button>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;gap:8px;flex-wrap:wrap">
|
<div style="display:flex;gap:8px;flex-wrap:wrap">
|
||||||
<div v-for="j in 6" :key="j" style="display:flex;align-items:center;gap:4px">
|
<div v-for="j in 6" :key="j" style="display:flex;align-items:center;gap:4px">
|
||||||
<span style="font-size:12px;color:#9aa0a6">J{% raw %}{ j }{% endraw %}</span>
|
<span style="font-size:12px;color:#9aa0a6">J{% raw %}{ j }{% endraw %}</span>
|
||||||
<input type="number" step="0.1"
|
<button class="btn btn-small" @click="adjustPoseAngle(m.id, pose.id, j-1, -0.5)" style="width:24px;height:24px;padding:0;font-size:12px">-</button>
|
||||||
|
<input type="number" step="0.5"
|
||||||
:value="pose.arm_angles && pose.arm_angles[j-1] !== undefined ? pose.arm_angles[j-1] : 0"
|
:value="pose.arm_angles && pose.arm_angles[j-1] !== undefined ? pose.arm_angles[j-1] : 0"
|
||||||
@change="updatePoseAngle(m.id, pose.id, j-1, $event.target.value)"
|
@change="updatePoseAngleAndMove(m.id, pose.id, j-1, $event.target.value)"
|
||||||
style="width:70px;padding:4px;border:1px solid #2a3441;border-radius:4px">
|
style="width:70px;padding:4px;border:1px solid #2a3441;border-radius:4px">
|
||||||
|
<button class="btn btn-small" @click="adjustPoseAngle(m.id, pose.id, j-1, 0.5)" style="width:24px;height:24px;padding:0;font-size:12px">+</button>
|
||||||
<span style="font-size:11px;color:#999">°</span>
|
<span style="font-size:11px;color:#999">°</span>
|
||||||
</div>
|
</div>
|
||||||
|
<div style="margin-top:8px;display:flex;gap:8px">
|
||||||
|
<button class="btn btn-secondary btn-small" @click="refreshPoseAngles(m.id, pose.id)">🔄 刷新角度</button>
|
||||||
|
<button class="btn btn-primary btn-small" @click="applyPoseAngles(m.id, pose.id)">✅ 应用角度</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<!-- 添加背面姿态 -->
|
<!-- 添加背面姿态 -->
|
||||||
@@ -439,7 +455,6 @@
|
|||||||
<button @mousedown="jogStart(j-1, 1)" @mouseup="jogStop(j-1)" @mouseleave="jogStop(j-1)">▶</button>
|
<button @mousedown="jogStart(j-1, 1)" @mouseup="jogStop(j-1)" @mouseleave="jogStop(j-1)">▶</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div class="btn-row">
|
<div class="btn-row">
|
||||||
<button class="btn btn-primary" @click="refreshAngles">🔄 刷新角度</button>
|
<button class="btn btn-primary" @click="refreshAngles">🔄 刷新角度</button>
|
||||||
<button class="btn btn-secondary" @click="applyAngles">✅ 应用角度</button>
|
<button class="btn btn-secondary" @click="applyAngles">✅ 应用角度</button>
|
||||||
@@ -505,7 +520,7 @@
|
|||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="/static/js/vue3.global.prod.js?v=20260514l"></script>
|
<script src="/static/js/vue3.global.prod.js?v=20260514m"></script>
|
||||||
<script src="/static/js/setting.js?v=20260514l"></script>
|
<script src="/static/js/setting.js?v=20260514m"></script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user