imu+wheel融合

news2024/9/20 14:56:05

Imu+Wheel融合

文章目录

  • Imu+Wheel融合
  • 1 轮速计
    • 1.1 航迹递推
      • 1.1.1 基于欧拉法
      • 1.1.2 基于二阶Runge-Kutta积分
      • 1.1.3 群空间闭式积分
    • 1.2 雅可比计算
  • 2 IMU观测更新
  • 3 数据处理

1 轮速计

1.1 航迹递推

​ 常见的轮速计积分的方式有三种:欧拉积分、二阶Runge-Kutta积分、群空间闭式积分。在我们代码中,分别实现了前面两种递归公式!

在这里插入图片描述

1.1.1 基于欧拉法

​ 误差主要来源于平移积分过程中认为角度恒定。直线运动时不受影响,以及 Δt 很小时误差影响也较小。

[ θ t + 1 x t + 1 y t + 1 ] = [ θ t x t y t ] + [ ω Δ t cos ⁡ ( θ t ) ∗ v x Δ t sin ⁡ ( θ t ) ∗ v x Δ t ] \begin{bmatrix}\theta_{t+1}\\x_{t+1}\\y_{t+1}\end{bmatrix}=\begin{bmatrix}\theta_t\\x_t\\y_t\end{bmatrix}+\begin{bmatrix}\omega\Delta t\\\cos\left(\theta_t\right)*v_x\Delta t\\\sin\left(\theta_t\right)*v_x\Delta t\end{bmatrix} θt+1xt+1yt+1 = θtxtyt + ωΔtcos(θt)vxΔtsin(θt)vxΔt

代码实现:下面旋转矩阵展开就是上面的形式。手推即可验证,有时间补充

// 方法1:利用旋转矩阵进行递推更新
const Eigen::Matrix3d delta_R = Eigen::AngleAxisd(u_now(1), Eigen::Vector3d::UnitZ()).toRotationMatrix();
const Eigen::Vector3d delta_p = Eigen::Vector3d(u_now(0), 0., 0.);

R_G_O = old_R_G_O * delta_R;       // R_Go(k+1) = R_Go(k)*delta_R
p_G_O = old_p_G_O + old_R_G_O * delta_p;
x_n = x_p + u_now(1); // theta

1.1.2 基于二阶Runge-Kutta积分

​ 平移积分过程中认为角度为运动前后的均值,误差比欧拉积分小一点

[ θ t + 1 x t + 1 y t + 1 ] = [ θ t x t y t ] + [ ω Δ t cos ⁡ ( θ t + ω Δ t 2 ) v x Δ t sin ⁡ ( θ t + ω Δ t 2 ) v x Δ t ] \begin{bmatrix}\theta_{t+1}\\x_{t+1}\\y_{t+1}\end{bmatrix}=\begin{bmatrix}\theta_t\\x_t\\y_t\end{bmatrix}+\begin{bmatrix}\omega\Delta t\\\cos{(\theta_t+\frac{\omega\Delta t}2)}v_x\Delta t\\\sin{(\theta_t+\frac{\omega\Delta t}2)}v_x\Delta t\end{bmatrix} θt+1xt+1yt+1 = θtxtyt + ωΔtcos(θt+2ωΔt)vxΔtsin(θt+2ωΔt)vxΔt

代码实现:

// 方法2
x_now(0) = x_pre(0) + u_now(0) * ::cos( x_pre(2) + 0.5 * u_now(1) ); // x
x_now(1) = x_pre(1) + u_now(0) * ::sin( x_pre(2) + 0.5 * u_now(1) ); // y
x_now(2) = x_pre(2) + u_now(1); // theta 

1.1.3 群空间闭式积分

参考

u就是Δp
[ θ t + 1 p t + 1 ] = [ θ t p t ] + [ α R ( θ t ) A ( α ) u ] \begin{bmatrix}\theta_{t+1}\\\mathbf{p}_{t+1}\end{bmatrix}=\begin{bmatrix}\theta_{t}\\\mathbf{p}_{t}\end{bmatrix}+\begin{bmatrix}\alpha\\\mathbf{R}(\theta_{t})\mathbf{A}(\alpha)\mathbf{u}\end{bmatrix} [θt+1pt+1]=[θtpt]+[αR(θt)A(α)u]

其中 A ( α ) \mathbf{A}(\alpha) A(α)
= [ sin ⁡ ( α ) α − 1 − cos ⁡ ( α ) α 1 − cos ⁡ ( α ) α sin ⁡ ( α ) α ] =\begin{bmatrix}\frac{\sin(\alpha)}{\alpha}&-\frac{1-\cos(\alpha)}{\alpha}\\\frac{1-\cos(\alpha)}{\alpha}&\frac{\sin(\alpha)}{\alpha}\end{bmatrix} =[αsin(α)α1cos(α)α1cos(α)αsin(α)]

代码实现:

// 方法3
const Eigen::Matrix3d A_old_yaw = xxx;		

const Eigen::Matrix3d delta_R = Eigen::AngleAxisd(u_now(1), Eigen::Vector3d::UnitZ()).toRotationMatrix();

const Eigen::Vector3d delta_p = Eigen::Vector3d(u_now(0), 0., 0.);

R_G_O = old_R_G_O * delta_R;       // R_Go(k+1) = R_Go(k)*delta_R
p_G_O = old_p_G_O + old_R_G_O * A_old_yaw * delta_p;
x_n = x_p + u_now(1); // theta

1.2 雅可比计算

如果只有 x y yaw三个状态量,雅可比计算如下:

F 3 × 3 = [ 1 0 − Δ s k s i n ( θ k + 1 2 Δ θ k ) 0 1 Δ s k c o s ( θ k + 1 2 Δ θ k ) 0 0 1 ] F_{3\times3}=\begin{bmatrix}1&0&-\Delta s_ksin(\theta_k+\frac12\Delta\theta_k)\\0&1&\Delta s_kcos(\theta_k+\frac12\Delta\theta_k)\\0&0&1\end{bmatrix} F3×3= 100010Δsksin(θk+21Δθk)Δskcos(θk+21Δθk)1

实际系统是三维的,所以共6个自由度,即由6个变量组成:

// 计算状态雅可比矩阵
F = Matrix6::Identity();
F(3, 2) = -u_now(0) * std::sin(x_p);
F(4, 2) = u_now(0) * std::cos(x_p);

分别对 r p yaw x y z进行求导
F = [ 1 0 0 0 0 0 0 1 0 0 0 0 0 0 1 0 0 0 0 0 − u now ( 0 ) sin ⁡ ( x p ) 1 0 0 0 0 u now ( 0 ) cos ⁡ ( x p ) 0 1 0 0 0 0 0 0 0 ] \begin{equation} F = \begin{bmatrix} 1 & 0 & 0 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 & 0 \\ 0 & 0 & -u_{\text{now}}(0) \sin(x_p) & 1 & 0 & 0 \\ 0 & 0 & u_{\text{now}}(0) \cos(x_p) & 0 & 1 & 0 \\ 0 & 0 & 0 & 0 & 0 & 0 \\ \end{bmatrix} \end{equation} F= 100000010000001unow(0)sin(xp)unow(0)cos(xp)0000100000010000000

// 更新状态向量
x_now(0) = x_pre(0);  // 保持滚转角 r 不变
x_now(1) = x_pre(1);  // 保持俯仰角 p 不变
x_now(2) = x_pre(2) + u_now(1);  // 更新偏航角 y
x_now(3) = x_pre(3) + u_now(0) * std::cos(x_pre(2));  // 更新位置 x
x_now(4) = x_pre(4) + u_now(0) * std::sin(x_pre(2));  // 更新位置 y
x_now(5) = x_pre(5);  // 保持位置 z 不变

2 IMU观测更新

只使用imu测出的角度增量作为观测值,而且观测方程刚好是线性的!不需要再次计算雅可比矩阵

2D: x y yaw

h ( X k ) = H X k = ( 0 , 0 , 1 ) [ x k y k θ k ] = θ k \begin{aligned}h(X_k)&=HX_k\\&=(0,0,1)\begin{bmatrix}x_k\\y_k\\\theta_k\end{bmatrix}\\&=\theta_k\end{aligned} h(Xk)=HXk=(0,0,1) xkykθk =θk

3D:r p yaw x y z

H << 0, 0, 1, 0, 0 , 0; 

标准EKF过程

double old_angle = x_p;  // 获取角度值
double new_angle = x_n; 

DataType h = new_angle - old_angle;  // 预测delta_theta

// 观测误差----测试把误差反过来会怎么样(会跑飞!)---常规EKF公式都是 残差r = 观测z-预测CX
double error = z - h;

// 卡尔曼增益
double S = H * P_now * H.transpose() + R;
Matrix6x1 K = P_now * H.transpose() * (1 / S);

// 状态更新
const Eigen::Matrix3d delta_R = Eigen::AngleAxisd(K[2] * error, Eigen::Vector3d::UnitZ()).toRotationMatrix();
R_G_O = R_G_O * delta_R;       // R_Go(k+1) = R_Go(k)*delta_R
p_G_O[0] += K[3] * error;
p_G_O[1] += K[4] * error;
x_n += K[2] * error;

3 数据处理

对于imu和wheel的处理(有时间再补代码)

① 简单处理:找到wheel最近的imu数据

② 线性插值处理,更精确!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2116567.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

拯救者y9000p外接显示器黑屏

一开始会出现偶尔黑屏的情况&#xff0c;短则一两秒&#xff0c;长则五分钟。开始以为是屏幕或者是hdmi线的问题。后来网上查&#xff0c;发现可能是联想自带的XRite颜色校准器。 如果不需要该软件可以设置成为开机禁用&#xff0c;这样暂时就没问题了。

【数据结构与算法 | 灵神题单 | 删除链表篇】力扣3217, 82, 237

总结&#xff0c;删除链表节点问题使用到列表&#xff0c;哈希表&#xff0c;递归比较容易超时&#xff0c;我觉得使用计数排序比较稳&#xff0c;处理起来也不是很难。 1. 力扣3217&#xff1a;从链表中移除在数组中的节点 1.1 题目&#xff1a; 给你一个整数数组 nums 和一…

LVM在Kubernetes下的最佳实践方案--TopoLVM

TopoLVM介绍及实践 LVM在Kubernetes下的最佳实践方案–TopoLVM。 1. 简介 TopoLVM 是一种基于 LVM&#xff08;Logical Volume Manager&#xff09;的 CSI&#xff08;Container Storage Interface&#xff09;插件&#xff0c;专为 Kubernetes 环境设计&#xff0c;旨在提供…

分布式部署②

&#x1f4d1;打牌 &#xff1a; da pai ge的个人主页 &#x1f324;️个人专栏 &#xff1a; da pai ge的博客专栏 ☁️宝剑锋从磨砺出&#xff0c;梅花香自苦寒来 对第四台服务器的补充 产品服务,订…

HTML 超链接

每一个网站都是由许多独立的网页组成&#xff0c;网页之家通常都是通过超链接来相互连接的。超链接可以让用户在各个独立的网页之间跳转。 <!DOCTYPE html> <html> <head><meta charset"utf-8" /><title>colspan属性</title>&l…

Linux一周大项目:库的移植

挂载--->将所需库文件夹复制到nfs文件夹中&#xff08;不在终端进行&#xff09;--->cp库文件到开发板 /usr/lib step1 step3 ​​​​​​​​​​​​​​ 一、解压文件 解压zip文件 sudo unzip xxx.zip 解压tar文件 sudo tar -xvf xxx.tar 修改权限 sudo ch…

Maven 依赖漏洞扫描检查插件 dependency-check-maven 的使用

前言 在现代软件开发中&#xff0c;开源库的使用愈加普遍&#xff0c;然而这些开源库中的漏洞往往会成为潜在的安全风险。如何及时的发现依赖的第三方库是否存在漏洞&#xff0c;就变成很重要了。 本文向大家推荐一款可以进行依赖包漏洞检查的 maven 插件 dependency-check-m…

828华为云征文|华为云Flexus云服务器X实例之openEuler系统下部署GitLab服务器

828华为云征文&#xff5c;华为云Flexus云服务器X实例之openEuler系统下部署Gitlab服务器 前言一、Flexus云服务器X实例介绍1.1 Flexus云服务器X实例简介1.2 Flexus云服务器X实例特点1.3 Flexus云服务器X实例使用场景 二、GitLab介绍2.1 GitLab简介2.2 GitLab主要特点 三、本次…

Java异常类

目录 Java异常类 Java中的异常体系 抛出异常 处理异常 处理异常的两种方式 try...catch和throws的区别 finally关键字 抛出异常注意事项 自定义异常类 Java异常类 Java中的异常体系 在Java中&#xff0c;异常类的父类为Throwable类&#xff0c;在Throwable下&#x…

git submodule子模块的使用

子模块的使用 添加子模块 添加子模块 git submodule add <子仓库URL> <子仓库路径> 例子&#xff1a; git submodule add http://192.168.100.181/guideir/poco.git 3rdparty/poco 若子模块存在好几个分支&#xff0c;可以在添加子模块时&#xff0c;指定分支 g…

全国糖酒会,就这5个字。“会天下美味”

“全国糖酒会&#xff0c;会天下美味”&#xff0c;是全国糖酒会的品牌口号。这个品牌口号来的非常偶然。 两年前&#xff0c;全国糖酒会准备更新标志之时&#xff0c;也设计了一个品牌口号。新标志发布前几天&#xff0c;临时作了调整&#xff0c;最终变成了“全国糖酒会&…

Day92 代码随想录打卡|动态规划篇---斐波那契数

题目&#xff08;leecode T509&#xff09;&#xff1a; 斐波那契数 &#xff08;通常用 F(n) 表示&#xff09;形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始&#xff0c;后面的每一项数字都是前面两项数字的和。也就是&#xff1a; F(0) 0&#xff0c;F(1) 1 F(n)…

C++11线程池、多线程编程(附源码)

Test1 示例源码展示&#xff1a; #include<iostream> #include<thread> #include<string> using namespace std;void printHelloWord(string s) {cout << s << endl;//return; } int main() {string s;s "wegfer";thread thread1(p…

【动手学深度学习】08 线性回归 + 基础优化算法(个人向笔记)

1. 线性回归 一个简化的模型&#xff1a; 我们可以这样来定义线性模型&#xff1a;注意这里先转置变成了列向量线性模型可以被看成时一个单层的神经网络&#xff1a;单层是因为单层参数 - 用一个函数来衡量预估质量&#xff1a;损失函数 在训练的时候寻找最小化的损失的参数 w…

Vivado编译报错黑盒子问题

1 问题描述 “Black Box Instances: Cell **** of type ** has undefined contents and is considered a back box. The contents of this cell must be defined for opt_design to complete successfully.” 检查工程代码提示的模块&#xff0c;该模块为纯手写的Veril…

使用AI赋能进行软件测试-文心一言

1.AI赋能的作用 提高速度和效率缺陷预测与分析 2.AI互动指令格式--文心一言 角色、指示、上下文例子、输入、输出 a 直接问AI 针对以下需求&#xff0c;设计测试用例。 需求&#xff1a; 1、账号密码登录系统验证账号和密码的正确性。 验证通过,用户登录成功,进入个人中心;验…

【优选算法】---前缀和

前缀和 一、【模板】一维前缀和二、【模板】二维前缀和三、寻找数组的中心下标四、除自身以外数组的乘积五、和为K子数组六、和可被 K 整除的子数组七、连续数组八、矩阵区域和 一、【模板】一维前缀和 一维前缀和&#xff0c;链接 1、预处理出来一个前缀和数组 注意&#xf…

C#学习 深入理解委托、匿名方法、Lamda表达式、Linq;

目录 一.委托 1.1 什么是委托 1.2 委托的使用 二.匿名方法和Lamda表达式 2.1 什么是匿名方法 2.2 Lambda表达式 三.Linq 3.1 Linq理解 3.2 Linq的扩展方法 一.委托 1.1 什么是委托 委托和类一样&#xff0c;是具有特定参数列表和返回值类型的方法函数的…

VSCode连接docker

1.启动ssh服务 vim /root/.bashrc 或者 vim ~/.bashrc /usr/sbin/sshd #启动ssh服务~代表主目录&#xff0c;cd ~会返回root目录 cd / 返回最根上的目录 为了防止每次打开容器都要输入此指令&#xff0c;我们直接在 ~/.bashrc文件最后一行添加sshd启动命令即可。 打开终端…

javase小项目--图书管理系统

前面我们已经学习到了javase的基本语法结构-继承&#xff0c;多态&#xff0c;接口&#xff0c;接下来就让我们大家一起来利用这些来手动实现一个小项目——简洁的图书管理系统 目录 1.思路 1.book类 1.book 2.booklist 2.user类 user AdminUser NormalUser 3.ioperat…