1. 为什么选择 Autoware.universe 而不是旧版 Autoware.AI
如果你在两三年前搭过自动驾驶环境,大概率接触的是 Autoware.AI 那一套——基于 ROS1 Melodic,用 Catkin 编译,节点之间靠自定义消息硬连。那套东西能跑,但维护起来很痛苦:传感器驱动版本锁死、感知模块耦合严重、想换个激光雷达型号就得改一堆 launch 文件。Autoware.universe 是 Autoware 基金会主导的下一代架构,底层直接切到 ROS2,整个代码库拆成了autoware.core、autoware.universe、autoware.iv等几个仓库,其中autoware.universe是功能最全、更新最活跃的那个,涵盖了感知、定位、规划、控制全链路。
我选它做实车调试环境,核心原因有三个。第一,ROS2 的 DDS 通信机制天然支持多机分布式部署,车上工控机和调试笔记本之间不需要额外写网络桥接代码,配好ROS_DOMAIN_ID就能互通。第二,Autoware.universe 的模块化程度高,感知和规划之间通过标准化的autoware_auto_perception_msgs等消息包解耦,你换一个检测模型不影响下游规划。第三,社区活跃,GitHub 上 issue 响应快,遇到编译报错基本能搜到同款。
但代价也很明显:ROS2 的构建系统colcon比catkin复杂,依赖管理用rosdep加vcstool,首次编译动辄两三个小时,而且对 Ubuntu 版本和 CUDA 驱动版本极其敏感。下面我按实际搭建顺序,把每一步的坑和理由都讲清楚。
1.1 硬件与系统版本的选择逻辑
实车调试环境和仿真环境最大的区别是:仿真里你可以随便用最新版,实车必须考虑工控机的算力和传感器驱动的兼容性。我用的配置是:
| 组件 | 型号/版本 | 选择理由 |
|---|---|---|
| 工控机 | Intel i7-12700 + 32GB RAM | 感知模型推理吃 CPU 单核性能,32GB 是跑通全栈的最低线 |
| GPU | NVIDIA RTX 3060 12GB | CUDA 核心数够跑 YOLO 系列,12GB 显存能同时加载多个模型 |
| 系统 | Ubuntu 22.04 LTS | Autoware.universe 官方主推 22.04 + ROS2 Humble |
| 激光雷达 | 速腾聚创 RS-16 | 驱动在 ROS2 下有现成包,点云格式标准 |
| 组合导航 | 华测 CGI-610 | 输出标准 NMEA 和 ROS2 话题,省去自己写驱动 |
注意:不要用 Ubuntu 20.04 硬装 Humble,虽然有人成功过,但
rosdep依赖树会出各种版本冲突,后期维护成本极高。直接上 22.04,省心。
1.2 ROS2 Humble 的安装与源配置细节
ROS2 Humble 的安装本身不复杂,但国内网络环境下apt源的速度直接决定你今晚能不能睡。我习惯先换清华源,再装 ROS2:
# 换系统源 sudo sed -i 's/archive.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list sudo sed -i 's/security.ubuntu.com/mirrors.tuna.tsinghua.edu.cn/g' /etc/apt/sources.list # 添加 ROS2 源 sudo apt install software-properties-common curl sudo curl -sSL https://raw.githubusercontent.com/ros/rosdistro/master/ros.key -o /usr/share/keyrings/ros-archive-keyring.gpg echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/ros-archive-keyring.gpg] http://packages.ros.org/ros2/ubuntu $(. /etc/os-release && echo $UBUNTU_CODENAME) main" | sudo tee /etc/apt/sources.list.d/ros2.list > /dev/null sudo apt update sudo apt install ros-humble-desktop ros-dev-tools装完之后source /opt/ros/humble/setup.bash,然后ros2 run demo_nodes_cpp talker测试一下。如果报command not found,八成是没 source 或者 bashrc 没写对。我建议直接把 source 写进~/.bashrc,但要注意顺序:先 source ROS2,再 source 你的工作空间。
2. Autoware.universe 源码拉取与依赖安装的完整链路
Autoware.universe 的源码管理用vcstool,它读取一个.repos文件,里面列出了所有需要克隆的仓库和对应分支。这个设计的好处是版本锁定明确,坏处是首次拉取量大,而且国内访问 GitHub 经常断。
2.1 用 vcstool 拉取源码的正确姿势
官方推荐的工作空间结构是:
autoware_ws/ ├── src/ │ ├── autoware.universe/ │ ├── autoware.core/ │ └── ...具体操作:
mkdir -p ~/autoware_ws/src cd ~/autoware_ws wget https://raw.githubusercontent.com/autowarefoundation/autoware/main/autoware.repos vcs import src < autoware.repos这里有个坑:autoware.repos里引用的仓库有几十个,vcs import是串行的,中途任何一个仓库克隆失败,整个命令就中断。我的做法是写个循环重试脚本:
for i in {1..5}; do vcs import src < autoware.repos && break echo "第 $i 次重试..." sleep 3 done如果某个仓库实在拉不下来,可以单独用git clone指定--depth 1浅克隆,然后手动放到对应目录。但要注意分支必须和.repos文件里写的一致,否则编译时消息类型对不上。
2.2 rosdep 依赖安装的加速与排错
rosdep是 ROS 的依赖管理工具,它会扫描package.xml里的依赖声明,然后调用apt安装。Autoware.universe 的依赖列表非常长,包括 PCL、OpenCV、Eigen、CUDA 相关库等。
sudo rosdep init rosdep update rosdep install -y --from-paths src --ignore-src --rosdistro humblerosdep update这一步在国内经常超时,因为要访问 raw.githubusercontent.com。解决办法是改rosdep的源地址,或者用代理(这里不展开)。另一个常见问题是rosdep install报某个包找不到,通常是该包的 ROS2 版本还没发布到 apt 源,需要从源码编译。遇到这种情况,先看报错信息里的包名,去 GitHub 搜ros2_<包名>,大概率能找到源码仓库,手动克隆到src/下再重新rosdep install。
提示:
rosdep install执行前先rosdep update,而且 update 成功后不要随便清缓存,否则又要重新拉。
2.3 CUDA 与 TensorRT 版本的匹配问题
Autoware.universe 的感知模块大量使用 TensorRT 做推理加速,而 TensorRT 版本和 CUDA 版本是强绑定的。我用的组合是 CUDA 11.8 + TensorRT 8.5,对应 Ubuntu 22.04。如果你装的是 CUDA 12.x,TensorRT 需要 8.6 以上,但 Autoware 的某些包在 CMake 里写死了find_package(TensorRT 8.5),会直接报错。
检查版本:
nvcc --version dpkg -l | grep tensorrt如果版本不匹配,要么降级 CUDA,要么改 CMakeLists.txt 里的版本号。我建议直接按官方 Docker 镜像里的版本组合来,那是经过验证的。官方autoware-universe:humble-latest镜像里 CUDA 是 11.8,TensorRT 是 8.5。
3. colcon 编译:从第一次报错到成功出包
colcon build是 ROS2 的构建命令,比catkin_make灵活,但也更容易因为环境变量没配好而失败。Autoware.universe 全量编译在 i7-12700 上大约需要 40 分钟到 1 小时,如果开了--parallel-workers可以快一些,但内存不够会 OOM。
3.1 编译前的环境变量检查清单
在敲colcon build之前,确认以下几项:
source /opt/ros/humble/setup.bash已执行echo $ROS_DISTRO输出humble- CUDA 路径在
PATH和LD_LIBRARY_PATH里 CMAKE_BUILD_TYPE设为Release(默认可能是RelWithDebInfo,编译慢)
我习惯写一个setup_env.sh:
#!/bin/bash source /opt/ros/humble/setup.bash export CUDA_HOME=/usr/local/cuda-11.8 export PATH=$CUDA_HOME/bin:$PATH export LD_LIBRARY_PATH=$CUDA_HOME/lib64:$LD_LIBRARY_PATH export CMAKE_BUILD_TYPE=Release每次开新终端先source setup_env.sh,避免环境漂移。
3.2 常见编译错误与对应修复
错误一:fatal error: Eigen/Core: No such file or directory
这是 Eigen3 没装或者路径不对。sudo apt install libeigen3-dev,然后确认/usr/include/eigen3存在。如果 CMake 找不到,在CMakeLists.txt里加include_directories(/usr/include/eigen3)。
错误二:undefined reference to 'cudnnCreate'
cuDNN 没链接上。检查libcudnn.so是否在LD_LIBRARY_PATH里,以及 CMake 里是否target_link_libraries了${CUDNN_LIBRARIES}。
错误三:error: ‘xxx’ is not a member of ‘autoware_auto_perception_msgs::msg’
消息包版本不一致。通常是autoware_auto_msgs仓库的分支和autoware.universe不匹配。回到.repos文件,确认两个仓库的版本号是对应的,然后重新拉取。
错误四:编译到某个包时卡死或 OOM
用--parallel-workers 2限制并行数,或者单独编译那个包:
colcon build --packages-select <包名> --cmake-args -DCMAKE_BUILD_TYPE=Release3.3 编译成功后的验证步骤
编译完成后,source install/setup.bash,然后:
ros2 launch autoware_launch autoware.launch.xml vehicle_model:=sample_vehicle sensor_model:=sample_sensor_kit如果 RViz2 能起来,并且看到地图和车辆模型,说明基础环境通了。但实车调试还需要配置传感器驱动和车辆接口,下面细说。
4. 实车传感器驱动接入与话题对齐
仿真里传感器数据是假的,实车必须把激光雷达、相机、组合导航的真实数据接进来。Autoware.universe 对传感器数据的话题名和坐标系有严格要求,对不上就不会显示。
4.1 激光雷达驱动的编译与点云格式转换
速腾 RS-16 的 ROS2 驱动在 GitHub 上有rslidar_sdk,编译后发布rslidar_points话题,消息类型是sensor_msgs/PointCloud2。Autoware 期望的话题名是/sensing/lidar/top/points,所以需要 remap:
<node pkg="rslidar_sdk" exec="rslidar_sdk_node" name="rslidar_sdk_node"> <remap from="rslidar_points" to="/sensing/lidar/top/points"/> </node>另外,Autoware 的感知模块要求点云带有ring和timestamp字段,RS-16 驱动默认输出是有的,但如果你用的是其他品牌雷达,可能需要用pointcloud_to_pointcloud2做格式转换。
4.2 组合导航与 TF 树的配置
组合导航输出的是经纬度和姿态,Autoware 需要的是nav_msgs/Odometry和 TF 变换。华测 CGI-610 有 ROS2 驱动,发布/gps/fix和/gps/imu。你需要写一个robot_localization的配置,把 GPS 和 IMU 融合成odom:
ekf_filter_node: ros__parameters: frequency: 50.0 sensor_timeout: 0.1 two_d_mode: false map_frame: map odom_frame: odom base_link_frame: base_link world_frame: odom odom0: /gps/odom imu0: /gps/imuTF 树是 Autoware 的命脉,base_link到lidar的外参必须准。我吃过亏:外参差 5 厘米,规划出来的轨迹就偏半米。标定方法是用卷尺量,然后在sensor_kit的 URDF 里改。
4.3 相机与激光雷达的联合标定
Autoware.universe 的感知融合需要相机和激光雷达的外参。标定工具推荐autoware_camera_lidar_calibrator,它通过 RViz2 里点选对应点来算变换矩阵。标定完成后,把结果写到sensor_kit的calibration目录下。
注意:标定时的光照条件要和实际跑车时接近,否则白天标定的参数晚上用会偏。
5. 车辆接口与 CAN 总线对接的实操细节
实车调试最后一步是让 Autoware 能控制车辆。这涉及 CAN 总线通信和车辆线控协议。
5.1 CAN 接口的初始化与权限配置
Ubuntu 下用can-utils工具:
sudo ip link set can0 type can bitrate 500000 sudo ip link set up can0每次重启都要重新配,所以写个 systemd 服务或者加到rc.local。另外,普通用户访问 CAN 需要权限,加 udev 规则:
SUBSYSTEM=="net", ACTION=="add", ATTRS{name}=="can0", MODE="0666"5.2 车辆线控协议的解析与适配
不同车辆的 CAN 协议不一样,Autoware 提供了vehicle_interface框架,你需要实现一个VehicleInterface子类,把 Autoware 的AckermannControlCommand转成 CAN 帧。以纵向控制为例:
void VehicleInterface::sendControlCommand(const AckermannControlCommand & cmd) { double speed = cmd.longitudinal.speed; double accel = cmd.longitudinal.acceleration; // 转成 CAN 帧 struct can_frame frame; frame.can_id = 0x123; frame.can_dlc = 8; // 填充数据... write(can_socket_, &frame, sizeof(frame)); }调试时先用candump can0看原始帧,确认 ID 和数据长度,再写解析代码。
5.3 实车调试的安全检查清单
上车之前,以下检查必须做:
- 急停按钮功能正常
- CAN 通信超时保护已启用(超过 100ms 没收到指令自动刹车)
- 车辆处于空旷场地,速度限制在 10km/h 以下
- 有人随时准备接管
我第一次实车调试时,因为没设超时保护,CAN 线松了之后车辆直接失控,幸好场地空旷。这个教训值一条命。
6. 调试过程中最容易忽略的三个配置项
6.1 ROS_DOMAIN_ID 与多机通信
车上工控机和调试笔记本要在同一 DDS 域才能通信。默认ROS_DOMAIN_ID=0,但如果局域网里有其他人也在跑 ROS2,会互相干扰。我习惯设成 42:
export ROS_DOMAIN_ID=42两台机器都要设,而且防火墙要放行 DDS 用的 UDP 端口。
6.2 时间同步与 PTP
实车调试对时间同步要求高,激光雷达和相机的时间戳差 10ms 就会导致融合失败。用 PTP 协议同步:
sudo apt install linuxptp sudo ptp4l -i eth0 -m如果传感器不支持 PTP,至少用 NTP 同步到同一台机器。
6.3 日志级别与调试信息输出
Autoware 默认日志级别是INFO,调试时改成DEBUG能看到更多细节:
ros2 run <包名> <节点名> --ros-args --log-level debug但DEBUG日志量很大,跑久了磁盘会满,记得定期清理~/.ros/log。
7. 从仿真到实车的迁移经验
仿真里跑通的配置,实车不一定能用。最大的差异是传感器噪声和延迟。仿真里点云是完美的,实车有雨雾、灰尘、反射。我的做法是先在仿真里把参数调到保守值,实车再逐步放开。
另一个差异是车辆动力学。仿真里的车辆模型是理想化的,实车的转向延迟、刹车响应都不一样。Autoware 的vehicle_model参数需要根据实车实测调整。我通常先做阶跃响应测试,记录转向指令和实际转角的关系,再拟合参数。
最后,实车调试一定要有数据记录。用ros2 bag record把所有传感器话题录下来,出问题可以回放分析。我习惯录/sensing/lidar/top/points、/sensing/camera/front/image、/localization/kinematic_state和/control/command/control_cmd这四个,基本能覆盖 90% 的问题。
提示:
ros2 bag record默认录所有话题,但实车数据量大,一小时能录几十 GB,建议只录关键话题,并且用外接硬盘存。
这套环境搭下来,从零到实车跑通大约需要两到三天,其中编译占一半时间。如果遇到网络问题或者版本冲突,可能更久。但一旦跑通,后续换传感器或者改算法就快很多了。我现在的习惯是每换一个车型,先复制一份工作空间,改配置不改代码,这样出问题能快速回滚。