1. 系统框架概述
本方案采用"三层标定框架",整体架构如下图所示:
系统组成:
- 感知层:Velodyne VLP-16激光雷达、Stereo ZED2摄像头、Xsens MTi-30 IMU、Ublox F9P GPS
- 计算层:Intel NUC with Ubuntu 20.04 + ROS Noetic
- 融合层:基于Kalman Filter的紧耦合融合架构
2. 传感器间标定(外参标定)
传感器的内参标定可以看我之前的文章:【传感器标定(一):张正友相机标定法原理与实现详解】、【传感器标定(二):IMU标定原理与实现详解】、【传感器标定(三):激光雷达标定原理与实现详解】。
2.1 激光雷达-相机标定
标定原理:
通过棋盘格建立两种传感器观测的几何约束,目标函数为:
T^camlidar=arg minT∑i=1N∥π(T⋅Pilidar)−picam∥2\hat{T}_{cam}^{lidar} = \argmin_{T} \sum_{i=1}^{N} \| \pi(T \cdot P_i^{lidar}) - p_i^{cam} \|^2 T^camlidar=Targmini=1∑N∥π(T⋅Pilidar)−picam∥2
其中:
- T∈SE(3)T \in SE(3)T∈SE(3)为待求变换矩阵
- PilidarP_i^{lidar}Pilidar为激光点云中的棋盘格角点
- picamp_i^{cam}picam为图像中的对应角点
- π(⋅)\pi(\cdot)π(⋅)为相机投影模型
实施步骤:
- 采集同步的棋盘格图像和点云数据(至少15组不同姿态)
- 使用OpenCV的
findChessboardCorners
检测图像角点 - 使用基于平面拟合的算法提取点云角点
- 采用Levenberg-Marquardt算法优化目标函数
2.2 IMU-激光雷达标定
旋转轴激励法:
通过主动旋转激励激发IMU的角速度响应:
ωimu=Rlidarimu⋅ωlidar\omega_{imu} = R_{lidar}^{imu} \cdot \omega_{lidar} ωimu=Rlidarimu⋅ωlidar
其中ωlidar\omega_{lidar}ωlidar通过连续两帧点云的ICP获得。
平移标定:
利用运动过程中IMU加速度积分与激光雷达观测的约束:
t^=arg mint∑∥(vk+1lidar−vklidar)−Rimulidar∫tktk+1(aimu−ba)dt∥2\hat{t} = \argmin_{t} \sum \| (v_{k+1}^{lidar} - v_k^{lidar}) - R_{imu}^{lidar} \int_{t_k}^{t_{k+1}} (a_{imu} - b_a)dt \|^2 t^=targmin∑∥(vk+1lidar−vklidar)−Rimulidar∫tktk+1(aimu−ba)dt∥2
2.3 GPS-IMU标定
杆臂效应补偿:
GPS天线相位中心与IMU中心的偏移向量lbl^blb满足:
pGPSw=pIMUw+Rwblbp_{GPS}^w = p_{IMU}^w + R_w^b l^b pGPSw=pIMUw+Rwblb
通过静态多位置观测建立方程组求解。
3. 时间同步方案
3.1 硬件同步
采用PTP (IEEE 1588)协议实现µs级同步:
时钟偏移计算:
θ=(t2−t1)−(t4−t3)2\theta = \frac{(t2 - t1) - (t4 - t3)}{2} θ=2(t2−t1)−(t4−t3)
3.2 软件同步
对于无法硬件同步的传感器(如相机),采用基于双缓冲的插值算法:
m(t)=αm(ti)+(1−α)m(ti+1),α=ti+1−tti+1−tim(t) = \alpha m(t_i) + (1-\alpha)m(t_{i+1}), \ \alpha = \frac{t_{i+1}-t}{t_{i+1}-t_i} m(t)=αm(ti)+(1−α)m(ti+1), α=ti+1−titi+1−t
3.3 运动补偿
对于激光雷达的扫描式采集,采用IMU辅助的运动补偿:
Pkw=Tt0tk⋅PklidarP_k^w = T_{t_0}^{t_k} \cdot P_k^{lidar} Pkw=Tt0tk⋅Pklidar
其中Tt0tkT_{t_0}^{t_k}Tt0tk由IMU积分得到。
4. 在线标定与误差补偿
4.1 基于EKF的在线标定
状态向量包含标定参数:
x=[p,v,q⏟状态,ba,bg⏟IMU偏置,tlidar,θcam⏟标定参数]x = [\underbrace{p,v,q}_{状态}, \underbrace{b_a,b_g}_{IMU偏置}, \underbrace{t_{lidar},\theta_{cam}}_{标定参数}] x=[状态p,v,q,IMU偏置ba,bg,标定参数tlidar,θcam]
系统模型:
x˙=f(x,u)+w,u=[aimu,ωimu]\dot{x} = f(x,u) + w, \ \ u=[a_{imu},\omega_{imu}] x˙=f(x,u)+w, u=[aimu,ωimu]
观测模型:
z=h(x)+v,z=[GPS,Lidar_Feature,Cam_Feature]z = h(x) + v, \ \ z=[GPS, Lidar\_Feature, Cam\_Feature] z=h(x)+v, z=[GPS,Lidar_Feature,Cam_Feature]
4.2 标定质量评估
采用Mahalanobis距离检测标定退化:
DM=(z−h(x))TS−1(z−h(x))D_M = \sqrt{(z-h(x))^T S^{-1} (z-h(x))} DM=(z−h(x))TS−1(z−h(x))
当DM>χdf,0.952D_M > \chi^2_{df,0.95}DM>χdf,0.952时触发重新标定。
5. 完整实施流程
阶段1:离线标定
- 单传感器标定(参见前文)
- 传感器对间标定(2.1-2.3节)
- 时间同步校准(3.1节)
阶段2:在线维护
- 启动时验证标定参数
- 运行时监控标定状态
- 动态更新标定参数(4.1节)
6. 实验验证方案
定量评估指标:
-
重投影误差(激光-相机):
ϵreproj=1N∑i=1N∥π(T⋅Pi)−pi∥\epsilon_{reproj} = \frac{1}{N}\sum_{i=1}^N \|\pi(T\cdot P_i) - p_i \| ϵreproj=N1i=1∑N∥π(T⋅Pi)−pi∥ -
轨迹对齐误差(GPS-激光):
ϵalign=RMSE(trajlidar,trajGPS)\epsilon_{align} = \text{RMSE}(traj_{lidar}, traj_{GPS}) ϵalign=RMSE(trajlidar,trajGPS) -
时间同步精度:
ϵsync=max∣ttrigger−tactual∣\epsilon_{sync} = \max |t_{trigger} - t_{actual}| ϵsync=max∣ttrigger−tactual∣
7. 关键实现细节
标定工具推荐:
- 激光-相机:Autoware的
calibration_camera_lidar
工具 - IMU-激光:Kalibr工具箱的
imu_lidar_calibration
- 时间同步:ROS的
message_filters
包
代码片段示例(时间对齐):
class TimeAligner:def __init__(self, max_delay=0.1):self.buffer = {}self.max_delay = max_delaydef add_msg(self, topic, msg):self.buffer.setdefault(topic, []).append((msg.header.stamp, msg))def get_synced_msgs(self, sync_topic):sync_msgs = {}for topic in self.buffer:idx = bisect.bisect_left([ts for ts,_ in self.buffer[topic]], self.buffer[sync_topic][0][0])if idx > 0 and abs(self.buffer[topic][idx-1][0] - self.buffer[sync_topic][0][0]) < self.max_delay:sync_msgs[topic] = self.buffer[topic][idx-1][1]return sync_msgs
8. 常见问题解决方案
标定失败排查:
- 特征提取不足:确保标定板在两种传感器中均清晰可见
- 运动激励不足:IMU标定需充分激励所有轴
- 时间戳异常:检查ROS的
/use_sim_time
参数设置
精度提升技巧:
- 在标定期间保持环境光照稳定
- 对GPS标定选择开阔场地
- 标定温度接近实际工作温度