#include "math.h"

// 最简单的航姿仪Mahony算法,所谓“最简单”就意味着在加速机动环境下效果会不太好,没做任何容错处理。

// 注意: 传感器/机体坐标系(b):x右-y前-z上; 导航坐标系(n):E东-N北-U天

// gx,gy,gz陀螺仪采样(deg/s), ax,ay,az加计采样(可为任意单位或归一化单位)

// mx,my,mz磁采样(可为任意单位或归一化单位),若三轴磁均输入零则表示不利用磁信息

// 根据网上程序整理优化 by Yan Gongmin, 2017-06-07

void MahonyInit(float tau);

void MahonyUpdate(float gx, float gy, float gz, float ax, float ay,

float az, float mx, float my, float mz, float ts);

float MahonyGetEuler(float *pitch, float *roll, float *yaw);

void MahonyGetDrift(float *driftx, float *drifty, float

*driftz);

#define DEG (3.1415926f/180.0f)

#define DPS (DEG/1.0f)

#define DPH (DEG/3600.0f)

static float q0,q1,q2,q3, exInt,eyInt,ezInt, tk;

static float C00,C01,C02, C10,C11,C12, C20,C21,C22;

static float Kp, Ki;

static void qua2cnb(void);

void MahonyInit(float tau)

{

float beta = 2.146f/tau;

Kp = 2.0f*beta, Ki = beta*beta;

q0 = 1.0f, q1 = q2 = q3 = 0.0f;

qua2cnb();

exInt = eyInt = ezInt = 0.0f;

tk = 0.0f;

}

void MahonyUpdate(float gx, float gy, float gz, float ax,

float ay, float az, float mx, float my, float mz, float ts)

{

float norm;

float by, bz, wx, wy, wz;

float ex, ey, ez, halfT, KiT;

float _q0, _q1, _q2, _q3;

tk += ts;

halfT = ts/2.0f; KiT = Ki*ts;

norm = (float)sqrt(ax*ax + ay*ay +

az*az); // 加计归一化

norm = norm>0.1f ? 1.0f/norm : 0.0f;

ax *= norm, ay *=

norm, az *= norm;

norm = (float)sqrt(mx*mx + my*my +

mz*mz); // 磁归一化

norm = norm>0.1f ? 1.0f/norm : 0.0f;

mx *= norm, my *=

norm, mz *= norm;

bz = C20*mx + C21*my + C22*mz; // 磁场的天向投影分量

by =

(float)sqrt(1.0f-bz*bz); //

磁场的水平(磁北)投影分量

// bx =

0.0f; // 磁场的磁东向投影分量

wx = C10*by +

C20*bz; //

磁场的理想b系投影分量

wy = C11*by + C21*bz;

wz = C12*by + C22*bz;

ex = (ay*C22-az*C21) +

(my*wz-mz*wy); // 加计测水平误差、磁测方位误差

ey = (az*C20-ax*C22) + (mz*wx-mx*wz);

ez = (ax*C21-ay*C20) + (mx*wy-my*wx);

exInt += ex * KiT;

eyInt += ey * KiT;

ezInt += ez * KiT;

gx *= DPS, gy *= DPS, gz *= DPS;

gx += Kp*ex +

exInt; // 陀螺修正

gy += Kp*ey + eyInt;

gz += Kp*ez + ezInt;

_q0 = q0 + (-q1*gx - q2*gy -

q3*gz)*halfT; // 解四元数微分方程

_q1 = q1 + ( q0*gx + q2*gz - q3*gy)*halfT;

_q2 = q2 + ( q0*gy - q1*gz + q3*gx)*halfT;

_q3 = q3 + ( q0*gz + q1*gy - q2*gx)*halfT;

norm = 1.0f/(float)sqrt(_q0*_q0 + _q1*_q1 +

_q2*_q2 + _q3*_q3); // 四元数归一化

q0 = _q0 * norm, q1 = _q1 * norm, q2 = _q2 *

norm, q3 = _q3 * norm;

qua2cnb();

}

float MahonyGetEuler(float *pitch, float *roll, float

*yaw)

{

*pitch = (float)asin(C21) /

DEG; // deg

*roll = (float)atan2(-C20, C22)

/ DEG;

*yaw =

(float)atan2(-C01, C11) /

DEG; // +-180deg, 北偏西为正

return tk;

}

void MahonyGetDrift(float *driftx, float *drifty, float

*driftz)

{

*driftx = exInt /

DPH; // deg/hur

*drifty = eyInt / DPH;

*driftz = ezInt / DPH;

}

static void qua2cnb(void)

{

float q00 = q0*q0, q01 = q0*q1, q02 = q0*q2, q03

= q0*q3;

float q11 = q1*q1, q12 = q1*q2, q13 =

q1*q3;

float q22 = q2*q2, q23 = q2*q3;

float q33 = q3*q3;

C00 = q00+q11-q22-q33, C01 =

2*(q12-q03), C02 = 2*(q13+q02); // 四元数转姿态阵

C10 =

2*(q12+q03), C11 = q00-q11+q22-q33, C12 = 2*(q23-q01);

C20 =

2*(q13-q02), C21 =

2*(q23+q01), C22 = q00-q11-q22+q33;

}

算法原理可参考:

陀螺仪c语言算法,最简单的航姿仪算法C程序(AHRS)相关推荐

  1. 进制转换算法 (C语言实现一个简单的二进制转换工具) ------- 算法笔记010

    进制转换算法概念 其核心是利用栈的存储结构性质,进行数据的入栈出栈时的计算,让后将计算好的数据存入另一个栈内,最后再出栈输出.由于栈的先进后出特性,最后输出的顺序和输入的顺序是一样的.具体如上图. 栈 ...

  2. 三个球数求最大值c语言,C语言中一个简单的球3个数最大数的程序中,最后一步:printf(apos;apos;max=%d\napos;apos;,max);怎么理解...

    int main() { printf("Hello,world\n"); while(1); } #includeint main() { int i = 1, j =2; pr ...

  3. 加油机程序C语言,不要认为简单!!要多少架飞机?怎样写程序?哪位高手能把程序写出来?...

    .setSubOil("供油");//右边起的两架飞机供油给 nPlane[2] nPlane[2].setAddOil("加油"); nPlane[2].se ...

  4. C语言实现简单的RSA加解密算法

    使用c语言实现了简单的RSA加解密算法. 实验内容: 1.输入两个素数,然后生成一个随机数,计算出随机数的逆元,然后保存这些信息: 2.选择加密,则输入明文,输出密文: 3.选择解密,则输入密钥,输出 ...

  5. 逻辑回归算法处理简单数据

    代码实现 (1)数据处理:(2)sigmoid函数:(3)梯度上升算法: (4)改进的随机梯度上升算法:  (5)绘图 # -*- coding:UTF-8 -*- import matplotlib ...

  6. 简单算法的举例c语言,计算机科学与技术系C语言程序设计22简单算法举例.PPT

    计算机科学与技术系C语言程序设计22简单算法举例 第2章 程序的灵魂--算法 本章主要介绍算法的思想及算法的表示方法. 2.0 绪论 2.1 算法的概念 2.2 简单算法举例 2.3 算法的特性 2. ...

  7. 2-路插入排序c语言算法,浅谈2路插入排序算法及其简单实现

    2路插入排序算法是在直接插入排序算法的基础上增加了一个辅助数组,其目的是减少排序过程中的移动次数,需要增加n个记录的辅助空间. 难点可能在于对取余的考虑吧,可以把辅助数组看成一个环状空间,这样就能更好 ...

  8. 用C语言实现一个简单的一元线性回归算法

    今天我们用C语言实现一个简单的线性回归算法:在代码前面我们在回顾一下线性回归. 线性回归是回归问题中的一种,线性回归假设目标值与特征是线性相关的,即满足一个多元一次方程式.通过构建损失函数,来求解损失 ...

  9. C语言排序算法之简单交换法排序,直接选择排序,冒泡排序

    C语言排序算法之简单交换法排序,直接选择排序,冒泡排序,最近考试要用到,网上也有很多例子,我觉得还是自己写的看得懂一些. 简单交换法排序 1 /*简单交换法排序 2 根据序列中两个记录键值的比较结果来 ...

最新文章

  1. linux shell 宏定义_Linux系统和Shell命令行简介,走上数据分析之路
  2. 回溯算法-03八皇后问题
  3. 01-基本配置与测试
  4. 震惊 | 某公司实习生跑路,竟为了学习偷盗面试题
  5. 下载丨2020数据技术嘉年华PPT(DTC 2020)更新中...
  6. mysql5.7的客户端软件_mysql数据库管理客户端工具|mysql数据库管理软件 v5.7.22 64位官方版 - 软件下载 - 绿茶软件园|33LC.com...
  7. delphi对比易语言_delphi 2007 vs E语言 vs C#运行速度 - Delphi编程
  8. Java开发 基础三十条 初学必看
  9. 堆叠柱状图显示具体数据和百分比
  10. 5.9 学习日记 万事成蹉
  11. uniapp 实现拨打电话
  12. Everything研究之快速获取USN记录的文件路径
  13. 如果恰巧有一台超微服务器,如何调节风扇转速
  14. 程序员用c语言写的新年祝福,程序员的新年祝福:Happy New Year
  15. HTML手机签到转盘抽奖页面模板,手机端转盘抽奖代码分享
  16. Mor.ai蓦然认知重磅推出智能家居IoT解决方案
  17. kafka: dial tcp: lookup xxxx(domain): no such host
  18. 对2009年2月编程语言排名的感想
  19. 【类似ppt的演示软件】Focusky教程 | 导入/导出素材
  20. NPAPI - Netscape Plugin API 与 PPAPI - Pepper Plugin API 的区别

热门文章

  1. 蛋花花分析Web前端高薪就业必须掌握的5个技能
  2. 自走棋最强阵容:如何把“王者模拟战”玩成LOL“云顶之弈”?
  3. 警惕!《马航MH370调查》之阴谋论,做一个科学吃瓜群众
  4. Apache IoTDB 毕业两周年庆典|限量版纪念T恤“点击”就送~
  5. 计算机趣味知识竞赛题库,2019年趣味知识竞赛试题题库及答案
  6. 经典的C++库【转帖】
  7. orbslam2(1)-初始化
  8. 西语写作 万能套话,柯桥西班牙语培训
  9. Install/uninstall .deb files
  10. 没有独立显卡,虚拟的显卡,能进行深度学习网络训练吗