ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

激光雷达标定原理与实现:从点云获取到内外参实战指南

激光雷达标定原理与实现:从点云获取到内外参实战指南 传感器标定这个系列写到第三个专题激光雷达终于要单独拿出来聊聊了。前两篇如果算是在跟相机标定原理较劲这一篇我们就把精力全部放到激光雷达标定原理和实现上。很多朋友听到“点云标定”就觉得高深其实它跟相机标定一样核心就三个问题测出来的点在哪儿、坐标系怎么对齐、误差怎么量化。搞清楚这三件事不管是做自动驾驶、机器人导航还是三维重建雷达到底准不准心里才会真正有底。这篇内容适合谁适合刚接触激光雷达、手里有台雷达但不知道怎么验证精度的工程师也适合做相机与激光雷达融合、需要先解决外参问题的同学。文章会从激光雷达原理讲起再聊Ubuntu 20.04下的驱动准备和点云获取接着给出一套可复现的内参与外参标定思路最后把我在实际项目中踩过的坑整理成表方便你直接避让。1. 标定到底在标什么先给激光雷达挑毛病1.1 激光雷达原理速览卷尺加量角器我刚开始接触激光雷达的时候一直觉得点云像照片一样是二维矩阵后来才发现完全不是这样。绝大多数商用旋转式激光雷达本质上是“一把卷尺”加“两个量角器”。测距模块测出目标距离 r再配合水平旋转角 α 和垂直出射角 β就能算出一个三维点。主流测距方式是飞行时间法公式很简单[ d \frac{c \cdot t}{2} ]其中 c 是光速t 是激光脉冲从发射到被物体反射回来的时间。这个原理跟用卷尺量距离一样只是尺子换成了光脉冲。除了 ToF 测距还有三角测距和 FMCW 调频连续波方式。三角测距多用于近距离低成本雷达FMCW 则因为能同时测角速度、抗干扰能力强近年在车载领域很火。但从标定角度看它们最终输出都是“距离、水平角、垂直角”这一组量。标定的本质就是在修正这些原始测量量的系统误差。1.2 从相机标定原理到雷达标定不是一回事很多人问我激光雷达标定能不能照搬相机标定原理结论是思路可以借鉴但内容完全不一样。相机标定原理的核心是内参矩阵 K、畸变系数包括径向畸变和切向畸变还有外参矩阵把相机坐标和世界坐标对应起来。标定时用棋盘格提取角点利用角点在像素平面和世界平面之间的约束来解未知数。激光雷达没有镜头没有焦距也没有像素坐标系。它的“内参”主要是距离补偿、水平角度零位、垂直角度安装偏差、旋转轴倾斜等。这些误差不像镜头畸变那样表现为图像弯曲而是让点云中的平面变弧、直角变钝、同一个特征在不同角度下厚度不一样。因此雷达标定用的约束条件通常不是“角点重投影”而是“点到平面距离最小”或“点云特征与真值特征对齐”。一句话总结相机标定要的是“拍出来的图像不变形”雷达标定要的是“打出来的点不偏、不飘、不厚”。1.3 雷达误差有哪些不要全怪驱动我接触过的雷达标定项目里很多点云异常并不是驱动问题而是标定问题。常见的系统误差大致分三类距离误差测距芯片线性度不够、光电信号串扰、温度漂移会导致点云整体变近或变远严重时形成距离拖尾。角度误差编码器零位不准、电机旋转抖动、垂直角扫描机构磨损会让一个本应水平的墙扫出一个斜坡。结构安装误差雷达外壳与内部扫描面不平行或者雷达装在车顶时有倾斜都会带进点云。这些误差对实际应用的影响很致命。比如一个 100m 远的障碍物如果水平角度误差只有 0.1°横向偏差就会达到约 17cm如果距离误差是 2cm纵向偏差就是 2cm。在自动驾驶里这两个量会直接决定刹车判断是否越线所以标定不是可做可不做的步骤而是感知链路的前置条件。2. 标定前必须弄懂的坐标变换和关键参数2.1 点云坐标是怎么从极坐标变成直角坐标的要标定激光雷达首先得知道点云坐标是怎么算出来的。假设雷达返回的是距离 r、水平角 α 和垂直角 θ在雷达坐标系中转换为三维坐标的公式是[ x r \cdot \cos(\theta) \cdot \cos(\alpha) ] [ y r \cdot \cos(\theta) \cdot \sin(\alpha) ] [ z r \cdot \sin(\theta) ]这里 θ 向上一般为正有些雷达的垂直角是负值向下扫描具体要查手册。如果知道了极坐标下的原始量才能写标定程序否则你只能把点云当成黑盒去调外参效率很低。加上误差项一个更常见的内参修正模型长这样[ x (r \Delta r) \cdot \cos(\theta \Delta \theta) \cdot \cos(\alpha \Delta \alpha) t_x ] [ y (r \Delta r) \cdot \cos(\theta \Delta \theta) \cdot \sin(\alpha \Delta \alpha) t_y ] [ z (r \Delta r) \cdot \sin(\theta \Delta \theta) t_z ]其中 (\Delta r) 是距离补偿量(\Delta \theta) 和 (\Delta \alpha) 是垂直和水平角偏差(t_x, t_y, t_z) 表示旋转中心与测距原点之间的不重合量。明白这个模型你就知道内参标定为什么不是只调一个距离常量那么简单——它是把好几个参数放到一起联合优化。2.2 Ubuntu 20.04 下让雷达快速转起来很多朋友卡在第一步雷达插到电脑上ROS 下看不到点云。这里给一个通用排查思路在 Ubuntu 20.04 下实测可用适用于多数基于 ROS 的激光雷达驱动。确认物理连接方式。机械式雷达很多用网口 UDP 传输要先设置电脑 IP 到相同网段串口转 USB 的则要确认设备节点存在。查看设备节点ls -l /dev/ttyUSB*如果没有检查驱动或换 USB 口。设置权限把当前用户加入 dialout 组或者直接chmod 666 /dev/ttyUSB0。编写 udev 规则固定设备名避免每次重启设备号变化。启动驱动 launch 文件在 RViz 中添加 PointCloud2 话题。# 查看 USB 转串口设备 lsusb | grep -i serial ls -l /dev/ttyUSB* # 临时授权当前用户操作串口 sudo usermod -aG dialout $USER这套操作不是标定本身但点云都进不来后面全白搭。我踩过最坑的一次是驱动节点启动成功但 RViz 里没数据最后发现是雷达和笔记本 IP 不在一个网段UDP 包根本没收到。2.3 标定前需要确认的参数清单不同雷达的参数差异很大建议在标定前先把下面这几个参数确认清楚否则后面的误差分析会跑偏。参数影响验证方法垂直角分辨率决定点云层数和墙面点密度查看点云中 ring 字段确认线数是否等于雷达型号水平角分辨率决定单圈点数和近处点密度用rostopic hz检查帧率解析角度增量回波模式影响测距偏差和混叠现象对比强反射目标在单回波与双回波下的测距值量程与反射率影响远距离点云噪声在不同距离放置漫反射标定板记录点云标准差举个例子很多多线雷达点云自带 ring 字段但你如果不知道它的垂直角分辨率就没办法判断哪些点是来自同一水平线平面拟合时也容易把不同层的点混到一起。这个准备工作值得花十分钟能省下后面反复排查的半天时间。3. 内参标定从平面拟合到高精度点云3.1 为什么平面是最好的标定对象相机标定原理里棋盘格提供亚像素角点激光雷达标定里平面则是天然的高质量靶标。原因很简单点云中的点落在平面上时点到平面距离可以解析计算你能直接量出“点云压在墙上”的程度。如果点云没有任何畸变和偏移所有点应该落在同一个平面方程上点到面距离近似为噪声水平如果有距离偏差或角度偏差点会整体前移、后移或让平面变成弧形。实际中可以使用墙面、地板或大面积标定板。关键要求是材质漫反射强、表面平整度好不能是镜面、玻璃或深色吸光材质。镜面反射会带来假点玻璃会把激光打到背后物体上深色材质测距噪声会明显变大。3.2 实验场地布置和采集要点我常用的采集规范是选择一面至少 3m×3m 的平整墙面把雷达放在距离墙面约 2m 的位置先调整雷达大致水平然后自动旋转采集 10 秒点云。为了覆盖不同距离和入射角我会把雷达分别放在 1m、3m、5m、8m 处并在每个位置把雷达小幅度俯仰让点云扫过墙面的不同区域。采集时注意三点保证室内无强红外干扰不要在太阳直射的窗边做标定。保持场地无人走动雷达会把人当成动态目标最好叠加多帧静态数据。关闭驱动里的运动畸变补偿功能让算法拿到原始测量值才能标定真实的系统误差。3.3 基于平面拟合的标定数据处理流程拿到静态点云后内参标定第一步是提取平面。我习惯用 PCL 的 RANSAC 分割平面阈值设在 1cm~2cm 之间。如果目标是地面可以直接拟合一个平面 (z ax by d)然后统计每个点到平面的残差。import numpy as np def fit_plane(points): # points: N x 3 centroid np.mean(points, axis0) centered points - centroid _, _, vh np.linalg.svd(centered) normal vh[-1] # 最小特征值对应的奇异向量 d -np.dot(normal, centroid) return normal, d def plane_residual(points, normal, d): return np.abs(points normal d)平面拟合之后如果平均残差超过 2cm说明点云里有系统性弯曲不能只靠平移雷达来消除。此时要回到 2.1 节的修正模型把 (\Delta r)、(\Delta \theta)、(\Delta \alpha) 作为优化变量让点到平面的残差平方和最小。这个目标函数没有闭式解但可以用高斯牛顿法或 L-BFGS 优化也可以用 Ceres、g2o 等开源工具实现。在优化前建议先手动粗调把所有点云往墙面真实位置平移让平均残差降到厘米内再做迭代稳定性会好很多。直接拿随机初值起步很容易陷到局部最优解里。3.4 距离偏差和角度偏差的联合优化思路平面拟合看起来简单但有个问题距离偏差和角度偏差都可以让点云在法线方向移动。比如一个距离系统偏移和一个小角度旋转在某些角度下对平面残差的贡献是混叠的。要区分它们数据里需要有不同距离和不同朝向的平面。同一块墙面在 1m 和 5m 处的点距离偏差影响会线性增大角度偏差影响会表现为旋转用多面墙或多次变换雷达姿态就能把两类误差解开。我用的优化目标是让所有点到所属平面的均方距离最小[ \min_{\Delta r, \Delta \theta, \Delta \alpha} \sum_{i} \frac{1}{N_i} \sum_{j1}^{N_i} \left( \hat{n}i \cdot p{ij}(\Delta r,\Delta \theta,\Delta \alpha) \hat{d}_i \right)^2 ]其中 (\hat{n}_i) 和 (\hat{d}i) 是第 i 个平面的法线和偏移(p{ij}) 是修正后的点云。实际项目里我一般把优化结果和出厂参数做对比看偏差是否在合理范围。比如 64 线雷达出厂垂直角精度通常优于 0.01°如果你标出来的 (\Delta \theta) 是 0.2°基本可以反推采集过程有问题或者雷达受过撞击而不是正常出厂漂移。4. 外参标定把激光雷达放进统一坐标系4.1 外参标定到底解决什么内参标定完后雷达测出来的点在自己的雷达坐标系里已经比较准了。但机器人要用它必须知道雷达在机器人什么位置、以什么姿态安装。这个变换关系就是外参。外参可以理解为雷达坐标系到底盘坐标系的刚体变换由三维平移向量和三维旋转矩阵组成。外参不准的典型表现是雷达点云与相机图像对不齐目标框和真实物体错位或者两片点云拼接后出现重影。很多 SLAM 效果差最后查出来不是算法不好而是外参有一个 2° 的偏角跑到 50m 外就成了 1.7m 的横向误差。所以外参标定不是锦上添花而是融合感知的刚需。4.2 对应点法求外参SVD解算原理与代码当你能拿到同一个特征点在两个坐标系下的坐标时外参求解就变成一个典型的最小二乘配准问题。假设源点集 (p_i) 是雷达坐标系下的坐标目标点集 (q_i) 是底盘坐标系下的真值坐标我们要找旋转 R 和平移 t使得 (R p_i t) 与 (q_i) 的差异最小。SVD 解法的核心是先去平移将两个点云都中心化再对互相关矩阵做奇异值分解得到最优旋转。步骤如下计算两组点的质心 (\bar{p}) 和 (\bar{q})。去中心化(p_i p_i - \bar{p})(q_i q_i - \bar{q})。计算 (H \sum p_i q_i^T)。对 H 做 SVD(H U S V^T)。旋转 (R V U^T)平移 (t \bar{q} - R \bar{p})。如果 (det(R) 0)说明出现反射解需要手动修复。import numpy as np def solve_rigid_transform(src, dst): assert src.shape dst.shape n src.shape[0] p_bar np.mean(src, axis0) q_bar np.mean(dst, axis0) p_prime src - p_bar q_prime dst - q_bar H p_prime.T q_prime U, _, Vt np.linalg.svd(H) R Vt.T U.T if np.linalg.det(R) 0: Vt[-1, :] * -1 R Vt.T U.T t q_bar - R p_bar return R, t很多人拿这段代码直接标外参却忽略了输入点对的准确性。如果对应点误差达到 10cm解出的旋转和平移就会明显偏差所以使用前一定要可视化手动选点至少选取 4~6 个非共面特征点。4.3 相机-雷达联合标定三种实用方案对比如果项目需要雷达和相机融合还要解决相机坐标系与雷达坐标系之间的外参。这里的标定原理和 4.2 类似不同在于怎么建立对应关系。我整理过三种常用方案各有适用场景方案原理精度注意事项目标板角点法用棋盘格或黑白板从相机图像提取角点从雷达点云提取板面中心或边缘角点形成3D-3D对应高雷达角点不如图像准需要做平面分割后求交平面法约束用平面法向量和距离作为约束构建点到平面残差中高至少需要三个不平行平面适合带地面场景自然场景ICP法初始化外参后把雷达点云投影到相机生成的三维点云用ICP精配中依赖初始值场景重叠度要求高适合精修用第一种方案时很多人对相机标定原理已经很熟知道相机内参要先标好。这里再提醒一句雷达点云里的“角点”并不是真正的点它是几个平面的交点。提取时要先对板面做平面分割再通过板面边缘线求交点不要直接用回波强度最大值。4.4 外参标定完成后怎么验证外参标定完不代表可以结束必须做闭环验证。我常用的验证方法有四个重投影误差把雷达点云通过外参投影到相机图像上观察是否叠在实物边缘。平均误差小于几个像素基本可接受。点面残差把雷达点云变换到底盘坐标拟合已知地面或墙面看平均残差是否在标定前的噪声水平。交叉验证用另一段不参与标定的数据做点云拼接若障碍物轮廓出现双重边缘说明外参仍有小角度残差。里程计一致性机器人走直线雷达点云中的静止物体应保持不动若出现横向漂移多半是外参旋转有偏差。这个验证动作会帮你发现很多无效标定。我见过不少人标完看一眼 RViz 里对得很齐第二天实测才发现偏差依然存在因为 RViz 的显示尺度很容易掩盖毫米级误差。5. 常见问题与避坑实录5.1 点云异常排查速查表这里把我踩过的问题整理成一张表建议收藏备用故障现象可能原因解决办法点云整体偏向一侧外参平移给错或雷达安装座松动重新测量或做外参标定平整墙面出现弧面距离偏移或角度零位偏差用第 3 节流程重新标内参点云中有不规则尖刺镜面反射、玻璃、强太阳光过滤回波模式换测试场地点云帧与帧之间漂移运动畸变未补偿或外参受振动影响低速采集先关闭运动补偿再标定驱动启动后无话题网口 IP 或串口权限问题检查网段、udev 规则、驱动日志表格内容都是我在项目里真实遇到过的。点云整体偏向一侧我一开始总以为是雷达损坏后来发现是快拆支架换过一次外参没有重新标。从此团队规范里加了一条拆装过雷达之后第一件事永远是重标外参。5.2 数据采集阶段最容易忽略的三个坑第一不要用手扶着雷达采集。手动会带入抖动相当于给数据叠了一层随机振动。第二入射角不要太斜。激光以极斜角度入射墙面时点云噪声会显著增大所以布置雷达时激光与平面法线的夹角最好不要超过 70°。第三不要把金属墙面当标定面。金属反光会产生多次回波测距被拉长或缩短点云会出现明显拖尾。还有一个很隐蔽的问题不同时间采集的数据不要直接合并。室内温度、雷达预热状态都会让测距分布发生几毫米漂移。真要对比建议在同一次开机、同一温度环境下完成。5.3 几条实用的标定工作流建议最后聊几个提高标定效率的习惯都是我踩过坑换来的。第一每次标定开始前先录一段 30 秒的原始 rosbag标定失败时还能回放不用重新摆场地。第二把标定参数版本化用表格记录日期、雷达序号、外参、RMSE。项目隔三个月后回来找问题有记录比纯记忆靠谱。第三标定完成之后拿一个已知尺寸的箱体放到不同距离测一遍点云边长这是最直观的精度验收方式。如果雷达是安装在车端或设备端建议每次撞击、拆装、吊装之后都强制复标。不要嫌麻烦很多后半夜排查的定位问题最后都指向外参被带偏。我再补充一点做传感器标定最忌讳“调出来能看就行”。激光雷达标定的价值是给感知一条可量化的精度基线。哪怕你只是做机器人小车也建议把残差记录在案然后轻推雷达一毫米看看点云会不会露出缝隙你就会明白标定精度对后面的定位和感知有多重要。
返回列表