Ardupilot — EKF3使用光流室内定位代码梳理
文章目录
前言
1 Copter.cpp
1.1 void IRAM_ATTR Copter::fast_loop()
1.2 void Copter::read_AHRS(void)
1.3 对象ahrs说明
2.3 对象EKF3说明
3.2 对象core说明
前言
故事的开始,要从参数 EK3_FLOW_USE 说起。
注意:该参数适用于高级用户。
控制是否将光流数据融合到 24 状态导航估算器或 1 状态地形高度估算器中。
RebootRequired | Values | ||||||||
---|---|---|---|---|---|---|---|---|---|
True |
|
本文主要梳理一下,在旋翼中 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;不使用辅助,因此只有姿态和高度估计值。必须使用 constVelMode 或 constPosMode 来限制倾斜漂移。
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第一个小程序 - 进度条
📝个人主页:Sherry的成长之路 🏠学习社区:Sherry的成长之路(个人社区) 📖专栏链接:Linux 🎯长路漫漫浩浩,万事皆有期待 上一篇博客: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下载安装教程(图解) IntelliJ IDEA 简称 IDEA,由 JetBrains 公司开发,是 Java 编程语言开发的集成环境,具有美观,高效等众多特点。在智能代码助手、代码自动提示、重构、J2EE 支持、各类版本…...

react 实现拖动元素
demo使用create-react-app脚手架创建 删除一些文件,创建一些文件后 结构目录如下截图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)
第二届声学,流体力学与工程国际学术会议 2023 2nd International Conference on Acoustics, Fluid Mechanics and Engineering(AFME 2023) 声学、流体力学两个古老的学科发展至今,无时无刻都在影响着我们的生活。小到日常使用的耳…...

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

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

怎么防止360安全卫士修改默认浏览器?
默认的浏览器 原先选项是360极速浏览器(如果有安装的话),我这里改成了Chrome。 先解锁 才能修改。...
调整参数提高mysql读写速度
要提升MySQL的写入速度,您可以采取一些参数调整和优化措施,这些措施可以根据您的具体应用和环境进行调整。以下是一些常见的参数和优化建议: InnoDB存储引擎: 如果您使用的是InnoDB存储引擎,确保以下参数被设置得合理: innodb_buffer_pool_size:增加内存池大小,以便更多…...

Go expvar包
介绍与使用 expvar 是 exposed variable的简写 expvar包[1]是 Golang 官方为暴露Go应用内部指标数据所提供的标准对外接口,可以辅助获取和调试全局变量。 其通过init函数将内置的expvarHandler(一个标准http HandlerFunc)注册到http包ListenAndServe创建的默认Serve…...
Yolo v8代码逐行解读
train.py文件 1.FILE Path(__file__).resolve() __file__代表的是train.py文件,Path(__file__).resolve()结果是train.py文件的绝对路径。 2.ROOT FILE.parents[0] 获得train.py父目录的绝对路径 3.sys.path 是一个列表list,里面包含了已经添加到系…...

9.18号作业
完善登录框 点击登录按钮后,判断账号(admin)和密码(123456)是否一致,如果匹配失败,则弹出错误对话框,文本内容“账号密码不匹配,是否重新登录”,给定两个按钮…...
Spring源码阅读(spring-framework-5.2.24)
spring-aop spring-aspects spring-beans spring-context 等等 第一步: Tags spring-projects/spring-framework GitHub 找到相应的release版本 第二步: 下载相应版本的gardle,如何看版本 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、离线设置 一…...

数据结构 第二章作业 线性表 西安石油大学
在顺序表中插入和删除一个结点需平均移动多少个结点?具体的移动次数取决于 哪两个因素? 在顺序表中插入和删除一个结点时,平均移动的结点数量取决于两个因素:插入/删除位置和当前顺序表的长度。 插入/删除位置:如果要…...
vue.mixin全局混合选项
在Vue.js中,Vue.mixin 是一个用来全局混合(mixin)选项的方法。它允许你在多个组件中共享相同的选项,例如数据、方法、生命周期钩子等。这可以用来在组件之间重复使用一些逻辑或共享一些通用的功能 Vue.mixin({// 在这里定义混合的选项data() {return {s…...

VMware Fusion 13+Ubuntu ARM Server 22.04.3在M2芯片的Mac上共享文件夹
因为Server版没有桌面,VMware Tools不能直接装,导致没办法共享文件。 Ubuntu中的包如果需要更新,先执行下面的步骤 sudo apt update 再执行 sudo apt upgrade 不需要更新的话,直接执行下面的步骤 先把open-vm-tools卸载了 …...
PostgreSQL serial类型
serial类型和序列 postgresql序列号(SERIAL)类型包括 smallserial(smallint,short),serial(int)bigserial(bigint,long long int) 不管是smallserial,serial还是bigserial,其范围都是(1,9223372036854775807)&#…...

CTF show Web 红包题第六弹
提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框,很难让人不联想到SQL注入,但提示都说了不是SQL注入,所以就不往这方面想了 先查看一下网页源码,发现一段JavaScript代码,有一个关键类ctfs…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

Ascend NPU上适配Step-Audio模型
1 概述 1.1 简述 Step-Audio 是业界首个集语音理解与生成控制一体化的产品级开源实时语音对话系统,支持多语言对话(如 中文,英文,日语),语音情感(如 开心,悲伤)&#x…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信
文章目录 Linux C语言网络编程详细入门教程:如何一步步实现TCP服务端与客户端通信前言一、网络通信基础概念二、服务端与客户端的完整流程图解三、每一步的详细讲解和代码示例1. 创建Socket(服务端和客户端都要)2. 绑定本地地址和端口&#x…...
在Ubuntu24上采用Wine打开SourceInsight
1. 安装wine sudo apt install wine 2. 安装32位库支持,SourceInsight是32位程序 sudo dpkg --add-architecture i386 sudo apt update sudo apt install wine32:i386 3. 验证安装 wine --version 4. 安装必要的字体和库(解决显示问题) sudo apt install fonts-wqy…...

RSS 2025|从说明书学习复杂机器人操作任务:NUS邵林团队提出全新机器人装配技能学习框架Manual2Skill
视觉语言模型(Vision-Language Models, VLMs),为真实环境中的机器人操作任务提供了极具潜力的解决方案。 尽管 VLMs 取得了显著进展,机器人仍难以胜任复杂的长时程任务(如家具装配),主要受限于人…...