:设计 NavigationManager 导航管理节点,实现 Qt 与 Nav2 自主导航交互)
在前两篇文章中我们分别完成了两个独立模块的设计与集成ModeManager统一管理 SLAM 建图与 Nav2 导航模式。MapManager封装底层地图保存服务实现 Qt 一键保存地图。至此小车已经可以通过 Qt 界面完成建图、保存地图和加载导航地图等操作。但还有一个重要问题当用户在 Qt 地图上指定一个目标位置时怎样才能让 Nav2 接收到目标并控制机器人完成导航虽然 Nav2 已经提供了完整的自主导航框架但如果希望将其集成到自定义 Qt 上位机中还需要解决几个问题1. Qt 如何向 ROS 2 发送目标位置和朝向2. 如何调用 Nav2 的导航任务接口3. 如何获取导航任务的执行状态4. 如何取消一个正在执行的导航任务5. 如何避免调试过程中误触发小车运动为解决这些问题本期围绕 NavigationManager 导航管理节点展开。它相当于Qt与Nav2之间的任务管理层负责衔接上位机交互和底层导航执行。一、NavigationManager 整体设计整个系统采用分层设计。系统的导航控制流采用了一条清晰的单向数据链路Qt 上位机 - /xuegecar/goal_pose - NavigationManager - /navigate_to_pose - Nav2 导航栈 - 底盘运动控制。Qt 上位机负责在地图上点选目标和取消任务NavigationManager作为中间件负责接收目标、进行权限安全检查、向Nav2提交导航任务并实时回传状态给 UI最终由 Nav2 内部的 bt_navigator、planner_server、controller_server 以及 AMCL 等组件协同计算驱动机器人运动。这种设计彻底解耦了界面交互与底层算法使得后续更换前端 UI 或升级 Nav2 算法时互不影响。在这个架构中NavigationManager 并不直接计算每一步电机速度也不负责底层 A* 路径搜索。二、核心功能1.接收Qt导航目标当用户在 Qt 地图上选择一个目标时需要发送的不仅是目标坐标还包括机器人到达目标时的朝向。在 ROS 2 中可以使用geometry_msgs/msg/PoseStamped表示目标位姿。本项目此前使用的话题为/xuegecar/goal_pose。可以通过 Ubuntu 终端进行检查ros2 topic echo /xuegecar/goal_pose --once。此前的实际测试中Qt 已经成功发布过地图坐标系下的目标位姿。2.调用Nav2导航Action这是NavigationManager 最关键的功能之一。Nav2 提供了多种 Action 接口其中有两个特别容易混淆。两者最大的区别是ComputePathToPose 负责规划NavigateToPose 负责执行完整导航任务。当使用 NavigateToPose 时Nav2可以组织全局规划、局部路径跟随以及必要的恢复行为。在 ROS 2节点中通常使用 rclpy.action.ActionClient与导航服务器交互。3.导航运动权限管理在真实机器人开发中有一个非常实际的问题如果刚刚写好 Qt 的目标点发送功能还没有确认地图、定位和控制器是否正常就直接让小车执行导航可能存在风险。因此我们在导航管理流程中引入了运动权限参数enable_motion。此前的测试设计是默认关闭运动权限。在权限关闭时我们仍然可以验证Qt 是否正确发送目标位姿、ROS 2 是否收到目标消息、地图坐标和目标朝向是否正确、导航管理节点是否按预期拒绝执行请求。这样就能够将“消息通信调试”和“真实底盘运动测试”分开。需要强调的是enable_motion主要用于控制是否允许提交新的导航执行请求不是物理紧急停止功能。即使把参数从true改回false已经执行中的导航任务也不一定自动取消。4.导航任务状态反馈为了使 Qt 上位机不只是一个发送目标的工具还需要让用户能够观察导航任务的执行情况。本项目提供过以下状态查询接口/xuegecar/navigation_status导航过程中需要关注的状态包括IDLE当前没有正在执行的导航任务ACTIVE导航任务正在执行SUCCEEDED导航任务成功完成ABORTED导航任务异常终止CANCELED导航任务已取消另外Nav2 的NavigateToPose可以提供剩余距离、当前位姿、导航时间及恢复次数等反馈信息。通过这些信息可以进一步扩展 Qt 的状态显示功能。本期源码仓库https://github.com/wy1977-wq/xuegecar-navigation-manager.git再次感谢出云科技及 ROS 2、Nav2 开源社区开发者的贡献