
机械式激光雷达装在车顶第一次跑通建图算法地图上墙是歪的地面是斜的车辆轨迹和点云对不上。排查了驱动、时间同步、TF树最后发现根因就是激光雷达的外参没标定。后面做相机和雷达融合的时候又踩了一遍标定的坑。这篇笔记就是把我在实际项目中反复用到的激光雷达标定方法、求解原理和实操细节整理出来给后面再做传感器融合的同学省点时间。这篇内容适合三类人看刚接手多传感器融合项目、需要自己完成传感器标定的工程师已经在用标定工具但遇到精度问题、不清楚原理只能盲目调参的开发者以及准备从单激光雷达升级到“雷达相机IMU”多传感器方案的团队。本文以机械式激光雷达Velodyne、禾赛、Ouster这类为主要对象以16线、32线、64线雷达为典型场景展开。1. 标定到底在解决什么问题先把坐标系这事掰扯清楚1.1 一个很直白的理解方式传感器之间互相“看不见”激光雷达标定这件事听起来很高深但本质上解决的问题非常朴素每个传感器都有自己独立的世界观标定就是让它们统一口径。拿我经常打的一个比方两个人站在同一个房间里一个人站在墙角、一个人站在窗边让他们分别描述房间中间那把椅子的位置。墙角的人说“椅子在我东北方向3米”窗边的人说“椅子在我正前方2米”。两个人说的都是真话但因为参考系不同说法完全对不上。要让两个人协同工作就必须知道彼此之间的相对位置和朝向。激光雷达、相机、IMU之间的关系就是这样的。激光雷达看到的是一堆三维点每个点用极坐标表示水平角度、垂直角度、距离。相机看到的是二维像素每个像素用行列坐标表示。IMU测量的是加速度和角速度连坐标都没有只有物理量。这三种设备各自输出的数据如果不经过坐标变换硬凑在一起融合算法根本没法用。标定就是求出它们之间的坐标变换关系。1.2 内参和外参两件完全不同的事很多刚入门的朋友容易把激光雷达的“标定”混为一谈其实要分清内参标定和外参标定两个层面。内参标定针对的是激光雷达本身的测量模型。对于机械式激光雷达来说出厂时每个激光器的垂直角度、水平角度偏移、距离测量偏差是标定过的正常情况下不需要用户重新标定。只有当雷达受到剧烈撞击、拆装维修、或者你拿到的是经过改装的特殊雷达时才需要考虑内参问题。学术界有一些做内参自标定的方法但工程中很少自己去折腾雷达内部的光学参数风险大、收益小一般直接返厂或者用出厂配置。外参标定才是工程中天天打交道的事情。它描述的是雷达坐标系相对于其他传感器坐标系或车辆坐标系的旋转和平移关系。举个例子一个典型的场景激光雷达坐标系L原点在雷达旋转中心车体坐标系V原点一般在后轴中心x向前y向左z向上相机坐标系C原点在相机光心IMU坐标系I原点在IMU物理中心我们要求的就是T_LV雷达→车体、T_LC雷达→相机、T_LI雷达→IMU这些变换矩阵。每个变换矩阵包含6个自由度3个旋转roll、pitch、yaw 3个平移x、y、z。提示外参标定一旦做完后续所有传感器数据都会统一到同一个坐标系下处理。外参错一点融合结果就错一片。尤其激光雷达和相机联合标定外参哪怕偏个两三厘米投影到图像上的误差就是几十个像素根本没法用。1.3 旋转和平移为什么不能用直尺量有人会问外参里的平移量不是可以直接用卷尺量安装位置吗旋转量不是可以用水平尺测吗理论上确实可以实际上误差大得离谱。原因有三雷达的坐标系原点是激光发射棱镜的旋转中心外壳上的某个螺丝孔并不等于坐标系原点你没办法从物理上直接量到坐标系原点。雷达坐标系的三轴方向也不是简单地和外壳对齐的不同品牌甚至不同固件版本定义都不一样。安装支架本身有加工公差靠人工量出来的安装角度误差超过一度很容易。对于100米处的点1度误差就会导致1.7米的横向偏差这在自动驾驶场景下属于灾难级误差。所以“量出来的初值 数据优化求解”是唯一的工程可行路径。先粗装再标定最后验证。2. 激光雷达外参标定的求解原理旋转矩阵、四元数、李代数这些到底怎么用2.1 刚体变换怎么表示先建立数学基础。三维空间中两个坐标系之间的变换用齐次变换矩阵表示T [ R t ] [ 0 1 ]R是 3x3 旋转矩阵满足R^T R Idet(R) 1t是 3x1 平移向量旋转矩阵有9个参数但实际只有3个自由度直接优化9个参数是有约束的工程中通常用四元数或轴角参数化旋转。四元数有4个参数满足单位模长约束轴角3个参数无约束两种都可以取决于你用什么优化库。2.2 激光雷达-IMU标定的核心思想激光雷达和IMU都是三维传感器它们之间的关系可以通过观测同一个环境特征来求解。以激光雷达-IMU外参标定为例最经典的思路是让设备做激励运动六个方向都动一动包括旋转和直线运动。利用激光雷达点云配准估计出雷达的连续运动轨迹也就是雷达在两帧之间的位姿变化。利用IMU积分估计出IMU的连续运动轨迹。因为雷达和IMU刚性安装在同一个平台上它们之间的相对位姿固定所以两者轨迹之间存在一个固定的刚体变换关系。在优化框架中同时优化雷达-IMU外参、时间延迟以及轨迹估计。这里有个关键点激励运动必须充分。如果设备只是静止不动点云配准给出的全是零位移你解出来的外参有无数种可能。只有让传感器在roll、pitch、yaw、x、y、z六个自由度上都有足够的运动激励才能约束住全部6个外参自由度。有一个经典的公开工具是lidar_aligngithub上能找到它做的是雷达与IMU的外部标定基于连续时间轨迹的优化思路不需要标定板对场景要求比较低找个走廊、停车场就能跑。2.3 手眼标定一个数学上很漂亮、落地上很坑的方法激光雷达和相机之间的外参标定很多教材第一反应是“手眼标定”AX XBA是相机在两帧之间的运动B是雷达在两帧之间的运动X是待求的手眼变换矩阵。解这个方程需要至少3组非平行旋转轴的运动数学上很成熟。但工程中我不建议把“手眼标定”作为唯一手段来做雷达-相机标定。原因很实际手眼标定要求两帧之间位姿估计的精度足够高而雷达点云配准、相机位姿估计各自的误差都会污染X的求解。纯旋转运动下手眼标定是退化场景解出来可能完全错误。实际工程中雷达帧率和相机帧率往往不同时间戳对齐本身就有误差。学界最近的研究也表明手眼标定对噪声敏感。**Joint Optimization联合优化**比“先分别估计轨迹、再闭式求解”要鲁棒得多。2.4 联合优化的思路才是正确方向那正确的思路是什么在标定雷达和相机的时候业内普遍认可的做法是布置好标定场景标定板/特征物。连续采集多帧雷达点云和图像数据。建立统一的优化目标所有变量外参、标定板位姿、畸变系数等一起优化。最小化两类误差重投影误差雷达点云中检测到的标定板角点/边缘投影到图像上应与图像中检测到的角点/边缘尽量重合。深度一致性误差相机估计的标定板位姿与雷达观测到的标定板点云位姿之间的差异。Autoware的calibration_camera_lidar工具就是这个思路的完整实现。它用标定板在雷达点云中拟合平面再提取标定板边界和角点与相机图像中的棋盘格角点做联合优化。虽然交互界面写得比较粗糙但数学本质是对的。3. 雷达相机联合标定的实操全流程基于Autoware工具链3.1 工具选型先说清楚各家的底细激光雷达-相机联合标定我实测过的工具有这么几个工具求解方式是否需要标定板上手难度实操评价Autoware calibration_camera_lidar棋盘格 联合优化需要中经典但交互代码偏老依赖多ACSCACSC: Automatic Calibration基于标定板的自动标定做得很完整需要中支持错误帧剔除精度好手动PCD点选 优化手动选点对求初值 优化否低但精度一般速度快应急用不适合量产自制OpenCV PCL完全定制视方案而定高最终量产往往是自制方案我自己在不同项目中都用过Autoware这套。Ubuntu 18.04 ROS Melodic下能比较顺利跑通Ubuntu 20.04 ROS Noetic下需要编译一堆依赖容易踩坑。如果只是验证标定效果建议用Docker跑或者换到18.04环境。3.2 标定板的设计与制作直接影响标定结果上限标定板是整个流程里最容易被轻视的环节。很多人在网上随便买一块棋盘格就开始标定结果在雷达点云里根本检测不到角点或者板面不清晰以为是算法问题其实是板子不合格。我的建议为了雷达-相机联合标定不要用那种很薄的打印棋盘格贴在纸板上至少要满足这几个条件材料对激光雷达反射率有区分度。雷达点云的强度信息intensity依赖材料反射率。深色哑光材料反射率低白色/浅色高反射材料反射率高。如果整个板面都是统一材料贴上打印的棋盘格因为打印墨水和纸张对905nm红外激光的反射差异很小雷达点云的强度图几乎是平的检测算法找不到棋盘格边界。这一点很关键。Autoware工具在雷达点云中提取棋盘格时依赖的是点云强度图中棋盘格黑白色块的边界如果强度没区分度后面全都白搭。推荐方案用铝板或不锈钢板做底板表面贴高反光材料棋盘格。比如在金属板上交替贴上高反光贴纸和黑色哑光贴纸这样在强度图中黑白边界非常明显。市面上有专门的标定板供应商比如OptoCal、MRL也可以自己按这个思路做。板面要平整。雷达点云中拟合平面时板面不平整直接导致平面参数误差角点位置跟着错。尺寸要合适。板子太小在点云中只能看到稀疏的几条扫描线拟合平面不准确板子太大搬运和架设都不方便。我的经验是标定距离在5~15米之间板子边长1.2米左右比较合适。16线雷达的垂直角分辨率约2度5米处相邻扫描线间距约17cm板子太小了扫描点太少。3.3 环境与依赖Ubuntu 18.04下跑通Autoware标定工具的完整步骤Autoware标定工具依赖ROS、Qt、PCL、OpenCV还有一些老的交互库。我推荐在Ubuntu 18.04 ROS Melodic环境下操作以下是命令行步骤# 安装ROS Melodic基础假设已装好 sudo apt-get install ros-melodic-desktop-full # 安装依赖 sudo apt-get install ros-melodic-pcl-ros ros-melodic-cv-bridge ros-melodic-image-transport sudo apt-get install ros-melodic-qt5-qmake ros-melodic-qt-build sudo apt-get install libgl1-mesa-dev libglu1-mesa-dev freeglut3-dev # 下载Autoware标定工具这是一个独立包不一定要下载整个Autoware mkdir -p ~/calib_ws/src cd ~/calib_ws/src git clone https://gitlab.com/autowarefoundation/autoware.ai/autoware_ai_external.git # 或者单独拉calibration_camera_lidar包 # git clone https://gitlab.com/autowarefoundation/autoware.ai/sensing/calibration_camera_lidar.git编译和启动cd ~/calib_ws catkin_make source devel/setup.bash roslaunch calibration_camera_lidar calibration_camera_lidar.launch如果用ROS NoeticUbuntu 20.04需要手动处理OpenCV版本冲突、Qt4/Qt5的API变化我建议非必要别折腾Noetic省下的时间足够完成很多次标定实验了。3.4 数据采集的实操要点这一步决定标定的成败标定工具本身只是求解器喂给它的数据质量不好神仙工具也救不回来。总结我踩过的坑数据采集阶段要注意这些静态采集并控制雷达的“自身旋转噪声”机械式雷达本身在旋转点云中每个点的时间戳不一样。如果标定板不动、雷达也不动安装在车架上静止点云的畸变来自雷达自身旋转产生的时间差这个在标定场景下影响很小可以忽略。但如果雷达装在车上、车在动或者有人扶着标定板在动点云畸变会直接毁掉标定结果。雷达视角要“看得清”标定板对于16线雷达标定板必须放在雷达正前方或接近正前方的位置让尽可能多的激光束扫到板面上。放到侧面扫描线过少点云中的板面会稀疏得无法拟合。距离要覆盖中近距离我一般让标定板在3米、6米、10米三个距离段分别采集每个距离段采集10~20帧。太近2米板面过大超出视场太远15米点云太稀疏检测不稳定。角度要有变化板面正对相机没问题但最好再加一些旋转角度左右各转20度、俯仰转10度让优化过程能够更充分地约束外参的不同自由度。时间同步必须提前处理雷达和相机如果时间戳没对齐每一帧点云和图像的对应关系错位标定结果就是错的而且这种错误很难在后处理阶段发现。3.5 标定流程中的步骤细节和判定方法Autoware工具的标准流程是加载一段雷达bag和对应相机图像。在GUI中选择第一帧和最后一帧或者逐帧点击。标定板检测工具会在点云强度图中识别棋盘格轮廓在图像中识别棋盘格角点。如果检测失败手动微调ROI区域把标定板框出来。初始化外参可以手动输入粗略值或者用默认值。执行优化求解。输出结果到终端和配置文件。判定标定结果好坏的快速办法点云投影到图像上看对齐效果。把标定后的外参用起来将雷达点云投影到图像上观察标定板边缘、树干、路沿石在图像上是否和真实像素对齐。好的标定结果点云彩色叠加图上看物体边缘的重合误差应该在2~3像素以内对于1080P图像50度视场角。4. 雷达-IMU外参标定没有标定板的场景下如何搞定4.1 为什么需要雷达和IMU之间的外参雷达和IMU是自动驾驶最核心的传感器对。IMU提供高频100~200Hz的加速度和角速度雷达提供低频10~20Hz的精确距离测量。两者融合之后可以在IMU帧之间用运动模型做点云畸变补偿。这个场景对外参精度要求极高。如果雷达-IMU外参的旋转误差超过0.5度畸变补偿后的点云会出现明显的运动模糊地图建出来会重影。平移误差没有旋转误差那么敏感但也不能差太多。4.2 实操方案基于连续时间轨迹的优化我实际用得最多的方案是开源的lidar_align工具思路是连续时间的B-spline轨迹拟合输入雷达点云bag IMU数据bag。雷达每帧点云先通过ICP配准得到一个离散的雷达轨迹估计。IMU数据通过积分得到IMU的轨迹估计。把两条轨迹放在一个连续时间模型中同时优化雷达-IMU外参6自由度时间延迟time offset通常是毫秒级雷达轨迹本身IMU bias使用的命令行很简单roslaunch lidar_align lidar_align.launch它会读取一个bag文件bag里必须包含雷达话题传感器消息中带点云数据IMU话题IMU数据4.3 数据采集过程中最容易犯的三个错误lidar_align虽然不需要标定板但数据采集的要求一点都不低错误一运动不够充分。很多人把设备放在桌上转几圈就觉得够了。实际上旋转运动的旋转轴如果过于单一比如只绕z轴旋转x、y、z三个平移自由度无法被有效约束解出来的外参会有一个明显方向“发飘”。正确做法是做“8字形”运动把roll、pitch、yaw和x、y、z六个自由度全部激励起来。错误二场景过于空旷。雷达点云配准在空旷场景下会退化因为没有足够的几何结构提供约束。尽量在楼道、车库、室内走廊这些特征丰富的场景中采集。错误三把时间同步问题留给求解器硬解。lidar_align虽然自带时间延迟估计但如果延迟太大比如超过100ms优化初值离真值太远迭代很难收敛到正确值。采集前先确认雷达和IMU的时间戳已经做了同步处理不要指望一个优化工具把所有工程问题都背下来。4.4 时间延迟和退化场景很多标定结果“看起来对、用起来错”的根本原因我见过太多案例lidar_align跑完了外参里旋转角度看起来合理点云畸变补偿后也看不出大问题但一跑在线SLAM就漂移回头看才发现是时间延迟标定错了几十毫秒。雷达和IMU的时间戳不同步在运动状态下等效于一个“伪外参”。假设外参是对的但时间延迟有30ms在1m/s的运动速度下就等效于3cm的平移误差旋转场景下相当于一个随速度变化的旋转误差在高速急转时甚至可以等效出0.5度以上的旋转偏差。这种误差不是固定值所以很难在静态验证中发现问题一旦跑起来就露馅。我的经验在标定前先单独估计时间延迟用互相关方法把雷达和IMU的粗略延迟算出来确保时间同步误差在1ms以内再交给正规标定流程。有些项目用软件同步比如事件触发、共享时钟可以从根源上解决这个问题。5. 标定结果的验证方法跑一遍静态投影还不够5.1 误差指标怎么量化很多同学标定完就只做一次点云投影到图像肉眼看觉得差不多就收工了。这样做远远不够必须用量化指标判断标定精度。我推荐至少做以下几个验证重投影误差统计选取N个目标标定板角点、路灯杆、树干的边缘分别获取它们在雷达点云中的三维坐标和图像中的二维像素坐标用标定外参投影计算像素误差统计均值、最大误差。2~3个像素内的均值误差属于合格5个像素以上需要重新标定。运动验证让车辆/机器人前进后退观察点云畸变补偿后静止物体墙面、柱子是否仍然锐利。如果外参准点云中静止物体边缘清晰如果外参中的旋转分量偏了物体会出现“双影”或者模糊边。不同距离下的验证只验证了10米内的目标是不够的。在雷达视野内找一个30~50米的目标比如远处的建筑角点、路牌杆投影到图像上检查误差。旋转误差对远距离目标影响更大这也是检验小角度误差是否达标的好办法。5.2 静态验证和动态验证的差异静态验证的本质是“检查外参几何变换是不是自洽”并不能真正反映动态场景下的性能。原因在于动态场景下还叠加了时间同步误差、点云畸变补偿误差、车体振动等因素。所以我建议标定完成后的第一步是静态验证第二步是拎着设备或者开着车跑一段路采集实时数据做在线验证。如果在线跑SLAM或者融合定位时地图重影、轨迹跳变仍然存在优先检查时间同步和运动畸变补偿别急着重新标定外参。外部参数标定只是多传感器融合的一个前置步骤而不是终点。你花一天完成的标定在后续工作中可能要反复验证多次。6. 从入门到量产不同项目阶段的标定策略6.1 研发验证阶段快速标定在你只需要验证算法可行性、不需要绝对精度的时候最快速的方法就是手动选点 拆解求解。在PCL中将雷达点云显示出来手动点选图像和点云中对应的特征点比如墙角、杆顶、标志牌的角点。选6组以上分布均匀的对应点对。用Umeyama算法最小二乘刚体变换估计求解外参初值。再用非线性优化精化。OpenCV和PCL里都有现成的函数一个小时就能搞定。这种方法的精度受限于点选精度一般只能到几十厘米级的平移和1度级的旋转但对于算法验证足够用了。6.2 系统集成阶段规模化标定进入系统集成阶段项目对精度和一致性要求提高这时候需要一个可重复执行的标定流程。我把自己的标定流程固定成下面这样这套流程后来也复制给了产线工程师使用# 1. 采集标定数据雷达bag 图像 IMU建议时长1~2分钟 rosbag record /lidar_points /camera/image_raw /imu/data # 2. 离线预处理 # - 检查时间戳差异如果差异过大先同步 # - 裁剪异常帧剔除雷达运动畸变严重的帧 # 3. 执行联合标定 # Autoware或自研工具输入预处理后的数据 # 4. 输出标定结果并做验证 # 投影误差统计 运动验证每一步的命令和脚本都可以沉淀为团队的工具包提升整个团队的交付效率。6.3 量产阶段效率与鲁棒性的平衡量产阶段需要考虑效率和自动化程度。每台车下线后都要标定如果标定流程需要人工在图形界面里逐帧点选产线根本跑不起来。量产标定方案一般遵循几个原则静态工位标定在产线上设置固定的标定场景固定位置放置标定板/目标物车辆停在固定位置通过自动化脚本完成数据采集和标定不需要人工干预。粗标精标分离粗标定用出厂初值/夹具定位保证外参在合理范围内精标定用数据优化微调最终外参。结果判据固化标定算法输出的置信度分数、重投影误差等指标以自动化测试脚本判定不再依赖工程师的主观判断。量产标定对鲁棒性的要求比精度还高。产线上环境复杂光照变化、反光表面、污渍都可能影响图像和点云质量。一个好的量产标定算法不仅要高精度还要能主动检测失败的帧并剔除或者提示操作员重新采集。7. 踩坑记录与经验总结7.1 实车标定过程中我遇到过的四类典型问题第一类是棋盘格检测失败根因通常是标定板的红外反射率问题深色棋盘格在905nm波段下边界不明显。解决办法就是换高反光标定板不要靠调算法参数硬撑。第二类是时间同步问题导致的标定发散。有一次标定结果怎么优化都收敛不到一个稳定值换成不同帧数据结果都不一样后来检查发现雷达和相机之间的时间戳有大约80ms的系统偏移。修正时间戳之后问题立即消失。第三类是外参初值给得太离谱导致优化陷入局部最优。Autoware的优化是迭代式的初值差太远求解器直接陷入错误局部极小值。我的习惯是先用Umeyama闭式解出一组初值再喂给非线性优化器。第四类是标定结果“过拟合”。在一段数据上标定误差极小但换一段数据就崩。原因通常是采集数据时标定板位置和姿势过于单一外参某些自由度没有被充分激励。解决办法是采集时多变换位置和角度让优化问题有足够的约束。7.2 标定结果准确性的三重检查每次标定完我习惯按顺序做三件事第一静态投影验证观察点云投影到图像后的边缘对齐度。这个检查需要点云颜色化后显示叠加在图像上观察。对齐良好说明外参的旋转和平移都没有大问题。第二距离变化验证。在5米、15米、30米三个距离各找一个参照物将雷达点云投影到图像看误差是否随距离增大而线性增大。如果投影误差随距离快速增大说明旋转误差偏大如果误差在各个距离上基本恒定可能是平移误差偏大。这个规律能帮你判断是旋转还是平移拖了后腿。第三状态估计验证。把标定后的外参接入融合定位或SLAM运行一段轨迹看地图重影是否消失、定位精度是否达标。这一步通过标定工作才算真正闭环。7.3 一个重要的经验标定不是一劳永逸的传感器装在车上经过一段时间的使用振动、温度变化、轻微碰撞都可能让外参发生微小漂移。尤其是激光雷达和相机分别安装在不同支架上的方案长期振动后外参变化非常常见。所以在生产、研发的不同阶段都要考虑标定结果的时效性问题。每次车辆维护、传感器拆装之后尽量重新跑一遍标定流程。如果做不到至少跑一遍静态投影验证发现问题再处理。在我个人做过的项目里最稳定的一套系统是传感器固定在同一个支架上支架整体刚性连接标定完后外参几乎不会漂移。而传感器分开安装的系统每隔两三个月就要重新标定一次否则融合效果肉眼可见地变差。另一个我后来养成的习惯是把每次标定的结果、数据、验证截图都存档。因为标定过程和数据本身的可重复性对后续排查问题非常有价值。很多时候你怀疑外参漂了其实就是两次标定之间某个环节的数据对不上回头翻一下存档就能快速定位问题。如果在一个堆满设备的实验室里旁边有人推着叉车来回跑标定数据烂了重新标定就是半天工时所以采集数据的时候一定要清场让环境保持静止。这是我交过学费后得出的经验。对激光雷达标定这件事我的最终体会是原理不难难的是把每个环节都做到位。标定板选对了吗时间戳对齐了吗运动激励够了吗验证做全面了吗任何一个环节偷懒最终都会在融合效果上付出代价。希望这篇笔记能帮你少走一些弯路。