1. 姿态角简介
- 俯仰角(Pitch):绕X轴旋转角度,表示前后倾斜
- 滚转角(Roll):绕Y轴旋转角度,表示左右倾斜
- 偏航角(Yaw):绕Z轴旋转角度,表示左右旋转(需要磁力计辅助,MPU6050无磁力计)
2. 传感器数据的特点
- 加速度计:测量重力方向,适合计算静态倾斜角,但对动态运动噪声敏感
- 陀螺仪:测量角速度,短期精度高,但长期存在漂移
3. 互补滤波算法
通过加权融合加速度计和陀螺仪数据,利用陀螺仪短期稳定性和加速度计长期稳定性,实现准确的姿态估计。
公式示例:Angle=α×(Angle+GyroRate×dt)+(1−α)×AccelAngle
- α 是滤波系数,一般取0.95左右
- dt 是采样时间间隔
- GyroRate是陀螺仪测得角速度
- AccelAngle是由加速度计计算得到的角度
4. 代码实现(Arduino示例)
#include <Wire.h>
const int MPU_ADDR = 0x68;
float gyroXangle = 0, gyroYangle = 0;
float compAngleX = 0, compAngleY = 0;
unsigned long timer, timerPrev;
float dt;
void setup() {
Wire.begin();
Serial.begin(9600);
// 唤醒MPU6050
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x6B);
Wire.write(0);
Wire.endTransmission(true);
timerPrev = micros();
}
void loop() {
unsigned long timerNow = micros();
dt = (timerNow - timerPrev) / 1000000.0; // 转换成秒
timerPrev = timerNow;
Wire.beginTransmission(MPU_ADDR);
Wire.write(0x3B);
Wire.endTransmission(false);
Wire.requestFrom(MPU_ADDR, 14, true);
int16_t AcX = Wire.read() << 8 | Wire.read();
int16_t AcY = Wire.read() << 8 | Wire.read();
int16_t AcZ = Wire.read() << 8 | Wire.read();
Wire.read(); Wire.read(); // 跳过温度数据
int16_t GyX = Wire.read() << 8 | Wire.read();
int16_t GyY = Wire.read() << 8 | Wire.read();
Wire.read(); Wire.read(); // 跳过GyZ
// 加速度计角度计算(单位:度)
float AccXangle = atan2(AcY, AcZ) * 180 / PI;
float AccYangle = atan2(-AcX, sqrt(AcY * AcY + AcZ * AcZ)) * 180 / PI;
// 陀螺仪角速度转换(单位:度/s,默认±250°/s量程)
float gyroXrate = GyX / 131.0;
float gyroYrate = GyY / 131.0;
// 角度积分
gyroXangle += gyroXrate * dt;
gyroYangle += gyroYrate * dt;
// 互补滤波融合
const float alpha = 0.96;
compAngleX = alpha * (compAngleX + gyroXrate * dt) + (1 - alpha) * AccXangle;
compAngleY = alpha * (compAngleY + gyroYrate * dt) + (1 - alpha) * AccYangle;
Serial.print("Pitch: ");
Serial.print(compAngleX);
Serial.print(" Roll: ");
Serial.println(compAngleY);
delay(10);
}
5. 说明
- 使用
atan2
函数计算加速度计对应的角度 - 角速度除以131是因为陀螺仪默认250°/s量程对应16位数据范围
- 互补滤波的权重 α 可以调节,常见0.95~0.98之间
- 该代码仅计算俯仰和滚转角,偏航角需用磁力计配合计算
6. 后续内容建议
- 使用卡尔曼滤波进一步提高姿态估计精度
- 增加偏航角计算,接入磁力计(MPU9250或外接HMC5883L)
- 基于STM32或其他MCU的MPU6050驱动与姿态融合代码
- 实际项目应用案例:无人机姿态控制、机器人平衡控制
发表回复