当前位置: 首页 > news >正文

Ardupilot — EKF3使用光流室内定位代码梳理

文章目录

前言

1 Copter.cpp

1.1 void IRAM_ATTR Copter::fast_loop()

1.2 void Copter::read_AHRS(void)

1.3 对象ahrs说明

2 AP_AHRS_NavEKF.cpp

2.1 void AP_AHRS_NavEKF::update(bool skip_ins_update)

2.2 void AP_AHRS_NavEKF::update_EKF3(void)

2.3 对象EKF3说明

3 AP_NavEKF3.cpp

3.1 void IRAM_ATTR NavEKF3::UpdateFilter(void)

3.2 对象core说明

4 AP_NavEKF3_core.cpp

4.1 void IRAM_ATTR NavEKF3_core::UpdateFilter(bool predict)

5 AP_NavEKF3_Control.cpp

5.1 void NavEKF3_core::controlFilterModes()

5.2 void NavEKF3_core::setAidingMode()

6 AP_NavEKF3_OptFlowFusion.cpp

6.1 void NavEKF3_core::SelectFlowFusion()

6.2 void NavEKF3_core::FuseOptFlow()


前言

故事的开始,要从参数 EK3_FLOW_USE 说起。

注意:该参数适用于高级用户。

控制是否将光流数据融合到 24 状态导航估算器1 状态地形高度估算器中。

RebootRequired

Values

True

Value

Meaning

0

None

1

Navigation

2

Terrain


本文主要梳理一下,在旋翼中 EKF3 的整个运行流程,以及在哪一步融合光流数据进行室内定位飞行。

前置参数:

1、AHRS_EKF_TYPE = 3

使用 EKF3 卡尔曼滤波器进行姿态和位置估算。

2、EK3_GPS_TYPE = 3

禁止使用 GPS - 当在 GPS 质量较差、多径误差较大的环境中使用光流量传感器飞行时,这一点非常有用。

1 Copter.cpp

1.1 void IRAM_ATTR Copter::fast_loop()

Ardupilot 代码中,需求资源多,运算频率高的任务,一般在 fast_loop() 函数中。这里我们只展示和 EKF3 运行相关的代码段。

运行 EKF 状态估算器(耗资巨大)。

// Main loop - 400hz
void IRAM_ATTR Copter::fast_loop()
{...// run EKF state estimator (expensive)// --------------------read_AHRS();...
}

1.2 void Copter::read_AHRS(void)

读取姿态航向参考系统信息的入口函数。

我们告诉 AHRS 跳过 INS 更新,因为我们已经在 fast_loop() 中进行了更新。

void Copter::read_AHRS(void)
{// Perform IMU calculations and get attitude info//-----------------------------------------------
#if HIL_MODE != HIL_MODE_DISABLED// update hil before ahrs updategcs().update_receive();gcs().update_send();
#endif// we tell AHRS to skip INS update as we have already done it in fast_loop()ahrs.update(true);
}

1.3 对象ahrs说明

在 Copter.h 中,我们用 AP_AHRS_NavEKF 类定义了 ahrs 对象。

AP_AHRS_NavEKF ahrs{EKF2, EKF3, AP_AHRS_NavEKF::FLAG_ALWAYS_USE_EKF};

2 AP_AHRS_NavEKF.cpp

2.1 void AP_AHRS_NavEKF::update(bool skip_ins_update)

所以,我们在跳转 update() 这个成员函数的时候,跳转到 AP_AHRS_NavEKF 类的 update() 函数。

根据 AHRS_EKF_TYPE = 3,我们运行 update_EKF3()

void AP_AHRS_NavEKF::update(bool skip_ins_update)
{...if (_ekf_type == 2) {// if EK2 is primary then run EKF2 first to give it CPU// priorityupdate_EKF2();update_EKF3();} else {// otherwise run EKF3 firstupdate_EKF3();update_EKF2();}...
}

2.2 void AP_AHRS_NavEKF::update_EKF3(void)

更新 EKF3

void AP_AHRS_NavEKF::update_EKF3(void)
{...if (_ekf3_started) {EKF3.UpdateFilter();...}
}

2.3 对象EKF3说明

在 AP_AHRS_NavEKF.h 中,我们用 NavEKF3 类定义了 EKF3 对象。

NavEKF3 &EKF3;

3 AP_NavEKF3.cpp

3.1 void IRAM_ATTR NavEKF3::UpdateFilter(void)

所以,我们在跳转 UpdateFilter() 这个成员函数的时候,跳转到 NavEKF3 类的 UpdateFilter() 函数。

更新滤波器状态 - 只要有新的 IMU 数据,就应调用该函数。

// Update Filter States - this should be called whenever new IMU data is available
void IRAM_ATTR NavEKF3::UpdateFilter(void)
{if (!core) {return;}imuSampleTime_us = AP_HAL::micros64();const AP_InertialSensor &ins = AP::ins();bool statePredictEnabled[num_cores];for (uint8_t i=0; i<num_cores; i++) {// if we have not overrun by more than 3 IMU frames, and we// have already used more than 1/3 of the CPU budget for this// loop then suppress the prediction step. This allows// multiple EKF instances to cooperate on schedulingif (core[i].getFramesSincePredict() < (_framesPerPrediction+3) &&(AP_HAL::micros() - ins.get_last_update_usec()) > _frameTimeUsec/3) {statePredictEnabled[i] = false;} else {statePredictEnabled[i] = true;}core[i].UpdateFilter(statePredictEnabled[i]);}...
}

3.2 对象core说明

在 AP_NavEKF3.h 中,我们用 NavEKF3_core 类定义了 core 对象。

NavEKF3_core *core = nullptr;

4 AP_NavEKF3_core.cpp

4.1 void IRAM_ATTR NavEKF3_core::UpdateFilter(bool predict)

所以,我们在跳转 UpdateFilter() 这个成员函数的时候,跳转到 NavEKF3_core 类的 UpdateFilter() 函数。

如果缓冲区中有新的 IMU 数据,则运行 EKF 方程,在融合时间跨度上进行估算。

/********************************************************
*                 UPDATE FUNCTIONS                      *
********************************************************/
// Update Filter States - this should be called whenever new IMU data is available
void IRAM_ATTR NavEKF3_core::UpdateFilter(bool predict)
{...// Check arm status and perform required checks and mode changescontrolFilterModes();...// Run the EKF equations to estimate at the fusion time horizon if new IMU data is available in the bufferif (runUpdates) {// Predict states using IMU data from the delayed time horizonUpdateStrapdownEquationsNED();// Predict the covariance growthCovariancePrediction();// Update states using  magnetometer or external yaw sensor dataSelectMagFusion();// Update states using GPS and altimeter dataSelectVelPosFusion();// Update states using range beacon dataSelectRngBcnFusion();// Update states using optical flow dataSelectFlowFusion();// Update states using body frame odometry dataSelectBodyOdomFusion();// Update states using airspeed dataSelectTasFusion();// Update states using sideslip constraint assumption for fly-forward vehiclesSelectBetaFusion();// Update the filter statusupdateFilterStatus();}...
}

这里有两个函数和 EKF3 使用光流传感器有关:controlFilterModes()SelectFlowFusion()

5 AP_NavEKF3_Control.cpp

5.1 void NavEKF3_core::controlFilterModes()

控制滤波器模式转换。

// Control filter mode transitions
void NavEKF3_core::controlFilterModes()
{...// Set the type of inertial navigation aiding usedsetAidingMode();...
}

5.2 void NavEKF3_core::setAidingMode()

设置所使用的惯性导航辅助类型。

我们把飞控连接 QGC,小喇叭会不断的弹出“...stopped aiding”和“...started relative aiding”消息。

根据 AidingMode 的枚举定义,分为三种情况。

1、AID_ABSOLUTE = 0;正在使用 GPS 或其他形式的绝对位置参考辅助(也可同时使用光流),因此位置估算是绝对的。

2、AID_NONE = 1;不使用辅助,因此只有姿态和高度估计值。必须使用 constVelModeconstPosMode 来限制倾斜漂移。

3、AID_RELATIVE = 2;只使用光流辅助,因此位置估算值将是相对的。

这里,如果光流传感器数据良好,我们运行 AID_RELATIVE;如果光流数据较差或没有,我们运行 AID_NONE

// Set inertial navigation aiding mode
void NavEKF3_core::setAidingMode()
{...// 检查我们是否开始或停止援助,并根据需要设置状态和模式// check to see if we are starting or stopping aiding and set states and modes as requiredif (PV_AidingMode != PV_AidingModePrev) {// set various usage modes based on the condition when we start aiding. These are then held until aiding is stopped.switch (PV_AidingMode) {case AID_NONE:// We have ceased aidinggcs().send_text(MAV_SEVERITY_WARNING, "EKF3 IMU%u stopped aiding",(unsigned)imu_index);// When not aiding, estimate orientation & height fusing synthetic constant position and zero velocity measurement to constrain tilt errors// 无辅助时,利用合成恒定位置和零速度测量来估计方位和高度,以限制倾斜误差...case AID_RELATIVE:// We are doing relative position navigation where velocity errors are constrained, but position drift will occur// 我们正在进行相对位置导航,速度误差受到限制,但位置漂移会发生gcs().send_text(MAV_SEVERITY_INFO, "EKF3 IMU%u started relative aiding",(unsigned)imu_index);...
}

6 AP_NavEKF3_OptFlowFusion.cpp

6.1 void NavEKF3_core::SelectFlowFusion()

选择性融合光学流量传感器的测量。

// select fusion of optical flow measurements
void NavEKF3_core::SelectFlowFusion()
{...// 将光流数据融合到主滤波器中// Fuse optical flow data into the main filterif (flowDataToFuse && tiltOK) {if (frontend->_flowUse == FLOW_USE_NAV) {// Set the flow noise used by the fusion processesR_LOS = sq(MAX(frontend->_flowNoise, 0.05f));// Fuse the optical flow X and Y axis data into the main filter sequentiallyFuseOptFlow();}// reset flag to indicate that no new flow data is available for fusionflowDataToFuse = false;}...
}

6.2 void NavEKF3_core::FuseOptFlow()

依次将光流 X 轴和 Y 轴数据融合到主滤波器中。

首次融合光流传感器数据,会提示:"EKF3 IMU%u fusing optical flow"。

void NavEKF3_core::FuseOptFlow()
{...// notify first time onlyif (!flowFusionActive) {flowFusionActive = true;gcs().send_text(MAV_SEVERITY_INFO, "EKF3 IMU%u fusing optical flow",(unsigned)imu_index);}...
}

相关文章:

Ardupilot — EKF3使用光流室内定位代码梳理

文章目录 前言 1 Copter.cpp 1.1 void IRAM_ATTR Copter::fast_loop() 1.2 void Copter::read_AHRS(void) 1.3 对象ahrs说明 2 AP_AHRS_NavEKF.cpp 2.1 void AP_AHRS_NavEKF::update(bool skip_ins_update) 2.2 void AP_AHRS_NavEKF::update_EKF3(void) 2.3 对象EKF3说…...

【Linux】自动化构建工具 —— make/makefileLinux第一个小程序 - 进度条

​ ​&#x1f4dd;个人主页&#xff1a;Sherry的成长之路 &#x1f3e0;学习社区&#xff1a;Sherry的成长之路&#xff08;个人社区&#xff09; &#x1f4d6;专栏链接&#xff1a;Linux &#x1f3af;长路漫漫浩浩&#xff0c;万事皆有期待 上一篇博客&#xff1a;Linux编译…...

tensorflow的unet模型

import tensorflow as tf from tensorflow.keras.layers import Input, Conv2D, MaxPooling2D, Dropout, UpSampling2D, concatenate# 定义 U-Net 模型 def unet(input_size(256, 256, 3)):inputs Input(input_size)# 编码器部分conv1 Conv2D(64, 3, activationrelu, padding…...

(2023 最新版)IntelliJ IDEA 下载安装及配置教程

IntelliJ IDEA下载安装教程&#xff08;图解&#xff09; IntelliJ IDEA 简称 IDEA&#xff0c;由 JetBrains 公司开发&#xff0c;是 Java 编程语言开发的集成环境&#xff0c;具有美观&#xff0c;高效等众多特点。在智能代码助手、代码自动提示、重构、J2EE 支持、各类版本…...

react 实现拖动元素

demo使用create-react-app脚手架创建 删除一些文件&#xff0c;创建一些文件后 结构目录如下截图com/index import Movable from ./move import { useMove } from ./move.hook import * as Operations from ./move.opMovable.useMove useMove Movable.Operations Operationse…...

【EI会议】第二届声学,流体力学与工程国际学术会议(AFME 2023)

第二届声学&#xff0c;流体力学与工程国际学术会议 2023 2nd International Conference on Acoustics, Fluid Mechanics and Engineering&#xff08;AFME 2023&#xff09; 声学、流体力学两个古老的学科发展至今&#xff0c;无时无刻都在影响着我们的生活。小到日常使用的耳…...

Android StringFog 字符串自动加密

一、StringFog 作用 一款自动对dex/aar/jar文件中的字符串进行加密Android插件工具&#xff0c;正如名字所言&#xff0c;给字符串加上一层雾霭&#xff0c;使人难以窥视其真面目。可以用于增加反编译难度&#xff0c;防止字符串代码重复。 支持java/kotlin。支持app打包生成…...

上四休三,未来的期许

近日“少上一天班&#xff0c;究竟香不香”引发关注&#xff0c;英国媒体2月21日报道&#xff0c;一项全世界目前为止参加人数最多的“四天工作制”试验&#xff0c;不久前在英国取得了成功。很多人表示上过四天班之后&#xff0c;给多少钱也回不去五天班的时代了。 来百度APP畅…...

怎么防止360安全卫士修改默认浏览器?

默认的浏览器 原先选项是360极速浏览器&#xff08;如果有安装的话&#xff09;&#xff0c;我这里改成了Chrome。 先解锁 才能修改。...

调整参数提高mysql读写速度

要提升MySQL的写入速度,您可以采取一些参数调整和优化措施,这些措施可以根据您的具体应用和环境进行调整。以下是一些常见的参数和优化建议: InnoDB存储引擎: 如果您使用的是InnoDB存储引擎,确保以下参数被设置得合理: innodb_buffer_pool_size:增加内存池大小,以便更多…...

第一届电子纸产业创新应用论坛-邀请函

...

Go expvar包

介绍与使用 expvar 是 exposed variable的简写 expvar包[1]是 Golang 官方为暴露Go应用内部指标数据所提供的标准对外接口&#xff0c;可以辅助获取和调试全局变量。 其通过init函数将内置的expvarHandler(一个标准http HandlerFunc)注册到http包ListenAndServe创建的默认Serve…...

Yolo v8代码逐行解读

train.py文件 1.FILE Path(__file__).resolve() __file__代表的是train.py文件&#xff0c;Path(__file__).resolve()结果是train.py文件的绝对路径。 2.ROOT FILE.parents[0] 获得train.py父目录的绝对路径 3.sys.path 是一个列表list&#xff0c;里面包含了已经添加到系…...

9.18号作业

完善登录框 点击登录按钮后&#xff0c;判断账号&#xff08;admin&#xff09;和密码&#xff08;123456&#xff09;是否一致&#xff0c;如果匹配失败&#xff0c;则弹出错误对话框&#xff0c;文本内容“账号密码不匹配&#xff0c;是否重新登录”&#xff0c;给定两个按钮…...

Spring源码阅读(spring-framework-5.2.24)

spring-aop spring-aspects spring-beans spring-context 等等 第一步&#xff1a; Tags spring-projects/spring-framework GitHub 找到相应的release版本 第二步&#xff1a; 下载相应版本的gardle&#xff0c;如何看版本 spring-framework/gradle/wrapper /gradl…...

【SpringMVC】文件上传与下载、JREBEL使用

目录 一、引言 二、文件的上传 1、单文件上传 1.1、数据表准备 1.2、添加依赖 1.3、配置文件 1.4、编写表单 1.5、编写controller层 2、多文件上传 2.1、编写form表单 2.2、编写controller层 2.3、测试 三、文件下载 四、JREBEL使用 1、下载注册 2、离线设置 一…...

数据结构 第二章作业 线性表 西安石油大学

在顺序表中插入和删除一个结点需平均移动多少个结点&#xff1f;具体的移动次数取决于 哪两个因素&#xff1f; 在顺序表中插入和删除一个结点时&#xff0c;平均移动的结点数量取决于两个因素&#xff1a;插入/删除位置和当前顺序表的长度。 插入/删除位置&#xff1a;如果要…...

vue.mixin全局混合选项

在Vue.js中&#xff0c;Vue.mixin 是一个用来全局混合(mixin)选项的方法。它允许你在多个组件中共享相同的选项&#xff0c;例如数据、方法、生命周期钩子等。这可以用来在组件之间重复使用一些逻辑或共享一些通用的功能 Vue.mixin({// 在这里定义混合的选项data() {return {s…...

VMware Fusion 13+Ubuntu ARM Server 22.04.3在M2芯片的Mac上共享文件夹

因为Server版没有桌面&#xff0c;VMware Tools不能直接装&#xff0c;导致没办法共享文件。 Ubuntu中的包如果需要更新&#xff0c;先执行下面的步骤 sudo apt update 再执行 sudo apt upgrade 不需要更新的话&#xff0c;直接执行下面的步骤 先把open-vm-tools卸载了 …...

PostgreSQL serial类型

serial类型和序列 postgresql序列号&#xff08;SERIAL&#xff09;类型包括 smallserial&#xff08;smallint,short&#xff09;,serial(int)bigserial(bigint,long long int) 不管是smallserial,serial还是bigserial&#xff0c;其范围都是(1,9223372036854775807)&#…...

心灵鸡汤01 - 人生九不争

一、跟父母&#xff0c;不争口舌&#xff1b; 二、跟朋友&#xff0c;不争面子&#xff1b; 三、跟领导&#xff0c;不争高低&#xff1b; 四、跟小人&#xff0c;不争道理&#xff1b; 五、跟伴侣&#xff0c;不争对错&#xff1b; 六、跟亲戚&#xff0c;不争穷富&#xff1b…...

3个真实问题告诉你:DdddOcr如何成为你的免费离线验证码识别助手

3个真实问题告诉你&#xff1a;DdddOcr如何成为你的免费离线验证码识别助手 【免费下载链接】ddddocr 带带弟弟 通用验证码识别OCR pypi版 项目地址: https://gitcode.com/gh_mirrors/dd/ddddocr 当你在自动化测试、数据采集或系统集成中遇到验证码时&#xff0c;是否曾…...

免费公式识别神器:img2latex-mathpix本地部署完全指南

免费公式识别神器&#xff1a;img2latex-mathpix本地部署完全指南 【免费下载链接】img2latex-mathpix Mathpix has changed their billing policy and no longer has free monthly API requests. This repo is now archived and will not receive any updates for the foresee…...

别再让Future.get()拖慢你的并发程序!手把手教你用CompletionService优化Java任务结果获取

解锁Java并发新姿势&#xff1a;CompletionService如何让任务结果获取效率翻倍 想象一下这样的场景&#xff1a;你精心设计的线程池正在处理一批耗时各异的任务&#xff0c;有的像闪电般完成&#xff0c;有的却像老牛拉车。当你用Future.get()逐个获取结果时&#xff0c;系统却…...

ARM A64指令集架构解析与优化实践

1. A64指令集架构概述A64指令集作为ARMv8-A架构的64位执行状态核心&#xff0c;采用固定32位长度编码设计&#xff0c;这种设计在指令获取和流水线处理上具有显著优势。与传统的变长指令集相比&#xff0c;固定长度编码使得指令预取和译码阶段更加高效&#xff0c;尤其适合现代…...

从‘幂的末尾’到RSA加密:一个模运算技巧如何贯穿编程竞赛与网络安全?

从竞赛编程到网络安全&#xff1a;模运算的双面人生 第一次在OpenJudge上遇到"幂的末尾"这道题时&#xff0c;我盯着屏幕上的数字发愣——计算a^b的最后三位数&#xff0c;这不就是求a^b模1000的结果吗&#xff1f;当时的我并不知道&#xff0c;这个看似简单的数学技…...

PDF顺手编辑器工具

版式文件编辑器是一款支持PDF和OFD 文件处理工具&#xff0c;可在任何网络下使用。软件完全免费&#xff0c;无广告零弹窗&#xff0c;而且资源占用极小。软件广泛应用在党、政、军及企事业单位中&#xff0c;适合电子公文、证照、票据等领域&#xff0c;应用范围非常广。为啥用…...

内容可寻址存储器(CAM)原理与创新设计解析

1. 内容可寻址存储器基础解析在传统计算机架构中&#xff0c;我们通常使用随机存取存储器&#xff08;RAM&#xff09;通过地址来访问数据。但有一种特殊的存储结构打破了这种范式——内容可寻址存储器&#xff08;Content-Addressable Memory, CAM&#xff09;。它的独特之处在…...

从PC到移动:DRAM市场如何从周期性震荡走向结构性稳定

1. DRAM市场格局的深层演变&#xff1a;从周期性震荡到结构性稳定干了十几年硬件设计和供应链的活儿&#xff0c;我算是亲眼见证了DRAM这个行当的“过山车”行情。早些年&#xff0c;跟同行聊起内存&#xff0c;大家第一反应都是“又涨了&#xff1f;”或者“崩盘了&#xff1f…...

Sora 2生成素材在AE中频繁掉帧?20年合成老炮儿用CUDA Graph重构图层管线,性能提升3.8倍(含Profile对比图)

更多请点击&#xff1a; https://intelliparadigm.com 第一章&#xff1a;Sora 2生成素材在AE中频繁掉帧&#xff1f;20年合成老炮儿用CUDA Graph重构图层管线&#xff0c;性能提升3.8倍&#xff08;含Profile对比图&#xff09; 当Sora 2输出的4K/60fps高动态范围视频序列导入…...