任务执行
This commit is contained in:
+67
-4
@@ -53,6 +53,7 @@ class GlobalState:
|
||||
self.machines_config = [] # 机器配置(每台机器的正面/背面点位+姿态)
|
||||
self.qr_config = [] # 二维码配置(独立点位列表)
|
||||
self.navigator = None # Nav2Navigator 实例
|
||||
self.error_msg = "" # 错误弹窗消息(waiting_error 状态时)
|
||||
self.lock = threading.Lock()
|
||||
|
||||
def reset(self):
|
||||
@@ -736,14 +737,16 @@ def api_mission_config_get():
|
||||
|
||||
@app.route("/api/mission/config", methods=["POST"])
|
||||
def api_mission_config_set():
|
||||
""""设置任务配置(网格尺寸+空位矩阵)"""
|
||||
""""设置任务配置(网格尺寸+空位矩阵+机械臂初始姿态)"""
|
||||
data = request.json
|
||||
rows = data.get("rows", 2)
|
||||
cols = data.get("cols", 3)
|
||||
grid = data.get("grid", [])
|
||||
arm_initial_pose = data.get("arm_initial_pose", [0.0] * 6)
|
||||
gs.mission_config["rows"] = rows
|
||||
gs.mission_config["cols"] = cols
|
||||
gs.mission_config["grid"] = grid
|
||||
gs.mission_config["arm_initial_pose"] = arm_initial_pose
|
||||
# 清除超出网格边界的 positions(只保留 front/back 且 row<rows, col<cols)
|
||||
gs.mission_config["positions"] = [
|
||||
p for p in gs.mission_config.get("positions", [])
|
||||
@@ -1242,6 +1245,9 @@ def api_agv_reset():
|
||||
@app.route("/api/mission/start", methods=["POST"])
|
||||
def api_mission_start():
|
||||
"""开始执行任务(V3: M×N Grid 蛇形路径)"""
|
||||
data = request.json or {}
|
||||
single_step = bool(data.get("single_step", False))
|
||||
|
||||
# 清除可能存在的旧实例,确保可以启动
|
||||
if hasattr(MissionExecutorV3, "_instance"):
|
||||
MissionExecutorV3._instance = None
|
||||
@@ -1250,7 +1256,7 @@ def api_mission_start():
|
||||
if hasattr(MissionExecutorV3, "_instance") and MissionExecutorV3._instance:
|
||||
return jsonify({"ok": False, "error": "任务已在运行中"}), 400
|
||||
|
||||
def run():
|
||||
def run(single_step):
|
||||
from config import AGV_CONFIG
|
||||
config = {
|
||||
"device": AGV_CONFIG.get("device", "/dev/agvpro_controller"),
|
||||
@@ -1275,14 +1281,15 @@ def api_mission_start():
|
||||
machines=machines_list,
|
||||
qr_configs=gs.qr_config,
|
||||
models=models_list,
|
||||
single_step=single_step,
|
||||
)
|
||||
gs.mission_report = report
|
||||
executor.disconnect_all()
|
||||
gs.state = State.IDLE if report.get("error") is None else State.PAUSED
|
||||
|
||||
thread = threading.Thread(target=run, daemon=True)
|
||||
thread = threading.Thread(target=run, args=(single_step,), daemon=True)
|
||||
thread.start()
|
||||
return jsonify({"ok": True, "message": "任务已启动"})
|
||||
return jsonify({"ok": True, "single_step": single_step})
|
||||
|
||||
@app.route("/api/mission/stop", methods=["POST"])
|
||||
def api_mission_stop():
|
||||
@@ -1373,6 +1380,18 @@ def api_mission_state():
|
||||
except Exception:
|
||||
result["tasks"] = []
|
||||
|
||||
# 错误弹窗状态
|
||||
if hasattr(MissionExecutorV3, "_instance") and MissionExecutorV3._instance:
|
||||
ex = MissionExecutorV3._instance
|
||||
st = ex.get_status()
|
||||
result["error_msg"] = st.get("error", "")
|
||||
result["waiting_step"] = (st.get("status") == "waiting_step")
|
||||
result["waiting_error"] = (st.get("status") == "waiting_error")
|
||||
else:
|
||||
result["error_msg"] = ""
|
||||
result["waiting_step"] = False
|
||||
result["waiting_error"] = False
|
||||
|
||||
return jsonify(result)
|
||||
|
||||
@app.route("/api/mission/log", methods=["GET"])
|
||||
@@ -1396,6 +1415,50 @@ def api_mission_manual_qr():
|
||||
return jsonify({"ok": False, "error": "没有运行中的任务"}), 400
|
||||
|
||||
|
||||
# ========== 错误弹窗 API ==========
|
||||
@app.route("/api/mission/error-skip", methods=["POST"])
|
||||
def api_mission_error_skip():
|
||||
"""用户选择:跳过当前错误"""
|
||||
if hasattr(MissionExecutorV3, "_instance") and MissionExecutorV3._instance:
|
||||
MissionExecutorV3._instance.set_error_choice("skip")
|
||||
return jsonify({"ok": True, "choice": "skip"})
|
||||
return jsonify({"ok": False, "error": "没有运行中的任务"}), 400
|
||||
|
||||
@app.route("/api/mission/error-abort", methods=["POST"])
|
||||
def api_mission_error_abort():
|
||||
"""用户选择:中断任务"""
|
||||
if hasattr(MissionExecutorV3, "_instance") and MissionExecutorV3._instance:
|
||||
MissionExecutorV3._instance.set_error_choice("abort")
|
||||
return jsonify({"ok": True, "choice": "abort"})
|
||||
return jsonify({"ok": False, "error": "没有运行中的任务"}), 400
|
||||
|
||||
|
||||
# ========== 单步执行 API ==========
|
||||
@app.route("/api/mission/singlestep/confirm", methods=["POST"])
|
||||
def api_mission_singlestep_confirm():
|
||||
"""单步执行:确认当前步骤正确,继续"""
|
||||
if hasattr(MissionExecutorV3, "_instance") and MissionExecutorV3._instance:
|
||||
MissionExecutorV3._instance.set_step_choice("confirm")
|
||||
return jsonify({"ok": True, "choice": "confirm"})
|
||||
return jsonify({"ok": False, "error": "没有运行中的任务"}), 400
|
||||
|
||||
@app.route("/api/mission/singlestep/retry", methods=["POST"])
|
||||
def api_mission_singlestep_retry():
|
||||
"""单步执行:重试当前步骤"""
|
||||
if hasattr(MissionExecutorV3, "_instance") and MissionExecutorV3._instance:
|
||||
MissionExecutorV3._instance.set_step_choice("retry")
|
||||
return jsonify({"ok": True, "choice": "retry"})
|
||||
return jsonify({"ok": False, "error": "没有运行中的任务"}), 400
|
||||
|
||||
@app.route("/api/mission/singlestep/abort", methods=["POST"])
|
||||
def api_mission_singlestep_abort():
|
||||
"""单步执行:中断任务"""
|
||||
if hasattr(MissionExecutorV3, "_instance") and MissionExecutorV3._instance:
|
||||
MissionExecutorV3._instance.set_step_choice("abort")
|
||||
return jsonify({"ok": True, "choice": "abort"})
|
||||
return jsonify({"ok": False, "error": "没有运行中的任务"}), 400
|
||||
|
||||
|
||||
# ========== 二维码配置 API ==========
|
||||
@app.route("/api/qr/configs", methods=["GET"])
|
||||
def api_qr_configs_get():
|
||||
|
||||
Reference in New Issue
Block a user