-
This commit is contained in:
+13
-4
@@ -1128,7 +1128,7 @@ def api_arm_camera_refresh():
|
|||||||
return resp
|
return resp
|
||||||
return "", 404
|
return "", 404
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.error(f"arm_refresh 失败: {ex}")
|
logger.info(f"arm_refresh 不可用: {ex}")
|
||||||
return "", 404
|
return "", 404
|
||||||
|
|
||||||
|
|
||||||
@@ -1160,7 +1160,7 @@ def api_arm_camera_preview():
|
|||||||
headers={"Cache-Control": "no-cache, no-store, must-revalidate, max-age=0"},
|
headers={"Cache-Control": "no-cache, no-store, must-revalidate, max-age=0"},
|
||||||
)
|
)
|
||||||
except Exception as ex:
|
except Exception as ex:
|
||||||
logger.error(f"arm_preview 失败: {ex}")
|
logger.info(f"arm_preview 不可用: {ex}")
|
||||||
return "", 404
|
return "", 404
|
||||||
|
|
||||||
|
|
||||||
@@ -1271,8 +1271,14 @@ def api_mission_start():
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
conn = executor.connect_all()
|
conn = executor.connect_all()
|
||||||
if not conn.get("agv") or not conn.get("arm"):
|
# 当所有机械臂相关步骤都关闭时,机械臂连接为可选
|
||||||
gs.mission_report = {"error": "连接失败", "details": conn}
|
need_arm = options.get("qr_scan", True) or options.get("front_photo", True) or options.get("back_photo", True)
|
||||||
|
if not conn.get("agv"):
|
||||||
|
gs.mission_report = {"error": "AGV 连接失败", "details": conn}
|
||||||
|
gs.state = State.IDLE
|
||||||
|
return
|
||||||
|
if need_arm and not conn.get("arm"):
|
||||||
|
gs.mission_report = {"error": "机械臂连接失败,请先连接机械臂", "details": conn}
|
||||||
gs.state = State.IDLE
|
gs.state = State.IDLE
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -1409,6 +1415,9 @@ def api_mission_state():
|
|||||||
result["machine_status"] = {}
|
result["machine_status"] = {}
|
||||||
result["tasks"] = []
|
result["tasks"] = []
|
||||||
|
|
||||||
|
# 机械臂摄像头状态
|
||||||
|
result["arm_camera_opened"] = gs.arm_camera_opened
|
||||||
|
|
||||||
# 错误弹窗状态和实时网格状态
|
# 错误弹窗状态和实时网格状态
|
||||||
if hasattr(MissionExecutorV3, "_instance") and MissionExecutorV3._instance:
|
if hasattr(MissionExecutorV3, "_instance") and MissionExecutorV3._instance:
|
||||||
ex = MissionExecutorV3._instance
|
ex = MissionExecutorV3._instance
|
||||||
|
|||||||
+2
-2
@@ -7,8 +7,8 @@ import os
|
|||||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
|
|
||||||
# ========== 网络配置(集中管理所有 IP 地址 — 修改此处即可全局生效)==========
|
# ========== 网络配置(集中管理所有 IP 地址 — 修改此处即可全局生效)==========
|
||||||
AGV_HOST = "192.168.50.93"
|
AGV_HOST = "192.168.60.177"
|
||||||
ARM_HOST = "192.168.50.91"
|
ARM_HOST = "192.168.60.88"
|
||||||
|
|
||||||
# ========== AGV 参数 ==========
|
# ========== AGV 参数 ==========
|
||||||
AGV_CONFIG = {
|
AGV_CONFIG = {
|
||||||
|
|||||||
@@ -8,8 +8,9 @@ createApp({
|
|||||||
progress: 0,
|
progress: 0,
|
||||||
tasks: [],
|
tasks: [],
|
||||||
report: null,
|
report: null,
|
||||||
|
armCameraOpened: false,
|
||||||
agvPreviewUrl: API + '/api/camera/preview',
|
agvPreviewUrl: API + '/api/camera/preview',
|
||||||
armPreviewUrl: API + '/api/camera/arm_preview',
|
armPreviewUrl: '',
|
||||||
polling: null,
|
polling: null,
|
||||||
logs: [],
|
logs: [],
|
||||||
showQrModal: false,
|
showQrModal: false,
|
||||||
@@ -52,15 +53,28 @@ createApp({
|
|||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
this.poll()
|
this.poll()
|
||||||
|
this.checkArmCamera()
|
||||||
},
|
},
|
||||||
beforeUnmount() {
|
beforeUnmount() {
|
||||||
if (this.polling) clearInterval(this.polling)
|
if (this.polling) clearInterval(this.polling)
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
async checkArmCamera() {
|
||||||
|
try {
|
||||||
|
const res = await fetch(API + '/api/status')
|
||||||
|
const data = await res.json()
|
||||||
|
if (!this.armCameraOpened) {
|
||||||
|
this.armPreviewUrl = ''
|
||||||
|
} else if (!this.armPreviewUrl) {
|
||||||
|
this.armPreviewUrl = API + '/api/camera/arm_preview'
|
||||||
|
}
|
||||||
|
} catch (e) {}
|
||||||
|
},
|
||||||
poll() {
|
poll() {
|
||||||
this.refresh()
|
this.refresh()
|
||||||
this.pollLogs()
|
this.pollLogs()
|
||||||
this.polling = setInterval(() => {
|
this.polling = setInterval(() => {
|
||||||
|
this.checkArmCamera()
|
||||||
this.refresh()
|
this.refresh()
|
||||||
this.pollLogs()
|
this.pollLogs()
|
||||||
}, 2000)
|
}, 2000)
|
||||||
@@ -79,6 +93,7 @@ createApp({
|
|||||||
if (data.grid) this.missionGrid = data.grid
|
if (data.grid) this.missionGrid = data.grid
|
||||||
if (data.point_status) this.pointStatus = data.point_status
|
if (data.point_status) this.pointStatus = data.point_status
|
||||||
if (data.machine_status) this.machineStatus = data.machine_status
|
if (data.machine_status) this.machineStatus = data.machine_status
|
||||||
|
this.armCameraOpened = data.arm_camera_opened
|
||||||
|
|
||||||
// 错误弹窗
|
// 错误弹窗
|
||||||
if (data.waiting_error) {
|
if (data.waiting_error) {
|
||||||
@@ -139,6 +154,7 @@ createApp({
|
|||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
|
arm_init: this.qrScanEnabled || this.frontPhotoEnabled || this.backPhotoEnabled,
|
||||||
agv_move: this.agvMoveEnabled,
|
agv_move: this.agvMoveEnabled,
|
||||||
qr_scan: this.qrScanEnabled,
|
qr_scan: this.qrScanEnabled,
|
||||||
front_photo: this.frontPhotoEnabled,
|
front_photo: this.frontPhotoEnabled,
|
||||||
|
|||||||
@@ -176,10 +176,14 @@
|
|||||||
<div class="camera-label">🎥 AGV 摄像头</div>
|
<div class="camera-label">🎥 AGV 摄像头</div>
|
||||||
<img :src="agvPreviewUrl" @error="onAgvPreviewError" class="camera-img">
|
<img :src="agvPreviewUrl" @error="onAgvPreviewError" class="camera-img">
|
||||||
</div>
|
</div>
|
||||||
<div class="camera-box">
|
<div class="camera-box" v-if="armCameraOpened">
|
||||||
<div class="camera-label">🦾 机械臂摄像头</div>
|
<div class="camera-label">🦾 机械臂摄像头</div>
|
||||||
<img :src="armPreviewUrl" @error="onArmPreviewError" class="camera-img">
|
<img :src="armPreviewUrl" @error="onArmPreviewError" class="camera-img">
|
||||||
</div>
|
</div>
|
||||||
|
<div class="camera-box" v-else>
|
||||||
|
<div class="camera-label">🦾 机械臂摄像头</div>
|
||||||
|
<div class="camera-placeholder">未连接(机械臂未就绪)</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|||||||
@@ -246,8 +246,7 @@ class MissionExecutorV3:
|
|||||||
options = {}
|
options = {}
|
||||||
opt_arm_init = options.get("arm_init", True)
|
opt_arm_init = options.get("arm_init", True)
|
||||||
opt_agv_move = options.get("agv_move", True)
|
opt_agv_move = options.get("agv_move", True)
|
||||||
if opt_agv_move:
|
# 不强制开启arm_init,允许AGV-only模式(无机械臂)
|
||||||
opt_arm_init = True
|
|
||||||
opt_qr_scan = options.get("qr_scan", True)
|
opt_qr_scan = options.get("qr_scan", True)
|
||||||
opt_front_photo = options.get("front_photo", True)
|
opt_front_photo = options.get("front_photo", True)
|
||||||
opt_back_photo = options.get("back_photo", True)
|
opt_back_photo = options.get("back_photo", True)
|
||||||
|
|||||||
+2
-2
@@ -1,13 +1,13 @@
|
|||||||
{
|
{
|
||||||
"agv": {
|
"agv": {
|
||||||
"ip": "10.247.46.236",
|
"ip": "192.168.50.93",
|
||||||
"ssh_user": "elephant",
|
"ssh_user": "elephant",
|
||||||
"ssh_password": "Elephant",
|
"ssh_password": "Elephant",
|
||||||
"map_file": "map.yaml",
|
"map_file": "map.yaml",
|
||||||
"map_dir": "/home/elephant"
|
"map_dir": "/home/elephant"
|
||||||
},
|
},
|
||||||
"arm": {
|
"arm": {
|
||||||
"ip": "10.247.46.165",
|
"ip": "192.168.50.91",
|
||||||
"ssh_user": "pi",
|
"ssh_user": "pi",
|
||||||
"ssh_password": "elephant",
|
"ssh_password": "elephant",
|
||||||
"socket_port": 5001,
|
"socket_port": 5001,
|
||||||
|
|||||||
Reference in New Issue
Block a user