传感器特性与误差模型:IMU、GPS、摄像头、激光雷达
做传感器融合这些年,我最大的体会就是:不了解传感器的脾气,融合就是瞎搞。每个传感器都有自己的性格——有的爱飘,有的爱抖,有的时好时坏。你得摸透它们,才能让它们好好配合。
这一章,咱们就聊聊四种最常见的传感器:IMU、GPS、摄像头、激光雷达。我会结合自己的项目经验,把它们的特性、误差来源和建模方法讲清楚。
IMU:又爱又恨的“惯性导航”
IMU(惯性测量单元)是我用得最多的传感器。它包含加速度计和陀螺仪,能测出物体的加速度和角速度。说白了,就是靠“积分”来推算位置和姿态。
优点很明显:
- 完全自主,不依赖外部信号
- 更新频率高(100Hz-1000Hz)
- 短时间精度不错
缺点也很致命:
- 误差会随时间累积(漂移)
- 对温度敏感
- 低频噪声大
核心误差来源:
- 零偏(Bias):静止时输出不为零。我遇到过最夸张的一次,某款MEMS陀螺仪零偏达到0.5°/s,积分10秒就偏了5度。
- 随机游走(Random Walk):噪声积分后产生的随机漂移。这玩意儿没法完全消除,只能靠滤波抑制。
- 尺度因子误差:输出值与真实值的比例偏差。一般标定后能控制在1%以内。
- 交轴耦合:一个轴的运动会影响到另一个轴的输出。高端IMU会做正交补偿。
误差建模方法:
我习惯用Allan方差来分析IMU噪声特性。它能帮你区分出量化噪声、角度随机游走、零偏不稳定性、速率随机游走等不同成分。
// 简化的IMU误差模型(C语言风格)
typedef struct {
float bias_acc[3]; // 加速度计零偏
float bias_gyro[3]; // 陀螺仪零偏
float scale_acc[3]; // 加速度计尺度因子
float scale_gyro[3]; // 陀螺仪尺度因子
float noise_acc[3]; // 加速度计噪声标准差
float noise_gyro[3]; // 陀螺仪噪声标准差
} ImuErrorModel;
// 应用误差模型
void applyImuError(float acc_raw[3], float gyro_raw[3],
ImuErrorModel *model, float acc_out[3], float gyro_out[3]) {
for (int i = 0; i < 3; i++) {
// 减去零偏,补偿尺度因子
acc_out[i] = (acc_raw[i] - model->bias_acc[i]) * (1.0f + model->scale_acc[i]);
gyro_out[i] = (gyro_raw[i] - model->bias_gyro[i]) * (1.0f + model->scale_gyro[i]);
// 加上高斯噪声(实际项目中用随机数生成)
acc_out[i] += gaussian_random() * model->noise_acc[i];
gyro_out[i] += gaussian_random() * model->noise_gyro[i];
}
}
我的经验:IMU上电后前几分钟零偏变化最大。我一般会做“上电自标定”——静止采集30秒数据,取平均作为初始零偏。这招能省掉不少麻烦。
GPS:精度看环境,别太信它
GPS(全球定位系统)是室外定位的主力。它靠卫星信号测距,精度受环境影响很大。
特性一览:
- 定位,无累积误差
- 更新频率低(1Hz-10Hz)
- 开阔环境下精度2-5米(单点定位)
- 城市峡谷、隧道内信号差
误差来源:
| 误差类型 | 典型大小 | 说明 |
|---|---|---|
| 电离层延迟 | 2-5米 | 白天比晚上严重,太阳活动期更糟 |
| 对流层延迟 | 0.5-1米 | 与温度、湿度、气压有关 |
| 卫星钟差 | 1-2米 | 卫星自身时钟偏差 |
| 多径效应 | 1-10米 | 高楼反射信号,最头疼的问题 |
| 接收机噪声 | 0.5-1米 | 硬件本身的热噪声 |
误差建模:
我一般用高斯分布来近似GPS噪声,但要注意——实际GPS误差不是高斯分布。多径效应会导致长尾分布,用卡尔曼滤波时得小心。
// GPS误差模型(简化版)
typedef struct {
double lat; // 纬度(度)
double lon; // 经度(度)
float hdop; // 水平精度因子
float vdop; // 垂直精度因子
float std_horiz; // 水平标准差(米)
float std_vert; // 垂直标准差(米)
} GpsMeasurement;
// 根据HDOP计算标准差
void computeGpsStd(GpsMeasurement *gps) {
// 经验公式:单点定位时,UERE(用户等效距离误差)约2.5米
float uere = 2.5f;
gps->std_horiz = uere * gps->hdop;
gps->std_vert = uere * gps->vdop;
}
避坑指南:我曾经在深圳做测试,GPS在高层建筑间跳了20多米。后来加了“速度约束”——如果GPS位置变化超过物理可能的速度,直接丢弃。这招简单但有效。
摄像头:信息丰富,但别被它骗了
摄像头是视觉传感器,能提供最丰富的环境信息。但它的误差模型比IMU和GPS复杂得多。
特性:
- 高分辨率,细节丰富
- 受光照影响大(逆光、暗光、反光)
- 单目无法直接测距
- 计算量大
误差来源:
- 内参误差:焦距、主点、畸变参数不准。标定不好,后面全白搭。
- 外参误差:摄像头安装位置和角度偏差。我见过因为摄像头松动导致融合结果飘移的案例。
- 特征匹配误差:图像特征点匹配错误。纹理少的地方尤其严重。
- 运动模糊:快速运动时图像模糊,特征提取精度下降。
误差建模:
摄像头误差很难用简单模型描述。我通常用重投影误差来评估——把3D点投影到图像上,看和实际像素位置的偏差。
// 摄像头投影模型(针孔模型)
void projectPoint(float X, float Y, float Z,
float fx, float fy, float cx, float cy,
float *u, float *v) {
// 归一化坐标
float x = X / Z;
float y = Y / Z;
// 像素坐标
*u = fx * x + cx;
*v = fy * y + cy;
}
// 重投影误差计算
float computeReprojectionError(float X, float Y, float Z,
float u_obs, float v_obs,
float fx, float fy, float cx, float cy) {
float u_proj, v_proj;
projectPoint(X, Y, Z, fx, fy, cx, cy, &u_proj, &v_proj);
float du = u_obs - u_proj;
float dv = v_obs - v_proj;
return sqrtf(du*du + dv*dv);
}
我的习惯:做视觉SLAM时,我会把重投影误差的阈值设成2个像素。超过这个值的匹配点,大概率是误匹配,直接扔掉。宁可少用,不可错用。
激光雷达:精度高,但别太依赖
激光雷达(LiDAR)是自动驾驶的“眼睛”。它直接测量距离,精度高,但也不是万能的。
特性:
- 直接测距,精度厘米级
- 不受光照影响
- 点云稀疏(相对摄像头)
- 价格贵,功耗高
误差来源:
- 测距误差:激光飞行时间测量不准。典型值±2cm。
- 角度误差:扫描电机角度偏差。16线激光雷达的垂直角度误差可达0.1°。
- 反射率影响:黑色物体吸收激光,测距变差。我遇到过黑色轮胎测距误差超过10cm。
- 多回波:激光穿过玻璃或雨滴时产生多个回波。
误差建模:
激光雷达的测距误差通常用高斯模型,但角度误差得用系统误差模型。
// 激光雷达点误差模型
typedef struct {
float range; // 测距值(米)
float azimuth; // 水平角(弧度)
float elevation; // 垂直角(弧度)
float intensity; // 反射强度
float range_std; // 测距标准差(米)
float angle_std; // 角度标准差(弧度)
} LidarPoint;
// 添加误差到点云
void addLidarNoise(LidarPoint *pt) {
// 测距噪声(高斯)
pt->range += gaussian_random() * pt->range_std;
// 角度噪声(高斯)
pt->azimuth += gaussian_random() * pt->angle_std;
pt->elevation += gaussian_random() * pt->angle_std;
}
避坑指南:我曾经在雨天测试激光雷达,点云里全是噪点。后来加了“强度滤波”——反射强度低于某个阈值的点直接丢弃。虽然损失了一些有效点,但整体数据质量提升明显。
四种传感器对比总结
做个表格,一目了然:
| 传感器 | 优点 | 缺点 | 典型误差 | 适用场景 |
|---|---|---|---|---|
| IMU | 自主、高频 | 漂移、累积误差 | 零偏0.1-1°/s | 短时定位、姿态估计 |
| GPS | 定位、无漂移 | 低频、受环境影响大 | 2-10米 | 室外导航、全局定位 |
| 摄像头 | 信息丰富、成本低 | 光照敏感、计算量大 | 1-3像素(重投影) | 视觉SLAM、目标检测 |
| 激光雷达 | 精度高、不受光照 | 稀疏、价格高 | 1-5cm | 高精度建图、避障 |
知识体系结构图
下面这张图,是我自己梳理的传感器误差模型知识框架。你看一眼,心里就有数了。
嗯,这张图把整个知识脉络串起来了。从传感器特性到误差来源,再到建模方法和融合策略,每一步都环环相扣。
做传感器融合,说白了就是跟误差打交道。你越了解每个传感器的“脾气”,就越能设计出鲁棒的融合算法。我在项目中吃过不少亏,也积累了一些经验,上面这些内容都是实战中总结出来的。
记住一句话:没有完美的传感器,只有好的融合算法。