匿名飞控位置估计笔记_px4位置速度估计-程序员宅基地

技术标签: 算法  状态估计  

摸着石头过河,一边看一边学。

感谢两位博主的文章:
1、px4位置估计-inav
2、根据两点的经纬度求方位角和距离

1、机体加速度转换

acc_bias为机体坐标系下加速度计的偏移量,初始值为0,imu_DCM为Body2NED转换矩阵,ori_xaccori_yaccori_zacc 为加速度计的原始值。将偏移修正后的加速度转到NED坐标系下,注意所使用的加速度计数据方向与标准方向需一致。

  b_acc[0] = ori_xacc - acc_bias[0];
  b_acc[1] = ori_yacc - acc_bias[1];
  b_acc[2] = ori_zacc - acc_bias[2];

  for (int i = 0; i < 3; i++) {
    
    ned_acc[i] = 0.0;
    for (int j = 0; j < 3; j++) {
    
      ned_acc[i] += imu_DCM[j][i] * b_acc[j];
    }
  }
  ned_acc[2] += 9.8; 

2、GPS测量值与推测值误差

函数(map_projection_project)用于计算两经纬度之间的N,E方向的球面距离,单位(m)。ref 为收到GPS信号那一刻的经纬度,为参考位置零点。measure_latmeasure_lon为 GPS 时时的测量值。

float Dis_NE[2]; // 参考位置零点距离[北,东](m)
map_projection_project(&ref, measure_lat, measure_lon, &Dis_NE[0], &Dis_NE[1]);

est_buf 数组用于存放预测结果的缓冲数列,该数列的默认值均为0,求出GPS位置测量值Dis_NE与位置预测值、测量速度(measure_vnmeasure_ve)与速度预测值的误差。如果有需要可对校正值作数据跳变处理,对误差值进行阈值判断即可。新定义序列 (est_i) 与 (buf_i) 区分,使用缓冲数列里边的不同序列的数组用于处理GPS数据延迟。

int est_i = buf_i - 1 - MIN(EST_BUF_SIZE - 1, MAX(0, (int)(GPS_DELAY / dt))); 
if(est_i < 0) est_i += EST_BUF_SIZE;  
/*
定义 EST_BUF_SIZE = 25
est_buf[EST_BUF_SIZE][3][2] = {
  { 0.0, 0.0 },		// N (pos, vel)
  { 0.0, 0.0 },		// E (pos, vel)
  { 0.0, 0.0 },		// D (pos, vel)
}
corr_gps[3][2] = { 
  { 0.0, 0.0 },		// N (pos, vel)
  { 0.0, 0.0 },		// E (pos, vel)
  { 0.0, 0.0 },		// D (pos, vel)
}
*/
corr_gps[0][0] = Dis_NE[0] - est_buf[est_i][0][0];      // N_Pos_Error
corr_gps[1][0] = Dis_NE[1] - est_buf[est_i][1][0];      // E_Pos_Error
      
corr_gps[0][1] = measure_vn - est_buf[est_i][0][1];     // N_Vel_Error
corr_gps[1][1] = measure_ve - est_buf[est_i][1][1];     // E_Vel_Error
corr_gps[2][1] =  0.0;

3、通过测量值与推测值的误差求NED坐标系下加速度的偏移ned_acc_bias_corr

选取合适的权值w_pw_v,可得出ned_acc_bias_corr

float ned_acc_bias_corr[3] = {
     0.0, 0.0, 0.0 };

ned_acc_bias_corr[0] -= corr_gps[0][0] * w_p + corr_gps[0][1] * w_v;
ned_acc_bias_corr[1] -= corr_gps[1][0] * w_p + corr_gps[1][1] * w_v;

4、将 ned_acc_bias_corr转为机体坐标系补偿到 acc_bias

R_gps 为 NED2Body 转换矩阵,params_w_acc_bias 为 bias 补偿的权值

for (int i = 0; i < 3; i++) {
    
	float c = 0.0; 
    for (int j = 0; j < 3; j++) {
    
      c += R_gps[i][j] * ned_acc_bias_corr[j];
    }  

    acc_bias[i] += c * params_w_acc_bias * dt; 
  }

这一步得出的 acc_bias 用于下一个周期的计算。

5、预测

(inertial_filter_predict) 为预测函数。其实也就是物理模型的表达式。
这一步其实就类似于卡尔曼滤波的 X = AX + Bu

u = ned_acc;

static float N_Est[2] = {
    Dis_NE[0] , measure_vn};
static float E_Est[2] = {
    Dis_NE[1] , measure_ve};

inertial_filter_predict(dt, N_Est, ned_acc[0]);
inertial_filter_predict(dt, E_Est, ned_acc[1]);

/*
static void inertial_filter_predict(float dt, float x[2], float acc)
{
  if (isfinite(dt)) 
  {
    if (!isfinite(acc)) 
    {
      acc = 0.0f;
    }
    
    x[0] += x[1] * dt + acc * dt * dt / 2.0;     // dis = vt + 0.5*a*t^2
    x[1] += acc * dt;                             // vel = a*t
  }
}
*/

6、校正

通过实际值与预测值之间的误差对预测值进行调整。
这过程就类似于卡尔曼滤波中的 X = X_pre + K * (Z - HX_pre)H为单位阵,K为权值。

你品,你细细品…

inertial_filter_correct(corr_gps[0][0], dt, N_Est, w_p);
inertial_filter_correct(corr_gps[1][0], dt, E_Est, w_p);     
inertial_filter_correct(corr_gps[0][1], dt, N_Est, w_v);
inertial_filter_correct(corr_gps[1][1], dt, E_Est, w_v);	

/*
static void inertial_filter_correct(float e, float dt, float x[2], float w)
{
  if (isfinite(e) && isfinite(w) && isfinite(dt)) 
  {
    float ewdt = e * w * dt;
    x[i] += ewdt;       //   积分对干扰信号有滤除作用
  }
}
*/

7、保存结果

(map_projection_reproject)函数为已知一点经纬度以及 NE 方向距离求另一点经纬度的函数.

est_buf[buf_i][0][0] = N_Est[0];
est_buf[buf_i][0][1] = N_Est[1];
est_buf[buf_i][1][0] = E_Est[0];
est_buf[buf_i][1][1] = E_Est[1];

buf_i++;
buf_i = buf_i >= EST_BUF_SIZE ? 0 : buf_i;
  
Result->pre_vn = Result->vn;
Result->pre_ve = Result->ve;
Result->n      = N_Est[0];
Result->vn     = N_Est[1];
Result->e      = E_Est[0];
Result->ve     = E_Est[1];

// 将NED位置数据转换到wsg184坐标系
// Result->est_lat\est_lon 初始值为传感器测量值
map_projection_reproject(&ref, Result->n, Result->e, &Result->est_lat, &Result->est_lon); 

// 计算NED加速度,速度控制使用
float n_acc = (Result->vn - Result->pre_vn)/dt;
float e_acc = (Result->ve - Result->pre_ve)/dt;
Result->n_acc = Result->nacc*(1 - 0.381) + n_acc *0.381;        
Result->e_acc = Result->eacc*(1 - 0.381) + e_acc *0.381;

仅作学习理解参考,实际使用还需要考虑GPS丢星等情况。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Ay_wanglaoda/article/details/108553859

智能推荐

分布式光纤传感器的全球与中国市场2022-2028年:技术、参与者、趋势、市场规模及占有率研究报告_预计2026年中国分布式传感器市场规模有多大-程序员宅基地

文章浏览阅读3.2k次。本文研究全球与中国市场分布式光纤传感器的发展现状及未来发展趋势,分别从生产和消费的角度分析分布式光纤传感器的主要生产地区、主要消费地区以及主要的生产商。重点分析全球与中国市场的主要厂商产品特点、产品规格、不同规格产品的价格、产量、产值及全球和中国市场主要生产商的市场份额。主要生产商包括:FISO TechnologiesBrugg KabelSensor HighwayOmnisensAFL GlobalQinetiQ GroupLockheed MartinOSENSA Innovati_预计2026年中国分布式传感器市场规模有多大

07_08 常用组合逻辑电路结构——为IC设计的延时估计铺垫_基4布斯算法代码-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏12次。常用组合逻辑电路结构——为IC设计的延时估计铺垫学习目的:估计模块间的delay,确保写的代码的timing 综合能给到多少HZ,以满足需求!_基4布斯算法代码

OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版-程序员宅基地

文章浏览阅读3.3k次,点赞3次,收藏5次。OpenAI Manager助手(基于SpringBoot和Vue)_chatgpt网页版

关于美国计算机奥赛USACO,你想知道的都在这_usaco可以多次提交吗-程序员宅基地

文章浏览阅读2.2k次。USACO自1992年举办,到目前为止已经举办了27届,目的是为了帮助美国信息学国家队选拔IOI的队员,目前逐渐发展为全球热门的线上赛事,成为美国大学申请条件下,含金量相当高的官方竞赛。USACO的比赛成绩可以助力计算机专业留学,越来越多的学生进入了康奈尔,麻省理工,普林斯顿,哈佛和耶鲁等大学,这些同学的共同点是他们都参加了美国计算机科学竞赛(USACO),并且取得过非常好的成绩。适合参赛人群USACO适合国内在读学生有意向申请美国大学的或者想锻炼自己编程能力的同学,高三学生也可以参加12月的第_usaco可以多次提交吗

MySQL存储过程和自定义函数_mysql自定义函数和存储过程-程序员宅基地

文章浏览阅读394次。1.1 存储程序1.2 创建存储过程1.3 创建自定义函数1.3.1 示例1.4 自定义函数和存储过程的区别1.5 变量的使用1.6 定义条件和处理程序1.6.1 定义条件1.6.1.1 示例1.6.2 定义处理程序1.6.2.1 示例1.7 光标的使用1.7.1 声明光标1.7.2 打开光标1.7.3 使用光标1.7.4 关闭光标1.8 流程控制的使用1.8.1 IF语句1.8.2 CASE语句1.8.3 LOOP语句1.8.4 LEAVE语句1.8.5 ITERATE语句1.8.6 REPEAT语句。_mysql自定义函数和存储过程

半导体基础知识与PN结_本征半导体电流为0-程序员宅基地

文章浏览阅读188次。半导体二极管——集成电路最小组成单元。_本征半导体电流为0

随便推点

【Unity3d Shader】水面和岩浆效果_unity 岩浆shader-程序员宅基地

文章浏览阅读2.8k次,点赞3次,收藏18次。游戏水面特效实现方式太多。咱们这边介绍的是一最简单的UV动画(无顶点位移),整个mesh由4个顶点构成。实现了水面效果(左图),不动代码稍微修改下参数和贴图可以实现岩浆效果(右图)。有要思路是1,uv按时间去做正弦波移动2,在1的基础上加个凹凸图混合uv3,在1、2的基础上加个水流方向4,加上对雾效的支持,如没必要请自行删除雾效代码(把包含fog的几行代码删除)S..._unity 岩浆shader

广义线性模型——Logistic回归模型(1)_广义线性回归模型-程序员宅基地

文章浏览阅读5k次。广义线性模型是线性模型的扩展,它通过连接函数建立响应变量的数学期望值与线性组合的预测变量之间的关系。广义线性模型拟合的形式为:其中g(μY)是条件均值的函数(称为连接函数)。另外,你可放松Y为正态分布的假设,改为Y 服从指数分布族中的一种分布即可。设定好连接函数和概率分布后,便可以通过最大似然估计的多次迭代推导出各参数值。在大部分情况下,线性模型就可以通过一系列连续型或类别型预测变量来预测正态分布的响应变量的工作。但是,有时候我们要进行非正态因变量的分析,例如:(1)类别型.._广义线性回归模型

HTML+CSS大作业 环境网页设计与实现(垃圾分类) web前端开发技术 web课程设计 网页规划与设计_垃圾分类网页设计目标怎么写-程序员宅基地

文章浏览阅读69次。环境保护、 保护地球、 校园环保、垃圾分类、绿色家园、等网站的设计与制作。 总结了一些学生网页制作的经验:一般的网页需要融入以下知识点:div+css布局、浮动、定位、高级css、表格、表单及验证、js轮播图、音频 视频 Flash的应用、ul li、下拉导航栏、鼠标划过效果等知识点,网页的风格主题也很全面:如爱好、风景、校园、美食、动漫、游戏、咖啡、音乐、家乡、电影、名人、商城以及个人主页等主题,学生、新手可参考下方页面的布局和设计和HTML源码(有用点赞△) 一套A+的网_垃圾分类网页设计目标怎么写

C# .Net 发布后,把dll全部放在一个文件夹中,让软件目录更整洁_.net dll 全局目录-程序员宅基地

文章浏览阅读614次,点赞7次,收藏11次。之前找到一个修改 exe 中 DLL地址 的方法, 不太好使,虽然能正确启动, 但无法改变 exe 的工作目录,这就影响了.Net 中很多获取 exe 执行目录来拼接的地址 ( 相对路径 ),比如 wwwroot 和 代码中相对目录还有一些复制到目录的普通文件 等等,它们的地址都会指向原来 exe 的目录, 而不是自定义的 “lib” 目录,根本原因就是没有修改 exe 的工作目录这次来搞一个启动程序,把 .net 的所有东西都放在一个文件夹,在文件夹同级的目录制作一个 exe._.net dll 全局目录

BRIEF特征点描述算法_breif description calculation 特征点-程序员宅基地

文章浏览阅读1.5k次。本文为转载,原博客地址:http://blog.csdn.net/hujingshuang/article/details/46910259简介 BRIEF是2010年的一篇名为《BRIEF:Binary Robust Independent Elementary Features》的文章中提出,BRIEF是对已检测到的特征点进行描述,它是一种二进制编码的描述子,摈弃了利用区域灰度..._breif description calculation 特征点

房屋租赁管理系统的设计和实现,SpringBoot计算机毕业设计论文_基于spring boot的房屋租赁系统论文-程序员宅基地

文章浏览阅读4.1k次,点赞21次,收藏79次。本文是《基于SpringBoot的房屋租赁管理系统》的配套原创说明文档,可以给应届毕业生提供格式撰写参考,也可以给开发类似系统的朋友们提供功能业务设计思路。_基于spring boot的房屋租赁系统论文