首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >MPU6050角度

MPU6050角度

原创
作者头像
用户3672714
发布2025-07-23 16:17:48
发布2025-07-23 16:17:48
8190
举报

MPU6050 是一个集成了三轴陀螺仪和三轴加速度计的惯性测量单元(IMU),常用来测量角度和角速度。 计算 MPU6050 的姿态角度(如俯仰角 Pitch、横滚角 Roll)主要有两种常用方法:


1. 利用加速度计计算角度(静态)

加速度计测量的是重力分量,根据加速度在各轴上的分量计算俯仰角和横滚角:

  • 俯仰角 Pitch:

Pitch=arctan⁡(axay2+az2)×180π

  • 横滚角 Roll:

Roll=arctan⁡(ayax2+az2)×180π

其中 ax,ay,az 是加速度计在三个轴上的读数(单位一般是 g)。


2. 利用陀螺仪积分角度(动态)

陀螺仪给出角速度 ωx,ωy,ωz,通过积分角速度计算角度:θ(t)=θ(t−1)+ω×Δt

但是陀螺仪有漂移,积分误差会累积。


3. 结合加速度计和陀螺仪 — 卡尔曼滤波或互补滤波

为克服加速度计受加速度影响大,陀螺仪漂移问题,通常采用滤波算法:

  • 互补滤波(简单实现):

Angle=α×(Angle+ω×Δt)+(1−α)×AccAngle

α 一般取 0.95 左右。


4. 示例代码(Arduino 风格 C++)

代码语言:javascript
复制
#include <Wire.h>#include <MPU6050.h>MPU6050 mpu;float gyroAngleX, gyroAngleY, gyroAngleZ;float accAngleX, accAngleY;float pitch, roll;unsigned long timer;void setup() {  Serial.begin(115200);  Wire.begin();  mpu.initialize();  timer = millis();}void loop() {  mpu.getMotion6(&ax, &ay, &az, &gx, &gy, &gz);  // 加速度计角度  accAngleX = atan2(ay, az) * 180 / PI;  accAngleY = atan2(-ax, sqrt(ay * ay + az * az)) * 180 / PI;  // 计算陀螺仪角度增量  float dt = (millis() - timer) / 1000.0;  timer = millis();    gyroAngleX += gx * dt / 131.0; // 陀螺仪灵敏度调整(假设±250度/秒)  gyroAngleY += gy * dt / 131.0;  // 互补滤波  pitch = 0.98 * (pitch + gyroAngleX * dt) + 0.02 * accAngleX;  roll = 0.98 * (roll + gyroAngleY * dt) + 0.02 * accAngleY;  Serial.print("Pitch: "); Serial.print(pitch);  Serial.print(" Roll: "); Serial.println(roll);  delay(10);}php859 Bytes© 菜鸟-创作你的创作

5. 总结

  • 加速度计角度适合静态测量,噪声较大;
  • 陀螺仪积分角度适合短时间动态,但会漂移;
  • 互补滤波结合两者优点,实用性好;
  • 如果要求更高精度,考虑卡尔曼滤波或使用 MPU6050 内部 DMP(数字运动处理器);

下面给你一个 Python 版的 MPU6050 角度计算示例,包含加速度计、陀螺仪读数解析,结合互补滤波计算俯仰角 Pitch 和横滚角 Roll。


Python 示例(使用 smbus2 读取 MPU6050)

代码语言:javascript
复制
import smbus2import timeimport math# MPU6050寄存器地址MPU6050_ADDR = 0x68PWR_MGMT_1 = 0x6BACCEL_XOUT_H = 0x3BGYRO_XOUT_H = 0x43bus = smbus2.SMBus(1)  # 树莓派I2C bus编号通常是1# 初始化MPU6050bus.write_byte_data(MPU6050_ADDR, PWR_MGMT_1, 0)def read_word(reg):    high = bus.read_byte_data(MPU6050_ADDR, reg)    low = bus.read_byte_data(MPU6050_ADDR, reg + 1)    val = (high << 8) + low    if val >= 0x8000:        val = -((65535 - val) + 1)    return valdef get_accel_data():    ax = read_word(ACCEL_XOUT_H)    ay = read_word(ACCEL_XOUT_H + 2)    az = read_word(ACCEL_XOUT_H + 4)    return ax, ay, azdef get_gyro_data():    gx = read_word(GYRO_XOUT_H)    gy = read_word(GYRO_XOUT_H + 2)    gz = read_word(GYRO_XOUT_H + 4)    return gx, gy, gz# 互补滤波参数alpha = 0.98dt = 0.01  # 10ms采样间隔pitch = 0.0roll = 0.0try:    while True:        ax, ay, az = get_accel_data()        gx, gy, gz = get_gyro_data()        # 加速度计转为g值        ax /= 16384.0        ay /= 16384.0        az /= 16384.0        # 陀螺仪转为角速度 (deg/s),灵敏度为±250度/s,16.4 LSB/deg/s        gx /= 131.0        gy /= 131.0        gz /= 131.0        # 计算加速度计角度 (单位:度)        acc_pitch = math.degrees(math.atan2(ay, math.sqrt(ax*ax + az*az)))        acc_roll = math.degrees(math.atan2(-ax, az))        # 互补滤波计算角度        pitch = alpha * (pitch + gx * dt) + (1 - alpha) * acc_pitch        roll = alpha * (roll + gy * dt) + (1 - alpha) * acc_roll        print(f"Pitch: {pitch:.2f}  Roll: {roll:.2f}")        time.sleep(dt)except KeyboardInterrupt:    print("结束")php1.52 KB© 菜鸟-创作你的创作

说明:

  • 读取加速度计和陀螺仪原始数据,并换算成实际单位;
  • 采用简单互补滤波公式融合两种传感器数据;
  • 采样间隔 dt 根据实际硬件设定(这里是10毫秒);
  • 运行环境需要有 I2C 接口和 MPU6050 硬件支持,如树莓派。

如果你想要:

  • C++ / Arduino 版本代码;
  • Java 版本算法实现;
  • 或更复杂的卡尔曼滤波方案;

告诉我,我可以帮你继续提供。https://www.52runoob.com/archives/4336

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 利用加速度计计算角度(静态)
  • 2. 利用陀螺仪积分角度(动态)
  • 3. 结合加速度计和陀螺仪 — 卡尔曼滤波或互补滤波
  • 4. 示例代码(Arduino 风格 C++)
  • 5. 总结
  • Python 示例(使用 smbus2 读取 MPU6050)
  • 说明:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档