一个轻量级、易于移植的微型IMU(惯性测量单元)姿态解算库,适用于嵌入式系统和资源受限环境。
- 姿态角解算:实时计算Roll、Pitch、Yaw欧拉角
- 加速度计矫正:可选的重力加速度补偿,提高姿态解算精度
- 绝对加速度解算:计算与IMU姿态无关的绝对坐标系加速度
- 多IMU支持:灵活的多IMU实例管理
- 多种姿态表示:支持四元数、旋转矩阵、欧拉角等多种姿态表示方式
- 轻量级设计:代码简洁,内存占用小,适合嵌入式系统
- 易于移植:纯C语言实现,无外部依赖
Micro_IMU_Lib/
├── micro_imu_lib.h # 核心库头文件
├── micro_imu_lib.c # 核心库实现
├── imu_api.h # 高级API头文件
├── imu_api.c # 高级API实现
├── LICENSE # GPLv3许可证
└── README.md # 项目说明文档
将以下文件添加到您的项目中:
micro_imu_lib.hmicro_imu_lib.cimu_api.h(可选)imu_api.c(可选)
#include "micro_imu_lib.h"
#include <stdio.h>
int main() {
// 初始化IMU句柄
MIL_Handle_t imu_handle;
mil_handle_init(&imu_handle);
// 模拟传感器数据(单位:rad/s, m/s², s)
float gx = 0.1f; // X轴角速度
float gy = 0.05f; // Y轴角速度
float gz = 0.02f; // Z轴角速度
float ax = 0.0f; // X轴加速度
float ay = 0.0f; // Y轴加速度
float az = 9.8f; // Z轴加速度(重力)
float time = 0.01f; // 时间戳
// 设置传感器数据
mil_get_imu(&imu_handle, gx, gy, gz, ax, ay, az, time);
// 运行姿态解算
mil_while_run(&imu_handle);
// 获取姿态角
float roll, pitch, yaw;
mil_get_ang(&imu_handle, &roll, &pitch, &yaw);
printf("姿态角: Roll=%.2f°, Pitch=%.2f°, Yaw=%.2f°\n", roll, pitch, yaw);
// 获取绝对加速度
float aax, aay, aaz;
mil_get_aaccel(&imu_handle, &aax, &aay, &aaz);
printf("绝对加速度: X=%.2f, Y=%.2f, Z=%.2f m/s²\n", aax, aay, aaz);
return 0;
}#include "imu_api.h"
// 初始化IMU系统
imu_api_init();
// 在主循环中运行
while (1) {
// 读取传感器数据并解算
imu_api_run();
// 获取姿态角
float roll, pitch, yaw;
imu_api_get_attu(&roll, &pitch, &yaw);
// 获取绝对加速度
float aax, aay, aaz;
imu_api_get_accel(&aax, &aay, &aaz);
// 处理数据...
}// IMU传感器数据
typedef struct {
float ax, ay, az; // 加速度 (m/s²)
float gx, gy, gz; // 角速度 (rad/s)
float time; // 时间戳 (s)
} MIL_IMU_t;
// 四元数
typedef struct {
float w, x, y, z; // 四元数分量
} MIL_Quat_t;
// 旋转矩阵
typedef struct {
float R11, R12, R13;
float R21, R22, R23;
float R31, R32, R33;
} MIL_RotMat_t;
// 姿态角(欧拉角)
typedef struct {
float roll; // 横滚角 (°)
float pitch; // 俯仰角 (°)
float yaw; // 偏航角 (°)
} MIL_AttiAng_t;
// 绝对坐标系加速度
typedef struct {
float x, y, z; // 绝对加速度 (m/s²)
} MIL_AcceAbs_t;
// IMU句柄(包含所有数据)
typedef struct {
MIL_IMU_t imuData; // 传感器数据
MIL_Quat_t quat; // 四元数
MIL_RotMat_t rotMat; // 旋转矩阵
MIL_AttiAng_t attiAng; // 姿态角
MIL_AcceAbs_t acceAbs; // 绝对加速度
} MIL_Handle_t;// 初始化IMU句柄
void mil_handle_init(MIL_Handle_t* p);
// 设置传感器数据
// 参数:gx,gy,gz - 角速度 (rad/s)
// ax,ay,az - 加速度 (m/s²)
// time - 时间戳 (s)
void mil_get_imu(MIL_Handle_t* p, float gx, float gy, float gz,
float ax, float ay, float az, float time);
// 获取绝对坐标系加速度
void mil_get_aaccel(MIL_Handle_t* p, float* aax, float* aay, float* aaz);
// 获取欧拉角
void mil_get_ang(MIL_Handle_t* p, float* roll, float* pitch, float* yaw);
// 运行姿态解算(应在主循环中调用)
void mil_while_run(MIL_Handle_t* p);// 初始化IMU系统
void imu_api_init();
// 运行IMU解算(读取传感器数据并解算)
void imu_api_run();
// 获取姿态角
void imu_api_get_attu(float* roll, float* pitch, float* yaw);
// 获取绝对加速度
void imu_api_get_accel(float* aax, float* aay, float* aaz);在 micro_imu_lib.c 中可配置以下参数:
// 是否计算绝对坐标系加速度
#define EN_ACC_ABS 1
// 是否使用重力加速度修正
#define EN_ACC_FIX 1
// 重力系数 (m/s²)
#define GRAV_FACT 9.8
// 加速度计修正系数最大值
#define ACC_FIX_FACT_MAX 0.8
// 加速度计修正指数衰减系数
#define ATTEN_FACT 100您需要实现传感器读取接口。参考 imu_api.c 中的示例:
// 需要实现的传感器接口
float read_accel_x(); // 读取X轴加速度 (g)
float read_accel_y(); // 读取Y轴加速度 (g)
float read_accel_z(); // 读取Z轴加速度 (g)
float read_gyro_x(); // 读取X轴角速度 (°/s)
float read_gyro_y(); // 读取Y轴角速度 (°/s)
float read_gyro_z(); // 读取Z轴角速度 (°/s)
float get_timestamp(); // 获取时间戳 (s)库使用以下单位:
- 加速度:m/s²
- 角速度:rad/s
- 时间:秒
如果您的传感器使用其他单位,需要进行转换:
- g → m/s²:乘以 9.8
- °/s → rad/s:乘以 0.0174533
- 传感器数据读取:获取加速度计和陀螺仪数据
- 加速度计矫正:使用重力向量修正陀螺仪漂移
- 四元数积分:使用陀螺仪数据进行四元数更新
- 归一化处理:保持四元数单位长度
- 姿态转换:四元数 → 旋转矩阵 → 欧拉角
- 绝对加速度计算:将加速度转换到绝对坐标系
当IMU接近静止状态时(加速度模长接近重力加速度),使用加速度计测量的重力方向来修正陀螺仪的累积误差。修正系数根据加速度模长与重力加速度的差异动态调整。
# 使用GCC编译测试程序
gcc -o test_imu test_imu.c micro_imu_lib.c -lm
./test_imu- 内存占用:每个IMU实例约 200 字节
- 计算复杂度:O(1) 时间复杂度,适合实时系统
- 浮点运算:使用单精度浮点数,可在支持FPU的MCU上高效运行
- 使用有意义的变量名和函数名
- 添加必要的注释
- 保持代码简洁和可读性
- 遵循现有的代码风格
本项目采用 GNU General Public License v3.0 许可证。详情请参阅 LICENSE 文件。
Micro IMU Library - 让嵌入式IMU开发更简单!