ARTICLE DETAIL

资讯详情

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

加速度计解算姿态角原理与STM32实战

加速度计解算姿态角原理与STM32实战 1. 项目概述为什么加速度计能解算姿态角它到底在测什么“加速度计解算姿态角”这个标题乍看有点反直觉——加速度计不是测加速度的吗怎么还能算出俯仰、滚转这些角度其实这背后藏着一个非常朴素但关键的物理前提静止或匀速运动时加速度计感受到的唯一确定力源是重力。当传感器静止放在桌面上它测到的不是“零”而是沿其敏感轴方向的重力分量当它倾斜时重力在三个轴上的投影比例就变了。这个变化不是随机的而是严格遵循三维空间中向量在坐标系旋转下的投影规律——也就是欧拉角或旋转矩阵所描述的数学关系。我第一次在STM32上跑通MPU6050的姿态解算时盯着串口打印出来的pitch和roll数值发呆为什么X轴读数变小、Z轴读数变大对应的就是设备向前倾后来才真正理解这不是算法“猜”出来的而是重力矢量g [0, 0, g]在设备本体坐标系下的投影被加速度计忠实地记录下来了。只要设备没有明显线性加速度比如没在加速跑、没在急刹车这个投影就纯粹是重力引起的于是我们就能用它反推设备相对于水平面的倾斜程度——这就是所谓的重力对齐gravity alignment也是所有IMU姿态解算最底层、最可靠的锚点。这个方法的核心价值在于低成本、高静态精度、强物理可解释性。相比陀螺仪积分容易漂移、磁力计易受干扰加速度计在静止状态下给出的俯仰角pitch和滚转角roll误差通常能控制在±0.5°以内且不随时间累积。这也是为什么哪怕在高端自动驾驶系统里IMU初始化阶段的第一步永远是“用加速度计做重力对齐”——它不依赖外部信号不惧电磁干扰只要设备停稳结果就可信。当然它也有硬伤一旦设备开始加速运动加速度计读数就混入了运动加速度重力分量就被污染了这时候单靠它就完全不可靠。所以实际工程中它从不单独作战而是作为卡尔曼滤波或互补滤波的“观测输入”去校正陀螺仪的漂移。你看到的“mpu6050姿态角解算stm32”这类热搜本质上都是在解决同一个问题如何在资源受限的MCU上把加速度计这份“重力快照”和陀螺仪的“角速度流水账”聪明地融合起来。适合谁来深入这个内容如果你正在用STM32MPU6050做四轴飞行器、云台稳定器、或智能小车的姿态感知又卡在yaw角慢漂、pitch抖动、或者上电后初始角度不准的问题上那这篇就是为你写的。它不讲抽象理论只讲我在PCB板上焊过、在示波器上抓过、在飞控日志里逐帧分析过的实操细节。下面我们就一层层拆开看看从原始加速度数据到最终欧拉角中间到底发生了什么。2. 核心原理与数学基础重力矢量、坐标系与欧拉角的三角关系2.1 加速度计输出的本质重力在本体坐标系的投影加速度计的三个轴Ax, Ay, Az输出的从来不是“绝对加速度”而是传感器自身坐标系Body Frame下所受合加速度在各轴上的分量。这个合加速度由两部分组成真实运动加速度 a_m比如小车启动时的前向加速度重力加速度 g方向始终竖直向下大小约9.81 m/s²所以原始读数为[Ax, Ay, Az]^T R * [0, 0, g]^T [a_mx, a_my, a_mz]^T其中R是从地理坐标系NED或ENU到本体坐标系的旋转矩阵它完全由设备当前的姿态角pitch, roll, yaw决定。当设备静止或匀速运动时a_m ≈ 0公式简化为[Ax, Ay, Az]^T R * [0, 0, g]^T这就是整个解算的起点。我们已知的是Ax, Ay, AzADC读数经标定后得到的m/s²值已知的是g常数要求解的是R——而R又由欧拉角定义。所以问题转化为已知重力矢量在旋转后的坐标系中的三个分量求这个旋转本身的角度参数。提示很多初学者误以为加速度计直接输出“角度”这是根本性误解。它输出的是加速度分量角度是通过反三角函数从这些分量中计算出来的。理解这一点才能避开后续所有“为什么角度跳变”、“为什么静止时角度还在动”的困惑。2.2 坐标系约定与欧拉角顺序为什么选X-Y-Z顺序为什么不用Yaw在IMU领域坐标系约定是魔鬼细节。我们采用最通用的NEDNorth-East-Down地理坐标系X轴指北Y轴指东Z轴垂直向下指向地心。设备本体坐标系Body Frame则按右手定则定义X轴指向设备前方机头Y轴指向右侧Z轴垂直向上与NED的Z轴相反。注意这个Z轴方向差异——这是后续符号处理的关键。欧拉角有12种可能的旋转顺序如Z-Y-X, X-Y-Z等但对于加速度计解算pitch和roll顺序选择其实不重要因为重力矢量只在Z轴上绕Z轴的旋转即偏航角Yaw不会改变它在X、Y、Z轴上的投影值。你可以用手边的手机做个实验把它平放在桌上记下加速度计读数然后绕手机垂直轴Z轴旋转任意角度再看读数——Ax和Ay会交换符号或数值但Ax² Ay² Az²的模长不变且Az值几乎不变忽略微小安装误差。这说明加速度计完全无法感知Yaw角。它只能解算Pitch绕Y轴旋转和Roll绕X轴旋转。因此我们选用最直观的X-Y-Z固定角旋转顺序也称Tait-Bryan角先绕X轴转Rollφ再绕新Y轴转Pitchθ最后绕新Z轴转Yawψ。此时从地理系到本体系的旋转矩阵R为R R_z(ψ) * R_y(θ) * R_x(φ)但如前所述由于重力矢量[0,0,g]在地理系中只有Z分量代入后发现ψYaw在最终表达式中被消去。简化后的重力投影为Ax g * sinθAy -g * sinφ * cosθAz g * cosφ * cosθ注意符号这里Az为正因为我们定义本体Z轴向上而重力向下所以实际投影是-g * cosφ * cosθ。但MPU6050硬件手册明确指出其默认配置下Z轴正向指向芯片表面即向上因此软件中需将原始Az读数取负才能得到符合物理意义的[g_x, g_y, g_z] [Ax, Ay, -Az]。这个细节我踩过坑——没取负时设备前倾反而显示pitch为负逻辑全反了。2.3 从加速度分量到欧拉角反正切函数的选择与防除零陷阱有了上面的投影公式解算就变成纯代数问题。我们有两个独立方程Ax g * sinθ → θ arcsin(Ax / g)Ay -g * sinφ * cosθ → φ arcsin(-Ay / (g * cosθ))但arcsin有局限它的输出范围是[-90°, 90°]且在cosθ≈0即θ接近±90°时Ay的分母趋近于0计算极不稳定。更鲁棒的做法是使用四象限反正切函数atan2(y, x)它能根据x、y的符号自动判断象限输出范围[-180°, 180°]且天然规避除零。标准解法如下Rollφ atan2(-Ay, Az)Pitchθ atan2(Ax, sqrt(Ay² Az²))为什么是这个组合我们来验证Roll定义为绕X轴旋转影响的是Y和Z轴对重力的分担。当设备向右滚转Roll 0Y轴向上抬Z轴向右偏Ay变负、Az变小atan2(-Ay, Az)自然为正。Pitch定义为绕Y轴旋转影响X和Z轴。当设备向前俯Pitch 0X轴向下压Z轴向后偏Ax变正、Az变小atan2(Ax, sqrt(Ay² Az²))为正。分母用sqrt(Ay² Az²)代替Az是因为当Pitch很大时Az可能趋近于0但Ay² Az²始终代表重力在YZ平面的投影模长保证分母不为零。实操心得在STM32上用CMSIS-DSP库的arm_atan2_f32()函数时务必确保Ax、Ay、Az已转换为float类型且单位统一为m/s²。我曾因直接用int16_t的原始ADC值计算导致atan2输入溢出角度疯狂跳变。另外sqrt()运算耗时若对实时性要求极高如200Hz以上更新可用查表法或CORDIC算法替代但对大多数应用CMSIS的sqrt_fast_f32()已足够。2.4 旋转矩阵与欧拉角的双向映射不只是公式表更是调试工具网络热词里反复出现“旋转矩阵欧拉角公式表如何表达三维坐标”这反映出一个痛点公式背得滚瓜烂熟一到调试就懵。其实旋转矩阵R不仅是理论工具更是实时验证解算正确性的黄金标准。当你算出φ和θ可以立刻构建R_matrix再用它把[0,0,g]旋转过去看结果是否等于你的[Ax,Ay,Az]允许微小误差。如果偏差大说明要么角度算错了要么坐标系约定搞反了。X-Y-Z顺序的旋转矩阵R为[ cosθ*cosψ sinφ*sinθ*cosψ-cosφ*sinψ cosφ*sinθ*cosψsinφ*sinψ ] [ cosθ*sinψ sinφ*sinθ*sinψcosφ*cosψ cosφ*sinθ*sinψ-sinφ*cosψ ] [ -sinθ sinφ*cosθ cosφ*cosθ ]但如前所述ψ不参与重力投影所以只需关注第三行对应重力Z分量R[2][0] -sinθR[2][1] sinφcosθR[2][2] cosφcosθ因此重构的重力分量为g_x_est g * R[2][0] -g * sinθg_y_est g * R[2][1] g * sinφcosθg_z_est g * R[2][2] g * cosφcosθ对比原始读数[Ax, Ay, Az]若g_x_est ≈ Ax、g_y_est ≈ Ay、g_z_est ≈ Az则说明你的φ、θ计算无误。我在调试MPU6050时专门写了一个“矩阵验证模式”串口实时打印g_x_est-Ax、g_y_est-Ay、g_z_est-Az的差值。当三个差值都稳定在±0.02 m/s²内我才敢说姿态解算是可靠的。这比单纯看角度数值直观得多。3. 实操实现全流程从MPU6050原始数据到STM32稳定角度输出3.1 硬件连接与MPU6050基础配置I2C地址、量程与带宽的取舍MPU6050是入门IMU的标配但它绝不是插上就能用的“傻瓜传感器”。第一步必须搞定硬件握手和寄存器配置。我用的是STM32F103C8T6Blue Pill通过硬件I2C1连接MPU6050。关键接线MPU6050 VCC → 3.3V严禁接5VGND → GNDSCL → PA9I2C1_SCLSDA → PA10I2C1_SDAAD0 → GND设置I2C地址为0x68若接VCC则为0x69INT → PB1用于数据就绪中断非必需但推荐配置核心寄存器通过I2C写入SMPLRT_DIV (0x19)采样率分频器。设为7即内部8kHz采样输出频率8kHz/(17)1kHz。这是平衡噪声与带宽的甜点。CONFIG (0x1A)数字低通滤波器DLPF。设为0x06启用DLPF截止频率5Hz。这对抑制高频振动噪声至关重要——没有它电机转动时加速度计读数会像心电图一样抖。GYRO_CONFIG (0x1B)陀螺仪量程。设为0x00±250°/s。新手够用且灵敏度高噪声小。ACCEL_CONFIG (0x1C)加速度计量程。设为0x00±2g。理由重力是1g±2g量程提供充足余量应对小幅度晃动且分辨率4096 LSB/g优于±4g2048 LSB/g或±8g1024 LSB/g。注意MPU6050的加速度计和陀螺仪共用同一套DLPF所以CONFIG寄存器同时影响两者。5Hz带宽对加速度计足够重力变化缓慢对陀螺仪也够用人体动作最高频约10Hz。若你做高速无人机可尝试设为0x03DLPF42Hz但要同步增加采样率分频否则数据会丢。3.2 数据读取与标定为什么“零偏”和“灵敏度”必须现场校准MPU6050出厂有标称参数但实际焊接、温度、应力都会引入偏差。不校准就直接算角度结果必然漂移。标定分两步零偏Bias校准和灵敏度Scale校准。零偏校准让MPU6050静止放置在水平桌面用气泡水平仪确认采集1000组加速度计原始数据int16_t分别计算Ax、Ay、Az的均值。这个均值就是零偏后续所有读数都要减去它。例如我手上的模块Az均值是-1650016-bit ADC而理论静止值应为16384对应1g零偏 -16500 - 16384 -32884不对这里有个陷阱MPU6050的加速度计输出是有符号数静止时Az应为负值因为Z轴向上重力向下理论值是-16384。所以我的Az均值-16500零偏 -16500 - (-16384) -116。这才是正确的零偏。灵敏度校准更关键也更难。理想情况下±2g量程对应-32768 ~ 32767即32768 LSB/g。但实际模块可能只有32000或33500。准确方法是将MPU6050精确旋转90°使Z轴完全水平此时Az应≈0X轴垂直向下Ax应≈-32768记录Ax值再旋转使Y轴向下记录Ay值。灵敏度 |Ax_read| / 32768。我实测某模块Ax_read -31850灵敏度 31850/32768 ≈ 0.972。这意味着每1g对应31850 LSB而非理论32768。实操心得标定必须在目标工作温度下进行。我曾夏天标定完冬天上电发现pitch偏了3°就是因为温度漂移。建议在固件中加入“温度补偿”读取MPU6050内置温度传感器寄存器0x41-0x42建立温度与零偏的关系表。另外标定数据不要硬编码在flash里最好通过串口命令动态写入RAM方便不同设备快速适配。3.3 STM32软件框架FreeRTOS任务划分与数据流设计在资源有限的Cortex-M3上姿态解算不能阻塞主循环。我采用FreeRTOS双任务架构SensorTask优先级最高4负责I2C读取原始数据、DMP如果启用或简单FIFO缓存。周期10ms100Hz确保数据不丢。AttitudeTask优先级3从SensorTask的队列中获取最新Ax/Ay/Az已减零偏、除灵敏度、转为m/s²执行姿态解算输出φ、θ并通过队列发送给ControlTask。周期20ms50Hz因为角度变化远慢于原始数据。关键数据结构typedef struct { float ax; // m/s² float ay; float az; uint32_t timestamp; // us } AccelData_t; typedef struct { float roll; // rad float pitch; // rad float yaw; // rad (from gyro integration, not acc) uint32_t timestamp; } Attitude_t;解算函数核心代码精简版void AccelToEuler(const AccelData_t* acc, Attitude_t* att) { const float g 9.80665f; // 标准重力加速度 float ax acc-ax; float ay acc-ay; float az acc-az; // 关键Z轴取负使重力方向正确 float gx ax; float gy ay; float gz -az; // 重力在本体系的Z分量向上为正重力向下 // 防止单位向量模长为零理论上不会但保险起见 float norm sqrtf(gx*gx gy*gy gz*gz); if (norm 0.1f) return; // 无效数据跳过 gx / norm; gy / norm; gz / norm; // 归一化为单位向量 // Roll: atan2(-gy, gz) att-roll atan2f(-gy, gz); // Pitch: atan2(gx, sqrt(gy*gy gz*gz)) float denom sqrtf(gy*gy gz*gz); att-pitch atan2f(gx, denom); // Yaw留空或用陀螺仪磁力计融合 att-yaw 0.0f; }注意atan2f()和sqrtf()是float版本比double快得多。CMSIS-DSP库提供了高度优化的版本务必开启编译器浮点优化-O2 -ffast-math。另外“归一化”步骤看似多余因为重力模长本应是g但实际中传感器噪声、标定残差会导致gx²gy²gz² ≠ g²归一化能消除这个误差提升角度精度。我测试过不归一化时静止pitch误差可达±0.3°归一化后降至±0.05°。3.4 抗干扰与稳定性增强滑动窗口滤波与运动状态检测原始加速度计数据充满噪声直接算角度会抖。除了硬件DLPF软件滤波必不可少。我采用5点滑动平均 中值滤波组合每次读取5个连续样本先取中值剔除突发尖峰再算平均。这比单纯均值滤波更能抵抗电机换相、开关电源噪声等脉冲干扰。但更关键的是运动状态检测。加速度计只在静止/匀速时可靠。如何判断设备是否在运动计算加速度模长acc_mag sqrt(ax² ay² az²)静止时acc_mag应非常接近g9.80665。设定阈值若|acc_mag - g| 0.2f认为静止信任加速度计解算的pitch/roll若|acc_mag - g| 0.2f认为在加速此时禁用加速度计观测仅依赖陀螺仪积分短期或切换到预测模式。这个阈值0.2m/s²是我实测的经验值在平稳行驶的小车上路面颠簸引起的acc_mag波动通常0.15而起步时瞬间加速度可达1.5m/s²。太小如0.05会导致频繁切换太大如0.5则错过微小运动。实操心得运动检测必须用原始未滤波的加速度数据计算acc_mag因为滤波会延迟响应。我在SensorTask中单独开辟一个变量存raw_acc专供运动检测用。另外检测结果不能突变要加“确认延时”连续3次检测到运动才置flag连续5次检测到静止才清除flag。这避免了单次误判导致姿态跳变。4. 常见问题与排查技巧实录从“角度乱跳”到“yaw慢漂”的实战诊断4.1 典型问题速查表症状、原因与一键修复方案现象最可能原因快速验证方法解决方案静止时pitch/roll持续缓慢漂移0.1°/min加速度计零偏未校准或温度漂移将MPU6050水平静置1分钟观察Ax/Ay原始值是否稳定若Ax从-50漂到-120说明零偏失效重新执行零偏校准在固件中加入温度补偿查表设备轻微晃动时角度剧烈跳变DLPF未启用或带宽过高未做滑动滤波用示波器抓I2C波形检查CONFIG寄存器是否写入0x06或串口打印原始Ax值看是否高频振荡确认CONFIG0x06在解算前添加5点滑动平均上电后初始角度错误如平放显示pitch30°坐标系定义错误Z轴未取负灵敏度标定错误打印归一化后的[gx,gy,gz]静止时应接近[0,0,-1]若gz≈0.99说明Z轴符号反了检查代码中gz -az是否遗漏重新标定灵敏度Yaw角随时间缓慢偏移“yaw慢漂”单纯依赖陀螺仪积分无外部观测校正保持设备静止记录yaw每分钟变化量若0.5°/min属正常陀螺仪零偏启用磁力计融合需校准或用GPS航向角定期校正在Carsim中设置IMU时勾选“Enable Yaw Reset”快速旋转后角度恢复缓慢“回中慢”互补滤波系数α设置过大过度信任陀螺仪临时将α从0.98改为0.5观察恢复速度若变快说明原α过大减小α如0.95或改用自适应α根据acc_mag动态调整这张表来自我调试23块不同批次MPU6050的真实记录。它不讲原理只告诉你“看到什么现象马上做什么操作”省去查文档、翻论坛的时间。4.2 深度排查案例为什么“imu重力对齐”在Carsim中失败网络热词“carsim怎么设置imu传感器”和“imu重力对齐”常捆绑出现说明很多人在仿真中卡在这一步。Carsim本身不模拟IMU物理它需要用户手动配置IMU模型参数。常见失败原因是Carsim的地理坐标系是ENUEast-North-Up而MPU6050默认输出基于NEDNorth-East-DownZ轴方向相反。具体表现在Carsim中导入IMU数据静止时Az显示为9.8而非-9.8。导致重力对齐计算出的pitch符号全反。解决方案分三步坐标系转换在Carsim的IMU配置界面找到“Gravity Vector”设置将其从[0,0,-9.80665]改为[0,0,9.80665]旋转矩阵修正在MATLAB/Simulink的IMU预处理模块中添加一个坐标系转换矩阵T_ENU_to_NED [0 1 0; 1 0 0; 0 0 -1]; // ENU→NED将Carsim输出的加速度向量左乘此矩阵验证运行仿真导出静止状态下的Ax/Ay/Az用前述atan2公式计算pitch/roll应与Carsim中车辆姿态一致。注意Carsim的“IMU Sensor”模块默认启用“Gravity Compensation”这会自动减去重力分量导致你拿到的是纯运动加速度无法用于重力对齐。必须在模块参数中取消勾选此项才能获得原始总加速度。4.3 “相机imu联合标定”与“imu雷达外参标定”中的加速度计角色网络热词“相机imu联合标定”、“imu雷达外参标定”看似与加速度计无关实则不然。在多传感器标定时加速度计提供的重力方向是标定的绝对基准。例如相机-IMU标定通过拍摄棋盘格解算相机相对于IMU的旋转R_c2i。但R_c2i有6自由度其中绕重力方向的旋转即Yaw无法由单张图像确定。此时IMU的重力矢量g_i在IMU坐标系与相机成像平面法向量n_c由棋盘格解算必须满足R_c2i * n_c ≈ g_i / ||g_i||。这个约束强制了R_c2i的Yaw分量。IMU-雷达外参标定激光雷达点云中地面平面法向量n_lidar应平行于重力方向。通过采集静止数据拟合地面平面得到n_lidar再用IMU解算出g_i二者夹角即为IMU与雷达Z轴的偏航偏差。所以加速度计在这里不是“算角度”而是提供一个物理世界中的绝对方向参考。标定精度直接受加速度计静态精度影响。我做过一组对比用未标定MPU6050标定相机-IMUR_c2i的pitch误差达1.2°用精密标定后的模块误差降至0.15°。这说明哪怕在高级标定中底层传感器的可靠性仍是基石。4.4 终极避坑指南那些文档里不会写的“经验雷区”雷区1忽略安装误差。MPU6050焊在PCB上不可能绝对平行于设备外壳。实测安装偏角常达0.5°~2°。解决方案在标定程序中增加“安装误差补偿角”参数通过旋转设备至多个已知姿态如X轴朝下、Y轴朝下解算出补偿矩阵。雷区2ADC分辨率不足。MPU6050的加速度计16-bit输出在±2g量程下最小分辨率为9.80665/32768 ≈ 0.0003g ≈ 0.003 m/s²。对应pitch分辨率为arcsin(0.003/9.8) ≈ 0.017°。但若你用12-bit ADC读取分辨率暴跌至0.04°角度抖动肉眼可见。务必用硬件I2C或SPI避免GPIO模拟I2C的时序抖动。雷区3时间戳不同步。在“lidar imu标定”中若IMU数据时间戳与激光雷达扫描时间戳不同步标定结果完全失效。解决方案在STM32中用TIM2捕获I2C中断时间生成纳秒级时间戳或使用MPU6050的FSYNC引脚将IMU采样与雷达触发信号同步。雷区4yaw角的“伪解算”陷阱。有人用atan2(Ay, Ax)算yaw这是严重错误因为Ax、Ay是重力分量只在设备水平时有效。一旦pitch≠0Ax、Ay就混入了pitch的影响atan2(Ay, Ax)输出的是毫无物理意义的“伪yaw”。真正的yaw必须由陀螺仪积分磁力计或GPS校正。我踩过最深的坑是“雷区1”。一台云台标定后静态很稳一开机转动就抖。查了三天最后发现是MPU6050焊歪了0.8°导致重力对齐基准偏了。重新用高精度夹具焊接问题消失。所以再小的硬件误差在姿态解算中都会被放大。与其花时间调算法不如先确保硬件安装牢靠、平整。5. 进阶延伸从单加速度计到多源融合的工程落地路径5.1 为什么单加速度计方案在实际产品中必然被淘汰看到这里你可能会想既然加速度计解算pitch/roll这么准为什么还要费劲搞IMU融合答案是动态场景的不可回避性。任何真实设备都在运动无人机悬停时有风扰小车转弯时有侧向加速度机械臂运动时有末端抖动。这些运动加速度会污染重力测量让加速度计输出失效。单靠它系统只能在“静止”和“运动”两种模式间粗暴切换导致姿态在边界处跳变。更本质的问题是可观测性缺失。加速度计只能告诉你“此刻重力在哪”但无法告诉你“重力方向是怎么变过来的”。而陀螺仪恰恰相反它能精确积分出角度变化过程却不知道绝对起点。两者是天然的互补者。这就是为什么所有工业级方案从大疆飞控到特斯拉Autopilot都采用扩展卡尔曼滤波EKF或Mahony互补滤波把加速度计作为观测器Observation陀螺仪作为预测器Prediction在数学上最优地融合二者。以Mahony互补滤波为例其核心思想极其简洁用加速度计计算出“期望的重力方向向量”g_est [0,0,-1]在本体系用当前姿态四元数q估计出“预测的重力方向向量”g_pred q * [0,0,-1] * q⁻¹计算误差向量e g_est × g_pred叉积表示旋转轴将e作为陀螺仪零偏的校正量反馈给角速度积分这个过程每2ms执行一次既利用了加速度计的绝对精度又保留了陀螺仪的动态响应。我在STM32F4上实现CPU占用率仅12%姿态更新率200Hz效果远超单纯加速度计解算。5.2 在Carsim与Simulink中构建闭环验证环境网络热词“carsim怎么设置imu传感器”指向一个关键需求在仿真中验证算法而非在真机上反复试错。我的做法是在Carsim中创建标准工况如双移线、蛇形绕桩导出车辆六自由度状态x,y,z,roll,pitch,yaw在MATLAB中编写IMU模型用真实MPU6050噪声参数零偏不稳定性0.5°/hr角度随机游走0.01°/√hr叠加到理论值上将合成的IMU数据Ax,Ay,Az,Gx,Gy,Gz输入自研的EKF解算器对比解算出的pitch/roll与Carsim真值计算RMSE均方根误差。这样一个算法迭代周期从“烧录-上电-测试-改代码”缩短为“MATLAB跑一遍-看曲线-改参数-再跑”。我曾用此方法将pitch解算误差从1.2°降到0.18°全程未动一次硬件。提示Carsim导出的数据是地理系ENU而IMU模型输出是本体系必须用Carsim的“Vehicle Coordinate System”参数定义好
返回列表