一、概念原理
1. 数据来源
三轴加速度计(如 MPU6050、ADXL345、LSM303 等)会输出三个方向的加速度值:
- ax:X 轴加速度
- ay:Y 轴加速度
- az:Z 轴加速度
在静止状态下,这些值主要反映重力加速度在各轴的分量。
2. 倾斜角计算公式
俯仰角(Pitch)
Pitch = arctan( -ax / √(ay² + az²) )
翻滚角(Roll)
Roll = arctan( ay / az )
总倾斜角(相对于水平面)
θ = arccos( az / √(ax² + ay² + az²) )
在代码中建议使用
atan2(),它能正确处理象限问题。
3. 数据处理建议
- 滤波:加速度计数据会有抖动,建议用滑动平均或低通滤波。
- 单位:确保加速度值已转换为 g(1g ≈ 9.81 m/s²)。
- 静态测量:如果设备在运动,需结合陀螺仪做姿态融合(如卡尔曼滤波)。
二、C语言示例代码
#include <stdio.h> #include <math.h> #define PI 3.14159265358979323846 #define FILTER_SIZE 10 // 滑动平均滤波窗口 // 滤波缓冲区 float ax_buf[FILTER_SIZE] = {0}; float ay_buf[FILTER_SIZE] = {0}; float az_buf[FILTER_SIZE] = {0}; int buf_index = 0; // 模拟读取加速度计数据(实际应替换为I2C/SPI读取函数) void read_accelerometer(float *ax, float *ay, float *az) { // 示例数据(单位:g) *ax = 0.02; *ay = 0.01; *az = 0.98; } // 滑动平均滤波 void filter_data(float *ax, float *ay, float *az) { ax_buf[buf_index] = *ax; ay_buf[buf_index] = *ay; az_buf[buf_index] = *az; buf_index = (buf_index + 1) % FILTER_SIZE; float sum_x = 0, sum_y = 0, sum_z = 0; for (int i = 0; i < FILTER_SIZE; i++) { sum_x += ax_buf[i]; sum_y += ay_buf[i]; sum_z += az_buf[i]; } *ax = sum_x / FILTER_SIZE; *ay = sum_y / FILTER_SIZE; *az = sum_z / FILTER_SIZE; } // 计算俯仰角、翻滚角、总倾斜角 void calculate_angles(float ax, float ay, float az, float *pitch, float *roll, float *tilt) { *pitch = atan2(-ax, sqrt(ay * ay + az * az)) * 180.0 / PI; *roll = atan2(ay, az) * 180.0 / PI; *tilt = acos(az / sqrt(ax * ax + ay * ay + az * az)) * 180.0 / PI; } int main() { float ax, ay, az; float pitch, roll, tilt; while (1) { // 1. 读取加速度计数据 read_accelerometer(&ax, &ay, &az); // 2. 滤波处理 filter_data(&ax, &ay, &az); // 3. 计算角度 calculate_angles(ax, ay, az, &pitch, &roll, &tilt); // 4. 输出结果 printf("Pitch: %.2f°, Roll: %.2f°, Tilt: %.2f°\n", pitch, roll, tilt); // 延时(实际应用中根据采样率调整) // delay_ms(100); } return 0; }三、代码解析
以上代码演示了从加速度计数据到倾斜角计算的完整流程:
- 数据读取:
read_accelerometer函数模拟获取三轴加速度值(单位:g)。 - 数据滤波:
filter_data函数使用滑动平均滤波器平滑数据,减少噪声影响。 - 角度计算:
calculate_angles函数使用atan2()和acos()计算俯仰角、翻滚角和总倾斜角,并将弧度转换为角度。 - 主循环:持续读取、滤波、计算并输出角度值。
四、注意事项
- 实际硬件接口:示例中的
read_accelerometer函数需要根据具体传感器(如 MPU6050 的 I2C 接口)进行实现。 - 滤波参数:
FILTER_SIZE需要根据实际采样率和噪声水平调整。 - 动态补偿:若设备处于运动状态,需结合陀螺仪数据进行姿态融合(如互补滤波、卡尔曼滤波),以消除线性加速度的影响。
- 角度范围:
atan2()返回的角度范围为 (-π, π](即 -180° 到 180°),需根据应用场景进行转换。
五、总结
通过三轴加速度计计算倾斜角是嵌入式系统和物联网设备中的常见需求。核心步骤包括:获取原始数据、进行滤波处理、应用三角函数公式计算角度。在实际应用中,需要根据具体传感器特性和应用场景调整滤波算法,并在动态环境下结合陀螺仪等传感器进行数据融合,以获得更稳定、准确的姿态信息。