IMU 原理:加速度计与陀螺仪
运动传感系列开篇。传感器是嵌入式系统感知物理世界的窗口,IMU(Inertial Measurement Unit)是最常用的一类。这篇文章不讲高深理论,只讲 MEMS 传感器怎么工作、怎么接线、怎么读数、读出来的数据长什么样。
IMU 坐标系
下图定义了 IMU 的三轴方向,后续所有公式和讨论都基于此坐标系:
flowchart TD
subgraph 设备坐标系
X["X 轴 → 右倾/翻滚 Roll"]
Y["Y 轴 → 前倾/俯仰 Pitch"]
Z["Z 轴 ↑ 偏航 Yaw"]
end
classDef axis fill:#9C27B0,color:#fff
class X,Y,Z axis除了上面这个示意图,还可以看看下面的 3D 旋转坐标系——红绿蓝三色分别对应 Roll/Pitch/Yaw,旋转展示三轴的空间关系:
MEMS 加速度计
加速度计测量的是物体受到的加速度,包含重力分量。MEMS 加速度计内部有一个微小的检测质量块(proof mass),通过硅悬臂梁悬挂在固定电极之间。当芯片整体加速时,质量块因惯性产生微小位移,两侧电容发生变化——一侧增大、一侧减小。通过测量差分电容的变化量,就能推算出加速度。
这里有个容易搞混的点:静止放在桌面上时,加速度计读到的不是 0,而是 1g(约 9.8 m/s²)指向地心。因为重力对质量块产生的效果和加速度完全等价——这就是等效原理。所以加速度计可以用来计算设备的倾角,但前提是没有线加速度干扰。
倾角计算
加速度计测量重力在三个轴上的分量,通过三角函数可以反推出设备的倾角:
$\theta = \text{atan2}(a_x, a_z)$
flowchart TD
A["设备水平放置<br/>θ=0°"] -->|"az=1g, ax=ay=0"| B["设备倾斜 θ°<br/>az=cos(θ)g<br/>ax=sin(θ)g"]
B --> C["atan2(ax, az)<br/>→ 倾角 θ"]
classDef state fill:#2196F3,color:#fff
classDef calc fill:#4CAF50,color:#fff
class A,B state
class C calc参数说明:
- ax: X 轴加速度读数(g)
- az: Z 轴加速度读数(g)
- atan2: 反正切函数,自动处理象限(比 atan 更安全)
数值例子: 设备倾斜 45° → ax=0.707g, az=0.707g → atan2(0.707, 0.707) = 45°
下面这个动图直观展示了设备从水平倾斜到 60° 的过程中,ax、az 和角度 θ 的变化:
⚠️ 注意:只有静止时才准确!有运动加速度时会污染测量。
输出格式
加速度计输出 X/Y/Z 三轴原始值,单位通常是 g 或 m/s²。数据手册会给出每个量程对应的灵敏度( Sensitivity),单位是 LSB/g。
| 量程 | 灵敏度 |
|---|---|
| ±2g | 16384 LSB/g |
| ±4g | 8192 LSB/g |
| ±8g | 4096 LSB/g |
| ±16g | 2048 LSB/g |
灵敏度转换
原始 ADC 读数转物理单位的公式:
$$a_g = \frac{\text{raw}}{\text{LSB_per_g}}$$
参数说明:
- raw: ADC 原始读数(int16,范围 -32768~32767)
- LSB_per_g: 灵敏度,±2g 量程下 = 16384 LSB/g
数值例子: raw=8192 → a_g = 8192 / 16384 = 0.5g
💡 温度变化时零偏会漂移,建议上电后静止 1 秒采集 1000 个样本做零偏校准。
关键参数
- 量程(Range):可测量的最大加速度范围。选型取决于应用场景——手持设备 ±2g 足够,无人机或机器人可能需要 ±8g 以上。
- 灵敏度(Sensitivity):数字输出每 g 对应的 LSB 数。灵敏度越高,分辨率越好。
- 噪声密度(Noise Density):单位是 µg/√Hz。决定了你能分辨的最小加速度变化。
- 零偏(Offset/Zero-g Bias):静止 0g 输入时的输出值。每颗芯片都不同,通常可以在上电后校准消除。
MEMS 陀螺仪
陀螺仪测量的是角速度,即物体绕某个轴旋转的快慢。MEMS 陀螺仪的工作原理比加速度计复杂一点儿:内部有一个持续振动的质量块(drive mode),当芯片绕敏感轴旋转时,哥里奥利力(Coriolis force)会将振动能量耦合到垂直于振动方向的检测方向(sense mode),产生位移,同样通过电容变化测量。
哥里奥利力的大小正比于角速度,所以测到的电容变化量直接反映了旋转速度。
输出格式
三轴角速度,单位 °/s(度每秒)或 rad/s。陀螺仪也按量程分档:
| 量程 | 灵敏度 |
|---|---|
| ±250 °/s | 131 LSB/(°/s) |
| ±500 °/s | 65.5 LSB/(°/s) |
| ±1000 °/s | 32.8 LSB/(°/s) |
| ±2000 °/s | 16.4 LSB/(°/s) |
关键参数
- 量程:能测量的最大角速度。人手持设备 ±250 °/s 够用,但快速旋转的物体需要更大量程。
- 灵敏度:每 °/s 对应的 LSB 数。
- 零偏稳定性(Bias Stability):陀螺仪静止时输出的稳定性,单位 °/h(度每小时)或 °/s。这是衡量陀螺仪品质的核心指标——消费级的在 5-20 °/h 左右,工业级可以做到 1 °/h 以下。
- 温漂(Temperature Drift):陀螺仪零偏随温度变化非常显著,这是实际项目里最头疼的问题之一。即使芯片静止,温度变了输出也跟着变。解决办法是温漂补偿:在电路板上靠近传感器的位置放温度传感器,建立零偏-温度曲线。
常见传感器型号
市面上常见的消费级 IMU 芯片:
| 型号 | 轴数 | 接口 | 特点 |
|---|---|---|---|
| MPU6050 | 六轴(三轴加速度 + 三轴陀螺仪) | I2C/SPI | 最经典,资料最多,DMP 内置融合算法 |
| MPU9250 | 九轴(六轴 + 磁力计 AK8963) | I2C/SPI | MPU6050 升级版,多加一个磁力计 |
| ICM-20948 | 九轴 | I2C/SPI | MPU9250 的继任者,更低功耗 |
| BMI160 | 六轴 | I2C/SPI | Bosch 出品,功耗极低,适合电池设备 |
| LSM6DS3 | 六轴 | I2C/SPI | ST 产品,带有限状态机,适合简单动作识别 |
接口方面,I2C 接线最少(SDA + SCL),但速度有限,适合低频读取。SPI 更快,适合需要高输出速率的场景。MPU6050 的 I2C 默认地址是 0x68,如果 AD0 引脚拉高则变为 0x69。
原始数据读取
下面是用 I2C 读取 MPU6050 加速度和陀螺仪原始值的代码片段。MPU6050 的寄存器是按顺序排列的——加速度 X 高字节从 0x3B 开始,连续读 14 个字节就能拿到加速度(6B)+ 温度(2B)+ 陀螺仪(6B)全部数据。
| |
读取到的原始值是有符号 16 位整数,范围取决于量程设置。要转成物理单位,除以对应量程的灵敏度系数即可。
原始数据的局限
拿到原始数据之后,千万别觉得可以直接用了。加速度计和陀螺仪各有各的毛病:
加速度计对振动敏感。走路、电机转动、甚至敲击桌面都会在读数上叠加很大的噪声。如果直接用加速度计数据算角度,得到的是一堆毛刺——必须过一遍低通滤波。但滤波又会引入延迟,这是一个需要权衡的地方。
陀螺仪有零偏和漂移。即使静止不动,陀螺仪输出也不完全是 0,总有一个小偏置。更麻烦的是,这个偏置会随时间缓慢变化(零偏不稳定性)和随温度变化(温漂)。对角速度积分得到角度时,零偏会不断累加——静止放一分钟,角度可能已经飘了好几度。
积分漂移问题
flowchart TD
A["陀螺仪原始角速度<br/>ω(t)"] --> B["积分<br/>θ = ∫ω dt"]
B --> C["角度输出"]
A -.->|"零偏误差 Δω"| D["积分后<br/>Δθ = Δω × t"]
D --> E["t=60s, Δω=0.01°/s<br/>→ Δθ=0.6° 漂移"]
E --> F["需要传感器融合修正<br/>(下篇展开)"]
classDef proc fill:#2196F3,color:#fff
classDef problem fill:#f44336,color:#fff
classDef solution fill:#4CAF50,color:#fff
class A,B,C proc
class D,E problem
class F solution下面的可视化演示了零偏累积的过程——静止 1 分钟,0.01 °/s 的微小零偏就能积分出 0.6° 的漂移:
正因为这两个传感器各有短板,实际项目里几乎不用单一传感器推算姿态。把加速度计的低频可靠性和陀螺仪的高频响应结合起来,就是传感器融合要做的事——后面单独开一篇展开。