飞行姿态计算
来源:互联网 发布:剪辑视频的软件 编辑:程序博客网 时间:2024/05/18 15:29
/******************** (C) COPYRIGHT 2014 ANO Tech *******************************
* ×÷Õß
#include "ANO_IMU.h"
ANO_IMU imu;
ANO_IMU::ANO_IMU()
{
}
//IMU³õʼ»¯
void ANO_IMU::Init()
{
//Â˲¨Æ÷²ÎÊý³õʼ»¯
filter_Init();
//´«¸ÐÆ÷³õʼ»¯
sensor_Init();
}
//¸üд«¸ÐÆ÷Êý¾Ý
void ANO_IMU::updateSensor()
{
//¶ÁÈ¡¼ÓËÙ¶È
mpu6050.Read_Acc_Data();
//¶ÁÈ¡½ÇËÙ¶È
mpu6050.Read_Gyro_Data();
//»ñÈ¡½ÇËٶȣ¬µ¥Î»Îª¶ÈÿÃë
Gyro = mpu6050.Get_Gyro_in_dps();
//»ñÈ¡¼ÓËٶȲÉÑùÖµ
Acc = mpu6050.Get_Acc();
}
//¼ÆËã·ÉÐÐÆ÷×Ë̬
void ANO_IMU::getAttitude()
{
float deltaT;
#ifdef ANO_IMU_USE_LPF_1st
//¼ÓËÙ¶ÈÊý¾ÝÒ»½×µÍͨÂ˲¨
Acc_lpf = LPF_1st(Acc_lpf, Acc, ano.factor.acc_lpf);
#endif
#ifdef ANO_IMU_USE_LPF_2nd
//¼ÓËÙ¶ÈÊý¾Ý¶þ½×µÍͨÂ˲¨
Acc_lpf = LPF_2nd(&Acc_lpf_2nd, Acc);
#endif
deltaT = getDeltaT(GetSysTime_us());
#ifdef ANO_IMU_USE_DCM_CF
DCM_CF(Gyro,Acc_lpf,deltaT);
#endif
#ifdef ANO_IMU_USE_Quaternions_CF
Quaternion_CF(Gyro,Acc_lpf_1st,deltaT);
#endif
}
//ÓàÏÒ¾ØÕó¸üÐÂ×Ë̬
void ANO_IMU::DCM_CF(Vector3f gyro,Vector3f acc, float deltaT)
{
static Vector3f deltaGyroAngle, LastGyro;
static Vector3f Vector_G(0, 0, ACC_1G), Vector_M(1000, 0, 0);
Matrix3f dcm;
//¼ÆËãÍÓÂÝÒǽǶȱ仯£¬¶þ½×Áú¸ñ¿âËþ»ý·Ö
deltaGyroAngle = (gyro + LastGyro) * 0.5 * deltaT;
LastGyro = gyro;
//¼ÆËã±íʾµ¥´ÎÐýתµÄÓàÏÒ¾ØÕó
dcm.from_euler(deltaGyroAngle);
//ÀûÓÃÓàÏÒ¾ØÕó¸üÐÂÖØÁ¦ÏòÁ¿ÔÚ»úÌå×ø±êϵµÄͶӰ
Vector_G = dcm * Vector_G;
//ÀûÓÃÓàÏÒ¾ØÕó¸üеشÅÏòÁ¿ÔÚ»úÌå×ø±êϵµÄͶӰ
Vector_M = dcm * Vector_M;
//»¥²¹Â˲¨£¬Ê¹ÓüÓËٶȲâÁ¿Öµ½ÃÕý½ÇËٶȻý·ÖƯÒÆ
Vector_G = CF_1st(Vector_G, acc, ano.factor.gyro_cf);
//¼ÆËã·ÉÐÐÆ÷µÄROLLºÍPITCH
Vector_G.get_rollpitch(angle);
//¼ÆËã·ÉÐÐÆ÷µÄYAW
Vector_M.get_yaw(angle);
}
#define Kp 2.0f //¼ÓËÙ¶ÈȨÖØ£¬Ô½´óÔòÏò¼ÓËٶȲâÁ¿ÖµÊÕÁ²Ô½¿ì
#define Ki 0.001f //Îó²î»ý·ÖÔöÒæ
//ËÄÔªÊý¸üÐÂ×Ë̬
void ANO_IMU::Quaternion_CF(Vector3f gyro,Vector3f acc, float deltaT)
{
Vector3f V_gravity, V_error, V_error_I;
//ÖØÁ¦¼ÓËٶȹéÒ»»¯
acc.normalize();
//ÌáÈ¡ËÄÔªÊýµÄµÈЧÓàÏÒ¾ØÕóÖеÄÖØÁ¦·ÖÁ¿
Q.vector_gravity(V_gravity);
//ÏòÁ¿²æ»ýµÃ³ö×Ë̬Îó²î
V_error = acc % V_gravity;
//¶ÔÎó²î½øÐлý·Ö
V_error_I += V_error * Ki;
//»¥²¹Â˲¨£¬×Ë̬Îó²î²¹³¥µ½½ÇËÙ¶ÈÉÏ£¬ÐÞÕý½ÇËٶȻý·ÖƯÒÆ
Gyro += V_error * Kp + V_error_I;
//Ò»½×Áú¸ñ¿âËþ·¨¸üÐÂËÄÔªÊý
Q.Runge_Kutta_1st(Gyro, deltaT);
//ËÄÔªÊý¹éÒ»»¯
Q.normalize();
//ËÄÔªÊýתŷÀ½Ç
Q.to_euler(&angle.x, &angle.y, &angle.z);
}
void ANO_IMU::filter_Init()
{
//¼ÓËÙ¶ÈÒ»½×µÍͨÂ˲¨Æ÷ϵÊý¼ÆËã
ano.factor.acc_lpf = LPF_1st_Factor_Cal(IMU_LOOP_TIME * 1e-6, ACC_LPF_CUT);
//¼ÓËٶȶþ½×µÍͨÂ˲¨Æ÷ϵÊý¼ÆËã
LPF_2nd_Factor_Cal(&Acc_lpf_2nd);
//»¥²¹Â˲¨Æ÷ϵÊý¼ÆËã
ano.factor.gyro_cf = CF_Factor_Cal(IMU_LOOP_TIME * 1e-6, GYRO_CF_TAU);
}
void ANO_IMU::sensor_Init()
{
//³õʼ»¯MPU6050£¬1Khz²ÉÑùÂÊ£¬42HzµÍͨÂ˲¨
mpu6050.Init(1000,42);
}
float ANO_IMU::getDeltaT(uint32_t currentT)
{
static uint32_t previousT;
float deltaT = (currentT - previousT) * 1e-6;
previousT = currentT;
return deltaT;
}
/******************* (C) COPYRIGHT 2014 ANO TECH *****END OF FILE************/
* ×÷Õß
#include "ANO_IMU.h"
ANO_IMU imu;
ANO_IMU::ANO_IMU()
{
}
//IMU³õʼ»¯
void ANO_IMU::Init()
{
//Â˲¨Æ÷²ÎÊý³õʼ»¯
filter_Init();
//´«¸ÐÆ÷³õʼ»¯
sensor_Init();
}
//¸üд«¸ÐÆ÷Êý¾Ý
void ANO_IMU::updateSensor()
{
//¶ÁÈ¡¼ÓËÙ¶È
mpu6050.Read_Acc_Data();
//¶ÁÈ¡½ÇËÙ¶È
mpu6050.Read_Gyro_Data();
//»ñÈ¡½ÇËٶȣ¬µ¥Î»Îª¶ÈÿÃë
Gyro = mpu6050.Get_Gyro_in_dps();
//»ñÈ¡¼ÓËٶȲÉÑùÖµ
Acc = mpu6050.Get_Acc();
}
//¼ÆËã·ÉÐÐÆ÷×Ë̬
void ANO_IMU::getAttitude()
{
float deltaT;
#ifdef ANO_IMU_USE_LPF_1st
//¼ÓËÙ¶ÈÊý¾ÝÒ»½×µÍͨÂ˲¨
Acc_lpf = LPF_1st(Acc_lpf, Acc, ano.factor.acc_lpf);
#endif
#ifdef ANO_IMU_USE_LPF_2nd
//¼ÓËÙ¶ÈÊý¾Ý¶þ½×µÍͨÂ˲¨
Acc_lpf = LPF_2nd(&Acc_lpf_2nd, Acc);
#endif
deltaT = getDeltaT(GetSysTime_us());
#ifdef ANO_IMU_USE_DCM_CF
DCM_CF(Gyro,Acc_lpf,deltaT);
#endif
#ifdef ANO_IMU_USE_Quaternions_CF
Quaternion_CF(Gyro,Acc_lpf_1st,deltaT);
#endif
}
//ÓàÏÒ¾ØÕó¸üÐÂ×Ë̬
void ANO_IMU::DCM_CF(Vector3f gyro,Vector3f acc, float deltaT)
{
static Vector3f deltaGyroAngle, LastGyro;
static Vector3f Vector_G(0, 0, ACC_1G), Vector_M(1000, 0, 0);
Matrix3f dcm;
//¼ÆËãÍÓÂÝÒǽǶȱ仯£¬¶þ½×Áú¸ñ¿âËþ»ý·Ö
deltaGyroAngle = (gyro + LastGyro) * 0.5 * deltaT;
LastGyro = gyro;
//¼ÆËã±íʾµ¥´ÎÐýתµÄÓàÏÒ¾ØÕó
dcm.from_euler(deltaGyroAngle);
//ÀûÓÃÓàÏÒ¾ØÕó¸üÐÂÖØÁ¦ÏòÁ¿ÔÚ»úÌå×ø±êϵµÄͶӰ
Vector_G = dcm * Vector_G;
//ÀûÓÃÓàÏÒ¾ØÕó¸üеشÅÏòÁ¿ÔÚ»úÌå×ø±êϵµÄͶӰ
Vector_M = dcm * Vector_M;
//»¥²¹Â˲¨£¬Ê¹ÓüÓËٶȲâÁ¿Öµ½ÃÕý½ÇËٶȻý·ÖƯÒÆ
Vector_G = CF_1st(Vector_G, acc, ano.factor.gyro_cf);
//¼ÆËã·ÉÐÐÆ÷µÄROLLºÍPITCH
Vector_G.get_rollpitch(angle);
//¼ÆËã·ÉÐÐÆ÷µÄYAW
Vector_M.get_yaw(angle);
}
#define Kp 2.0f //¼ÓËÙ¶ÈȨÖØ£¬Ô½´óÔòÏò¼ÓËٶȲâÁ¿ÖµÊÕÁ²Ô½¿ì
#define Ki 0.001f //Îó²î»ý·ÖÔöÒæ
//ËÄÔªÊý¸üÐÂ×Ë̬
void ANO_IMU::Quaternion_CF(Vector3f gyro,Vector3f acc, float deltaT)
{
Vector3f V_gravity, V_error, V_error_I;
//ÖØÁ¦¼ÓËٶȹéÒ»»¯
acc.normalize();
//ÌáÈ¡ËÄÔªÊýµÄµÈЧÓàÏÒ¾ØÕóÖеÄÖØÁ¦·ÖÁ¿
Q.vector_gravity(V_gravity);
//ÏòÁ¿²æ»ýµÃ³ö×Ë̬Îó²î
V_error = acc % V_gravity;
//¶ÔÎó²î½øÐлý·Ö
V_error_I += V_error * Ki;
//»¥²¹Â˲¨£¬×Ë̬Îó²î²¹³¥µ½½ÇËÙ¶ÈÉÏ£¬ÐÞÕý½ÇËٶȻý·ÖƯÒÆ
Gyro += V_error * Kp + V_error_I;
//Ò»½×Áú¸ñ¿âËþ·¨¸üÐÂËÄÔªÊý
Q.Runge_Kutta_1st(Gyro, deltaT);
//ËÄÔªÊý¹éÒ»»¯
Q.normalize();
//ËÄÔªÊýתŷÀ½Ç
Q.to_euler(&angle.x, &angle.y, &angle.z);
}
void ANO_IMU::filter_Init()
{
//¼ÓËÙ¶ÈÒ»½×µÍͨÂ˲¨Æ÷ϵÊý¼ÆËã
ano.factor.acc_lpf = LPF_1st_Factor_Cal(IMU_LOOP_TIME * 1e-6, ACC_LPF_CUT);
//¼ÓËٶȶþ½×µÍͨÂ˲¨Æ÷ϵÊý¼ÆËã
LPF_2nd_Factor_Cal(&Acc_lpf_2nd);
//»¥²¹Â˲¨Æ÷ϵÊý¼ÆËã
ano.factor.gyro_cf = CF_Factor_Cal(IMU_LOOP_TIME * 1e-6, GYRO_CF_TAU);
}
void ANO_IMU::sensor_Init()
{
//³õʼ»¯MPU6050£¬1Khz²ÉÑùÂÊ£¬42HzµÍͨÂ˲¨
mpu6050.Init(1000,42);
}
float ANO_IMU::getDeltaT(uint32_t currentT)
{
static uint32_t previousT;
float deltaT = (currentT - previousT) * 1e-6;
previousT = currentT;
return deltaT;
}
/******************* (C) COPYRIGHT 2014 ANO TECH *****END OF FILE************/
0 0
- 飞行姿态计算
- 四轴飞行的姿态估计
- 四轴飞行的姿态估计
- 飞行姿态解算笔记(一)
- 飞行姿态解算笔记(二)
- 大气飞行姿态动力学大作业
- 超小型遥控直升机飞行姿态稳定器的设计
- 小卫星编队飞行姿态协同控制及仿真
- [003]飞行操作脚本写完,进军姿态变换和武器系统
- 姿态结算中旋转计算的基础
- 体感9D姿态角计算
- 飞行
- [反重力与飞行]需要精确计算力场的数值
- 使用 MWC V2.5 中的 MPU6050中的DMP进行计算姿态
- 使用 MWC V2.5 中的 MPU6050中的DMP进行计算姿态(转载)
- 四旋翼飞行器教学笔记2.2——姿态读取的计算
- 生活姿态
- 姿态估计
- Flume-将数据写入动态分区表
- C++模板实现的队列多线程安全
- MATLAB简单矩阵的输入方法
- Ecshop模板开发(十八):侧边栏目分类列表
- ZOJ3212-K-Nice
- 飞行姿态计算
- 杭电oj 1005 Number Sequence
- Android修改AlertDialog宽和高以及设置AlertDialog的背景
- 【黑科技】C++输入输出优化技巧
- day26_netstore
- CentOS7开启中文拼音输入法_设置方法
- Android获取屏幕实际高度跟显示高度,判断Android设备是否拥有虚拟功能键
- 关于kcptun加速ss配置的一些问题
- Qt容器类及其遍历(Java风格和STL风格迭代器)