7、陀螺仪数据解读:x、y、z 轴角速度的含义,单位(rad/s)
好,咱们接着聊。上一章我们把加速度计聊透了,这一章轮到陀螺仪了。
说实话,我当年刚接触陀螺仪时,最头疼的就是理解「角速度」这三个字。加速度计好歹能想象出「往左推、往右推」的感觉,但角速度?转得快慢?这玩意儿到底怎么读?
别急,今天我就用最直白的方式,把 x、y、z 三个轴的角速度给你讲明白。
7.1 角速度到底是什么?
先问一个问题:你小时候玩过陀螺吗?
陀螺转得越快,它就越稳。这个「转得快慢」,就是角速度。
在物理上,角速度描述的是物体绕某个轴旋转的快慢。单位是 rad/s(弧度每秒)。
1 rad/s 是什么意思?就是每秒转大约 57.3 度。一圈是 2π ≈ 6.28 弧度,所以 6.28 rad/s 就是每秒转一圈。
核心概念:
- 角速度 ≠ 速度。速度是直线移动的快慢,角速度是旋转的快慢。
- 陀螺仪测量的是「旋转」,不是「倾斜」。这一点和加速度计完全不同。
- 单位 rad/s 是国际标准,所有 Android 手机陀螺仪都输出这个单位。
7.2 三个轴:x、y、z 分别代表什么?
Android 手机陀螺仪的数据是一个三维向量:[x, y, z],单位都是 rad/s。
每个轴对应手机的一个旋转方向。我习惯用「右手定则」来记忆——你伸出右手,拇指指向轴的正方向,四指弯曲的方向就是正旋转方向。
| 轴 | 旋转方向 | 手机动作 | 典型场景 |
|---|---|---|---|
| x 轴 | 绕手机宽度方向旋转 | 手机前后翻转(像点头) | 抬头/低头检测 |
| y 轴 | 绕手机长度方向旋转 | 手机左右翻转(像摇头) | 横竖屏切换 |
| z 轴 | 绕手机厚度方向旋转 | 手机水平旋转(像转盘) | 指南针/地图旋转 |
举个例子:你把手机平放在桌上,然后顺时针旋转手机(像拧瓶盖),这时候 z 轴的角速度就是正的。反过来逆时针转,z 轴就是负的。
我的小技巧:
我在调试陀螺仪时,经常用这个办法验证方向对不对:
- 把手机平放,快速向右旋转 90 度
- 看 z 轴数据:应该先出现一个正峰值,然后归零
- 如果出现负峰值,说明坐标系定义反了
7.3 数据长什么样?
咱们直接看代码。Android 的 SensorEvent.values 数组里,三个值依次就是 x、y、z 轴的角速度。
// 陀螺仪数据回调
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
float gyroX = event.values[0]; // 绕 x 轴角速度,单位 rad/s
float gyroY = event.values[1]; // 绕 y 轴角速度,单位 rad/s
float gyroZ = event.values[2]; // 绕 z 轴角速度,单位 rad/s
// 举个例子:手机静止时,三个值都接近 0
// 快速翻转手机时,对应轴的值会瞬间跳到 ±2~±10 rad/s
Log.d("Gyro", String.format("x=%.2f, y=%.2f, z=%.2f", gyroX, gyroY, gyroZ));
}
}
你想想看,手机静止不动时,陀螺仪输出应该是多少?
对,接近 0。因为没在转嘛。但注意,不是绝对的 0,会有一些噪声,通常在 ±0.01 rad/s 以内。
注意:
陀螺仪对「静止」的定义是「没有旋转」,而不是「没有移动」。你把手机从桌上拿起来,只要没旋转,陀螺仪数据依然是 0。这和加速度计完全不同——加速度计在移动时会有明显变化。
7.4 角速度的正负号
正负号代表旋转方向。这个很容易搞混,我当初就栽过跟头。
规则很简单:
- 正值:绕轴正方向逆时针旋转(从轴的正方向看向原点)
- 负值:绕轴正方向顺时针旋转
举个例子:你把手机屏幕朝上平放,然后:
- 手机绕 x 轴向前翻转(屏幕朝下):x 轴角速度为 正
- 手机绕 x 轴向后翻转(屏幕朝上):x 轴角速度为 负
- 手机绕 y 轴向右翻转(右侧抬起):y 轴角速度为 正
- 手机绕 y 轴向左翻转(左侧抬起):y 轴角速度为 负
嗯,这里要注意:不同手机厂商的坐标系定义可能略有差异。我遇到过一台平板,它的 y 轴正方向是反的。所以拿到新设备,第一件事就是验证一下方向。
7.5 从角速度到角度:积分
陀螺仪直接输出的是角速度,但很多时候我们需要的是「转了多少度」。
怎么算?积分。
简单来说:角度 = 角速度 × 时间
但实际代码里不能这么粗暴,因为陀螺仪数据是离散的采样点。正确的做法是累加:
// 角度积分(简化版)
private float angleX = 0;
private long lastTimestamp = 0;
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
long currentTimestamp = event.timestamp;
if (lastTimestamp != 0) {
float dt = (currentTimestamp - lastTimestamp) / 1e9f; // 纳秒转秒
float gyroX = event.values[0];
angleX += gyroX * dt; // 积分:角度 += 角速度 × 时间差
}
lastTimestamp = currentTimestamp;
}
}
重要提醒:
积分会累积误差。陀螺仪有零偏(bias),即使静止时输出也不是完美的 0。积分几分钟后,角度可能漂移好几度。
这就是为什么纯陀螺仪不能长时间做姿态估计——必须配合加速度计和磁力计做融合。
7.6 知识体系图
下面这张图帮你理清陀螺仪数据的核心逻辑:
7.7 避坑指南
最后,分享几个我踩过的坑:
- 不要直接用陀螺仪算角度——积分漂移会让你怀疑人生。我曾经用纯陀螺仪做 VR 头显姿态,3 分钟后画面就歪了 30 度。
- 注意采样率——陀螺仪通常比加速度计采样率高(200Hz 左右)。积分时一定要用正确的时间戳,别用固定间隔。
- 零偏校准——静止时采集几秒数据,取平均值作为零偏,后续数据减去这个值。能大幅减少漂移。
- 温度影响——陀螺仪对温度敏感。手机刚开机和运行半小时后,零偏可能不一样。我习惯在 app 启动后做一次自动校准。
一句话总结:
陀螺仪告诉你「转得多快」,而不是「转了多少度」。要得到角度,必须积分。要积分稳,必须校准和融合。
好了,这一章就到这里。记住这三个轴的方向,记住 rad/s 的含义,下次你看到陀螺仪数据就不会懵了。