增加机型配置

This commit is contained in:
ywb
2026-05-14 22:22:30 +08:00
parent 94c1043f4d
commit fdb88b21a1
2 changed files with 128 additions and 82 deletions
+42
View File
@@ -292,5 +292,47 @@
], ],
"poses": [] "poses": []
} }
},
{
"id": "m_1_1",
"row": 1,
"col": 1,
"front": {
"coords": [
0,
0,
0
],
"poses": []
},
"back": {
"coords": [
0,
0,
0
],
"poses": []
}
},
{
"id": "m_1_0",
"row": 1,
"col": 0,
"front": {
"coords": [
0,
0,
0
],
"poses": []
},
"back": {
"coords": [
0,
0,
0
],
"poses": []
}
} }
] ]
+42 -38
View File
@@ -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=20260514e"> <link rel="stylesheet" href="/static/css/style.css?v=20260514l">
</head> </head>
<body> <body>
<div id="app"> <div id="app">
@@ -20,8 +20,8 @@
<!-- Tabs --> <!-- Tabs -->
<div class="tabs"> <div class="tabs">
<button class="tab" :class="{active: tab === 'map'}" @click="tab = 'map'">🗺️ 地图</button> <button class="tab" :class="{active: tab === 'map'}" @click="tab = 'map'">🗺️ 地图</button>
<button class="tab" :class="{active: tab === \'model\'}" @click="tab = \'model\'">📦 机型配置</button>
<button class="tab" :class="{active: tab === 'mission'}" @click="tab = 'mission'">🎯 任务配置</button> <button class="tab" :class="{active: tab === 'mission'}" @click="tab = 'mission'">🎯 任务配置</button>
<button class="tab" :class="{active: tab === 'model'}" @click="tab = 'model'">📦 机型配置</button>
<button class="tab" :class="{active: tab === 'arm'}" @click="tab = 'arm'">🤖 机械臂</button> <button class="tab" :class="{active: tab === 'arm'}" @click="tab = 'arm'">🤖 机械臂</button>
<button class="tab" :class="{active: tab === 'agv'}" @click="tab = 'agv'">🚗 AGV控制</button> <button class="tab" :class="{active: tab === 'agv'}" @click="tab = 'agv'">🚗 AGV控制</button>
</div> </div>
@@ -64,70 +64,69 @@
</section> </section>
</div> </div>
<!-- ========== 机型配置 Tab ========== --> <!-- ========== 机型配置 Tab ========== -->
<div v-if="tab === 'model'"> <div v-if="tab === 'model'">
<section class="card"> <section class="card">
<h2>📦 机型配置</h2> <h2>📦 机型配置</h2>
<!-- 添加新机型 --> <!-- 添加新机型 -->
<div class="form-section" style="background:#f5f5f5;padding:16px;border-radius:8px;margin-bottom:20px"> <div class="form-section" style="background:#1a2332;padding:16px;border-radius:8px;margin-bottom:20px">
<h3 style="margin-top:0">添加新机型</h3> <h3 style="margin-top:0">添加新机型</h3>
<div class="form-row"> <div class="form-row">
<div class="form-group" style="flex:1"> <div class="form-group" style="flex:1">
<label>机型名称</label> <label>机型名称</label>
<input type="text" v-model="newModelName" placeholder="例如:SMT-A" style="width:100%;padding:8px;border:1px solid #ddd;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> </div>
<div class="form-row"> <div class="form-row">
<div class="form-group" style="flex:1"> <div class="form-group" style="flex:1">
<label>描述</label> <label>描述</label>
<input type="text" v-model="newModelDesc" placeholder="描述信息" style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px"> <input type="text" v-model="newModelDesc" placeholder="描述信息" style="width:100%;padding:8px;border:1px solid #2a3441;border-radius:4px">
</div> </div>
<div class="form-group" style="flex:1"> <div class="form-group" style="flex:1">
<label>备注</label> <label>备注</label>
<input type="text" v-model="newModelNotes" placeholder="备注信息" style="width:100%;padding:8px;border:1px solid #ddd;border-radius:4px"> <input type="text" v-model="newModelNotes" placeholder="备注信息" style="width:100%;padding:8px;border:1px solid #2a3441;border-radius:4px">
</div> </div>
</div> </div>
<button class="btn btn-primary" @click="addModel" style="margin-top:8px"> 添加机型</button> <button class="btn btn-primary" @click="addModel" style="margin-top:8px"> 添加机型</button>
</div> </div>
<!-- 机型列表 --> <!-- 机型列表 -->
<div v-if="models.length === 0" style="text-align:center;color:#888;padding:40px"> <div v-if="models.length === 0" style="text-align:center;color:#9aa0a6;padding:40px">
<p>暂无机型配置,请添加新机型</p> <p>暂无机型配置,请添加新机型</p>
</div> </div>
<div v-else> <div v-else>
<div v-for="m in models" :key="m.id" style="border:1px solid #ddd;border-radius:8px;margin-bottom:20px;overflow:hidden"> <div v-for="m in models" :key="m.id" style="border:1px solid #2a3441;border-radius:8px;margin-bottom:20px;overflow:hidden">
<!-- 机型头部 --> <!-- 机型头部 -->
<div style="background:#e8f4e8;padding:12px 16px;display:flex;justify-content:space-between;align-items:center"> <div style="background:#1b3a2f;padding:12px 16px;display:flex;justify-content:space-between;align-items:center">
<div> <div>
<strong style="font-size:16px">{{ m.name }}</strong> <strong style="font-size:16px">{% raw %}{ m.name }{% endraw %}</strong>
<span style="margin-left:12px;color:#666;font-size:13px">ID: {{ m.id }}</span> <span style="margin-left:12px;color:#9aa0a6;font-size:13px">ID: {% raw %}{ m.id }{% endraw %}</span>
<span v-if="m.description" style="margin-left:12px;color:#888;font-size:13px">{{ m.description }}</span> <span v-if="m.description" style="margin-left:12px;color:#9aa0a6;font-size:13px">{% raw %}{ m.description }{% endraw %}</span>
<span v-if="m.notes" style="margin-left:12px;color:#aaa;font-size:13px">【{{ m.notes }}】</span> <span v-if="m.notes" style="margin-left:12px;color:#9aa0a6;font-size:13px">【{% raw %}{ m.notes }{% endraw %}】</span>
</div> </div>
<div style="display:flex;gap:8px"> <div style="display:flex;gap:8px">
<button class="btn btn-danger btn-small" @click="deleteModel(m.id)">🗑️ 删除机型</button> <button class="btn btn-danger btn-small" @click="deleteModel(m.id)">🗑️ 删除机型</button>
</div> </div>
</div> </div>
<!-- 姿态配置 -->
<div style="padding:16px">
<!-- 正面姿态 --> <!-- 正面姿态 -->
<div style="margin-bottom:20px"> <div style="padding:16px;background:#0f1923">
<h4 style="margin:0 0 12px 0;color:#1976d2">🔵 正面姿态</h4> <h4 style="margin:0 0 12px 0;color:#388e3c">🟢 正面姿态</h4>
<div v-for="pose in m.poses.filter(p => p.photo_type === 'front')" :key="pose.id" style="background:#f8f8f8;padding:12px;border-radius:6px;margin-bottom:8px"> <div v-for="pose in m.poses.filter(p => p.photo_type === 'front')" :key="pose.id" style="background:#0f1923;padding:12px;border-radius:6px;margin-bottom:8px">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px"> <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
<strong>{{ pose.name or '正面姿态' }}</strong> <strong>{% raw %}{ pose.name or '正面姿态' }{% endraw %}</strong>
<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:#666">J{{j}}</span> <span style="font-size:12px;color:#9aa0a6">J{% raw %}{ j }{% endraw %}</span>
<input type="number" step="0.1" <input type="number" step="0.1"
: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, )" @change="updatePoseAngle(m.id, pose.id, j-1, $event.target.value)"
style="width:70px;padding:4px;border:1px solid #ddd;border-radius:4px"> style="width:70px;padding:4px;border:1px solid #2a3441;border-radius:4px">
<span style="font-size:11px;color:#999">°</span> <span style="font-size:11px;color:#999">°</span>
</div> </div>
</div> </div>
@@ -137,13 +136,18 @@
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap"> <div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap">
<input type="text" v-model="newPoseForm[m.id + '_front']" <input type="text" v-model="newPoseForm[m.id + '_front']"
placeholder="姿态名称(如:取料)" placeholder="姿态名称(如:取料)"
style="flex:1;min-width:120px;padding:6px;border:1px solid #ddd;border-radius:4px"> style="flex:1;min-width:120px;padding:6px;border:1px solid #2a3441;border-radius:4px">
<button class="btn btn-secondary btn-small" @click="addPose(m.id, 'front', newPoseForm[m.id + '_front'])"> 添加正面姿态(当前角度)</button> <button class="btn btn-secondary btn-small" @click="addPose(m.id, 'front', newPoseForm[m.id + '_front'])"> 添加正面姿态(当前角度)</button>
</div> </div>
<div style="margin-top:6px;font-size:12px;color:#888"> <div style="margin-top:6px;font-size:12px;color:#9aa0a6">
当前机械臂角度: 当前机械臂角度:
<span v-if="currentAngles.length"> <span v-if="currentAngles && currentAngles.length">
J1={{ currentAngles[0]?.toFixed(1) }}° J2={{ currentAngles[1]?.toFixed(1) }}° J3={{ currentAngles[2]?.toFixed(1) }}° J4={{ currentAngles[3]?.toFixed(1) }}° J5={{ currentAngles[4]?.toFixed(1) }}° J6={{ currentAngles[5]?.toFixed(1) } J{% raw %}{ currentAngles[0] ? currentAngles[0].toFixed(1) : '—' }{% endraw %
J{% raw %}{ currentAngles[1] ? currentAngles[1].toFixed(1) : '—' }{% endraw %}°
J{% raw %}{ currentAngles[2] ? currentAngles[2].toFixed(1) : '—' }{% endraw %}°
J{% raw %}{ currentAngles[3] ? currentAngles[3].toFixed(1) : '—' }{% endraw %}°
J{% raw %}{ currentAngles[4] ? currentAngles[4].toFixed(1) : '—' }{% endraw %}°
J{% raw %}{ currentAngles[5] ? currentAngles[5].toFixed(1) : '—' }{% endraw %}°
</span> </span>
<span v-else>(未连接机械臂)</span> <span v-else>(未连接机械臂)</span>
</div> </div>
@@ -151,20 +155,20 @@
</div> </div>
<!-- 背面姿态 --> <!-- 背面姿态 -->
<div> <div style="padding:16px;background:#0f19238f8">
<h4 style="margin:0 0 12px 0;color:#d32f2f">🔴 背面姿态</h4> <h4 style="margin:0 0 12px 0;color:#d32f2f">🔴 背面姿态</h4>
<div v-for="pose in m.poses.filter(p => p.photo_type === 'back')" :key="pose.id" style="background:#fff0f0;padding:12px;border-radius:6px;margin-bottom:8px"> <div v-for="pose in m.poses.filter(p => p.photo_type === 'back')" :key="pose.id" style="background:#0f1923;padding:12px;border-radius:6px;margin-bottom:8px">
<div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px"> <div style="display:flex;justify-content:space-between;align-items:center;margin-bottom:8px">
<strong>{{ pose.name or '背面姿态' }}</strong> <strong>{% raw %}{ pose.name or '背面姿态' }{% endraw %}</strong>
<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:#666">J{{j}}</span> <span style="font-size:12px;color:#9aa0a6">J{% raw %}{ j }{% endraw %}</span>
<input type="number" step="0.1" <input type="number" step="0.1"
: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, )" @change="updatePoseAngle(m.id, pose.id, j-1, $event.target.value)"
style="width:70px;padding:4px;border:1px solid #ddd;border-radius:4px"> style="width:70px;padding:4px;border:1px solid #2a3441;border-radius:4px">
<span style="font-size:11px;color:#999">°</span> <span style="font-size:11px;color:#999">°</span>
</div> </div>
</div> </div>
@@ -174,18 +178,18 @@
<div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap"> <div style="display:flex;gap:8px;align-items:center;flex-wrap:wrap">
<input type="text" v-model="newPoseForm[m.id + '_back']" <input type="text" v-model="newPoseForm[m.id + '_back']"
placeholder="姿态名称(如:放料)" placeholder="姿态名称(如:放料)"
style="flex:1;min-width:120px;padding:6px;border:1px solid #ddd;border-radius:4px"> style="flex:1;min-width:120px;padding:6px;border:1px solid #2a3441;border-radius:4px">
<button class="btn btn-secondary btn-small" @click="addPose(m.id, 'back', newPoseForm[m.id + '_back'])"> 添加背面姿态(当前角度)</button> <button class="btn btn-secondary btn-small" @click="addPose(m.id, 'back', newPoseForm[m.id + '_back'])"> 添加背面姿态(当前角度)</button>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</div>
</section> </section>
</div> </div>
<!-- ========== 任务配置 Tab ========== -->
<!-- ========== 任务配置 Tab ========== -->
<div v-if="tab === 'mission'"> <div v-if="tab === 'mission'">
<!-- 上:网格配置 --> <!-- 上:网格配置 -->
@@ -399,7 +403,7 @@
<div class="hint" style="margin-top:4px"> <div class="hint" style="margin-top:4px">
当前: ({% raw %}{{ pointEditor.x.toFixed(2) }}{% endraw %}, {% raw %}{{ pointEditor.y.toFixed(2) }}{% endraw %}, {% raw %}{{ pointEditor.yaw.toFixed(2) }}{% endraw %}) 当前: ({% raw %}{{ pointEditor.x.toFixed(2) }}{% endraw %}, {% raw %}{{ pointEditor.y.toFixed(2) }}{% endraw %}, {% raw %}{{ pointEditor.yaw.toFixed(2) }}{% endraw %})
</div> </div>
<div class="hint" style="margin-top:6px;font-size:12px;color:#888"> <div class="hint" style="margin-top:6px;font-size:12px;color:#9aa0a6">
💡 此点位服务于: {% raw %}{{ getPointOwnerLabel(editingPoint.pointRow, editingPoint.col).split('·')[1] || '无' }}{% endraw %} 💡 此点位服务于: {% raw %}{{ getPointOwnerLabel(editingPoint.pointRow, editingPoint.col).split('·')[1] || '无' }}{% endraw %}
</div> </div>
</div> </div>
@@ -501,7 +505,7 @@
</main> </main>
</div> </div>
<script src="/static/js/vue3.global.prod.js?v=20260513b"></script> <script src="/static/js/vue3.global.prod.js?v=20260514l"></script>
<script src="/static/js/setting.js?v=20260514k"></script> <script src="/static/js/setting.js?v=20260514l"></script>
</body> </body>
</html> </html>