上个月处理一批无人机试飞记录数据时,我被一个看上去根本不是问题的问题卡了两整天。采集日志里IMU跑着200Hz、GPS跑着10Hz、机载相机录着30fps的画面,各路时间戳齐全,文件也没有损坏。我把数据倒进Matlab,套用现成的方向估计流程,结果姿态角画出来一塌糊涂——航向角在匀速直行的时候来回漂移几十度,横滚角莫名其妙地跟着车速跳。滤波参数我调了无数遍,甚至把扩展卡尔曼滤波的噪声协方差揉碎了重新猜,依然压不下去。后来一步步追查才发现,问题根本不在算法,而在数据入口:三路传感器的记录数据没有在时间轴上对齐,坐标系也没有统一清理过。
这篇博文要讲的就是这套"基于Matlab对齐传感器数据,再做方向估计"的完整流程。我会把三种最容易忽视的对齐方式——时间轴对齐、采样率对齐、坐标系对齐——逐一说清楚,附上可以直接复现的Matlab代码,再讲一些教程里基本不会写的实测经验。适合正在做姿态解算、航向估计、行人导航、机器人运动分析的人参考,尤其是那些手里已经攒了一批传感器记录数据、却不知道从哪一步开始预处理的朋友。
1. 先搞清楚一件事:方向估计的准确性,一大半在数据对齐
1.1 方向估计的本质是一笔"时间账加空间账"
方向估计,通俗地说就是求载体当前朝向的计算过程。你手上有一堆传感器记录:加速度计告诉你在重力方向上的分量,陀螺仪告诉你在三个轴上的旋转角速度,磁力计告诉你在磁场中的朝向,GPS或相机则给出载体在空间里的位置变化。姿态解算算法——互补滤波、Mahony、扩展卡尔曼滤波——做的事情就是把这些信息以自洽的方式融合成一个旋转关系。
几乎所有算法推导教程都会默认一个前提:这些传感器的数据是同一时刻、同一坐标系下采集到的。但实际工程中,这个前提几乎从来不会被自动满足。因为每一路传感器都有自己独立的时钟、独立的采样率、独立的安装朝向。你采集时看到的是"各采各的",算法看到的是"各算各的",最终方向估计就变成了在错误的时间点上融合错误的坐标数据,结果自然不对。
1.2 记录的传感器数据为什么天然不会对齐
这里有一个很扎心的现实:大多数人拿到的数据都是"记录数据",而不是"实时同步流"。换句话说,数据已经采下来了,硬件已经撤场了,你没法回去改采集端。IMU的数据和GPS的数据虽然都躺在同一个文件或者同一批目录里,但它们来自不同的芯片、不同的晶振、不同的时钟源。
我见过太多人拿到数据后直接把所有序列从1开始编号,然后按下标对应起来做融合。如果两路传感器采样率恰好一样,这种方法偶尔能跑通,但一旦遇到采样率不同、时间戳有抖动、采集过程中有丢包,按下标对齐就会完全失真。正确做法是先看时间戳,再做对齐,最后才能谈方向估计。
1.3 对齐要解决的三件事
我把方向估计前的数据对齐归结为三个层面,这也是整篇文章的主线:
| 错位类型 | 具体表现 | 影响 | 应对手段 |
|---|---|---|---|
| 时间轴错位 | 各路传感器时间戳基准不同,同一物理时刻对应不同记录时刻 | 融合时把不同时刻状态当同一时刻,姿态角出现无规律跳动 | 时间戳预处理加插值 |
| 采样率错位 | 不同传感器采样频率不同,且实际采样率与标称值有出入 | 低频数据混叠,高频信息被截断 | 抗混叠滤波加重采样 |
| 坐标系错位 | 传感器安装朝向与载体坐标系不一致,各轴定义不统一 | 估计出固定偏差,且滤波无法消除 | 旋转矩阵补偿与标定 |
后面每一章会对应其中一层。你如果只是急着跑通某个现成的方向估计算法,建议也先把这三件事过一遍,因为算法里那些参数调得再好,也补不了数据入口上的窟窿。
2. 数据不对齐的三种错位:时间、频率、坐标系各自怎么毁掉姿态解算
2.1 时间不同步:融合时像两只脚不在一个节拍上
时间不同步是影响方向估计最明显、也最容易被忽视的问题。设想一个转弯场景:车辆在100毫秒前开始打方向,IMU已经测到了当前时刻的角速度,而GPS因为输出频率低,上报的位移还是转弯前的状态。算法把这两组数据当作同一时刻的信息去融合,航向角就会被GPS的"旧信息"往反方向拽一把。转弯越快,这种滞后造成的误差越大。
时间不同步的另一个来源是系统任务调度抖动。采集程序里IMU回调刚触发完,GPS的数据还在串口缓冲区里排队,等到真正被打上时间戳时,已经是几十毫秒之后的事了。对高频动作来说,几十毫秒足以让车辆转过好几度。所以在做方向估计前,先做时间轴对齐是绝对绕不开的。
2.2 采样率不一致:低频数据像一块块"慢半拍的积木"
假设IMU以200Hz输出,GPS以10Hz输出。从200Hz的IMU角度看,每20个点才出现一个GPS点。如果直接把上一个GPS值当作当前时刻的值(零阶保持),那么GPS信息在融合时永远是滞后的,而且这个滞后的时间还因系统调度的不确定而在变化。
更麻烦的是采样率不一致引发的混叠问题。如果GPS原始信号本身包含高频变化(比如速度突变、转向瞬时变化),以10Hz采样会把这些高频成分折叠到低频。这时候你对GPS数据做任何插值,得到的中间值都是一种"看似合理但物理上并不真实"的合成数据。采样率差异越大,混叠的影响越严重,这也是我后面强调"先滤波再重采样"的原因。
2.3 坐标系不统一:传感器"歪着装",算法再努力也白搭
方向估计最终输出的姿态,通常定义在载体坐标系下。但传感器有自己的坐标系——比如MPU6050的X轴朝芯片某个方向,Y轴垂直,Z轴朝上。安装时只要偏了哪怕几度,传感器读到的东西和载体实际运动之间就有了固定的坐标偏差。
这个偏差最狠的地方在于:它不会随时间收敛,也很难靠滤波抹平。陀螺仪积分会把这个偏差累积进角度,加速度计修正也会基于带有偏差的重力分量。最后表现出来的就是:无论你怎么调滤波器增益,姿态角里总有一个甩不掉的恒定偏移。要解决它,只能做坐标系对齐,也就是通过旋转矩阵把传感器坐标下的数据转换到载体坐标下。
有一个常见误解需要澄清:很多人以为坐标系对齐只是"传感器安装方向"的问题,实际上还包括各轴定义、正方向取反、左手系和右手系的差异。比如有的陀螺仪Z轴朝上,有的朝下;有的加速度计量程是正负8g,有的正负16g。这些如果不统一换算,方向估计的天生误差就很大。
3. 时间轴对齐:用Matlab把不同采样时刻的传感器数据拉到同一条时间线上
3.1 先做时间戳预处理,不要拿到就插值
时间轴对齐的第一步不是急着插值,而是先检查和修正时间戳本身。我处理数据时通常会先做四件事:
- 把时间戳统一成秒,并减去第一个有效时间戳,得到相对时间。
- 检查是否单调递增,有倒序就先排序。
- 检查是否有重复时间戳,有就去重并记录数量。
- 检查时间戳差值是否剧烈跳变,找出因为丢包或缓冲造成的时间跳变点。
代码可以这样写:
% 假设t_raw是原始时间戳,单位是毫秒,需要转成秒 t = (t_raw - t_raw(1)) / 1000; % 排序保证单调 [t, idx] = sort(t); data = data(idx, :); % 查看时间差是否有异常跳变 dt = diff(t); figure; plot(dt, '.'); title('时间戳差值序列');如果时间戳差值里有明显的尖峰,说明那个时刻发生了丢包或者数据堆叠,要在后续对齐时特别留意。这类数据如果不处理,插值结果是错的。
3.2 选好基准时间轴,再用interp1做插值
时间对齐的方法论其实很简单:选一条可靠的时间轴作为基准,把其他所有传感器插值到这条时间轴上。对方向估计来说,基准时间轴一般选IMU的时间轴,因为陀螺仪积分和姿态更新需要高频数据,而且IMU的时间戳通常最稳定。
% 以IMU时间为基准 t_base = t_imu; % 对GPS数据做线性插值 gps_vel_aligned = interp1(t_gps, gps_vel, t_base, 'linear', 'extrap'); gps_pos_aligned = interp1(t_gps, gps_pos, t_base, 'linear', 'extrap');这里我建议把插值方式设为'linear'。原因很简单:线性插值不会在数据点之间制造额外的波动,保守可靠。样条插值虽然曲线更光滑,但在时间戳本身有噪声的情况下,它会把噪声也拟合成波动,反而引入不存在的加速度变化。
3.3 时间戳有抖动时,先平滑再对齐
真实数据里时间戳往往不是严格等间隔的。尤其串口设备,时间戳抖动可以达到几十毫秒。这时候如果直接拿原始时间戳做插值,相当于把时间测量误差也当成了信号的一部分。
我的做法是先对时间戳做平滑,再基于平滑后的时间轴做插值。比如用滑动中值滤波处理时间戳:
% 对时间戳做滑动中值平滑 t_smooth = movmedian(t_gps, 5); % 用平滑后时间戳插值 gps_vel_aligned = interp1(t_smooth, gps_vel, t_base, 'linear', 'extrap');注意这样处理后,插值结果仍然在高频信息上有一定失真,但至少不会因为单次时间戳抖动产生明显的相位错误。如果你有足够多的静态时段数据,更稳妥的办法是先用静止段的真实时间差估算平均采样周期,再用均匀网格重构时间轴。
3.4 两路传感器频率接近时,可以用最近邻匹配
当两路传感器的采样频率接近(比如IMU是100Hz,相机是100Hz),时间对齐不需要做插值,直接找最近时间戳匹配就行。匹配的误差上限是半个采样周期,也就是5毫秒左右,对大多数方向估计场景来说足够用。
% 对每个IMU时间点寻找最近的GPS时间点 [~, idx_gps] = min(abs(t_gps - t_imu(i)));不过要注意,最近邻匹配在时间戳抖动大的场景下会产生"重复匹配"和"空匹配",也就是某个GPS点被用了两次,某个点一次都没用上。所以用之前还是要先看时间戳质量。频率相差很大的情况,就不要考虑最近邻了,直接插值。
4. 采样率对齐与重采样:先做抗混叠滤波还是直接插值,差别很大
4.1 为什么不能拿interp1当重采样用
很多人处理完时间戳对齐后,发现数据的采样率还是不一样,于是习惯性地再用interp1把所有序列都插到统一频率。这样做的风险在于:interp1只做插值,不做抗混叠滤波。如果你的高频信号在降采样前没有滤掉高频分量,降采样后这些分量会折叠回低频,产生混叠。
举个例子,IMU是200Hz,你想把它降到50Hz。假如原始信号里有一个80Hz的振动分量,按50Hz采样后,这个分量会被折叠到30Hz(80 - 50 = 30),出现在低频区间里。方向估计里的姿态角如果被这个伪造的30Hz分量污染,画出来的曲线会莫名其妙地振荡。
4.2 正确做法:先均匀化,再用resample
Matlab的resample函数自带抗混叠滤波和多相滤波结构,比直接interp1可靠得多。但它有一个隐含要求:输入信号必须是均匀采样序列。如果你的IMU时间戳本身是均匀的,直接用就行;如果不是,先按我第3章的方法把数据均匀化,再喂给resample。
fs_imu = 200; % IMU标称采样率 fs_out = 50; % 目标采样率 % 如果不是均匀时间戳,先插值到均匀网格 t_uni = linspace(t_imu(1), t_imu(end), round((t_imu(end)-t_imu(1))*fs_imu)+1); acc_uni = interp1(t_imu, acc_imu, t_uni, 'linear'); % 抗混叠重采样 acc_50 = resample(acc_uni, fs_out, fs_imu);resample里的p和q参数表示新采样率与旧采样率的比值,比如从200Hz降到50Hz,就是resample(x, 50, 200)。它内部会先做低通滤波,把高于新奈奎斯特频率的成分滤掉,再做抽取。这样得到的降采样数据在频域上是干净的。
4.3 方向估计里,IMU数据通常保留高频,GPS和视觉再插过来
这里有一点需要强调:方向估计的场景里,IMU数据通常不值得降采样。陀螺仪积分需要高频的角速度输入,200Hz的数据能比50Hz更精确地捕捉快速转动。所以更合理的策略是:保持IMU原始采样率,把GPS、磁力计这类低频数据插值到IMU的时间轴上。这样既避免了IMU高频信息被破坏,又让所有数据在做融合时能逐点对应。
低频传感器插值到高频时间轴后,数据点数量会暴增,这并不代表信息量增加了,只是"占位置"而已。姿态解算算法里,低频数据的权重通常靠噪声协方差来体现,插值后的重复信息并不改变融合的实质。在EKF里,这一步其实等价于在两次量测之间做预测更新,而插值只是把量测值放到了每个IMU点上。有些工程实现会在每个IMU点上判断"这个时刻是否有新的GPS量测",如果没有就跳过量测更新,这样做比插值更符合滤波原理。但如果是在做离线后处理,插值方案因为简单直观,反而是我更推荐的。
5. 坐标系对齐:从"传感器歪着装"到载体坐标系的旋转补偿
5.1 先确定坐标轴定义,再把传感器数据转到载体坐标系
坐标系对齐的第一步,是明确载体坐标系定义。常见的约定是:X轴朝前、Y轴朝右、Z轴朝下,或者X轴朝前、Y轴朝左、Z轴朝上。不同行业约定不同,航空、汽车、机器人各有习惯。你先定好载体坐标系,再看传感器坐标系与它差多少。
假设传感器坐标系相对载体坐标系存在一个固定的旋转关系,用一个旋转矩阵R表示。那么传感器坐标系下的向量v_sensor转换到载体坐标系下的v_body就是:
% 传感器到载体系旋转矩阵,由安装偏差角roll_off、pitch_off、yaw_off决定 % 这里按Z-Y-X欧拉角顺序构造 % 定义通用旋转矩阵,避免依赖工具箱 Rx = @(a) [1 0 0; 0 cos(a) -sin(a); 0 sin(a) cos(a)]; Ry = @(a) [cos(a) 0 sin(a); 0 1 0; -sin(a) 0 cos(a)]; Rz = @(a) [cos(a) -sin(a) 0; sin(a) cos(a) 0; 0 0 1]; R_sb = Rz(yaw_off) * Ry(pitch_off) * Rx(roll_off); % 对整段数据做坐标变换 acc_body = (R_sb * acc_sensor')'; gyro_body = (R_sb * gyro_sensor')';5.2 安装偏差怎么估:静置加旋转,两步搞定
安装偏差角不是靠尺子量出来的,而是靠数据标定出来的。我用过比较简单可靠的办法:
第一步,把载体放在一个已知水平的地面上静置一到两分钟。加速度计读到的重力方向就是当前水平状态下的重力方向。如果载体坐标系定义是Z轴朝下,那么静止时加速度计在载体坐标系下的读数应该近似是(0,0,1)。如果装歪了,读到的三个轴上都会有分量。把这些分量归一化后,可以反推出安装的横滚和俯仰偏差。
第二步,让载体绕已知轴旋转。比如让车辆在平整场地上转一个90度的弯,对比磁力计或者GPS航向的变化和陀螺仪积分角度的变化,就能标定出安装的航向偏角。这一步对纯陀螺仪安装偏差来说,往往结合角速度积分的方向和实际转轴方向来推算。
如果你用的传感器模块支持DMP或者自带姿态输出,也可以利用它的输出配合已知姿态做标定。核心思路不变:用一个已知的参考姿态,反推传感器坐标到载体坐标的旋转关系。
5.3 磁力计还需要额外的"坐标系内校准"
方向估计里如果用到磁力计,它还有一层更特殊的对齐问题。磁力计测量的是地磁场在三轴上的分量,但它很容易受到周围铁磁性物质的影响,产生硬磁偏移和软磁失真。反映在数据上,就是三个轴上的磁场强度画出来不是围绕原点的一个球,而是一个偏离原点的椭球。
处理办法是做一个椭圆拟合校准。采集载体在多个方向上的磁力计数据,让载体原地转几圈,翻一翻各个角度,然后拟合椭球参数,把椭球纠正成标准球。Matlab里可以用最小二乘拟合椭球,拿到偏移和缩放矩阵:
% 假设mag是Nx3的磁力计原始数据 % 拟合椭球,得到中心offset和变换矩阵A % 校准后的磁场: mag_calib = (mag - offset) * Ainv;做完这一步,磁力计数据才算和IMU数据处在同一个"坐标系语境"里。否则融合时磁力计给出的方向会带上硬磁干扰产生的固定偏差,表现为航向角在不同朝向时准确度不一样。
5.4 坐标系对齐是否成功,一个快速验证方法
坐标系对齐做没做对,有一个非常直观的验证方法:让载体静置在水平面上,把加速度计的数据转到载体坐标系后,三轴读数应该基本是(0,0,1)(或者按你的坐标约定接近某个轴)。如果转换后重力分量仍然明显出现在多个轴上,说明旋转矩阵没配平。
另一个验证方法是绕已知轴旋转。让载体绕垂直轴匀速旋转90度,观察陀螺仪角速度在载体坐标系下的分量。如果对齐正确,角速度应该集中在你期望的旋转轴分量上,其他两个轴的分量应该接近零。如果对齐不正确,旋转轴分量会分散到多个轴上。这个验证法我几乎每次处理新数据时都会跑一遍,花两分钟就能避免后面一整天的返工。
6. 一个完整实操案例:MPU6050加GPS数据,在Matlab里从原始数据到方向估计
6.1 数据背景与预处理目标
我拿一个实际处理过的场景来说明:一辆实验小车,上面装了一颗MPU6050,加速度和角速度都是200Hz;一个GPS模块,10Hz,输出速度和位置。目标是估计车辆的航向角,用于后续的路径分析。
原始数据文件里IMU是60000帧,GPS是3000帧。两个设备的时钟独立,GPS的时间戳还比IMU的时间戳晚了13秒。这个偏移如果不处理,方向估计根本没法看。
我的预处理流程是:先检查时间戳,再统一时间基准,接着做采样率对齐,最后坐标转换和零偏校正。
6.2 原始时间戳检查与零偏估计
加载数据后,我先把IMU和GPS的时间戳都转成秒并减去各自的基准:
t_imu = (imu_ts_ms - imu_ts_ms(1)) / 1000; t_gps = (gps_ts_ms - gps_ts_ms(1)) / 1000;然后我发现GPS时间戳有时会跳变,也就是相邻两个点的时间差偶尔不是0.1秒而是0.2秒。这是因为GPS偶尔丢包。对于这种数据,直接插值会把这0.2秒的间隔当成"GPS在那个间隔里没有运动",从而低估运动变化。我先做了一个丢包标记,把大间隔位置记下来,后续统计时避开。
零偏估计也要在预处理阶段完成。取小车启动前静止30秒的IMU数据,计算陀螺仪三轴均值,这个值就是零偏:
gyro_bias = mean(gyro_raw(1:6000, :)); gyro_corrected = gyro_raw - gyro_bias;6.3 时间对齐与重采样:把GPS插到IMU时间轴上
整体对齐思路是:保持IMU的200Hz时间轴,把GPS的位置和速度插值到这个时间轴上。GPS频率只有10Hz,与IMU时间轴的点数相差20倍,插值后GPS在每两个原始点之间会有多个新的点,这些点之间是线性关系,符合GPS这类低频平滑运动的特点。
% 以IMU时间为基准 t_base = t_imu; % GPS数据插值到IMU时间轴 gps_speed_aligned = interp1(t_gps, gps_speed, t_base, 'linear', 'extrap'); gps_course_aligned = interp1(t_gps, gps_course, t_base, 'linear', 'extrap');这里有一个细节:GPS输出的航向(course)是运动方向,取值范围通常是0到360度,在正北方向附近会从359度跳变到0度。直接对这个角度序列做插值会产生错误结果。插值前要先做相位展开:
% 把角度展开成连续值,避免359到0的跳变 gps_course_unwrap = unwrap(deg2rad(gps_course)); gps_course_aligned = rad2deg(unwrap(interp1(t_gps, gps_course_unwrap, t_base, 'linear')));这个坑我踩过一次,当时航向曲线在正北方向附近出现了一个明显的尖峰,查了半天才发现是角度环绕没处理。
6.4 坐标系转换与简易姿态解算
把MPU6050数据从传感器坐标系转换到载体坐标系后,我用一个简化版互补滤波来做方向估计:
% 简易互补滤波(示意) q = [1 0 0 0]; % 初始四元数 alpha = 0.05; % 加速度计修正权重 for i = 2:length(t_base) dt = t_base(i) - t_base(i-1); % 陀螺仪积分 omega = gyro_body(i, :); % 弧度每秒 dq = quat_multiply([0, omega], q) * (0.5 * dt); q = q + dq; q = quat_normalize(q); % 加速度计修正 acc_norm = acc_body(i, :) / norm(acc_body(i, :)); g_body = quat_rotate(q, [0 0 1]); % 重力在机体系投影 error_vec = cross(acc_norm, g_body); % 基于误差修正四元数 q = q + quat_multiply([0, error_vec * alpha], q); q = quat_normalize(q); euler(i, :) = quat_to_euler(q); end这里为了简洁,我用了自定义的函数quat_multiply、quat_normalize、quat_rotate。实际工程里可以直接用Matlab的quaternion类简化代码。重点是看流程:陀螺仪积分负责高频姿态更新,加速度计修正负责拉回低频漂移。数据对齐后的效果比不对齐时好了太多——航向角在直线行驶段基本稳定,转弯处也能跟随GPS航向的趋势,而不是像之前那样乱跳。
6.5 对齐前后结果对比
我把只做零偏校正、不做时间对齐的结果,和完整对齐后的结果放在同一张图里对比。差异极其明显:不对齐时航向角在直行段漂移了20多度,转弯时和GPS航向相差很大;对齐后,航向角在直行段漂移量降到3度以内,转弯处的响应也跟上了实际动作。
这个对比让我深刻认识到,方向估计的精度瓶颈往往不是算法复杂度,而是数据时间对齐的精度。你用再复杂的EKF,也救不了一组时间错位的数据。
7. 实际数据上踩过的坑:时间戳、插值、重采样和坐标系验证的注意事项
7.1 坑一:时间戳原点不一致,必须先统一基准
多路传感器记录的起点往往不同。有的设备在上电瞬间就开始记录,有的设备要等第一位有效数据,有的设备还额外叠加了UTC时间。我处理过一批数据,IMU的时间戳从33秒开始,GPS的时间戳从0开始,如果不统一基准,两者的时间差是一个固定的大偏移。解决办法就是各自减去各自的第一个时间戳,转成相对时间,再做对齐。这一点看起来很简单,但在多文件批量处理时最容易漏。
7.2 坑二:时间戳精度不足,会随时间积累误差
有些传感器的时间戳精度是毫秒,但内部用32位整数存储,在长时间记录时会溢出。更隐蔽的是,一些数据采集脚本把时间戳用单精度浮点存下来,记录超过若干小时,小数位精度就不够了。反映在数据上,就是后期时间戳的相邻间隔开始不规则跳动。处理这种数据时要特别小心,先观察时间戳差值的分布,如果规律性变差,说明精度出了问题。解决办法是尽可能用double类型保存时间戳,或者在采集时就同时记录设备的内部时间和系统时间。
7.3 坑三:插值会制造"看似真实的合成数据"
插值产生的中间数据点并不是真实测量值,这一点我在第3章提过,但值得再强调一次。不是说插值就不能用,而是你要清楚自己的数据里哪些点是真的、哪些点是填进去的。尤其是后续要做带宽分析或频谱分析时,插值数据会改变频谱形状,容易被误会成真实信号的特征。我的习惯是把对齐后数据里所有插值点做一个掩码标记,后续做特征分析时知道哪些地方需要谨慎。
7.4 坑四:重采样前忘记抗混叠,噪声被折叠进低频
这个坑在第4章详细讲过,实际表现是:重采样后数据看起来噪声更大了,或者出现原来看不见的低频振荡。原因是原始信号里有一堆高频噪声,降采样前没有滤掉,混叠进了低频区间。如果你发现重采样后的信号比原始信号还"难看",大概率就是这个问题。解决方案是在降采样前先用低通滤波器把高于目标奈奎斯特频率的成分压掉,或者直接用resample而不是interp1。
7.5 坑五:坐标系定义不一致,连正负号都是错的
IMU的Z轴朝上还是朝下、X轴朝前还是朝后,每个模块的约定都可能不一样。我在移植代码时遇到过不少次:在A模块上标定好的旋转矩阵,换到B模块上直接失效,因为两者的Z轴方向正好相反。所以每次拿到新传感器,都要先读数据手册确认坐标轴定义,再用第5章的静置方法验证重力方向。这一步建议作为标准流程,不要靠猜。
7.6 我现在的工作习惯
处理过几批数据后,我给自己定了一条规矩:任何传感器记录数据进入方向估计流程前,必须先经过一个统一的预处理脚本。脚本里固定做五次校准——时间戳检查、时间对齐、采样率统一、坐标系转换、传感器单位换算。每次拿到新数据,不管看起来多干净,都先跑一遍这个脚本,把时间戳差值的分布图和静置时的零偏值打出来看一眼。确认无异常了,才允许进入姿态解算环节。
这个小习惯帮我在后面的项目里省了大量排查时间。方向估计算法本身已经非常成熟,各种开源的互补滤波、EKF、因子图优化方案都写得很完善,真正容易出错的地方恰恰是数据进入算法前的这一步。基于Matlab做对齐的好处是可视化方便,所有中间结果都可以随时画图确认,每一个变换都看得见、摸得着,比起闷头调算法参数,先把数据劳动关系理顺,往往才是解决问题的捷径。