这套从仿真到实车的开发路线,我在不同项目里反复走了好几轮,每一步踩坑的规律其实都很一致。这篇文章我会以 ROS2 小车开发为主线,围绕 Autoware 这套开源软件栈,把从仿真环境搭建到实车部署的完整链路掰开讲清楚,包括版本选型、接口转换、标定、参数调优和故障排查。内容比较长,但可以按需跳读,适合刚准备入手智能小车、又被"仿真能跑、上车就废"困扰的开发者。
1. 整体路线设计:为什么先仿真再上车
1.1 先想清楚你要做一台什么样的车
很多人在第一步就栽了跟头:买了一台现成小车底盘,就直接往车上塞 Autoware,结果一启动系统就崩,根本分不清是传感器问题、驱动问题还是算法问题。我建议所有项目开始之前,先花一整天只做一件事——把需求写成一句话。
这句话至少要回答四个问题:车辆运动模型是什么?运行场景是室内还是园区?速度上限是多少?要完成什么任务?
运动模型决定了底层控制接口。阿克曼底盘和差速底盘在 Autoware 里的控制接口完全不同,阿克曼多了前轮转角,控制指令是速度和转向角;差速底盘是左右轮速,需要换算成纵向速度和横摆角速度。如果你一开始就打算用 Autoware 的规划控制模块,最好选阿克曼底盘,否则很多行为规划逻辑在差速模型上表现得很别扭,需要额外做一层运动模型转换。
运行场景决定了传感器方案。室内小场景可以用单线雷达加轮式里程计,园区场景至少要 3D 激光雷达加 IMU,想要弱 GNSS 环境下也能稳定运行,定位就得靠点云配准而不是坐标直接读取。速度上限则直接关系到安全机制的设计,低速車可以简单用限速节点,高速车踏板和转向必须硬线冗余。
我强烈建议第一版项目选一个低速园区配送场景,限定速度不超过 10 公里/小时。在这个区间内,Autoware 的大部分默认参数都能正常工作,你只需要聚焦于打通链路,而不是跟参数较劲。
1.2 渐进式替换策略:先熟悉全链路再动细节
从仿真到实车,核心指导思想就是"渐进式替换"。不要试图一次性把整套系统从仿真切到实车,而是一次只替换一个环节,跑通了再替换下一个。
最常见的替换顺序是:先替换传感器输入,再替换底盘输出,最后替换硬件计算平台。
具体来说,仿真阶段你用的是仿真雷达发出的 /sensing/lidar/pointcloud 消息,实车阶段要替换成真实雷达驱动的同一消息名。这个替换对你的上层定位模块是透明的,你在仿真阶段调试好的参数可以部分保留。但如果一上来就同时换雷达、换相机、换底盘、换主机,出了问题你根本定位不了是哪个环节引入的。
我在某园区小车项目里就是这么做的:先在 CARLA 仿真环境里跑通完整 Autoware 路径规划,确认行为规划、轨迹生成、控制输出都是正常的;然后让真实雷达录制一段 rosbag,把仿真里的点云订阅源替换成 rosbag 回放,验证定位模块在真实点云上的表现;再之后才接通底盘驱动,用遥控手柄切到 Autoware 控制,最后完整跑通一趟固定路线。每一步之间只改一个变量,排查成本降到最低。
1.3 版本选型与工具链规划:ROS2 和 Autoware 的搭配
版本选型是很多人忽略、却最容易导致后面大量返工的地方。Autoware 的代码迭代非常快,不同版本依赖的 ROS2 发行版、中间件、甚至 Ubuntu 版本都不同。
目前最稳的组合是 Ubuntu 22.04 + ROS2 Humble + Autoware Universe 的某个稳定发布版。这套组合兼容性好,社区文档也多,相关功能包基本都是现成的。Foxy 版本太老,Humble 是目前最平衡的选择;更高版本对系统要求和编译依赖都更苛刻,对小车来说没有实际收益。
工具链规划上,我建议从一开始就用 Docker。Autoware 官网提供的镜像已经把依赖装好了,你只需要在容器里编译自己的工作区,实车上的部署也是拉取同一个镜像,这样仿真和实车的软件环境完全一致,避免出现"仿真好好的、实车编译不过"这种尴尬局面。
除此之外,还要规划好代码仓库结构。我会把工程分成三层:
- 不修改的 Autoware 本体(只依赖官方镜像)
- 自己开发的车辆适配层(底盘驱动、传感器驱动、接口转换)
- 场景配置层(地图、参数、启动脚本)
这样 Autoware 升级时,只需要适配车辆层和配置层,核心算法不被破坏,迁移成本很低。
2. 仿真环境的搭建与核心细节:不出门跑通完整链路
2.1 仿真器选型:三种主流方案怎么取舍
仿真器选型直接影响你后续的开发效率。目前主流的三个选择是 Gazebo、CARLA 和专门为 Autoware 设计的 AWSIM 类仿真器,各有侧重点。
| 仿真器 | 优势 | 短板 | 适合场景 |
|---|---|---|---|
| Gazebo | 轻量、部署快、与 ROS 原生集成度最高 | 场景真实感弱、光照和物理效果有限 | 快速验证算法逻辑、室内小场景 |
| CARLA | 传感器仿真和场景丰富度好、支持多种天气光照 | 依赖较重、与 Autoware 对接需要额外转换层 | 园区复杂环境、感知算法调试 |
| AWSIM 类 | 支持完整的 Autoware 原生接口、传感器仿真质量较高 | 配置门槛高、硬件资源占用大 | 希望模拟最接近真实 Autoware 数据流 |
如果只是想把链路跑通,我建议从 Gazebo 起步,因为它的 Topic 接口最直接,雷达模型也能在模拟环境里发出标准 /sensing/lidar/pointcloud 消息。CARLA 的优势在于场景编辑和传感器配置更精细,适合验证感知算法在复杂光照下的表现,但你需要写 ROS2 桥接节点,把 CARLA 的传感器数据转成 Autoware 约定的话题格式。
我在实际工作中更推荐组合拳:用 Gazebo 做日常开发验证,用 CARLA 做定期的全流程场景测试,这样既保证迭代速度,又能在接近真实的仿真环境里暴露问题。
2.2 Docker 工作流与编译依赖管理
仿真环境搭建最怕的就是编译报错补依赖、补完依赖又冲突。Autoware 官方 Docker 镜像解决了大部分问题,你只需要按版本拉取对应镜像即可。
我习惯的自底向上的工作流是这样的:
先拉取 Autoware Universe 官方镜像,并在容器内创建一个独立工作区,把所有自己的代码都放在这个工作区的 src 下,单独维护;然后基于基础镜像编写一个新的 Dockerfile,在镜像里安装你项目特有的依赖,比如雷达厂商驱动库、CAN 通信库等,这样你拉一下镜像、启动容器,所有依赖就都具备了。
需要注意的一个坑是,容器内外的时间戳和共享内存配置必须保持一致。Autoware 的许多节点依赖共享内存做传感器数据传输,如果你在容器里跑仿真,记得加--ipc=host参数。不然节点启动时报"unable to create shared memory"是家常便饭。还要注意主机和容器之间的用户权限一致问题,我的建议是在启动容器时用--user $(id -u):$(id -g),否则生成的地图文件和 rosbag 在宿主机上经常没有写权限,后续处理很麻烦。
2.3 打通传感器数据流:把仿真话题转成 Autoware 的规范接口
Autoware 不是直接订阅任何仿真器的话题,它对传感器话题名、消息类型、坐标系定义都有严格约定。你需要在仿真器和 Autoware 之间加一层"接口适配节点",把仿真器的输出映射成 Autoware 需要的格式。
最核心的几件事是:
- 点云消息类型转换。仿真器可能输出 SensorData 自定义类型或者点云数据格式,但 Autoware 的感知模块期望的是
sensor_msgs/PointCloud2,这层转换必须做。 - 坐标系连接。Autoware 内部有一套基于 TF 的坐标体系,比如
map、odom、base_link、sensor_*这些坐标帧必须全部存在且连续。仿真器如果没给你稳定的 TF,你需要自己广播一个静态变换,让base_link到雷达坐标的变换存在。 - 时间戳同步。仿真环境容易一次性把整帧传感器数据发出来,导致各话题时间戳完全一致,这在仿真里没问题,但会让你的缓存机制失效。建议在仿真阶段就加入人为的时间偏移模拟,让每个传感器话题的时间戳都稍微错开,更接近实车情况。
这块工作做得好不好,直接决定后面实车迁移的顺畅度。我在仿真阶段花了不少时间整理这套适配层,后来换真实雷达时,只需要把仿真器 Topic 的 source 替换成真实驱动应用,完全不用动其他代码。
2.4 地图制作与坐标系统一:最容易卡壳的环节
很多人以为先把小车放进去就能跑自动驾驶,结果卡在了地图上。Autoware 使用点云地图做定位、再用 Lanelet2 格式的矢量地图做规划,这两类地图缺一不可。
点云地图的生成流程是:先通过遥控或 SLAM 程序让车辆在场地里跑一圈,采集激光雷达点云,然后离线拼接生成 PCD 文件。这里有一个容易踩的坑——位姿初值。你扫描地图时的起点位姿和每次运行系统时的位姿不可能完全一样,所以定位模块需要一个足够接近真实位姿的初始值。明确的做法是,在地图制作流程中记录起点位置,并在每次启动时手动输入或通过 GNSS 给一个大致的初值,否则 NDT 配准会直接发散。
矢量地图(Lanelet2)可以用 Autoware 配套的绘图工具手动标注车道中心线、停止线、人行横道等,也可以用自动化工具从点云地图提取。对低速园区小车来说,新手阶段手动标一段几百米的路就够用了,不需要追求全场景覆盖。关键是坐标系统一,矢量地图和点云地图必须在同一个坐标系下,一般以map为根,所有变换最终都要回到这根坐标树上。
这个环节我建议你专门留出一到两天来调,因为它是后面所有模块能跑起来的物理基础。地图偏一点,定位就偏一点,规划和控制全都会跟着偏。
3. 从仿真走到实车:硬件线控、传感器标定与 Adapter 开发
3.1 底盘线控改造与底层通信协议设计
实车部署的第一步是把车本身改造成可以被上层软件控制的设备。市面上大多数小车底盘出厂时自带遥控功能,但不一定开放底层通信协议,你需要和供应商确认能否提供指令通道。
我踩过最典型的坑是买来的底盘协议是闭源的,只能在厂商提供的上位机软件里控制。后来更换了一款支持 CAN 协议开放的底盘,才把上游控制打通。所以选型阶段第一件事不是看动力参数,而是看通信协议是否开放、是否有完整文档。
底层通信协议设计上,我建议你定义一个统一的线控指令话题,不要直接用厂商协议。比如自定义一个/vehicle/cmd_vel话题,消息内容包含纵向速度和前轮转角,然后写一个底盘驱动节点去订阅这个话题并转换成 CAN 帧。这样上层 Autoware 只面向/vehicle/cmd_vel,和硬件无关,将来换底盘只需要替换驱动节点。
还要设计底盘的实时状态反馈。驱动节点要定期上报当前速度、转角、电量、异常状态码等,并转发成一个/vehicle/status话题给 Autoware 的车辆状态模块。如果这个状态话题缺失,Autoware 的控制器会进入保险模式,表现为"目标速度一直下发但车辆毫无反应"。
3.2 传感器安装与联合标定:雷达、相机、IMU 缺一不可
实车传感器标定是另一个容易被轻视、却直接决定感知和定位质量的环节。
先讲安装。激光雷达最好装在车顶或车头中央,保持水平,尽量让点云能够覆盖车辆四周,特别是前方。IMU 的安装位置要尽量靠近车辆质心,远离电机等震动源。相机安装高度和俯仰角要根据你的检测目标来定,如果是低速园区车,前方 45 度左右俯视是比较稳妥的。
标定要解决的核心问题是:每个传感器在车辆几何中心坐标系下的位姿(位置和姿态)。这个位姿不对,Autoware 就无法正确地把点云投影到相机图像上,也无法把 IMU 的加速度和角速度正确关联到车体运动。
雷达和相机之间的外参标定我建议用标定板法,在场景里放一块已知尺寸的标定板,同时采集点云和图像,提取角点并求解位姿变换。雷达和 IMU 的标定更麻烦一些,常见做法是在无 GNSS 遮挡的场地里让车辆做缓慢的加减速和转向运动,用连续时间优化方法估计雷达与 IMU 之间的变换和时序偏移。这一步如果没做准,定位模块即使在仿真里完美运行,实车上也会频繁发散。
标定结果一般保存为 YAML 文件或 TF 静态变换,务必检查每个传感器到base_link的坐标帧变换顺序是否一致。一个常见的低级错误是把雷达的 X 轴方向标反了,定位模块直接认为车辆朝后走,轨迹规划方向相反。
3.3 车辆接口节点:把 Autoware 的控制指令变成真实的油门、刹车和转向
Autoware 的内部控制接口分为几层,最终输出控制命令的控制模块会发送到一个车辆接口节点上。开发和实车部署时,你需要实现一个车辆适配节点,接收 Autoware 输出的速度指令和转向指令,然后转换成底盘能执行的指令格式。
在 Autoware Universe 中,这套接口的默认实现是 AutowareVehicleInterface。你需要做的就是继承或实现其中的消息类型,将控制消息映射到驾驶命令,并且从中拆出目标速度、目标转向、目标挡位等字段,逐条映射到底盘协议里。
有一个经常被忽略的细节:Autoware 输出的速度指令是连续变化的期望值,底盘执行时需要有加速度限制和启动逻辑。如果底盘没有自带的加速度斜坡限制,你要在适配节点里加一个斜坡生成器,否则启动瞬间会出现突然窜出去的情况,这种体验在仿真里完全模拟不出来。
同样的,转向指令要限制最大角速度。否则仿真里没事,实车上转向电机容易过流保护,导致底盘直接停摆。
3.4 安全保障:急停、限速、心跳监控
实车安全机制的优先级排在所有功能开发之前。没有安全机制的自动驾驶小车是一颗定时炸弹,这句话不是开玩笑。
我的最低安全配置有三层:
第一层是硬线急停。一个物理急停按钮直接串联在控制回路里,按下即切断驱动电源或把指令置零,不经过任何软件逻辑。
第二层是软件看门狗。底盘驱动节点和 Autoware 之间要有一个心跳机制,比如每 100 毫秒发送一次心跳消息,如果底盘连续 500 毫秒没收到心跳,自动进入安全停车状态。这个机制能在上层软件崩溃时救你一命。
第三层是速度与边界限制。在车辆适配节点里写死最高绝对速度值和最大转角值,Autoware 的算法即使发疯输出超大速度,底盘层也不会执行超过限制的指令。我还会在这个节点里加一条规则:如果当前速度超过设定值持续时间超过一定长度,自动刹车并触发急停状态,需要手动复位才能重新启动。
这三层机制每一层之间是独立的,任何一层失效其他层仍能兜底。千万别让自动驾驶算法成为唯一的安全依赖。
4. 实车部署中的工程化调优:定位、规划与控制
4.1 定位模块:NDT/ICP 点云配准与初值设置
Autoware 中最常用的定位方式是基于点云配准的 NDT 匹配。原理是把当前帧点云对齐到预先构建的点云地图上,输出位姿。这听起来简单,实际操作中需要注意的参数远比想象中多。
首先是初值质量。NDT 是局部优化算法,如果初值偏差太大,根本配不上。园区小车建议启动时让 GNSS 给一个绝对初值,如果没有 GNSS,就在固定停车位设计一个启动等待逻辑,让车辆摆放位置尽量固定,然后把固定位置硬编码为默认初值,这是最朴素也最有效的方案。
其次是配准参数。NDT 的分辨率参数(ndt_resolution)过大,匹配结果粗糙;过小又容易受局部点云噪声影响。以 3D 雷达为例,园区场景 2 到 3 米的体素分辨率是比较合理的起点。另外需要关注点云降采样参数,保留太多点会拖慢计算,导致定位频率下降;太少又会降低匹配精度,我一般会控制每帧参与匹配的点数在五千到一万左右。
最后是 IMU 融合。Autoware 的定位模块支持把 NDT 的结果和 IMU、轮式里程计融合输出平滑位姿,实测下来比纯 NDT 稳定很多。但这个融合效果的上下限由 IMU 的标定质量和车辆振动水平决定,如果车辆震动过大,IMU 数据里有大量噪声,融合反而会把噪声传进位姿,导致轨迹抖动。这也是为什么我在前面强调 IMU 安装位置和标定质量。
4.2 规划模块:场景配置与行为规划参数
Autoware 的规划模块分为行为规划和运动规划两层,行为规划负责决策(停车、直行、变道),运动规划负责生成具体可执行的轨迹。在低速园区场景下,这两个层面需要调的参数不太一样。
行为规划的默认参数偏向于乘用车高速场景,在小车上会出现几个典型问题:一是停车线检测过远,车辆在很远处就减速;二是对障碍物的碰撞检测范围偏大,导致小车频繁急刹。处理方式是在行为规划配置中缩小检测距离和减速距离参数,让决策节奏和低速小车的合理行为一致。
运动规划层面的关键参数是采样频率和轨迹平滑度。Autoware 的轨迹生成一般有周期性,你需要在平滑度和实时性之间做取舍。我在小车上的经验是,把重新规划周期设在 100 到 200 毫秒之间,速度采样步长压缩到小车可达范围,否则规划器经常生成无法执行的急加速轨迹。
还有一点,Autoware 的轨迹规划默认是"完整的轨迹点"输出,也就是从当前位置到目标点的全段路径。实际部署中我建议开启轨迹裁剪功能,只发布未来一段时间内的轨迹点,这样遇到突发障碍物时,控制模块能更快响应,轨迹重规划延迟也更低。
4.3 控制模块:横纵向 PID/LQR 参数整定
控制是最后把规划轨迹变成车轮转动的一环,也是最能直观感受到"差一点就是不行"的部分。Autoware 默认控制算法的参数很大概率在小车上不合适,你需要自己整定。
纵向控制常见的组合是 PID,关键参数是比例、积分、微分增益。小车负载小、惯性小,积分项容易引起超调,我实际使用时会明显减小积分增益,甚至置零,只依靠比例和微分控制。起步阶段平滑性比速度跟踪精度更重要,因为突然的大误差会导致突然的大输出,表现在车辆上就是猛冲。
横向控制我推荐用纯跟踪或 LQR 两者搭配。纯跟踪的好处是参数少、直观,一个预瞄距离参数就能调出稳定效果;缺点是在曲率变化大的路段容易出现切弯误差。LQR 的调优更复杂,但稳定性更好。对小车的建议是先用纯跟踪跑通,等所有链路稳定后再切 LQR 并做细致标定。
纯跟踪的预瞄距离跟速度直接相关,低速下预瞄太远,轿车会明显切内弯。我通常用动态预瞄公式,让预瞄距离随速度增加而增大,速度为零时有一个最小预瞄距离保证起步不抖动。
4.4 时序同步与消息丢帧:实车上最容易翻车的点
仿真和实车一个巨大的差异是时间行为完全不同。仿真里所有节点都在同一台处理器上,几乎没有延迟和丢帧;实车上传感器通过不同的通信链路进入主机,时序完全不一致。
这个问题最典型的表现是,底层收到转向指令时,实际响应已经晚了。如果控制频率是 10 到 20 赫兹,几百毫秒的延迟就会被放大成明显的蛇形轨迹。处理办法有几个:
- 尽量提高车辆状态和指令的发布频率,比如 50 赫兹,减少控制周期带来的固定延迟。
- 在车辆适配节点里记录发送时间戳,底盘返回位置时也记录时间戳,通过往返时间估算系统的实际通信延迟,在控制补偿中减去这个值。
- 检查某个传感器话题的消息频率是否稳定。真实雷达和模拟雷达的一个明显区别是,真实雷达在激光返回强度弱时偶尔丢帧,这会导致定位模块的输入突变。我的做法是不直接中断控制,而是让定位模块保留最后一置信位姿,并设一个超时判定,只有连续多帧都不更新才切换状态。
时序问题往往比参数问题更难发现,因为它表现出的症状和参数没调好非常像,都会让车走不直、停不准。排查时先检查消息时间戳,再用 rosbag 回放对比仿真和实车的数据流节奏。
5. 常见问题与踩坑实录(含速查表)
5.1 仿真能跑、实车不动的排查思路
这类问题是群里问得最多的。仿真里 Autoware 正常规划,拉到实车上车辆完全不动,或者只动一下就不动了。我总结出一个系统性的排查顺序,按这个顺序走,大概率能快速定位问题。
第一步,确认车辆适配节点是否收到控制指令。用监听工具看/vehicle/cmd_vel话题是否有稳定的消息输出,如果没有,说明上游规划或控制模块没有正确输出,需要回看规划状态和 TF 树。
第二步,确认适配节点到底盘的通信是否畅通。很多协议坑都在这层,比如 CAN 波特率不对、帧 ID 错误、校验位格式对不上,消息虽然从软件中发出去了,但底盘根本解析不出来。建议在开发阶段就封装一个"离线发帧工具",不依赖 Autoware 就能直接向底盘发送测试指令,先排除硬件链路。
第三步,检查底盘的状态上报。如果上报的速度、角度一直是零,有可能是底盘自带的线控使能信号没有被激活。很多底盘需要先发一帧使能指令才能对后续速度指令产生响应,这个逻辑往往藏在厂商文档不太显眼的位置。
第四步,查看 TF 树。Autoware 的控制模块要求所有坐标变换都存在,如果base_link到odom的变换不是持续广播,控制器状态估计会异常,输出会被抑制。
| 症状 | 优先排查项 | 常见坑 |
|---|---|---|
| 小车完全无反应 | 心跳使能信号、CAN 帧格式 | 厂商协议需要先发使能才能响应 |
| 小车动一下即停 | 速度斜坡超限、安全看门狗超时 | 加速度过大会触发底盘保护 |
| 小车只转向不前进 | 速度指令消息类型映射错误 | 输入输出单位不一致(m/s 与 km/h 混淆) |
| 原地抖动 | 纵向 PID 超调 | 积分项增益过大或控制频率过低 |
5.2 定位漂移和轨迹不平滑的排查路径
定位漂移是实车部署最折磨人的问题,因为它的原因非常多样。我习惯按四个维度排查:地图质量、初值、传感器时间戳和 IMU 融合。
地图质量是首要嫌疑。如果你扫描点云地图时本身就有漂移,那么所有在该地图上的定位都会有系统偏移。检查方法很简单,把一帧实时点云叠加到地图上,看边缘轮廓是否对齐,如果有个固定几厘米甚至几十厘米的偏差,那大概率是地图本身有问题,重新扫描地图比重调参数更有效。
初值排查相对容易,记录启动时 NDT 输出的初始位姿和车辆真实位姿的偏差,如果超过 50 厘米或 5 度,肯定配不上。这种场景我会在启动脚本里强制要求操作员确认初始位姿,或者在停车位位置设计码盘和磁条定位限位,让每次启动位置尽量固定。
时间戳问题比较隐蔽。如果雷达点云的时间戳来自不同时钟域,比如驱动节点用了本地时间而其他模块用了系统时间,定位模块的内部积分会引入位移偏移。用手动检查工具查看点云消息的时间戳和真值差距,偏差超过几十毫秒就要处理。
IMU 融合问题常常表现为车辆低速时定位正常、转弯时突然跳变。这说明 IMU 的角速度数据没有被正确积分。重新检查 IMU 的内参和安装坐标,必要时重新做在线标定。
5.3 Autoware 启动异常与 TF/地图问题快速检查
Autoware 启动时报错和运行时莫名中断是最频繁的软性问题。很多新手一看到日志一堆红色报错就懵了,其实很多报错不会直接影响运行。
最基础也是最重要的检查项是 TF 树完整性。Autoware 正常运行依赖完整且无跳变的 TF 树。用相关工具打印 TF 树,确认从map到base_link再到所有传感器坐标的变换都存在且更新频率正常。一个常见错误是某些静态变换只发布了一次,但在某些节点内部临时请求变换时因为没有缓存而返回失败,表现为偶发规划中断。
第二个检查项是地图文件路径和坐标帧是否匹配。点云地图的 PCD 文件加载后要确认它是否有有效的坐标系标注,Lanelet2 地图里的每段车道线要确保都在地图坐标系下有正确的坐标值。我遇到过 Lanelet2 地图的参考点偏移了几十米,点云地图正常但规划轨迹直接冲出场地的诡异问题。
第三个检查项是参数文件中是否有 NaN 或异常的大数。Autoware 的配置文件有时会因手误写进错误参数,比如将速度上限设成 100 米/秒,规划器会在后台生成一条无法执行的轨迹,控制模块无法追踪,表面看起来像是卡死。
| 症状 | 快速检查 | 典型原因 |
|---|---|---|
| 节点启动后崩溃 | 查看依赖话题是否存在 | 消息类型或话题名不匹配 |
| 规划时断时续 | 打印 TF 树、查看漂移类话题 | TF 跳变或某传感器偶发丢帧 |
| 轨迹全部偏出道路 | 检查地图原点与参考点 | Lanelet2 地图坐标系偏移 |
| 运行几分钟后停止 | 检查 rosbag node 内存占用和消息队列 | 共享内存溢出或日志磁盘写满 |
5.4 时间线与学习路线建议:从零到 Demo 的合理排期
很多朋友问我,从零开始、没有相关基础,多久能把这套东西跑起来。以每周能投入 10 到 15 个小时为例,我的建议是一个月内先跑通仿真全流程,两个月内实现一个小范围实车 Demo。
第一周重点是环境搭建和熟悉 ROS2。先把 Ubuntu 和 Docker 装好,跑通 Autoware 的官方 Demo 仿真,理解话题、节点、TF 树这些基本概念。不用急着改代码,先让系统跑起来是最重要的。
第二周到第三周重点做地图和接口适配。用仿真器跑一圈场景,生成点云地图并手动标注 Lanelet2 地图。同时把仿真数据接入 Autoware,确认传感器话题和车辆话题都满足规范。
第四周开始写车辆适配节点。先在仿真的车辆模型上测试驱动逻辑,然后把真实的底盘接入,至少要让车能在遥控模式下被 Autoware 接管并回应指令。
第五周到第六周做标定和参数调试。传感器联合标定、定位调参、规划控制参数整定,让小车能沿一条固定路线稳定运行。第七周留出足够的余量处理各种突发问题,做最后的 Demo 录像。
这个排期比较紧凑但对大部分人来说可执行。如果仿真阶段压得太紧,后面的实车阶段一定会加倍奉还。我见过太多人为了省两周时间跳过仿真细节,最后在实车上花了两个月调都不回来。
一些最终的体会
把 ROS2 小车从仿真带到实车,最大的感受就是仿真和实车的墙永远存在,但墙的厚度取决于你在仿真阶段花了多少心思。接口适配层、时间戳处理、地图坐标系、驾驶能力限制,这些抽象问题如果在仿真阶段提前模拟,实车上的大部分灾难都可以提前消化掉。我一个人在这条路上踩过不少坑,写出来就是希望大家少走几步。如果你也是刚起步,别急着追求复杂功能,先让一辆小车在一段几百米的固定路线上整圈跑稳,再谈扩展。空间越小,你越能看清整个系统里每一环的真实脾气。