ROS2 无人车学习第二章

机器人

Posted by LXG on June 30, 2026

RTAB-Map 数据库

RTAB-Map 并不是只存“地图点”,它存的是一个完整的图优化 SLAM 结构,主要包括:

🔹 节点(Nodes)

每一帧关键数据:

  • RGB / Depth 图像(可选压缩存储)
  • 特征点(SURF/SIFT/ORB)
  • IMU(如果有)
  • 位姿(初始估计)

🔹 边(Edges)

节点之间的约束关系:

  • odometry constraint(里程计)
  • loop closure(回环)
  • ICP / visual matching

🔹 地图数据

  • 2D occupancy grid(如果用2D模式)
  • 3D point cloud(可选)
  • compressed data / raw data

🔹 回环检测信息

  • BoW(Bag of Words)
  • feature database
  • visual words index

RTAB-Map 本质不是“建图算法”,而是:📌 “图优化 + 回环检测 + 数据库存储系统”

RTAB-Map 使用 SQLite 的主要缺点

1️⃣ 写入瓶颈(最致命)

2️⃣ BLOB(图像/点云)导致 IO 压力大

3️⃣ 内存 & Cache 抖动明显

4️⃣ 不适合高频传感器流

5️⃣ 并发能力弱(单进程瓶颈)

6️⃣ 大地图扩展性一般

7️⃣ 崩溃恢复成本高

8️⃣ 不适合“实时多机器人共享地图”

硬件配置

计算平台(核心大脑)

  1. NVIDIA Jetson Orin Nano(主流方案)
  2. RK3588 树莓派
  3. x86 工控机(高性能但功耗大)

感知传感器(眼睛)

  1. 相机(视觉 SLAM / AI识别)
  2. 激光雷达
  3. IMU(姿态)
  4. 轮速编码器(必须)

底盘系统(执行机构)

底盘结构

  • 差速(最常见)
  • 全向轮(展厅机器人)
  • 四轮独立驱动(高端)

电机

  • 直流减速电机(主流)
  • 无刷电机(高性能)

电机驱动器

  • L298N(低端)
  • Cytron / Roboclaw(工业级)
  • CAN 电机驱动(推荐)

控制接口

  • PWM
  • CAN(推荐)
  • UART

电源系统

  • 锂电池(12V / 24V)
  • BMS 电池管理系统
  • DC-DC 转换(12V → 5V / 3.3V)
  • 电源隔离(抗干扰)

通信系统

车内通信

  • USB(相机)
  • UART(IMU / MCU)
  • CAN(电机)
  • Ethernet(高带宽传感器)

外部通信

  • WiFi(调试 / ROS2 remote)
  • 4G/5G(远程控制)
  • MQTT(云控制)

控制 MCU(实时层)

通常 ROS2 不直接控制电机

MCU 常见:

  • STM32(最常见)
  • ESP32(轻量)
  • NXP / TI 工业控制芯片

职责:

  • 速度闭环
  • 编码器采集
  • PWM/CAN 控制

无人车建图仿真

Gazebo 仿真(机器人 + 展厅世界 + 话题桥接)


lxg@lxg:~$ source /opt/ros/humble/setup.bash
source /home/lxg/code/xt/gitlab/ros2_learn_ws/install/setup.bash
export ROS_LOCALHOST_ONLY=1
export ROS_DOMAIN_ID=0
cd /home/lxg/code/xt/gitlab/ros2_learn_ws
ros2 launch description sim_robot.launch.py \
  world_file:='/home/lxg/code/xt/gitlab/ros2_learn_ws/src/description/worlds/exhibition_hall.sdf' \
  config_file:='/home/lxg/code/xt/gitlab/ros2_learn_ws/src/description/config/omni_base.yaml' \
  bridge_config_file:='/home/lxg/code/xt/gitlab/ros2_learn_ws/src/description/config/sim_bridge.yaml' \
  headless:=false \
  x:=0.0 \
  y:=0.0 \
  yaw:=0.0
[INFO] [launch]: All log files can be found below /home/lxg/.ros/log/2026-07-03-11-08-10-695410-lxg-31655
[INFO] [launch]: Default logging verbosity is set to INFO
[INFO] [ruby $(which gz) sim-1]: process started with pid [31656]
[INFO] [robot_state_publisher-2]: process started with pid [31658]
[INFO] [create-3]: process started with pid [31660]
[INFO] [parameter_bridge-4]: process started with pid [31663]
[create-3] [INFO] [1783048090.813578775] [spawn_robot]: Requesting list of world names.
[robot_state_publisher-2] [INFO] [1783048090.826255075] [robot_state_publisher]: got segment base_link
[robot_state_publisher-2] [INFO] [1783048090.826320649] [robot_state_publisher]: got segment front_left_wheel_link
[robot_state_publisher-2] [INFO] [1783048090.826326951] [robot_state_publisher]: got segment front_left_wheel_motor_link
[robot_state_publisher-2] [INFO] [1783048090.826330828] [robot_state_publisher]: got segment front_left_wheel_steer_link
[robot_state_publisher-2] [INFO] [1783048090.826334305] [robot_state_publisher]: got segment front_right_wheel_link
[robot_state_publisher-2] [INFO] [1783048090.826337611] [robot_state_publisher]: got segment front_right_wheel_motor_link
[robot_state_publisher-2] [INFO] [1783048090.826340857] [robot_state_publisher]: got segment front_right_wheel_steer_link
[robot_state_publisher-2] [INFO] [1783048090.826344023] [robot_state_publisher]: got segment gps
[robot_state_publisher-2] [INFO] [1783048090.826347410] [robot_state_publisher]: got segment lidar_left
[robot_state_publisher-2] [INFO] [1783048090.826351077] [robot_state_publisher]: got segment lidar_link
[robot_state_publisher-2] [INFO] [1783048090.826354253] [robot_state_publisher]: got segment lidar_right
[robot_state_publisher-2] [INFO] [1783048090.826357429] [robot_state_publisher]: got segment rear_gps
[robot_state_publisher-2] [INFO] [1783048090.826360705] [robot_state_publisher]: got segment rear_left_wheel_link
[robot_state_publisher-2] [INFO] [1783048090.826363871] [robot_state_publisher]: got segment rear_left_wheel_motor_link
[robot_state_publisher-2] [INFO] [1783048090.826367027] [robot_state_publisher]: got segment rear_left_wheel_steer_link
[robot_state_publisher-2] [INFO] [1783048090.826370183] [robot_state_publisher]: got segment rear_right_wheel_link
[robot_state_publisher-2] [INFO] [1783048090.826373269] [robot_state_publisher]: got segment rear_right_wheel_motor_link
[robot_state_publisher-2] [INFO] [1783048090.826376284] [robot_state_publisher]: got segment rear_right_wheel_steer_link
[create-3] [INFO] [1783048091.387409585] [spawn_robot]: Waiting messages on topic [robot_description].
[create-3] [INFO] [1783048091.398587116] [spawn_robot]: Requested creation of entity.
[create-3] [INFO] [1783048091.398605300] [spawn_robot]: OK creation of entity.
[INFO] [create-3]: process has finished cleanly [pid 31660]
[parameter_bridge-4] [INFO] [1783048091.822585142] [ros_gz_bridge]: Creating GZ->ROS Bridge: [/clock (gz.msgs.Clock) -> /clock (rosgraph_msgs/msg/Clock)] (Lazy 0)
[parameter_bridge-4] [INFO] [1783048091.865080404] [ros_gz_bridge]: Creating ROS->GZ Bridge: [/cmd_vel (geometry_msgs/msg/Twist) -> /cmd_vel (gz.msgs.Twist)] (Lazy 0)
[parameter_bridge-4] [INFO] [1783048091.866260952] [ros_gz_bridge]: Creating GZ->ROS Bridge: [/odom (gz.msgs.Odometry) -> /odom (nav_msgs/msg/Odometry)] (Lazy 0)
[parameter_bridge-4] [INFO] [1783048091.866969230] [ros_gz_bridge]: Creating GZ->ROS Bridge: [/tf (gz.msgs.Pose_V) -> /tf (tf2_msgs/msg/TFMessage)] (Lazy 0)
[parameter_bridge-4] [INFO] [1783048091.867619697] [ros_gz_bridge]: Creating GZ->ROS Bridge: [/scan (gz.msgs.LaserScan) -> /scan (sensor_msgs/msg/LaserScan)] (Lazy 0)
[ruby $(which gz) sim-1] libEGL warning: egl: failed to create dri2 screen
[ruby $(which gz) sim-1] libEGL warning: egl: failed to create dri2 screen
[ruby $(which gz) sim-1] Warning [Utils.cc:132] [/sdf/model[@name="xintiangui_omni_sim"]/link[@name="base_link"]/sensor[@name="lidar_sensor"]/gz_frame_id:<urdf-string>:L0]: XML Element[gz_frame_id], child of element[sensor], not defined in SDF. Copying[gz_frame_id] as children of [sensor].
[ruby $(which gz) sim-1] Warning [Utils.cc:132] [/sdf/model[@name="xintiangui_omni_sim"]/link[@name="base_link"]/sensor[@name="lidar_sensor"]/gz_frame_id:<data-string>:L223]: XML Element[gz_frame_id], child of element[sensor], not defined in SDF. Copying[gz_frame_id] as children of [sensor].
[ruby $(which gz) sim-1] libEGL warning: egl: failed to create dri2 screen
[ruby $(which gz) sim-1] libEGL warning: egl: failed to create dri2 screen


环境初始化


# ROS2 Humble 基础环境
source /opt/ros/humble/setup.bash

# 你的 workspace(ros2_learn_ws)覆盖上层包
source /home/lxg/code/xt/gitlab/ros2_learn_ws/install/setup.bash

网络限制

# ROS2 只允许本机通信: 仿真 + RViz + Gazebo + 多进程调试时很关键
export ROS_LOCALHOST_ONLY=1

# DDS 通信域
# 如果你有多套 ROS 环境,这个容易冲突
export ROS_DOMAIN_ID=0

传入参数解释

  • exhibition_hall.sdf : 仿真世界
  • omni_base.yaml: 机器人参数
  • sim_bridge.yaml: ROS2 ↔ 仿真通信桥
  • 仿真模式: true: 纯后台(无渲染) false: 打开 GUI
  • 初始位姿:机器人初始位置

SLAM Toolbox(建图模式,online_async)


lxg@lxg:~$ source /opt/ros/humble/setup.bash
source /home/lxg/code/xt/gitlab/ros2_learn_ws/install/setup.bash
export ROS_LOCALHOST_ONLY=1
export ROS_DOMAIN_ID=0
cd /home/lxg/code/xt/gitlab/ros2_learn_ws
ros2 run slam_toolbox async_slam_toolbox_node \
  --ros-args --params-file '/home/lxg/code/xt/gitlab/ros2_learn_ws/config/slam_toolbox_mapping_sim.yaml' \
  -p use_sim_time:=true
[INFO] [1783048591.670109311] [slam_toolbox]: Node using stack size 40000000
[INFO] [1783048591.684464340] [slam_toolbox]: Using solver plugin solver_plugins::CeresSolver
[INFO] [1783048591.684561713] [slam_toolbox]: CeresSolver: Using SCHUR_JACOBI preconditioner.
[INFO] [1783048591.789260966] [slam_toolbox]: Message Filter dropping message: frame 'lidar_link' at time 498.200 for reason 'discarding message because the queue is full'
[WARN] [1783048591.789604573] [slam_toolbox]: maximum laser range setting (20.0 m) exceeds the capabilities of the used Lidar (12.0 m)
Registering sensor: [Custom Described Lidar]

slam_toolbox_mapping_sim.yaml


# slam_toolbox 建图模式参数(仿真专用)
# 基于 /opt/ros/humble/share/slam_toolbox/config/mapper_params_online_async.yaml 复制,
# 仅修改 base_frame(本工作区机器人 TF 树以 base_link 为基座,无 base_footprint)。
# 用于 mapping_sim.sh:Gazebo + slam_toolbox(online_async) 建图。
slam_toolbox:
  ros__parameters:

    # =========================
    # 🔧 求解器配置(优化位姿图)
    # =========================

    solver_plugin: solver_plugins::CeresSolver   # 使用 Ceres 非线性优化器(主流)
    ceres_linear_solver: SPARSE_NORMAL_CHOLESKY   # 稀疏矩阵求解方式(推荐默认)
    ceres_preconditioner: SCHUR_JACOBI           # Schur 分解预条件
    ceres_trust_strategy: LEVENBERG_MARQUARDT    # LM优化策略(稳定)
    ceres_dogleg_type: TRADITIONAL_DOGLEG        # dogleg策略(较保守)
    ceres_loss_function: None                    # 不使用鲁棒核(可改Huber更抗噪)

    # ⚠️ 建议:如果地图抖动,可以改成 HuberLoss

    # =========================
    # 🌍 坐标系配置(最关键)
    # =========================

    odom_frame: odom          # 里程计坐标系(必须稳定)
    map_frame: map            # 全局地图坐标系
    base_frame: base_link     # ⚠️ 你这里是关键(无 base_footprint)

    # 👉 注意:
    # slam_toolbox 默认更推荐 base_footprint(你这里省略了中间层)

    scan_topic: /scan        # 激光雷达输入

    # =========================
    # 📌 模式
    # =========================

    use_map_saver: true      # 允许保存地图
    mode: mapping            # 建图模式(非 localization)

    # =========================
    # ⚡ 性能 / 时间控制
    # =========================

    debug_logging: false

    throttle_scans: 1        # 每几帧处理一次 scan(1=全量)
    # ⚠️ 如果 CPU高或丢包 → 改 2~3

    transform_publish_period: 0.02  # TF 发布周期(50Hz)
    map_update_interval: 5.0        # 地图更新频率(秒)
    resolution: 0.05               # 地图分辨率(5cm)

    min_laser_range: 0.15          # 最小有效距离
    max_laser_range: 20.0          # ⚠️ 这里你之前报错:雷达只有12m

    minimum_time_interval: 0.5     # scan最小时间间隔(限制频率)
    transform_timeout: 0.2
    tf_buffer_duration: 30.0

    stack_size_to_use: 40000000
    enable_interactive_mode: true

    # =========================
    # 📡 Scan匹配(核心SLAM质量)
    # =========================

    use_scan_matching: true       # 是否使用 scan matching
    use_scan_barycenter: true     # 使用质心对齐(稳定)

    minimum_travel_distance: 0.3  # 位移超过0.3m才更新
    minimum_travel_heading: 0.3   # 旋转超过0.3rad才更新

    scan_buffer_size: 10          # scan缓存大小
    scan_buffer_maximum_scan_distance: 10.0

    link_match_minimum_response_fine: 0.1

    link_scan_maximum_distance: 1.5  # scan匹配最大距离

    # =========================
    # 🔁 回环检测(loop closure)
    # =========================

    loop_search_maximum_distance: 3.0

    do_loop_closing: true

    loop_match_minimum_chain_size: 10

    loop_match_maximum_variance_coarse: 3.0
    loop_match_minimum_response_coarse: 0.35
    loop_match_minimum_response_fine: 0.45

    # =========================
    # 🔍 相关性搜索(scan matching精度)
    # =========================

    correlation_search_space_dimension: 0.5
    correlation_search_space_resolution: 0.01
    correlation_search_space_smear_deviation: 0.1

    # =========================
    # 🔁 回环搜索空间
    # =========================

    loop_search_space_dimension: 8.0
    loop_search_space_resolution: 0.05
    loop_search_space_smear_deviation: 0.03

    # =========================
    # 📉 权重惩罚(优化稳定性)
    # =========================

    distance_variance_penalty: 0.5
    angle_variance_penalty: 1.0

    # =========================
    # 🔎 角度搜索策略
    # =========================

    fine_search_angle_offset: 0.00349
    coarse_search_angle_offset: 0.349
    coarse_angle_resolution: 0.0349

    minimum_angle_penalty: 0.9
    minimum_distance_penalty: 0.5

    use_response_expansion: true
    min_pass_through: 2

    occupancy_threshold: 0.1

RViz2


source /opt/ros/humble/setup.bash
source /home/lxg/code/xt/gitlab/ros2_learn_ws/install/setup.bash
export ROS_LOCALHOST_ONLY=1
export ROS_DOMAIN_ID=0
cd /home/lxg/code/xt/gitlab/ros2_learn_ws
rviz2 -d '/home/lxg/code/xt/gitlab/ros2_learn_ws/config/mapping_sim.rviz' --ros-args -p use_sim_time:=true

键盘遥控(驱动小车)


source /opt/ros/humble/setup.bash
source /home/lxg/code/xt/gitlab/ros2_learn_ws/install/setup.bash
export ROS_LOCALHOST_ONLY=1
export ROS_DOMAIN_ID=0
cd /home/lxg/code/xt/gitlab/ros2_learn_ws
ros2 run teleop_twist_keyboard teleop_twist_keyboard

按键:i/, 前进后退,j/l 原地左右转,u/o/m/. 斜向移动,k 急停,Ctrl+C 退出。记得点击该面板让它获得焦点,按键才会生效。

建图完成后:保存地图


source /opt/ros/humble/setup.bash
source /home/lxg/code/xt/gitlab/ros2_learn_ws/install/setup.bash
export ROS_LOCALHOST_ONLY=1
export ROS_DOMAIN_ID=0

# 保存 slam_toolbox 位姿图(nav2_sim.sh 定位阶段需要,filename 是纯 string,不要套 {data: ...})
ros2 service call /slam_toolbox/serialize_map slam_toolbox/srv/SerializePoseGraph \
  "{filename: '/home/lxg/code/xt/gitlab/ros2_learn_ws/maps/sim/exhibition_hall'}"

# 保存标准占据栅格地图(仅可视化/存档用途,name 是 std_msgs/String,需要套 {data: ...})
ros2 service call /slam_toolbox/save_map slam_toolbox/srv/SaveMap \
  "{name: {data: '/home/lxg/code/xt/gitlab/ros2_learn_ws/maps/sim/exhibition_hall'}}"


生成的地图文件


lxg@lxg:~/code/xt/gitlab/ros2_learn_ws$ ls -al maps/sim/exhibition_hall.*
-rw-rw-r-- 1 lxg lxg  3595956 Jul  2 18:54 maps/sim/exhibition_hall.data
-rw-rw-r-- 1 lxg lxg   111336 Jul  2 18:54 maps/sim/exhibition_hall.pgm
-rw-rw-r-- 1 lxg lxg 15032062 Jul  2 18:54 maps/sim/exhibition_hall.posegraph
-rw-rw-r-- 1 lxg lxg      133 Jul  2 18:54 maps/sim/exhibition_hall.yaml

无人车导航仿真

终端 1:Gazebo 仿真(机器人 + 展厅世界 + 话题桥接)

作用:加载展厅世界模型、生成仿真机器人、启用 ROS 话题桥接,发布 /scan 激光扫描数据。

source /opt/ros/humble/setup.bash
source /home/lxg/code/xt/gitlab/ros2_learn_ws/install/setup.bash
export ROS_LOCALHOST_ONLY=1
export ROS_DOMAIN_ID=0
cd /home/lxg/code/xt/gitlab/ros2_learn_ws
ros2 launch description sim_robot.launch.py \
  world_file:='/home/lxg/code/xt/gitlab/ros2_learn_ws/src/description/worlds/exhibition_hall.sdf' \
  config_file:='/home/lxg/code/xt/gitlab/ros2_learn_ws/src/description/config/omni_base.yaml' \
  bridge_config_file:='/home/lxg/code/xt/gitlab/ros2_learn_ws/src/description/config/sim_bridge.yaml' \
  headless:=false \
  x:=0.0 \
  y:=0.0 \
  yaw:=0.0

终端 2:SLAM Toolbox(定位模式,加载已保存位姿图,不再建图)

前置:终端 1 的 Gazebo 已完全启动,/scan 话题有数据。

作用:加载预先保存的地图位姿图,对机器人进行定位(不再建图),发布 map → odom → base_link 的转换树。

source /opt/ros/humble/setup.bash
source /home/lxg/code/xt/gitlab/ros2_learn_ws/install/setup.bash
export ROS_LOCALHOST_ONLY=1
export ROS_DOMAIN_ID=0
cd /home/lxg/code/xt/gitlab/ros2_learn_ws
ros2 run slam_toolbox localization_slam_toolbox_node \
  --ros-args --params-file '/home/lxg/code/xt/gitlab/ros2_learn_ws/config/slam_toolbox_localization_sim.yaml' \
  -p use_sim_time:=true \
  -p map_file_name:='/home/lxg/code/xt/gitlab/ros2_learn_ws/maps/sim/exhibition_hall' \
  -p map_start_pose:='[0.0, 0.0, 0.0]'

等待事项

  • 终端显示 [INFO] [localization_slam_toolbox_node-*]: Done initializing. Waiting on nav2_lifecycle_manager to activate navigation.
  • 验证 TF 树就绪(在另一个终端执行 ros2 run tf2_ros tf2_echo map base_link
  • 确认输出包含 Translation 和 Rotation 信息

成功标志:TF 转换树建立完成,定位模块就绪。

终端 3:Nav2 导航

前置:终端 2 的 SLAM Toolbox 已启动并定位就绪。

作用:启动 Nav2 导航栈,使用官方 nav2_mppi_controller::MPPIController 进行路径规划和控制。

source /opt/ros/humble/setup.bash
source /home/lxg/code/xt/gitlab/ros2_learn_ws/install/setup.bash
export ROS_LOCALHOST_ONLY=1
export ROS_DOMAIN_ID=0
cd /home/lxg/code/xt/gitlab/ros2_learn_ws
ros2 launch nav2_bringup navigation_launch.py \
  use_sim_time:=true \
  params_file:='/home/lxg/code/xt/gitlab/ros2_learn_ws/config/nav2_sim.yaml' \
  autostart:=true \
  use_composition:=False \
  use_respawn:=False \
  log_level:=info

等待事项

  • 终端显示 [INFO] [navigation_launcher.py-*]: All launch files completed successfully
  • 各个导航模块(planner、controller、behaviors 等)完成生命周期初始化

成功标志:Nav2 导航栈完全启动,可以接收导航目标点。

备注

  • 默认配置使用官方 nav2_mppi_controller::MPPIController(参考 config/nav2_sim.yaml

终端 4:RViz2

前置:终端 1-3 已启动完成。

作用:提供可视化界面,显示地图、机器人状态、成本地图、规划路径等;交互下发导航目标。

source /opt/ros/humble/setup.bash
source /home/lxg/code/xt/gitlab/ros2_learn_ws/install/setup.bash
export ROS_LOCALHOST_ONLY=1
export ROS_DOMAIN_ID=0
cd /home/lxg/code/xt/gitlab/ros2_learn_ws
rviz2 -d '/opt/ros/humble/share/nav2_bringup/rviz/nav2_default_view.rviz' \
  --ros-args -p use_sim_time:=true

等待事项

  • RViz 窗口打开,显示加载的 nav2_default_view.rviz 配置
  • 能看到地图、激光数据、机器人模型等显示元素

成功标志:所有 4 个终端都启动完毕,系统就绪可开始导航测试。

ros2 node list


lxg@lxg:~/code/xt/gitlab/ros2_learn_ws$ ros2 node list
/amcl
/amcl
/behavior_server
/bt_navigator
/bt_navigator_navigate_through_poses_rclcpp_node
/bt_navigator_navigate_to_pose_rclcpp_node
/controller_server
/global_costmap/global_costmap
/lifecycle_manager_localization
/lifecycle_manager_navigation
/local_costmap/local_costmap
/map_server
/map_server
/map_to_odom
/nav2_container
/planner_server
/remapper
/smoother_server
/transform_listener_impl_5d7a8c4f0e70
/transform_listener_impl_7aea100017c0
/transform_listener_impl_7aea140017c0
/transform_listener_impl_7aea280017f0
/transform_listener_impl_7aea300017f0
/transform_listener_impl_7aea50001e00
/velocity_smoother
/waypoint_follower

为什么仿真未运行就有这么多节点

本质原因是:

🟢 你执行了 Nav2 / SLAM 的 launch 文件 🟢 这些 launch 一次性启动了整套系统 🟢 节点是长期运行进程

定位与地图层(Localization & Map)

节点 作用 输入 输出 关键点
/map_server 提供静态地图 map文件 /map 只读地图,不参与计算
/amcl 粒子滤波定位 /scan, /tf, /map /pose 机器人在地图中的位置
/map_to_odom map→odom修正 AMCL结果 TF变换 保证全局定位稳定

导航决策层(Nav2 Core)

节点 作用 输入 输出 关键点
/bt_navigator 行为树导航控制中心 goal action执行 Nav2“大脑”
/behavior_server 行为控制(恢复/避障) planner结果 控制指令 卡住时负责“救车”
/planner_server 全局路径规划 map + pose global path A*/Smac等
/controller_server 局部轨迹控制 path + scan /cmd_vel 真正控制车动
/smoother_server 路径平滑 global path smooth path 减少抖动

地图代价系统(Costmap)

节点 作用 输入 输出 关键点
/global_costmap/global_costmap 全局障碍地图 map + tf + scan global costmap 规划用
/local_costmap/local_costmap 局部避障地图 scan + odom local costmap 避障用

生命周期管理(Nav2控制器)

节点 作用 说明
/lifecycle_manager_navigation 控制Nav2启动顺序 自动activate各模块
/lifecycle_manager_localization 控制定位模块 AMCL生命周期管理

运动控制层(Motion Control)

节点 作用 输入 输出
/velocity_smoother 速度平滑 cmd_vel 平滑cmd_vel
/controller_server 核心控制 path cmd_vel

TF & 系统基础层

节点 作用 说明
/transform_listener_impl_* TF监听器 Nav2内部自动创建
/tf(话题) 坐标变换 map→odom→base_link
/odom 里程计 来自仿真/底盘

任务执行层(行为系统)

节点 作用
/waypoint_follower 路径点巡航
/bt_navigator_navigate_to_pose_rclcpp_node 单目标导航
/bt_navigator_navigate_through_poses_rclcpp_node 多点导航