# Navigation2 详解:nav2_bringup 与 nav2_gps_waypoint_follower_demo ## 1. Navigation2 整体介绍 Navigation2(简称Nav2)是ROS2生态中最成熟的开源导航框架,是ROS1 Navigation Stack的官方继任者,专为移动机器人自主导航设计。 ### 1.1 核心功能 - **定位**:支持AMCL、SLAM(Cartographer、SLAM Toolbox等)、GPS/RTK等多源定位 - **全局路径规划**:支持A*、Dijkstra、NavFn等多种规划算法 - **局部路径跟踪**:支持DWA、TEB、MPPI、Pure Pursuit等跟踪算法 - **避障与行为树**:通过行为树实现复杂导航逻辑,支持动态障碍物规避 - **重规划与恢复行为**:导航失败时自动执行恢复策略(旋转、回退、清图等) - **多机器人支持**:支持命名空间隔离的多机器人导航 ### 1.2 整体架构 Nav2采用模块化插件式设计,核心模块包括: ``` ├── 感知层 │ ├── 传感器数据处理(LiDAR、Camera、IMU、GPS等) │ └── 障碍物检测/语义分割 ├── 定位层 │ ├── AMCL(蒙特卡洛定位) │ ├── SLAM 建图 │ └── 多传感器融合定位 ├── 地图层 │ ├── 代价地图(全局/局部) │ ├── 图层插件(静态层、障碍层、膨胀层、社会层等) ├── 规划层 │ ├── 全局路径规划器 │ └── 平滑器 ├── 控制层 │ ├── 局部路径规划器 │ └── 轨迹跟踪控制器 ├── 行为决策层 │ ├── 行为树执行器 │ └── 恢复行为管理器 └── 接口层 ├── RViz 可视化 ├── Action/Topic API └── 配置参数系统 ``` --- ## 2. nav2_bringup 包详解 nav2_bringup是Nav2的官方启动集成包,提供了开箱即用的启动文件、配置模板和参数集合,是快速部署Nav2系统的入口。 ### 2.1 代码结构 ``` nav2_bringup/ ├── bringup/ # 启动相关核心目录 │ ├── launch/ # 启动文件集合 │ │ ├── bringup_launch.py # 主启动文件,集成所有导航模块 │ │ ├── localization_launch.py # 单独启动定位模块(AMCL/SLAM) │ │ ├── navigation_launch.py # 单独启动导航模块(规划/控制/行为树) │ │ ├── rviz_launch.py # 启动RViz可视化 │ │ ├── slam_launch.py # 启动SLAM建图 │ │ └── urdf_launch.py # 加载机器人URDF模型 │ ├── params/ # 参数配置文件目录 │ │ ├── nav2_params.yaml # 导航全模块默认参数 │ │ ├── nav2_params_no_odom.yaml # 无里程计场景参数 │ │ ├── nav2_slam_params.yaml # SLAM模式参数 │ │ └── robot_localization/ # 传感器融合参数模板 │ └── rviz/ # RViz配置文件 │ └── nav2_default_view.rviz # Nav2默认RViz配置 ├── docker/ # Docker部署相关文件 ├── scripts/ # 辅助脚本 ├── CMakeLists.txt ├── package.xml └── README.md ``` ### 2.2 核心启动文件说明 #### 2.2.1 bringup_launch.py 这是最常用的一站式启动文件,集成了完整的导航流程,支持参数配置: ```python # 关键参数 'namespace': '', # 多机器人命名空间 'use_sim_time': False, # 是否使用仿真时间 'rviz_config_file': '', # RViz配置文件路径 'params_file': '', # 导航参数文件路径 'autostart': True, # 启动后自动激活导航栈 'use_composition': True, # 使用组件化节点(减少进程数,提高性能) 'use_respawn': False, # 节点崩溃时自动重启 'map': '', # 静态地图文件路径(.yaml/.pgm) 'slam': False, # 是否启用SLAM模式 'localization_type': 'amcl' # 定位方式:amcl/slam_toolbox等 ``` 启动示例: ```bash # 仿真环境启动导航 ros2 launch nav2_bringup bringup_launch.py use_sim_time:=True map:=/path/to/map.yaml # 真机环境启用SLAM建图 ros2 launch nav2_bringup bringup_launch.py slam:=True params_file:=/path/to/my_params.yaml ``` #### 2.2.2 localization_launch.py 单独启动定位模块,适合只需要定位不需要完整导航的场景: ```bash # 仅启动AMCL定位 ros2 launch nav2_bringup localization_launch.py map:=/path/to/map.yaml use_sim_time:=True ``` #### 2.2.3 navigation_launch.py 单独启动导航模块(规划/控制/行为树),适合定位已由其他系统提供的场景: ```bash # 仅启动导航模块,使用已有的定位信息 ros2 launch nav2_bringup navigation_launch.py params_file:=/path/to/my_params.yaml ``` ### 2.3 配置文件详解 nav2_params.yaml是核心参数配置文件,采用分层结构,每个模块单独配置: ```yaml amcl: ros__parameters: base_frame_id: "base_footprint" # 机器人基坐标系 global_frame_id: "map" # 全局坐标系 odom_frame_id: "odom" # 里程计坐标系 max_particles: 2000 # 最大粒子数 min_particles: 500 # 最小粒子数 update_min_a: 0.2 # 角度变化超过0.2rad时更新 update_min_d: 0.25 # 位移超过0.25m时更新 bt_navigator: ros__parameters: use_sim_time: False bt_xml_filename: "navigate_w_replanning_and_recovery.xml" # 行为树文件 global_costmap: global_costmap: ros__parameters: update_frequency: 1.0 publish_frequency: 1.0 global_frame: map robot_base_frame: base_footprint resolution: 0.05 plugins: - {name: static_layer, type: "costmap_2d::StaticLayer"} - {name: obstacle_layer, type: "costmap_2d::ObstacleLayer"} - {name: inflation_layer, type: "costmap_2d::InflationLayer"} local_costmap: local_costmap: ros__parameters: update_frequency: 5.0 publish_frequency: 2.0 global_frame: odom robot_base_frame: base_footprint width: 3 height: 3 resolution: 0.05 rolling_window: true # 局部代价地图随机器人移动 planner_server: ros__parameters: expected_planner_frequency: 1.0 planner_plugins: ["GridBased"] GridBased: plugin: "nav2_navfn_planner/NavfnPlanner" # 默认使用NavFn规划器 use_astar: true # 启用A*算法 controller_server: ros__parameters: controller_frequency: 20.0 min_x_velocity_threshold: 0.001 min_y_velocity_threshold: 0.5 controller_plugins: ["FollowPath"] FollowPath: plugin: "nav2_regulated_pure_pursuit_controller/RegulatedPurePursuitController" # 默认使用Pure Pursuit控制器 ``` ### 2.4 最佳实践 1. **不要直接修改默认参数文件**:将nav2_params.yaml复制到自己的工作空间进行修改,通过`params_file`参数传入 2. **组件化启动**:默认启用`use_composition:=True`可以显著减少内存占用和通信开销 3. **分层配置**:将通用参数和机器人特定参数分开存放,便于维护 4. **仿真与真机分离**:使用`use_sim_time`参数区分仿真和真机环境,分别配置不同的参数值 --- ## 3. nav2_gps_waypoint_follower_demo 详解 这是Nav2官方提供的室外导航示例,演示了如何结合GPS/RTK定位实现全局航点跟随功能,适用于无人车、巡检机器人等室外场景。 ### 3.1 代码结构 该包位于navigation2_tutorials仓库中,结构如下: ``` nav2_gps_waypoint_follower_demo/ ├── bringup/ │ ├── launch/ │ │ ├── gps_waypoint_follower_launch.py # Demo主启动文件 │ │ ├── rviz.launch.py # RViz启动 │ │ └── dual_ekf.launch.py # 双EKF传感器融合启动 │ ├── params/ │ │ ├── dual_ekf.yaml # 传感器融合参数 │ │ ├── nav2_params.yaml # 导航参数(适配GPS场景) │ │ └── waypoint_follower_params.yaml # 航点跟随器参数 │ ├── rviz/ │ │ └── gps_waypoint.rviz # GPS导航专用RViz配置 │ └── worlds/ │ └── gps_world.world # 仿真世界文件(含GPS插件) ├── config/ │ └── sample_waypoints.yaml # 示例航点配置文件 ├── src/ │ └── gps_waypoint_logger.cpp # 航点到达日志节点(可选) ├── CMakeLists.txt ├── package.xml └── README.md ``` ### 3.2 核心组件说明 GPS航点跟随系统主要由三个核心部分组成: 1. **传感器融合模块**(robot_localization):融合GPS、IMU、轮式里程计数据,输出全局定位 2. **导航栈模块**:基于全局定位进行路径规划和跟踪 3. **航点跟随器**:按照预设的GPS航点序列依次导航 #### 3.2.1 双EKF传感器融合 demo使用两个扩展卡尔曼滤波器(EKF)实现多传感器融合: ```yaml # dual_ekf.yaml 核心配置 ekf_filter_node_odom: ros__parameters: frequency: 30.0 sensor_timeout: 0.1 two_d_mode: true publish_tf: true odom_frame: odom base_link_frame: base_link world_frame: odom # 融合IMU和轮式里程计,输出odom->base_link变换 imu0: /imu/data odom0: /wheel/odometry ekf_filter_node_map: ros__parameters: frequency: 30.0 sensor_timeout: 0.1 two_d_mode: true publish_tf: true odom_frame: odom base_link_frame: base_link world_frame: map # 融合GPS数据,输出map->odom变换 odom1: /gps/fix odom1_differential: false odom1_relative: false ``` - 第一个EKF(odom系):融合IMU和轮式里程计,提供短时间内高精度的局部定位,无漂移 - 第二个EKF(map系):融合GPS数据,提供全局绝对定位,修正长期漂移 #### 3.2.2 导航参数适配(nav2_params.yaml) GPS导航场景需要对默认导航参数进行调整: ```yaml amcl: ros__parameters: # GPS导航场景下禁用AMCL,使用EKF融合提供定位 use_sim_time: False # AMCL相关参数全部注释或删除 global_costmap: global_costmap: ros__parameters: # GPS模式下不使用静态地图,使用动态生成的代价地图 plugins: - {name: obstacle_layer, type: "costmap_2d::ObstacleLayer"} - {name: inflation_layer, type: "costmap_2d::InflationLayer"} # 代价地图大小足够覆盖所有航点范围 width: 1000 height: 1000 resolution: 0.1 rolling_window: false # 全局代价地图固定,不随机器人移动 origin_x: -500 origin_y: -500 planner_server: ros__parameters: # 使用适合长距离规划的算法 GridBased: plugin: "nav2_navfn_planner/NavfnPlanner" use_astar: true allow_unknown: true # 允许在未知区域规划路径 controller_server: ros__parameters: # 使用适合高速行驶的控制器 FollowPath: plugin: "nav2_mppi_controller/MPPIController" # 或者TEB控制器 max_vel_x: 5.0 # 室外场景允许更高速度 ``` #### 3.2.3 航点跟随器配置 ```yaml # waypoint_follower_params.yaml waypoint_follower: ros__parameters: loop: False # 航点是否循环执行 waypoint_timeout: 300.0 # 单个航点导航超时时间(秒) stop_on_failure: True # 某个航点导航失败时停止 action_server_name: "follow_waypoints" # 航点到达阈值 goal_tolerance_x: 0.5 goal_tolerance_y: 0.5 goal_tolerance_yaw: 0.25 ``` ### 3.3 航点配置 sample_waypoints.yaml是预设的GPS航点文件,格式如下: ```yaml waypoints: - latitude: 37.7749 longitude: -122.4194 yaw: 0.0 # 到达后的朝向(弧度) frame_id: "wgs84" # GPS坐标系 - latitude: 37.7750 longitude: -122.4195 yaw: 1.57 frame_id: "wgs84" - latitude: 37.7751 longitude: -122.4196 yaw: 3.14 frame_id: "wgs84" ``` 航点使用WGS84坐标系(标准GPS坐标),也可以配置为UTM坐标系。 ### 3.4 运行流程 1. **启动仿真/真机驱动**:加载机器人模型、传感器驱动、GPS插件 2. **启动传感器融合**:`ros2 launch nav2_gps_waypoint_follower_demo dual_ekf.launch.py` 3. **启动导航栈**:`ros2 launch nav2_gps_waypoint_follower_demo gps_waypoint_follower_launch.py` 4. **加载航点**:`ros2 run nav2_waypoint_follower waypoint_follower --ros-args -p waypoint_file:=/path/to/sample_waypoints.yaml` 5. **启动航点跟随**:通过RViz发送FollowWaypoints action请求,或者用命令行启动: ```bash ros2 action send_goal /follow_waypoints nav2_msgs/action/FollowWaypoints "{waypoints: []}" ``` ### 3.5 关键注意事项 1. **GPS信号质量**:室外场景下需要确保GPS信号良好,RTK定位能达到厘米级精度,普通GPS只有米级精度,可能影响导航效果 2. **坐标系转换**:需要正确配置WGS84到UTM再到机器人本地坐标系的转换参数 3. **航点规划**:航点之间需要有可行路径,避免有障碍物阻挡 4. **动态障碍物**:室外场景需要配置合适的障碍物检测和避障参数 5. **TF树检查**:确保`map->odom->base_link`的TF变换正确发布,这是GPS导航的基础 --- ## 4. 常用调试技巧 1. **查看TF树**:`ros2 run tf2_tools view_frames`,检查坐标系变换是否正确 2. **检查定位质量**:`ros2 topic echo /gps/fix` 查看GPS信号质量,`ros2 topic echo /odometry/filtered` 查看融合后的定位输出 3. **可视化调试**:在RViz中显示全局/局部代价地图、规划路径、当前目标点等信息 4. **参数动态调整**:使用`ros2 param`命令动态修改参数,无需重启导航栈 5. **日志分析**:查看`/tf`, `/cmd_vel`, `/plan`等话题的输出,排查导航失败原因 --- ## 参考资料 - [Navigation2 官方文档](https://navigation.ros.org/) - [nav2_bringup 源码](https://github.com/ros-navigation/navigation2/tree/main/nav2_bringup) - [GPS Waypoint Follower 教程](https://navigation.ros.org/tutorials/docs/gps_waypoint_follower.html) - [navigation2_tutorials 仓库](https://github.com/ros-navigation/navigation2_tutorials)