Nav2 导航集成:新增 nav2_navigator.py,mission_executor 改用 Nav2 action 导航
- 新增 agv_app/utils/nav2_navigator.py:Nav2Navigator 类,通过 ros2 action /navigate_to_pose 和 /navigate_through_poses 与 Nav2 通信,支持路径点导航 - app.py:navigate/to, navigate/path, navigate/status 三个 API 改用 Nav2Navigator - mission_executor.py:_execute_point 中调用 _nav2_go_to_point() 替代原来的 time.sleep 模拟移动,Nav2 负责从当前点到目标点的自主导航 - 原有的 map_navigator.py(A* + Pure Pursuit 自实现)保留不动,供无 Nav2 时降级用
This commit is contained in:
+18
-13
@@ -17,7 +17,7 @@ from utils.agv_controller_ros2 import AGVController
|
||||
from utils.qr_scanner import QRScanner
|
||||
from utils.image_uploader import ImageUploader
|
||||
from utils.mission_executor import MissionExecutor, TaskStatus
|
||||
from utils.map_navigator import MapNavigator, NavStatus
|
||||
from utils.nav2_navigator import Nav2Navigator, Nav2Status
|
||||
|
||||
# 配置日志
|
||||
logging.basicConfig(
|
||||
@@ -51,7 +51,7 @@ class GlobalState:
|
||||
"positions": [] # 独立点位配置 [{row, col, side, coords, poses}]
|
||||
}
|
||||
self.machines_config = [] # 机器配置(每台机器的正面/背面点位+姿态)
|
||||
self.navigator = None # MapNavigator 实例
|
||||
self.navigator = None # Nav2Navigator 实例
|
||||
self.lock = threading.Lock()
|
||||
|
||||
def reset(self):
|
||||
@@ -412,12 +412,13 @@ def api_navigate_to():
|
||||
|
||||
try:
|
||||
if gs.navigator is None:
|
||||
gs.navigator = MapNavigator(gs.map_config["map_yaml"])
|
||||
ok = gs.navigator.navigate_to(float(goal_x), float(goal_y))
|
||||
gs.navigator = Nav2Navigator()
|
||||
# navigate_to_pose(x, y, yaw=None, timeout_sec=120, blocking=False)
|
||||
ok = gs.navigator.navigate_to_pose(float(goal_x), float(goal_y), blocking=False)
|
||||
if ok:
|
||||
return jsonify({"ok": True, "message": "导航已启动"})
|
||||
else:
|
||||
return jsonify({"ok": False, "error": "路径规划失败或导航正在进行中"}), 400
|
||||
return jsonify({"ok": False, "error": "导航启动失败,可能是Nav2未运行或AGV未连接"}), 400
|
||||
except Exception as e:
|
||||
logger.error(f"导航失败: {e}")
|
||||
return jsonify({"ok": False, "error": str(e)}), 500
|
||||
@@ -437,12 +438,12 @@ def api_navigate_status():
|
||||
"""获取导航状态"""
|
||||
if gs.navigator:
|
||||
return jsonify(gs.navigator.get_status())
|
||||
return jsonify({"status": "idle", "current_position": [0, 0, 0], "path_length": 0, "path": []})
|
||||
return jsonify({"status": "idle", "current_position": [0, 0, 0], "nav2_available": False})
|
||||
|
||||
|
||||
@app.route("/api/navigate/path", methods=["POST"])
|
||||
def api_navigate_path():
|
||||
"""预览路径(仅规划不执行)"""
|
||||
"""预览路径(仅规划不执行)- Nav2版本不支持预计算路径,返回当前导航状态"""
|
||||
if not gs.map_config or "map_yaml" not in gs.map_config:
|
||||
return jsonify({"ok": False, "error": "地图未加载"}), 400
|
||||
|
||||
@@ -454,12 +455,16 @@ def api_navigate_path():
|
||||
|
||||
try:
|
||||
if gs.navigator is None:
|
||||
gs.navigator = MapNavigator(gs.map_config["map_yaml"])
|
||||
path = gs.navigator.get_path_preview(float(goal_x), float(goal_y))
|
||||
if path is not None:
|
||||
return jsonify({"ok": True, "path": path, "length": len(path)})
|
||||
else:
|
||||
return jsonify({"ok": False, "error": "路径规划失败,目标点不可达"}), 400
|
||||
gs.navigator = Nav2Navigator()
|
||||
# Nav2 不提供路径预览,直接返回可用状态
|
||||
current = gs.navigator.get_current_position()
|
||||
status = gs.navigator.get_status()
|
||||
return jsonify({
|
||||
"ok": True,
|
||||
"message": "Nav2 路径预览不可用,请在 RViz 中查看规划路径",
|
||||
"current_position": current,
|
||||
"nav2_available": status.get("nav2_available", False)
|
||||
})
|
||||
except Exception as e:
|
||||
logger.error(f"路径预览失败: {e}")
|
||||
return jsonify({"ok": False, "error": str(e)}), 500
|
||||
|
||||
Reference in New Issue
Block a user