IMU:姿态解算算法集合

2023-05-16

文章目录

      • 一、IMU原理
      • 二、源码

一、IMU原理

二、源码

源文件:

#include "IMU.h"
#include "math.h"

#define Kp 1.6f                        // proportional gain governs rate of convergence to accelerometer/magnetometer
#define Ki 0.001f                      // integral gain governs rate of convergence of gyroscope biases
#define halfT 0.001f                   // half the sample period 采样周期的一半
#define Gyro_Gr		0.0010653f		//角速度变成弧度 此参数对应陀螺2000度每秒
#define Gyro_G 		0.0610351f		//角速度变成度   此参数对应陀螺2000度每秒	
#define FILTER_NUM 	20

float 	AngleOffset_Rol=0,AngleOffset_Pit=0;
float q0 = 1, q1 = 0, q2 = 0, q3 = 0;  // quaternion elements representing the estimated orientation
float exInt = 0, eyInt = 0, ezInt = 0; // scaled integral error

FLOAT_XYZ 	Acc,Acc_out,Gyro;	              //把陀螺仪的各通道读出的数据,转换成弧度制
FLOAT_ANGLE Att_Angle;

void Prepare_Data(FLOAT_XYZ *acc_in,FLOAT_XYZ *acc_out)
{
	static uint8_t 	filter_cnt=0;
	static int16_t	ACC_X_BUF[FILTER_NUM],ACC_Y_BUF[FILTER_NUM],ACC_Z_BUF[FILTER_NUM];
	int32_t temp1=0,temp2=0,temp3=0;
	uint8_t i;

	ACC_X_BUF[filter_cnt] = acc_in->X;
	ACC_Y_BUF[filter_cnt] = acc_in->Y;
	ACC_Z_BUF[filter_cnt] = acc_in->Z;
	for(i=0;i<FILTER_NUM;i++)
	{
		temp1 += ACC_X_BUF[i];
		temp2 += ACC_Y_BUF[i];
		temp3 += ACC_Z_BUF[i];
	}
	acc_out->X = temp1 / FILTER_NUM;
	acc_out->Y = temp2 / FILTER_NUM;
	acc_out->Z = temp3 / FILTER_NUM;
	filter_cnt++;
	if(filter_cnt==FILTER_NUM)	filter_cnt=0;
}

void IMUupdate(FLOAT_XYZ *gyr, FLOAT_XYZ *acc, FLOAT_ANGLE *angle)
{
	float ax = acc->X,ay = acc->Y,az = acc->Z;
	float gx = gyr->X,gy = gyr->Y,gz = gyr->Z;
	float norm;
	
	float vx, vy, vz;
	float ex, ey, ez;

// 先把这些用得到的值算好
	float q0q0 = q0*q0;
	float q0q1 = q0*q1;
	float q0q2 = q0*q2;
//  float q0q3 = q0*q3;
	float q1q1 = q1*q1;
//  float q1q2 = q1*q2;
	float q1q3 = q1*q3;
	float q2q2 = q2*q2;
	float q2q3 = q2*q3;
	float q3q3 = q3*q3;

	if(ax*ay*az==0)
	return;

	gx *= Gyro_Gr;
	gy *= Gyro_Gr;
	gz *= Gyro_Gr;

	norm = sqrt(ax*ax + ay*ay + az*az);       //acc数据归一化
	ax = ax /norm;
	ay = ay / norm;
	az = az / norm;
	
//	if(norm>16500)
//	{Rc_C.ARMED=0;}
	
	// estimated direction of gravity and flux (v and w)      估计重力方向和流量/变迁
	// 这是把四元数换算成《方向余弦矩阵》中的第三列的三个元素。
	// 根据余弦矩阵和欧拉角的定义,地理坐标系的重力向量,转到机体坐标系,正好是这三个元素。
	// 所以这里的vx\y\z,其实就是当前的欧拉角(即四元数)的机体坐标参照系上,换算出来的重力单位向量。      
	vx = 2*(q1q3 - q0q2);												
	vy = 2*(q0q1 + q2q3);
	vz = q0q0 - q1q1 - q2q2 + q3q3 ;

	// error is sum of cross product between reference direction of fields and direction measured by sensors
	ex = (ay*vz - az*vy) ;     	//向量外积在相减得到差分就是误差                   					
	ey = (az*vx - ax*vz) ;
	ez = (ax*vy - ay*vx) ;

	exInt = exInt + ex * Ki;	//对误差进行积分
	eyInt = eyInt + ey * Ki;
	ezInt = ezInt + ez * Ki;

	// adjusted gyroscope measurements
	gx = gx + Kp*ex + exInt;	//将误差PI后补偿到陀螺仪,即补偿积分漂移
	gy = gy + Kp*ey + eyInt;	
	gz = gz + Kp*ez + ezInt;	//这里的gz由于没有观测者进行矫正会产生漂移,表现出来的就是积分自增或自减

	// integrate quaternion rate and normalise						  
	//四元素的微分方程,一阶毕卡求解法,更新四元数
	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;

	// normalise quaternion
	norm = sqrt(q0*q0 + q1*q1 + q2*q2 + q3*q3);

	q0 = q0 / norm;
	q1 = q1 / norm;
	q2 = q2 / norm;
	q3 = q3 / norm;

	angle->yaw += -gyr->Z*Gyro_G*0.002f;
	angle->rol = -asin(-2 * q1 * q3 + 2 * q0* q2)* 57.3 - AngleOffset_Pit; // pitch
	angle->pit = -atan2(2 * q2 * q3 + 2 * q0 * q1, -2 * q1 * q1 - 2 * q2* q2 + 1)* 57.3 - AngleOffset_Rol; // roll
}

头文件:

#ifndef _IMU_H_
#define _IMU_H_
#include  "stm32f1xx_hal.h"


#define G			9.80665f		      	// m/s^2	
#define RadtoDeg    57.324841f				//弧度到角度 (弧度 * 180/3.1415)
#define DegtoRad    0.0174533f				//角度到弧度 (角度 * 3.1415/180)

//三轴浮点型
typedef struct
{
	int16_t X;
	int16_t Y;
	int16_t Z;
}FLOAT_XYZ;

//姿态解算后的角度
typedef struct
{
	float rol;
	float pit;
	float yaw;
}FLOAT_ANGLE;

extern FLOAT_XYZ 	Acc,Acc_out,Gyro;	              //把陀螺仪的各通道读出的数据,转换成弧度制
extern FLOAT_ANGLE Att_Angle;
void Prepare_Data(FLOAT_XYZ *acc_in,FLOAT_XYZ *acc_out);
void IMUupdate(FLOAT_XYZ *Gyr_rad,FLOAT_XYZ *Acc_filt,FLOAT_ANGLE *Att_Angle);

#endif

调用方式:

#include "IMU.h"

Prepare_Data(&Acc,&Acc_out);//Acc输入、Acc_out输出
IMUupdate(&Gyro,&Acc_out,&Att_Angle);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IMU:姿态解算算法集合 的相关文章

  • C/C++ 日常学习总结(第十九篇)多线程详解

    这些讲解多线程文章都是非常好的 xff0c 我这边就归结出一个 lt 多线程详解 gt 出来 xff0c 感谢各位原创作者的辛苦劳动 xff0c 这些收藏起来方便自己消化 1 多线程笔试面试题汇总 解答地址 xff1a 概念问答 2 深入分
  • python3 算法题:七进制加法

    题目 xff1a 要求键盘输入两个七进制 0 6 数 xff0c 以空格分开 xff0c 计算两者之和输出 xff0c 例如 xff1a 输入 xff1a 16 1 输出 xff1a 20 思路 xff1a 这个题目跟十进制加法一样 xff
  • python3 实现麻将胡牌问题

    题目描述 xff1a 清一色是麻将番种之一 xff0c 指由一种花色的序数牌组成的和牌 数字1 9 xff0c 每个数字最多有4张牌 我们不考虑具体花色 xff0c 我们只看数字组合 刻子 xff1a 三张一样的牌 xff1b 如 111
  • python3爬虫简单介绍

    本文是为了防止自己以后忘了 xff0c 小白可以参考 xff0c 大神请绕道 先来扫盲 xff0c 什么是爬虫 xff1a 爬虫就是一系列按照某种规则自动从网上爬取信息的代码或者脚本 本文代码功能 xff1a 从百度百科里面爬取20个和py
  • python3 使用urllib.request.urlopen及re.findall爬取网页图片并保持本地

    本例使用urllib及re正则表达式 xff0c 爬取网页上 xff08 王俊凯百度百科 xff09 所有以jpg结尾的图片 xff0c 并保存本地 import re from urllib span class token punctu
  • python3 爬取网页内容解析并存入MySQL数据库

    爬取网页内容解析并存入MySQL数据库 用到的第三方库 xff1a BeautifulSoup xff1a 解析网页内容 xff0c 建议安装方法 xff1a pip install beautifulsoup4 pymysql xff1a
  • python二维列表按照某列(字符串列)排序;忽略大小写+区分大小写

    python二维列表按照某列 xff08 字符串列 xff09 排序 xff1b 忽略大小写 43 区分大小写 使用list自带的sorted 方法 xff0c data 61 sorted data key 61 lambda x x 1
  • tkinter 出现两个窗口 tk(未响应) 解决方法

    问题 xff1a tkinter界面开发 xff0c 莫名出现一个叫 tk 未响应 的小窗口 xff0c 最后发现是因为自定义了窗口图标导致产生多余窗口 解决方法 xff1a 将设置窗口图标代码放到设置窗口大小代码之后即可 xff08 该方
  • python3适配pykml教程

    pykml是用python2写的 xff0c 由于python3和python2语法及函数名有所不同 xff0c python3使用的时候需要手动修改几个地方 xff0c 如下 xff1a 1 出现 xff1a ModuleNotFound
  • c51单片机学习笔记-独立按键实验

    目的 xff1a 通过开发板上的独立按键 K1 控制 D1 指示灯亮灭 编译软件 xff1a keil5 过程 xff1a xff08 1 xff09 定义独立按键控制脚 sbit KEY1 61 P3 1 sbit KEY2 61 P3
  • openpyxl为指定区域设置边框为粗匣框线

    前言 xff1a 最近在用openpyxl分析Excel数据 xff0c 为了让表格层次更分明 xff0c 想给制定区域添加粗匣框线 xff0c 网上没有找到现成的方法 xff0c 自己摸索了一下 xff0c 终于解决了 xff0c 现在记
  • ubuntu上网问题以及ping通网络设备

    问题一 xff1a ubuntu上网问题 如何ping www baidu com Ubuntu上网模式有两种 xff1a 桥接和NAT 1 桥接模式 xff1a 前提是 xff1a 主机是连接的无线网 xff0c 主机有线网卡的IP设置的
  • Python脚本调用C++动态库,C++调用Python脚本实操

    一 Python调用C 43 43 动态库 实现方法 xff1a 使用python 的ctypes 模块加载dll 首先 xff0c 需要用VS创建一个dll动态库 xff0c 网上方法很多 xff0c 就不细说了 xff0c 代码如下 x
  • 利用GPU训练时的常见错误

    1 CUDA VIDIBLE DEVICES 61 4 5 python3 main py 我想在集群条件下利用4 5号GPU xff0c 由于模型较小 xff0c 并不清楚是都可以指定4 5号GPU xff08 内存占用情况看不出来 后续
  • Jetson TX1底板的接口调试

    1 I2C总线上外设查询 I2C Tools的安装和使用 在控制台输入 sudo apt get install i2c tools 安装完成后可以使用命令验证安装成功 sudo i2cdetect l I2C设备查询使用 sudo i2c
  • 驱动——platform驱动总线三种匹配方式

    三种platform驱动匹配方式代码案例以及现象 方式一 xff1a 通过设置名字进行匹配 相关API简介 xff1a 1 platform device的API 分配对象 struct platform device const char
  • 开源框架APM工具--SkyWalking原理与应用

    一 分布式链路追踪简介 随着业务系统的不断发展 微服务架构的演进 xff0c 从原来的单体应用架构 垂直应用架构 分布式 SOA 架构到现在的微服务架构 xff0c 系统逐步走向微服务化以适应用户高并发请求等需求 在微服务架构中 xff0c
  • 什么是弹性云服务器?

    ecs云服务器是由CPU 内存 镜像 云硬盘组成的一种可随时获取 弹性可扩展的计算服务器 xff0c 同时它结合虚拟私有云 虚拟防火墙 数据多副本保存等能力 xff0c 为您打造一个高效 可靠 安全的计算环境 xff0c 确保您的服务持久稳
  • linux下修改MAC地址的问题解决

    在linux中 xff0c 修改MAC地址 ifdown eth0 ifconfig eth0 hw ether 12 xff1a 34 xff1a 56 xff1a 78 xff1a 90 xff1a 12 xff08 修改的MAC地址跟
  • 51串口发送数据的格式

    串行口控制寄存器SCON SCON的字节地址是98H xff0c 其格式如下 xff1a SM0 SM1 xff1a 串行口工作方式控制位 xff1a SM0 SM1 工作方式 功能 波特率 00 方式0 同步移位寄存器 fosc 12 0

随机推荐

  • c51单片机学习笔记-矩阵按键实验

    目的 xff1a 通过数码管显示矩阵按键 S1 S16 按下后键值 0 F 编译软件 xff1a keil5 过程 xff1a xff08 1 xff09 定义各端口 include 34 reg52 h 34 typedef unsign
  • CMake 添加第三方库的几种依赖方式

    转载链接 xff1a C 43 43 工程 xff1a 总结 CMake 添加第三方库依赖方式git submodule find library FetchContent CPM等 github地址 cpp cmake example 第
  • vue.js中v-for的使用及索引获取

    vue js中v for的使用及索引获取 1 v for 直接上代码 示例一 xff1a lt DOCTYPE html gt lt html gt lt head gt lt meta charset 61 34 utf 8 34 gt
  • (转贴)Windows CE 5.0下串口驱动硬件FIFO控制Bug分析及修正方法

    转贴自 xff1a 驱动开发网 原贴地址 xff1a http bbs driverdevelop com read php tid 61 109193 amp fpage 61 0 amp toread 61 amp page 61 1
  • 四剑客和正则表达式常见故障及困惑集合(待更新)

    一 find命令 warning警告 maxdepth 这个参数要放在其他参数之前 root 64 oldboyedu59 find type d maxdepth 1 find warning you have specified the
  • sed的使用

    一 xff0c 替换文本 s pattern replacement flags replacement会替换pattern 例如 xff1a root 64 node1 sed cat data2 txt This is a test o
  • KVM虚拟化-创建-桥接-硬盘-快照

    1 创建 使用virt manager进行创建 virt manager进入管理器 点击如图进行创建 将ISO下载到虚拟机里面 点击浏览 下面是虚拟机名字 选择本地浏览 选中CentOS的iso 选择后前进 选择内存和cpu xff0c 前
  • 串口专题(一)——基础知识

    前言 xff1a 为了方便查看博客 xff0c 特意申请了一个公众号 xff0c 附上二维码 xff0c 有兴趣的朋友可以关注 xff0c 和我一起讨论学习 xff0c 一起享受技术 xff0c 一起成长 1 概念介绍 串行口是计算机一种常
  • STM32中晶振的原理与作用

    前言 xff1a 为了方便查看博客 xff0c 特意申请了一个公众号 xff0c 附上二维码 xff0c 有兴趣的朋友可以关注 xff0c 和我一起讨论学习 xff0c 一起享受技术 xff0c 一起成长 转载地址 STM32中晶振的原理与
  • STM32学习笔记一一UCOSII(1)

    前言 xff1a 为了方便查看博客 xff0c 特意申请了一个公众号 xff0c 附上二维码 xff0c 有兴趣的朋友可以关注 xff0c 和我一起讨论学习 xff0c 一起享受技术 xff0c 一起成长 1 简介 UCOSII 是一个可以
  • PADS 原理图库文件绘制

    前言 xff1a 为了方便查看博客 xff0c 特意申请了一个公众号 xff0c 附上二维码 xff0c 有兴趣的朋友可以关注 xff0c 和我一起讨论学习 xff0c 一起享受技术 xff0c 一起成长 1 PADS Logic 参数设置
  • prometheus监管平台(一)(开源)

    prometheus监管平台 xff08 一 xff09 xff08 开源 xff09 一 登录二 首页三 General Management功能四 Host Management功能五 Job Management功能六 Alarm M
  • vncserver连接后窗口显示太小

    VNC server的默认的分辨率是1024x768 如果要改变VNC server的分辨率 1 可以用一下命令启动VNC server root 64 localhost vncserver geometry 1280x1024 这种修改
  • dfs (二进制枚举,暴力,马的管辖)

    在中国象棋中 xff0c 马是走日字的 一个马的管辖范围指的是当前位置以及一步之内能走到的位置 xff0c 下图的绿色旗子表示马能走到的位置 如果一匹马的某个方向被蹩马脚 xff0c 它就不能往这个方向跳了 xff0c 如下图所示 xff0
  • linux进程(四)——进程的几种状态

    usr src linux headers 4 15 0 45 include linux Used in tsk gt state define TASK RUNNING 0x0000 define TASK INTERRUPTIBLE
  • linux网络设备驱动(一)

    一 框架 1 xff09 网络协议接口层 向网络层协议提供统一的数据包收发接口 xff0c 不论上层协议是ARP xff0c 还是IP xff0c 都通过dev queue xmit 函数发送数据 xff0c 并通过netif rx 函数接
  • linux taskset命令

    一 简介 taskset命令用于设置进程 xff08 或线程 xff09 的处理器亲和性 xff08 Processor Affinity xff09 xff0c 可以将进程 xff08 或线程 xff09 绑定到特定的一个 或 多个CPU
  • STM32使用cubemx、HAL库硬件SPI驱动ICM20602

    软件平台 xff1a cubemx mdk 硬件平台 xff1a stm32f103rct6 ICM20602 工程源代码链接 xff1a https download csdn net download wwwlyj123321 1099
  • 【OBS】OBS Studio 的安装、参数设置和录屏、摄像头使用教程

    提示 xff1a 作者简介 xff1a 盐焗小星球 wyb xff0c 一名在读的电子信息工程专业大学生 x1f4d1 个人主页 xff1a 盐焗小星球 wyb的主页 x1f4eb 如果文章知识点有错误的地方 xff0c 请指正 xff01
  • IMU:姿态解算算法集合

    文章目录 一 IMU原理二 源码 一 IMU原理 二 源码 源文件 xff1a span class token comment include 34 IMU h 34 span span class token comment inclu