六轴融合算法

2023-11-12

先说什么叫六轴融合?

在3Dof姿态追踪功能中,最主要的传感器就是陀螺仪(Gyroscope),它可以提供3个轴的角加速度,对时间进行积分,就可以得出物体旋转的方向角度。但是因为硬件精度等各方面原因,会产生误差,随着时间的累积,计算得到的角度误差就会越来越大,即产生漂移。

为了防止漂移,这就引入了另一个传感器,加速度计(Accelerometer)。在一般的3Dof运动中,由运动产生的加速度较少,对物体影响最大的是重力,而重力始终是垂直向下。引入Acc的本质就是利用重力来做参考,对Gyro计算的数据进行校正。

所谓六轴融合,就是Gyro三个轴+Acc三个轴,计算得到3Dof姿态。

值得注意的是:

1. 重力只能校准Roll和Pitch方向,Yaw方向依然会有误差,还要再引入地磁计(Magnetic),那就是九轴融合算法了。在Android上,SensorManager提供了注册监听的类型,其中TYPE_GAME_ROTATION_VECTOR就是用的六轴融合,TYPE_ROTATION_VECTOR用的就是九轴融合

2. 因为硬件本身的精度,还有设备组装等方面的原因,传感器必然存在原始的误差,需要做零漂校准。也就是尽量保证设备在水平静置状态下,Gyro数据都是0,Acc只有垂直水平面的轴数据为重力值,其余为0。

(很惭愧,这两样我都没有做过)

下面是摘自网上的一个简单算法,还有好多不懂的地方,先记下来,慢慢再研究。

public class IMUTest {
    private final float Kp = 4.0f;   //Kp越大代表重力校正的权重越大,过大可能产生抖动。
    private final float Ki = 0.001f; //Ki应该是零漂校准产生的,没仔细研究过还不确定,先用个较小的值,没啥影响
    private float q0, q1, q2, q3; //依次对应四元数的w,x,y,z
    private float exInt, eyInt, ezInt;
    private long lastTime;

    public IMUTest() {
        q0 = 1.f;
        q1 = 0.f;
        q2 = 0.f;
        q3 = 0.f;
        exInt = 0.f;
        eyInt = 0.f;
        ezInt = 0.f;
    }

    public void update(float GyroX, float GyroY, float GyroZ, float AccX, float AccY, float AccZ, long timeMS) {
        long diff = timeMS - lastTime;
        lastTime = timeMS;
        float halfT = diff * 0.001f * 0.5f;//单位毫秒转为秒

        //加速度计处于自由落体状态时,不进行姿态解算,因为三个轴都为0,会产生分母无穷大的情况
        if ( Math.abs(AccX * AccY * AccZ) < 0.000001f) return;

        float norm; //矢量的模或四元数的模

        //归一化加速度计,这样变更量程也不需要修改Kp参数
        norm = (float)Math.sqrt(AccX * AccX + AccY * AccY + AccZ * AccZ);
        float ax = AccX / norm;
        float ay = AccY / norm;
        float az = AccZ / norm;
        //用当前姿态计算出重力在三个轴上的分量,
        //参考坐标n系转化到载体坐标b系,用四元数表示的方向余弦矩阵第三列即是,为啥?
        float vx = 2.f * (q1 * q3 - q0 * q2);
        float vy = 2.f * (q0 * q1 + q2 * q3);
        float vz = q0 * q0 - q1 * q1 - q2 * q2 + q3 * q3;
        //计算传感器测量重力与姿态计算的重力之间的误差,叉乘可以表示这一误差,又是为啥?
        float ex = ay * vz - az * vy;
        float ey = az * vx - ax * vz;
        float ez = ax * vy - ay * vx;
        //对误差进行积分
        exInt = exInt + ex * Ki;
        eyInt = eyInt + ey * Ki;
        ezInt = ezInt + ez * Ki;
        //将误差PI后补偿到陀螺仪,即补偿零点漂移
        //这里的水平旋转方向由于没有观测者进行矫正会产生漂移,表现出来的就是积分自增或自减,所以应该直接用GyroX?
        float gx = GyroX + Kp * ex + exInt;
        float gy = GyroY + Kp * ey + eyInt;
        float gz = GyroZ + Kp * ez + ezInt;

        //下面进行姿态的更新,也就是四元数微分方程的求解
        float q0temp = q0;
        float q1temp = q1;
        float q2temp = q2;
        float q3temp = q3;
        //采用一阶毕卡解法,相关知识可参见《惯性器件与惯性导航系统》P212
        q0 = q0temp + (-q1temp * gx - q2temp * gy - q3temp * gz) * halfT;
        q1 = q1temp + (q0temp * gx + q2temp * gz - q3temp * gy) * halfT;
        q2 = q2temp + (q0temp * gy - q1temp * gz + q3temp * gx) * halfT;
        q3 = q3temp + (q0temp * gz + q1temp * gy - q2temp * gx) * halfT;
        //对四元数做归一化,单位化四元数在空间旋转时不会拉伸,仅有旋转角度,这类似线性代数里的正交变换
        norm = (float)Math.sqrt(q0 * q0 + q1 * q1 + q2 * q2 + q3 * q3);
        q0 /= norm;
        q1 /= norm;
        q2 /= norm;
        q3 /= norm;
    }
}

参考自https://blog.csdn.net/asr9k/article/details/53258308?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control&dist_request_id=ccb9df40-57cb-4714-873f-727e69a96dee&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.control

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

六轴融合算法 的相关文章

  • 获取当前 android.intent.category.LAUNCHER 活动的实例

    我创建了一个库项目 并在多个应用程序之间共享 我实现了一个简单的会话过期功能 该功能将在一段时间后将用户踢回到登录屏幕 登录屏幕活动是我的主要活动 因此在清单中它看起来像这样
  • 你的CPU不支持NX

    我刚刚下载了 android studio 但是我遇到了一个问题 当我运行它时 它说你的 cpu 不支持 NX 我应该怎么办 NX 或实际上是 NX 处理器位 是处理器的一项功能 有助于保护您的 PC 免受恶意软件的攻击 当此功能未启用并且
  • 我想实现下面的布局,按钮应该在屏幕底部,当惰性列被填充时,按钮不应该出去

    顶部有惰性列 惰性列下方有输入电话号码布局并从电话簿布局添加联系人 我希望当未添加联系人时此布局位于顶部 当我添加大量联系人时输入电话号码并添加电话簿布局中的联系人会随着惰性列滚动并移出屏幕 我不让他们走出屏幕 当接触较多时 它们必须粘在底
  • 如何使用InputConnectionWrapper?

    我有一个EditText 现在我想获取用户对此所做的所有更改EditText并在手动将它们插入之前使用它们EditText 我不希望用户直接更改中的文本EditText 这只能由我的代码完成 例如通过使用replace or setText
  • Android Studio 0.4.3 Eclipse项目没有gradle

    在此版本之前 在 Android Studio 中按原样打开 Eclipse 项目似乎很容易 无需任何转换 我更喜欢 Android Studio 环境 但我正在开发一个使用 eclipse 作为主要 IDE 的项目 我不想只为这个项目下载
  • Java Integer CompareTo() - 为什么使用比较与减法?

    我发现java lang Integer实施compareTo方法如下 public int compareTo Integer anotherInteger int thisVal this value int anotherVal an
  • 如何在 javadoc 中使用“<”和“>”而不进行格式化?

    如果我写
  • 在 Mac 上正确运行基于 SWT 的跨平台 jar

    我一直致力于一个基于 SWT 的项目 该项目旨在部署为 Java Web Start 从而可以在多个平台上使用 到目前为止 我已经成功解决了由于 SWT 依赖的系统特定库而出现的导出问题 请参阅相关thread https stackove
  • Android Studio - Windows 7 上的 Android SDK 问题

    我对 Google i o 2013 上发布的最新开发工具 Android Studio 有疑问 我已经成功安装了该程序并且能够正常启动 我可以导入现有项目并对其进行编辑 但是 当我尝试单击 SDK 管理器图标或 AVD 管理器图标时 或者
  • 我的设备突然没有显示在“Android 设备选择器”中

    我正在使用我的三星 Galaxy3 设备来测试过去两个月的应用程序 它运行良好 但从今天早上开始 当我将设备连接到系统时 它突然没有显示在 Android 设备选择器 窗口中 我检查过 USB 调试模式仅在我的设备中处于选中状态 谁能猜出问
  • 如何从终端运行处理应用程序

    我目前正在使用加工 http processing org对于一个小项目 但是我不喜欢它附带的文本编辑器 我使用 vim 编写所有代码 我找到了 pde 文件的位置 并且我一直在从 vim 中编辑它们 然后重新打开它们并运行它们 重新加载脚
  • 如何从泛型类调用静态方法?

    我有一个包含静态创建方法的类 public class TestClass public static
  • 如何根据 gradle 风格设置变量

    我想传递一个变量test我为每种风格设置了不同的值作为 NDK 的定义 但出于某种原因 他总是忽略了最后味道的价值 这是 build gradle apply plugin com android library def test andr
  • 声明的包“”与预期的包不匹配

    我可以编译并运行我的代码 但 VSCode 中始终显示错误 早些时候有一个弹出窗口 我不记得是什么了 我点击了 全局应用 从那以后一直是这样 Output is there but so is the error The declared
  • 在activity_main.xml中注释

    我是安卓新手 据我所知 XML 中的注释与 HTML 中的注释相同 使用 形式 我想在 Android 项目的 Activity main xml 配置文件中写一些注释 但它给了我错误 值得注意的是 我使用的是 Eclipse 但目前 我直
  • 静态变量的线程安全

    class ABC implements Runnable private static int a private static int b public void run 我有一个如上所述的 Java 类 我有这个类的多个线程 在里面r
  • 一次显示两条Toast消息?

    我希望在一个位置显示一条 Toast 消息 并在另一位置同时显示另一条 Toast 消息 多个 Toast 消息似乎总是按顺序排队和显示 是否可以同时显示两条消息 是否有一种解决方法至少可以提供这种外观并且不涉及扰乱活动布局 Edit 看来
  • 实现滚动选择 ListView 中的项目

    我想使用 ListView 您可以在其中滚动列表来选择一个项目 它应该像一个 Seekbar 但拇指应该是固定的 并且您必须使用该栏来调整它 我面临的一个问题是 我不知道这种小部件是如何调用的 这使得我很难搜索 所以我制作了下面这张图片 以
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch
  • Crashlytics 出现 Android Studio 构建错误

    我正在尝试将 CrashLytics 与 Android Studio 和 gradle 一起使用 但出现一个令人困惑的错误 java lang NoSuchMethodError 我的 build gradle 是 buildscript

随机推荐

  • 杰理之芯片丝印说明【篇】

    第一行 杰理公司LOGO 第二行 字母 代表芯片的生产信息 即 批次号 2C4 代表芯片型号的末3位 从芯片丝印 是 看不出 芯片的具体型号 例如 图片的丝印 对应的型号有可能是 AC6322C4 AC6352C4 AC6362C4 等
  • OpenWrt目录结构及编译过程

    OpenWrt代码有8个固定的顶层目录以及7个编译时创建的临时目录 顶层目录 docs docs目录 用于存放开发文档 编译时不需要 包含了整个宿主机的文件源码的介绍 里面还有Makefile为目标系统生成docs 使用make C doc
  • 〖Web全栈开发①〗—网络编程基础(上)

    网络编程基础 网络编程 网络编程概述 TCP IP协议 IP地址 什么是IP IP组成 IP 地址使用过程 查看IP Ip地址分类 子网掩码 端口 socket Socket原理 什么是Socket 2 创建一个tcp socket tcp
  • Redis基础语法

    noSQL 主要解决高并发数据 可以提高访问性能 将低服务器负担 Redis 底层结构 采用键值对存储 工作机制 采用单线程 Redis的数据结构 实用度左至右 string hash list set zset key value key
  • 新博客地址

    现在新的博客地址 https rpz105 com https rpz105 com
  • 【 unity3d 】天空盒的创建和使用

    天空盒 周围环境 天空 注意不是地形 一 创建天空盒材质 1 先创建材质 材质里的Shader里找Skybox 有3个制作方式 但是他们的渲染效果一样 只是制作方式不一样
  • LaTeX基本命令使用教程(清晰实例)(Overleaf平台)(论文排版)

    前言 本文是笔者在学习LaTeX的记录文档 主要是一些常用命令 发至博客分享给大家 笔者的感受是熟悉这些常用命令后即可上手编辑简单的论文 效率很高 体验比word好很多 希望本文能够对LaTeX的初学者有所帮助 有任何问题可以在评论区留言
  • 存储过程进行数据合并导入

    CREATE PROCEDURE sp mytest1 mytype int AS declare pro varchar 50 declare pro1 varchar 50 select pro typename from table1
  • web浏览器访问后端提示‘没有javascript支持,将不能正常工作’

    如图提示 网上找了一下解决办法 说是可能浏览器js支持没有开启 但我的浏览器js支持是开启的 后面清理了下浏览器的缓存 问题解决
  • 如何使用 Kubernetes 监测定位慢调用

    监控作者 李煌东 大家好 我是阿里云的李煌东 今天我为大家分享 Kubernetes 监测公开课第四节 如何使用 Kubernetes 监测定位慢调用 今天的课程主要分为三大部分 首先我会介绍一下慢调用的危害以及常见的原因 其次我会介绍慢调
  • Java&JS时间格式转化

    时间格式转化 一 Java格式转化 1 1 接收前端传值转化 1 2 String转化LocalDate 1 3 LocalDate与Date相互转换 二 Javascript格式转化 2 1 JS时间格式转化 一 Java格式转化 1 1
  • openswan中ISAKMP交互过程关键函数接口

    1 ISAKMP交互过程中关键函数接口 下面分别说明不同的阶段和模式下的函数接口以及对应的报文 2 第一阶段 Phase I 主模式函数接口 发送端 响应端 main outI1 主模式第一包
  • MySQL中的索引事务(1)索引----》数据库运行的原理知识+面试题~

    本篇文章主要讲述MySQL索引事务 所谓的索引index就是指 目录 索引存在的意义 加快查找的速度 省略了遍历的过程 但付出了一定的代价 付出的代价如下 1 需要付出额外的空间代价来保存索引数据 2 索引可能会拖慢新增 删除 修改数据的速
  • 华为OD机试真题-最差产品奖【2023.Q1】

    题目内容 题目描述 A公司准备对他下面的N个产品评选最差奖 评选的方式是首先对每个产品进行评分 然后根据评分区间计算相邻几个产品中最差的产品 评选的标准是依次找到从当前产品开始前M个产品中最差的产品 请给出最差产品的评分序列 输入描述 第一
  • Windows terminal + WSL 美化教程的笔记——解决遇到的问题

    文章目录 前言 问题1 如何打开Windows Terminal 的设置 修改配置文件 问题2 打开windows terminal有更新提示怎么办 问题3 打开windows terminal报错怎么办 参考文献 前言 学习过程中突感字体
  • vaultwarden密码库 搭建流程

    系统工程 建设篇 第二章 vaultwarden密码库 搭建流程 系统工程 建设篇 系列文章回顾 前言 前置条件 实施步骤 注意事项 浏览器插件下载链接 部署 vaultwarden密码库 宝塔面板配置docker 开启docker服务 从
  • python连接clickhouse使用方法

    前沿 clickhouse现在作为分布式存储成熟的解决方案 在python开发中经常会用到clickhouse的连接方案 下面所列一个简单的连接clickhouse的写法 正文 from clickhouse driver import C
  • 焉建伟:3.31黄金走势看涨看跌?黄金原油今日如何操作? 实时策略

    消息面 美东时间周二 美国媒体援引两名知情人士的话报道 拜登周三预计将在匹兹堡宣布2 25万亿美元的一揽子基础设施和就业支持计划 具体而言 大约6500亿美元会被用于重建美国基础设施 如道路 桥梁 高速公路和港口 4000亿美元用于老年人和
  • 蓝桥杯单片机前言(经验分享)

    本人在今年省赛的获得了省一等奖 这是战利品hhh 国赛由于没有好好准备 所以没有取得好名次 已经后悔了555 个人经历 当时是寒假开始学习蓝桥杯单片机开发板的 本人情况是有模电 电路理论基础 c语言基础 当时差不多忘记完了 没有51和模电基
  • 六轴融合算法

    先说什么叫六轴融合 在3Dof姿态追踪功能中 最主要的传感器就是陀螺仪 Gyroscope 它可以提供3个轴的角加速度 对时间进行积分 就可以得出物体旋转的方向角度 但是因为硬件精度等各方面原因 会产生误差 随着时间的累积 计算得到的角度误