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

news2024/11/15 5:10:16

文章目录

前言

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 update
    gcs().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
        // priority
        update_EKF2();
        update_EKF3();
    } else {
        // otherwise run EKF3 first
        update_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 scheduling
        if (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 changes
    controlFilterModes();
    ...

    // Run the EKF equations to estimate at the fusion time horizon if new IMU data is available in the buffer
    if (runUpdates) {
        // Predict states using IMU data from the delayed time horizon
        UpdateStrapdownEquationsNED();

        // Predict the covariance growth
        CovariancePrediction();

        // Update states using  magnetometer or external yaw sensor data
        SelectMagFusion();

        // Update states using GPS and altimeter data
        SelectVelPosFusion();

        // Update states using range beacon data
        SelectRngBcnFusion();

        // Update states using optical flow data
        SelectFlowFusion();

        // Update states using body frame odometry data
        SelectBodyOdomFusion();

        // Update states using airspeed data
        SelectTasFusion();

        // Update states using sideslip constraint assumption for fly-forward vehicles
        SelectBetaFusion();

        // Update the filter status
        updateFilterStatus();
    }
    ...
}

这里有两个函数和 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 used
    setAidingMode();
    ...
}

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 required
    if (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 aiding
            gcs().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 filter
    if (flowDataToFuse && tiltOK) {
        if (frontend->_flowUse == FLOW_USE_NAV) {
            // Set the flow noise used by the fusion processes
            R_LOS = sq(MAX(frontend->_flowNoise, 0.05f));
            // Fuse the optical flow X and Y axis data into the main filter sequentially
            FuseOptFlow();
        }
        // reset flag to indicate that no new flow data is available for fusion
        flowDataToFuse = false;
    }
    ...
}

6.2 void NavEKF3_core::FuseOptFlow()

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

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

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

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

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

相关文章

LeetCode【27. 移除元素】

为国捐躯赴战场&#xff0c;丹心可并日争光。 给你一个数组 nums 和一个值 val&#xff0c;你需要 原地 移除所有数值等于 val 的元素&#xff0c;并返回移除后数组的新长度。 不要使用额外的数组空间&#xff0c;你必须仅使用 O(1) 额外空间并 原地 修改输入数组。 元素的顺…

[面试] 15道最典型的k8s面试题

文章目录 在 Kubernetes 中&#xff0c;有以下常见的资源对象&#xff1a;1.什么是 Kubernetes&#xff1f;它的主要特点是什么&#xff1f;2. Kubernetes 中的 Pod 是什么&#xff1f;它的作用是什么&#xff1f;3.Kubernetes 中的 Deployment 和 StatefulSet 有何区别&#x…

无涯教程-JavaScript - MATCH函数

描述 MATCH函数在单元格范围内搜索指定的项目,然后返回该项目在该范围内的相对位置。 当您需要某个项目在范围中的位置而不是项目本身时,请使用MATCH而不是LOOKUP函数之一。如。您可以使用MATCH函数为INDEX函数的row_num参数提供一个值。 语法 MATCH (lookup_value, lookup…

【送书活动】大模型赛道如何实现华丽的弯道超车

文章目录 导读前言AI/ML 模型训练任务对数据平台的需求01 具备对海量小文件的频繁数据访问的 I/O 效率02 提高 GPU 利用率&#xff0c;降低成本并提高投资回报率03 支持各种存储系统的原生接口04 支持单云、混合云和多云部署 核心密码01 通过数据抽象化统一数据孤岛02 通过分布…

Linux命令200例:apt-get软件包管理工具的使用

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌。CSDN专家博主&#xff0c;阿里云社区专家博主&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师&#xff0…

一文带你了解2023年最新央企名单、业务和管理机构(附资料)

前两天有个朋友留言问华研荟关于国企和央企的问题&#xff0c;他说经常在电视或网上看到国企、央企的表述&#xff0c;这两个的区别是什么&#xff1f;国企不都是国家所有吗&#xff1f;为什么还要有央企一说呢&#xff1f; 今天华研荟就来带大家了解一下两者的区别&#xff0…

RISC-V Reader 笔记(六)RV32V

RV32V 早期并行数据计算&#xff1a;采用 SIMD 单指令多数据&#xff0c;把一个64位宽寄存器拆成若干个32 16 8 位长度部分并行计算。这种方法前期看起来十分简单诱人。但是后来如果要扩展 SIMD 寄存器宽度&#xff0c;也要复杂化指令集&#xff0c;复杂开销越来越大。 向量操作…

【微服务】六. Nacos配置管理

6.1 Nacos实现配置管理 配置更改热更新 在nacos左侧新建配置管理 Data ID&#xff1a;就是配置文件名称 一般命名规则&#xff1a;服务名称-环境名称.yaml 配置内容填写&#xff1a;需要热更新需求的配置 配置文件的id&#xff1a;[服务名称]-[profile].[后缀名] 分组&#…

启用新的精细服务权限来更好地控制账单、成本管理和账户服务的访问权限

12 月 11 日&#xff0c;亚马逊云科技将在服务前缀 aws-portal 下停用账单、成本管理和账户控制台&#xff08;https://docs.amazonaws.cn/en_us/service-authorization/latest/reference/list_awsbillingconsole.html&#xff09;的 Amazon Identity and Access Management&am…

LeetCode-热题100-笔记-day29

199. 二叉树的右视图https://leetcode.cn/problems/binary-tree-right-side-view/ 给定一个二叉树的 根节点 root&#xff0c;想象自己站在它的右侧&#xff0c;按照从顶部到底部的顺序&#xff0c;返回从右侧所能看到的节点值。 示例 1: 输入: [1,2,3,null,5,null,4] 输出: [1…

音乐网站设计与实现

目 录 摘要 Abstract 1、引言 1.1 课题的目的和意义 1.2 国内现状分析 2、可行性研究与需求分析 2.1 可行性研究 2.1.1 经济可行性 2.1.2 技术可行性 2.1.3 运行可行性 2.1.4 时间可行性 2.1.5 法律可行性 2.2 需求分析 2.2.1 系统需求 2.2.2 …

如何让两台手机相互远程控制?

你的两台手机是什么系统的&#xff1f;如果你的两台手机都是安卓系统&#xff0c;而且都是安卓7.0及以上版本的系统&#xff0c;那么恭喜你&#xff0c;这两台手机可以相互远程控制&#xff01; 你可以利用两个软件实现将两台手机相互远程控制的想法。为了避免混淆&#xff0c…

中小企业建设数字化工厂,选择集成还是重构

随着科技的飞速发展和市场竞争的日益激烈&#xff0c;数字化工厂管理系统已成为中小企业未来发展的必经之路。然而&#xff0c;对于许多中小企业来说&#xff0c;建设数字化工厂并非易事。在建设数字化工厂的过程中&#xff0c;企业需要面对许多问题&#xff0c;其中最关键的问…

Git:Git的一些基本操作

文章目录 基本认识使用方法创建本地仓库配置本地仓库 工作区、暂存区、版本库的概念添加文件版本回退撤销修改删除操作 基本认识 首先要对Git有一个基本的认知&#xff1a; Git本质上是一个版本控制器&#xff0c;可以对一个信息的多个版本进行一些控制&#xff0c;而能对版本…

牛客: BM6 判断链表中是否有环

牛客: BM6 判断链表中是否有环 文章目录 牛客: BM6 判断链表中是否有环题目描述题解思路题解代码 题目描述 题解思路 一个慢指针,每次跳一次,一个快指针,每次跳两次,如果快指针遍历到链表终点,则链表无环,若慢指针和快指针相遇,则链表有环 题解代码 package main import . &…

MySQL基础运维知识点大全

一. MySQL基本知识 1. 目录的功能 通用 Unix/Linux 二进制包的 MySQL 安装下目录的相关功能 目录目录目录binMySQLd服务器&#xff0c;客户端和实用程序docs信息格式的 MySQL 手册manUnix 手册页include包括&#xff08;头&#xff09;文件lib图书馆share用于数据库安装的错…

第二章 进程与线程 四、进程通信

目录 一、共享存储 1、基于数据结构的共享 2、基于存储区的共享 二、消息传递 1、直接通信方式&#xff08;消息发送进程要指明接收进程的ID&#xff09; 2、间接通信方式&#xff08;通过“信箱”间接地通信。因此又称“信箱通信方式”&#xff09; 三、管道通信 注意&…

postgresql-视图

postgresql-视图 视图概述使用视图的好处 创建视图修改视图删除视图递归视图可更新视图WITH CHECK OPTION 视图概述 视图&#xff08;View&#xff09;本质上是一个存储在数据库中的查询语句。视图本身不包含数据&#xff0c;也被称为 虚拟表。我们在创建视图时给它指定了一个…

MySQL的sql_mode合理设置

MySQL的sql_mode合理设置 1、sql_mode设置介绍说明 sql_mode是个很容易被忽视的变量&#xff0c;默认值是空值&#xff0c;在这种设置下是可以允许一些非法操作的&#xff0c;比如允许一些非法数据的插入。在生产环境必须将这个值设置为严格模式&#xff0c;所以开发、测试环…

Linux系统——远程连接Linux系统(图形化、命令行、使用命令行学习Linux系统、FinalShell)

目录 图形化、命令行 使用命令行学习Linux系统 FinalShell 安装 连接 图形化、命令行 对于操作系统的使用&#xff0c;有2种使用形式&#xff1a; 图形化页面使用操作系统以命令的形式使用操作系统 不论是Windows还是Linux亦或是MacOS系统&#xff0c;都是支持这两种使…