3. 自动驾驶系统架构

自动驾驶系统本质上是一个强实时、强耦合、跨域协同的机器人系统。在ROS2中,我们不再把功能堆叠进一个巨型进程,而是按“感知—定位—规划—控制—底盘—HMI”六大功能域拆分为可独立编译、独立部署、独立观测的节点。节点化的核心价值在于:让每个模块拥有清晰的数据契约、明确的生命周期和可替换的通信中间件,从而支持仿真与实车共用同一套软件栈。

节点化设计的三条主线:
1. 数据契约:用自定义msg定义感知目标、定位位姿、轨迹、控制指令,避免“裸数组”传递;
2. 通信语义:高频传感器用零拷贝/共享内存,控制指令用实时优先级,HMI用低频率状态回传;
3. 生命周期:传感器驱动、感知、规划、控制按需启动,支持仿真模式与实车模式切换。

一、六大模块的ROS2节点职责与数据流

感知模块通常拆分为lidar_driver、camera_driver、object_detection、fusion_tracker等节点,输出统一的目标列表ObstacleArray。定位模块由gnss_driver、imu_driver、lidar_odometry、map_matcher和ekf_localizer组成,最终发布Odometry与TF树。规划模块分为global_planner与local_planner,前者生成路由,后者生成带时间戳的Trajectory。控制模块controller订阅轨迹与车辆状态,输出ControlCommand。底盘模块chassis_driver将控制指令转换为CAN报文,并回传轮速、转角、挡位。HMI模块hmi_bridge负责可视化、接管请求与状态显示。

ROS2 自动驾驶节点化架构:感知 → 定位 → 规划 → 控制 → 底盘 → HMI 感知 Perception lidar_driver camera_driver object_detection fusion_tracker → ObstacleArray 定位 Localization gnss_driver imu_driver lidar_odometry ekf_localizer → Odometry / TF 规划 Planning global_planner local_planner behavior_selector trajectory_smoother → Trajectory 控制 Control controller lateral_ctrl longitudinal_ctrl safety_monitor → ControlCommand 底盘 Chassis chassis_driver can_bridge steer_actuator brake_actuator → ChassisState 底盘状态 / 定位反馈 / 感知目标 回传至规划与控制(闭环) HMI 人机交互 hmi_bridge / rviz2 / 状态面板 接管请求 · 故障告警 · 模式切换 订阅:/diagnostics /vehicle_state /planning/trajectory 前向数据流 闭环反馈 HMI 监控与接管

二、节点化设计的关键方法

第一,按频率与实时性分层。传感器驱动与底盘CAN收发属于硬实时层,建议使用rclcpp并配置SensorDataQoS;感知与定位属于软实时层,可用rclcpp_components组合进同一进程减少拷贝;规划与控制属于周期任务,建议使用timer以固定周期触发。第二,用自定义接口固化契约。例如定义Obstacle.msg包含id、pose、velocity、confidence,避免下游反复解析原始点云。第三,生命周期管理。通过lifecycle_node实现未配置、未激活、激活、去激活四态,仿真时只激活感知与规划,实车时全部激活。

# 典型节点启动片段(launch.py)
perception = Node(
    package='perception',
    executable='fusion_tracker',
    name='fusion_tracker',
    parameters=[{'use_sim_time': True}],
    remappings=[('/input/objects', '/detection/objects')]
)
controller = Node(
    package='control',
    executable='controller',
    name='controller',
    parameters=[{'control_rate': 50.0, 'lookahead': 3.5}]
)

三、仿真与实车联调场景

在仿真环境中,use_sim_time必须为true,所有节点时间源统一到/clock。感知节点订阅Gazebo或CARLA发布的/lidar/points与/camera/image_raw,定位节点使用仿真真值或模拟GNSS噪声。规划节点接收/map与/goal_pose,控制节点输出/control/command,底盘节点在仿真中由ackermann_drive插件替代真实CAN。HMI通过rviz2显示轨迹、目标框与车辆状态。切换到实车时,只需替换驱动层节点与use_sim_time参数,上层算法节点保持不变,这正是节点化设计的最大收益。

模块 核心节点 输入话题 输出话题 建议频率
感知 fusion_tracker /lidar/points, /camera/image_raw /perception/objects 10–20 Hz
定位 ekf_localizer /gnss/fix, /imu/data, /lidar/odom /localization/odom, /tf 50 Hz
规划 local_planner /perception/objects, /localization/odom /planning/trajectory 10 Hz
控制 controller /planning/trajectory, /vehicle_state /control/command 50 Hz
底盘 chassis_driver /control/command /vehicle_state, /can/frames 100 Hz
HMI hmi_bridge /diagnostics, /vehicle_state /hmi/request, /hmi/display 5–10 Hz

四、常见误区与复盘

误区一:把所有功能塞进一个节点,导致仿真时无法单独替换传感器模型。
误区二:话题命名随意,仿真与实车使用不同话题名,联调时大量重映射。
误区三:忽略QoS配置,高频点云使用默认可靠传输,造成内存暴涨与延迟抖动。
误区四:HMI直接订阅原始点云,导致界面卡顿,应订阅降采样或目标级数据。

复盘建议:在项目初期就建立interface包统一管理msg与srv,建立bringup包统一管理launch与参数YAML,建立sim与vehicle两套参数覆盖文件。每次联调前用ros2 topic hz与ros2 topic delay检查关键链路,用ros2 doctor排查网络与中间件配置。只有把节点边界、数据契约和生命周期三件事做扎实,感知、定位、规划、控制、底盘与HMI才能真正做到“仿真即实车、实车即仿真”的高效联调。