首页 / 资讯中心 / 文章详情

GPS+IMU数据融合必看:MATLAB开源惯性导航与EKF实现解析

GPS+IMU数据融合必看:MATLAB开源惯性导航与EKF实现解析 ★ FEATURED ARTICLE
简介面向惯性导航与组合导航开发者提供基于MATLAB的GPS/IMU数据融合开源实现。资源围绕NaveGo框架整合扩展卡尔曼滤波、传感器建模与误差补偿适合学习INS原理、开展仿真实验或搭建原型系统的中高级研究人员与工程师。压缩包共66个文件以56个m脚本为主涵盖主程序、EKF核心算法、IMU/GPS模型与数据处理函数另有5个mat数据文件、2个txt配置、1个kml轨迹、1个md说明及1个license整体大小约50.4MB目录结构清晰便于按模块阅读和复用。已有8578人学习下载是实践惯性导航与多传感器融合的热门参考资料。通过研读NaveGo代码可掌握EKF在非线性系统中的应用、IMU误差建模与Allan方差分析并可直接运行实例、替换数据验证算法效果为自身项目提供可扩展的MATLAB实现基础。1. 为什么拿 GPS 和 IMU 做数据融合的人都应该先跑一遍这套 MATLAB 开源程序有一次我在做车载组合导航调研手里只有一组手机 IMU 数据位置漂得离谱。当时在 GitHub 上翻到这套惯性导航 MATLAB 开源程序它把 GPS 和 IMU 的数据融合链路做成了完整工程从传感器仿真、惯性解算到扩展卡尔曼滤波每一步都有独立的 MATLAB 函数可以直接跑通。跑完之后我才真正看懂“机械编排”和“量测更新”在代码里分别对应哪几行矩阵运算。这套程序适合要做组合导航算法验证、惯性导航课程作业、以及快速上手 EKF 数据融合的人——新手能靠它跑通整个闭环熟手能拿它当骨架改自己的传感器模型和滤波策略。2. 技术栈与数据形态先搞懂 IMU 和 GPS 在程序里各自扮演什么角色2.1 程序吃进去的数据长什么样这套程序的核心输入是两类传感器数据IMU 和 GPS。IMU 以高频输出角速度和加速度描述的是“相对变化”GPS 以低频输出经纬度和高度描述的是“绝对位置”。两者单独用都有硬伤IMU 积分会漂移GPS 更新率低且在城市峡谷里会掉星。程序要做的就是把 IMU 的短时高精度和 GPS 的长时稳定性凑到一条轨迹上。数据项符号单位典型频率在程序里的作用陀螺仪角速度gyrorad/s100 Hz姿态变化率的来源加速度计比力accm/s²100 Hz速度变化率的来源需扣除重力GPS 纬度latdeg1 Hz位置量测基准GPS 经度londeg1 Hz位置量测基准GPS 高度altm1 Hz北向位置之外的天向修正程序一般用一个加载函数把 CSV 读成结构体常见写法如下function [imu_data, gps_data, t] load_sensor_data(file_path) % 读取 IMU 数据并转成 rad/s 和 m/s^2 raw csvread(file_path, 1, 0); t raw(:, 1); % 时间戳秒 imu_data.gyro raw(:, 2:4); % 角速度rad/s imu_data.acc raw(:, 5:7); % 比力m/s^2 gps_data.lat raw(:, 8); % 纬度 gps_data.lon raw(:, 9); % 经度 gps_data.alt raw(:, 10); % 高度 end这里关键的坑在于单位。很多采集设备输出的是 deg/s 和 g不换算直接用的话姿态更新第一轮就被夸大 57 倍轨迹直接起飞。所以加载函数的职责不只是读数据还要把陀螺输出从 deg/s 乘以 pi/180把加速度计从 g 乘以 9.8。如果你是自己写采集程序我一般建议在固件端就把单位统一掉不要在 MATLAB 里反复做量纲换算。没有真实设备的时候程序还提供了一个仿真数据生成脚本用一组运动学模型加上传感器噪声和零偏合成一段带真实轨迹标签的 IMU 数据function [imu, gps_truth] generate_sim_trajectory(dt, T) % 仿真一条直线加速运动轨迹 N round(T / dt); t (0:N-1) * dt; % 速度曲线前3秒静止然后以 2 m/s^2 加速 5 秒最后匀速 vel zeros(N, 1); for i 2:N if t(i) 3 vel(i) 0; elseif t(i) 8 vel(i) 2 * (t(i) - 3); else vel(i) 10; end end % 由速度差计算比力并加入陀螺仪和加速度计的噪声 imu.acc(:, 1) diff(vel) / dt 9.8; % 前向比力叠加重力分量 imu.gyro 0.3 * randn(N-1, 3); % 模拟噪声角速度 gps_truth.lat 30.0 cumsum(vel * dt) / 111320; end仿真数据的好处是有一个“标准答案”可以对照。真实数据融合完只能凭直觉判断路径合不合理仿真数据可以直接算误差曲线看得出程序是状态估计的问题还是代码写错了的问题。我建议第一次跑这套程序的人先跑仿真脚本把真实标签和融合结果画在一张图上确认融合没有系统性偏差之后再换自己的数据集。2.2 坐标系约定NED 还是 ENU这是最容易错的一步组合导航程序里 90% 的“玄学”问题出在坐标系。这套程序内部统一用 NED北东地坐标系但 MATLAB 里很多地理工具箱默认用 ENU东北天传感器厂家给的参考系也五花八门。NED 下重力向量是 (0, 0, 9.8) 作为比力的基准ENU 下则是 (0, 0, -9.8)符号错了静态对准出来的初始姿态就直接偏 180 度。程序里有一段经纬度转局部坐标的函数把 GPS 的经纬度差换算成当地 NED 平面的米function [x_north, y_east, z_down] geodetic_to_ned(lat, lon, alt, lat0, lon0, alt0) % 将 WGS-84 经纬度差值转换为 NED 米制坐标 RE 6378137; % 地球长半轴 e2 0.00669437999; % 第一偏心率平方 % 参考点的卯酉圈曲率半径 Rn RE / sqrt(1 - e2 * sin(lat0)^2); d_lat lat - lat0; d_lon lon - lon0; d_alt alt - alt0; x_north d_lat * (Rn alt0); % 北向 y_east d_lon * (Rn alt0) * cos(lat0); % 东向 z_down -d_alt; % 地向NED 向下为正 end注意这句z_down -d_alt。NED 的三轴指向北、东、地高度增量在天向所以转成地向坐标要取负。很多踩坑现场就是这里少了一个负号导致融合结果垂直方向抖得厉害水平方向倒是正常看起来很像 GPS 噪声突然变大。小范围的经纬度差用这个方法转米足够了误差在几公里范围内可以忽略。如果你是跑高动态飞行器轨迹需要换更严格的椭球模型但这套程序面向的是车载和低速无人机场景近似处理没有问题。2.3 为什么选 EKF 而不是互补滤波或紧耦合这套程序的数据融合核心选了松耦合的误差状态 EKF。相比互补滤波EKF 的价值在于把姿态、速度、位置、陀螺零偏、加计零偏都放进同一个状态向量里用协方差矩阵显式表达“我有多相信当前估计”。互补滤波只能做姿态层面的融合位置和速度漂移管不了而松耦合 EKF 把 GPS 位置当作量测能同时压住速度和位置的漂移。误差状态的好处是线性化更可靠。如果把姿态直接用四元数放进状态向量做 EKF状态方程的非线性很强一阶近似容易发散改成姿态误差角这种小量更新增量始终很小线性化误差就控制住了。程序里的状态向量通常长这样x [姿态误差(3); 速度误差(3); 位置误差(3); 陀螺零偏(3); 加计零偏(3)]总共 15 维。每次 IMU 数据进来做一次机械编排预测每次 GPS 数据进来做一次量测更新。零偏放在状态里是这套程序能不能跑长时程的关键IMU 零偏会随时间缓慢变化如果不在线估计10 分钟后位置误差就会以三次方速度增长。这一点在仿真里不明显真实数据上立竿见影。3. 目录结构解析这套程序的模块划分和运行入口3.1 顶层目录一览data、lib、demo、output 怎么分工整套程序目录结构不大但分层很清爽一条主线从数据到结果一目了然ins_matlab/ ├── data/ # 存放采集或仿真生成的传感器数据 │ ├── imu.csv │ ├── gps.csv │ └── sim_data.mat ├── lib/ # 核心函数库所有算法都在这里 │ ├── load_data.m # 数据读取与单位换算 │ ├── initial_align.m # 静态初始对准 │ ├── imu_mech.m # 机械编排姿态/速度/位置递推 │ ├── ekf_update.m # EKF 量测更新 │ ├── quat_ops.m # 四元数运算工具函数 │ ├── geodetic_to_ned.m # 经纬度转 NED 米制坐标 │ └── plot_traj.m # 轨迹和误差绘图 ├── demo/ # 可运行脚本从这里启动 │ ├── run_demo.m # 跑真实数据的示例 │ └── run_sim.m # 跑仿真数据的示例 ├── config/ │ └── set_default_config.m # 全局参数配置 └── output/ # 运行后生成的图表和 mat 结果data 目录只放原始数据任何处理过的中间量都不落盘保证每次运行都是从原始数据重新算起减少“数据被上一版脚本改过”的排查麻烦。lib 目录里的函数都是无状态纯函数输入结构体、输出结构体不依赖全局变量这样单元测试和替换算法都方便。demo 目录只放入口脚本本身不实现任何算法逻辑。3.2 函数分层读取、对准、编排、融合、绘图各干各的各模块职责分得很清楚调用关系是单向的没有循环依赖函数文件职责主要输入主要输出load_data.mCSV 读取、单位换算文件路径imu/gps 结构体initial_align.m静态段求初始姿态与零偏前 3~5 秒 IMU 数据初始四元数、零偏估计imu_mech.m姿态、速度、位置递推上一帧状态、IMU 增量预测状态与预测协方差ekf_update.m用 GPS 量测修正状态预测状态、GPS 量测校正后的状态与协方差plot_traj.m绘制轨迹、误差和姿态曲线状态序列、真实轨迹图像文件新手最容易犯的错是往 imu_mech 里塞 GPS 数据或者往 ekf_update 里塞 IMU 数据觉得“反正都是数据融合放哪儿都一样”。实际上这套程序的设计核心是“高频 IMU 驱动预测、低频 GPS 驱动校正”两个模块的更新频率完全不同数据结构也不同混在一起最后就是时间轴错位。3.3 运行入口demo 脚本的启动顺序两个 demo 脚本的流程几乎一样区别只在数据来源。这里用伪代码描述 run_demo 的完整逻辑1. load_data 读取 imu.csv 和 gps.csv 2. initial_align 用前 3 秒静态段做初始对准 3. 初始化 15 维误差状态向量和协方差矩阵 P 4. 循环每一帧 IMU 数据 - imu_mech 做姿态、速度、位置递推 - 更新状态协方差 P - 若当前时刻有 GPS 量测调用 ekf_update 做校正 5. 把全部状态序列存成结构体plot_traj 绘图主循环是整个程序的脊柱理解了它二次开发就知道该往哪里插代码。如果你要给程序加零速检测ZUPT就是在第 4 步的循环里多加一个 if 分支如果要加磁力计量测就是在 GPS 量测的同一位置新增一个更新分支。3.4 参数配置噪声与协方差值从哪来参数配置集中在 set_default_config.m 里打开就能看到全部需要调的旋钮config.imu_freq 100; % IMU 输出频率Hz config.gps_freq 1; % GPS 更新频率Hz % IMU 噪声参数按 Allan 方差分析结果填写 config.gyro_noise 0.001; % 陀螺白噪声rad/s/sqrt(Hz) config.gyro_bias 0.0001; % 陀螺零偏rad/s config.acc_noise 0.01; % 加计白噪声m/s^2/sqrt(Hz) config.acc_bias 0.001; % 加计零偏m/s^2 % GPS 量测噪声1 个标准差 config.gps_pos_noise 3; % 位置噪声米 config.gps_vel_noise 0.2; % 速度噪声m/s % 初始协方差矩阵 config.P_init diag([ 0.1 * pi/180, 0.1 * pi/180, 0.1 * pi/180, % 姿态误差角 0.1, 0.1, 0.1, % 速度误差 1.0, 1.0, 1.0, % 位置误差 0.0001, 0.0001, 0.0001, % 陀螺零偏 0.001, 0.001, 0.001 % 加计零偏 ]);这些值看起来随意实际都对应传感器的手册指标或者 Allan 方差分析结果。GPS 位置噪声 3 米对应普通民用单频接收机的典型精度如果你用的是 RTK 厘米级定位可以缩到 0.1 甚至更小。协方差初值差一个量级通常不会发散但会影响前几秒的收敛速度真正敏感的是一旦把量测噪声 R 写小滤波器就会过度信任 GPS动态路段会看到轨迹出现锯齿状跳动。4. 核心模块拆解从一条 IMU 数据帧到修正后的位置完整链路4.1 主循环run_demo.m 是怎么把各模块串起来的真实的主循环代码比伪代码略长一点但逻辑完全一致% run_demo.m 主循环核心片段 imu load_data(data/imu.csv); gps load_data(data/gps.csv); config set_default_config(); % 初始对准用前 3 秒静态数据估计姿态和零偏 [q0, bias_est] initial_align(imu, config); % 15 维误差状态初始化全部置零 x zeros(15, 1); P config.P_init; N length(imu.t); gps_idx 1; % GPS 数据索引 for k 1:N dt imu.t(k) - imu.t(max(k-1, 1)); % 机械编排预测步IMU 每帧都执行 [x, P] imu_mech(x, P, imu.gyro(k,:), imu.acc(k,:), dt, q0, bias_est, config); % 量测更新当前时刻恰好有 GPS 采样 if imu.t(k) gps.t(gps_idx) gps_idx length(gps.t) z [gps.lat(gps_idx); gps.lon(gps_idx); gps.alt(gps_idx)]; [x, P] ekf_update(x, P, z, gps_idx, q0, bias_est, config); gps_idx gps_idx 1; end end这里的q0和bias_est是初始对准的结果整个循环里保持不变作为误差状态线性化的参考点。gps_idx按 GPS 事件递增而不是用mod(k, 100)去卡频率这样即使在真实数据里 IMU 掉帧、GPS 双帧也不会错位。主循环本身不关心传感器是否“严格等间隔”只认时间戳——这一点是这套程序能直接换真实数据的关键设计。4.2 姿态更新四元数积分为什么比欧拉角稳定机械编排的第一步是姿态更新程序里用四元数递推避免欧拉角的奇异性function [q] attitude_update(q_prev, gyro_body, dt) % 四元数姿态更新采用一阶毕卡算法 w gyro_body(:); % 角速度rad/s wn norm(w); if wn 1e-12 q q_prev; % 静止不动姿态保持不变 return; end % 构造增量四元数 dq [cos(wn * dt / 2); sin(wn * dt / 2) * w / wn]; % 四元数乘法q_new q_prev ⊗ dq q quat_multiply(q_prev, dq); % 归一化防止累积误差 q q / norm(q); end这段代码的逻辑是把角速度增量转成一个小角度旋转的四元数然后左乘到当前姿态上。wn接近零时直接返回避免除零每次更新后归一化一次因为四元数漂移是数值误差的主要来源。一阶毕卡算法在 100 Hz 以下的 IMU 数据上精度足够不需要上更高阶的龙格库塔。姿态更新的频率必须和 IMU 采样率一致每收到一帧陀螺数据就执行一次。如果你把姿态更新放到 GPS 频率去跑相当于用 1 Hz 的采样率积分角速度动态场景下姿态会在两次更新之间漏掉大量角运动融合结果必定发散。4.3 速度与位置更新比力是怎么变成位移的速度更新要把加速度计输出的比力换算到导航系扣掉重力和地球自转的影响function [v_new, pos_new] velocity_position_update(v_prev, pos_prev, ... acc_body, q_nb, dt) % 比力从机体坐标系转到 NED 导航坐标系 acc_ned quat_rotate(q_nb, acc_body); % 扣除重力NED 下重力为 (0, 0, 9.8) g [0; 0; 9.8]; acc_effective acc_ned - g; % 梯形积分更新速度 v_new v_prev acc_effective * dt; % 位置更新使用二阶近似v_prev*dt 0.5*a*dt^2 pos_new pos_prev v_prev * dt 0.5 * acc_effective * dt^2; end加速度计测的是比力不代表物体真实的加速度。静止时加速度计读数是向上的 9.8 m/s²因为它在支撑重力真实加速度是零所以要减掉当地的 g 向量。很多移植代码的人在这里漏掉重力补偿结果静态对准的加速度分量全部被当成真实运动位置以二次方速度飞出去。此外速度更新用的是上一时刻的比力和当前时刻的比力做梯形平均还是只用当前值会影响高频振动下的精度。这套程序在车载场景默认用梯形积分因为汽车底盘振动大瞬时比力噪声很高梯形平均能压掉一部分高频分量。如果你要跑无人机数据建议改成中值积分倾斜时比力变化更剧烈梯形积分会有明显滞后。4.4 EKF 量测更新GPS 位置进来后发生了什么当主循环检测到 GPS 量测事件时调用 ekf_update 做校正。这是数据融合的“题眼”function [x_corr, P_corr] ekf_update(x_pred, P_pred, z_gps, gps_idx, ... q0, bias_est, config) % 量测残差GPS 量测映射到状态误差空间 % 这里 H 矩阵只选择位置误差三个状态分量 H zeros(3, 15); H(1, 7) 1; % 北向位置误差 H(2, 8) 1; % 东向位置误差 H(3, 9) 1; % 地向位置误差 % 预测的 GPS 位置从累积位置状态得到 z_pred H * x_pred; % GPS 实际量测与预测之差 y z_gps - z_pred; % 新息协方差 S H * P_pred * H config.R_gps; % 卡尔曼增益 K P_pred * H / S; % 状态与协方差更新 x_corr x_pred K * y; P_corr (eye(size(P_pred)) - K * H) * P_pred; % 强制协方差对称避免后续计算出现复数特征值 P_corr 0.5 * (P_corr P_corr); end这里最值得琢磨的是 H 矩阵只取了位置误差三个分量不代表姿态估计不受 GPS 影响。因为状态向量的位置误差和姿态误差在协方差矩阵里是耦合的位置观测通过 P_pred 的非对角块间接修正了姿态误差。这就是状态融合的“隐藏链路”。量测更新里config.R_gps是 GPS 位置的协方差矩阵平时设成一个对角阵三个方向各给一个标准差平方。RTK 接收机可以设置 0.01 量级普通导航型接收机给 10 左右比较合适——R 给得越小滤波器越激进轨迹越贴 GPS 但也越容易把 IMU 的高频噪声放大成锯齿。4.5 误差状态更新后的状态重置EKF 更新完误差状态之后程序还要把误差状态归零这是误差状态滤波和全状态滤波最大的区别% 用误差状态校正真实状态再把误差状态清零 q_nb quat_delta(q_nb, x_corr(1:3)); % 四元数姿态校正 v_nb v_nb - x_corr(4:6); % 速度校正 pos_nb pos_nb - x_corr(7:9); % 位置校正 bias_est bias_est x_corr(10:15); % 零偏估计更新 % 误差状态清零下一轮继续估计新误差 x zeros(15, 1); P 0.5 * (P_corr P_corr);如果不做 reset小误差会不断累积叠加几个循环之后状态向量里存的就不是“误差”而是“累计误差”EKF 的线性化基础就崩了。每次量测更新完成后清零让滤波器始终只估计最近两个量测时刻之间累积的误差这是误差状态卡尔曼滤波的标准操作。5. 避坑与排查跑这套程序最容易翻车的五个地方5.1 现象三连轨迹飞掉、姿态爆掉、协方差 NaN我见过很多人第一次跑这套程序结果无外乎三种轨迹 10 秒内飞出地图、姿态角突然跳到 90 度、协方差矩阵出现 NaN 之后一切失控。这三个现象往往指向同一个根因——数据在进入机械编排之前就已经错了只是在 EKF 阶段才爆发。先按顺序排查第一看加载后的 IMU 数据数量级是否正确静止时加速度计的模长应该在 9.8 附近陀螺应在 0 附近第二看时间戳是否有重复值或跳变IMU 掉帧会导致dt算成负数第三看 GPS 经纬度是否有野值个别跳变点会把整个轨迹拉歪。程序里建议加一段数据体检打印出上述三个检查项的最小值、最大值和均值。5.2 坑一量纲没有统一第一轮姿态更新就偏了现象是静止时段姿态还能稳住一动起来姿态明显超前或震荡位置误差随时间增长异常快。原因是陀螺用的 deg/s 直接当 rad/s 用了一个量级差了 57 倍。解决方法是把单位换算收敛到 load_data 一个函数里不要在 imu_mech 里做换算。只要所有后续模块都从结构体取 rad/s 和 m/s^2量纲问题就只在入口出现一次。如果你换了新的数据源第一件事是打印前 100 帧的max(abs(imu.gyro))如果数值超过 3.14八成还是 deg/s。5.3 坑二时间同步错位GPS 和 IMU 对不上榫头现象是静止时融合结果和 GPS 吻合一进入动态就出现周期性偏差轨迹看起来像“爬楼梯”。原因是 GPS 时间戳和 IMU 时间戳基准不同常见的是 GPS 用出厂秒IMU 用复位后的相对秒两者之间有一个恒定偏移。解决方法是先对齐起始时刻把两边第一条数据的时间戳都归零看 GPS 第一条数据在 IMU 时间轴的什么位置把这个偏移量写进 config。千万别在循环里用mod(k, 100)这种按帧数对齐的做法真实数据帧率从来不是严格均匀的。这套程序按时间戳事件触发的方式已经规避了这个问题前提是你别擅自改成计数对齐。5.4 坑三初始对准偷懒EKF 收敛半天拉不回来现象是轨迹第一分钟误差明显大于后面或者初始姿态误差超过 30 度时滤波器发散。原因是没有做静态初始对准直接从零姿态开始跑机械编排。姿态误差一大比力投影到导航系之后方向全错速度误差迅速增长GPS 位置量测虽然能修正位置但对姿态的修正传导链很长且非线性。解决方法是给 initial_align 足够的时间通常取 3~5 秒静止数据求平均加速度方向用重力方向确定初始俯仰和横滚角。这一步不需要外部设备代价只是开始跑之前多等几秒但换来的是整个滤波过程的稳定性。我一般会在对准后打印估计出的欧拉角如果横滚或俯仰超过 5 度说明设备没放平或者对准段里有明显运动需要重新采集。5.5 坑四协方差矩阵不会调越滤波结果越差现象是 GPS 信号好的时候轨迹贴着 GPS一到树荫或隧道里轨迹立刻飞。原因是 GPS 协方差 R 设得太小滤波器无条件信任 GPS当 GPS 噪声突然增大时完全失去抵抗能力。解决方法是给 R 留一点余量普通单频 GPS 量测噪声按 3~5 米设不要设到 1 米以下。RTK 接收机可以收紧到 0.1~0.3 米但前提是你的 IMU 频率足够高且动态范围够。另一个常见问题是初始协方差 P_init 设得过大导致滤波器在最初几秒疯狂震荡。记住一句话P_init 过大让前几秒像抽风R 过小让整段轨迹像 GPS 的跟屁虫。5.6 坑五仿真数据和真实数据的噪声根本不是一回事现象是仿真跑得完美一换真实数据就全线崩溃。原因是仿真脚本只加了高斯白噪声没有加零偏、零偏稳定性、温度漂移和低频振动误差真实 MEMS 传感器的噪声谱远比白噪声复杂。解决方法是先把仿真数据的噪声参数调成“偏宽松”而不是“干净”陀螺零偏给到 0.01 rad/s 量级加计给到 0.01 m/s²这样测试出的结果更接近真实水平。更重要的是跑真实数据之前先把 Allan 方差算一遍把算出来的零偏不稳定性和随机游走系数直接填进 config比凭直觉调参靠谱得多。6. 二次开发把别人的惯性导航程序变成自己的工具箱6.1 换数据源接入自己采集的 CSV这套程序的 load_data 接口只依赖结构体字段名所以换数据源只需要写一个新加载函数输出同样的结构体格式。注意点就两个单位必须统一成 rad/s 和 m/s²时间戳必须单调递增且以秒为单位。我自己改过一版把采集到的二进制包解析逻辑单独放到 parse_firmware.mload_data 只做转发逻辑清晰很多。6.2 换滤波器从 EKF 到 UKF如果你想做算法对比程序的主循环已经把预测和更新拆开了EKF 换 UKF 只需替换 imu_mech 和 ekf_update 两个函数内部实现保留输入输出接口不变。代价是 UKF 需要对 15 维状态生成 31 个 sigma 点计算量大一些但应对强非线性初始化场景时不容易崩。如果你要加里程计、视觉位姿这类非线性量测可以直接在量测更新里加一组分支。6.3 验证方法跑基线、灌噪声、看误差每次改完代码先跑一遍仿真脚本确认误差在预期范围再叠加一个已知的陀螺零偏比如 0.01 rad/s看滤波器能不能估计出来。能把这组验证走通说明你的改动没有破坏核心链路。从那以后我每次拿到新的传感器数据集都强制自己走一遍这套流程先静态对准再看 Allan 方差定噪声参数最后才跑融合。这个习惯帮我少翻了很多车。希望这套程序也能帮你少走这些弯路。本文还有配套的精品资源点击获取
阅读完成 · 觉得有帮助?
咨询建站