ArduPilot开源飞控之AP_AHRS

ArduPilot开源飞控之AP_AHRS

  • 1. 源由
  • 2. 框架设计
    • 2.1 启动代码
    • 2.2 任务代码
  • 3. 重要例程
    • 3.1 init
    • 3.2 update
  • 4. 外部AHRS传感模块
    • 4.1 init
    • 4.2 update
  • 5. 参考资料

1. 源由

AHRS(Attitude Heading Reference System): 飞控最为重要的一个任务就是姿态、位置、方向计算。

本章节,将从代码层面研读下AP_AHRS的整体框架和设计逻辑。

其中AHRS可以分成两块内容:

  1. 依赖内部sensor的AHRS,详见ArduPilot开源代码之AP_InertialSensor
  2. 外部AHRS传感器

但是最终汇聚到数据算法处理的是AP_AHRS

2. 框架设计

2.1 启动代码

Copter::init_ardupilot└──> Copter::startup_INS_ground└──> AP_AHRS::init

2.2 任务代码

FAST_TASK(read_AHRS)└──> Copter::read_AHRS└──> AP_AHRS::update

3. 重要例程

3.1 init

模块初始化例程:

  1. EKF算法类型选择(目前不再支持EKF1);
  2. DCM & EXTERNAL_AHRS初始化;
  3. 自定义板子方向初始化;
// init sets up INS board orientation
void AP_AHRS::init()││  /********************************************************************************│   * EKF1 is no longer supported - handle case where it is selected               *│   ********************************************************************************/├──> <_ekf_type.get() == 1>│   └──> AP_BoardConfig::config_error("EKF1 not available")├──> <_ekf_type.get() == 2>  //!HAL_NAVEKF2_AVAILABLE && HAL_NAVEKF3_AVAILABLE│   ├──> _ekf_type.set(3)│   └──> EKF3.set_enable(true)├──> <_ekf_type.get() == 3>  //!HAL_NAVEKF3_AVAILABLE && HAL_NAVEKF2_AVAILABLE│   ├──> _ekf_type.set(2)│   └──> EKF2.set_enable(true)├──> <HAL_NAVEKF2_AVAILABLE && HAL_NAVEKF3_AVAILABLE> <_ekf_type.get() == 2 && !EKF2.get_enable() && EKF3.get_enable()>│  // a special case to catch users who had AHRS_EKF_TYPE=2 saved and│  // updated to a version where EK2_ENABLE=0│   └──> _ekf_type.set(3)││  /********************************************************************************│   * DCM & external AHRS init                                                     *│   ********************************************************************************/├──> last_active_ekf_type = (EKFType)_ekf_type.get()├──> <AP_AHRS_DCM_ENABLED>│   └──> _dcm.init() // init backends├──> <HAL_EXTERNAL_AHRS_ENABLED>│   └──> external.init()││  /********************************************************************************│   * convert to new custom rotaton, PARAMETER_CONVERSION - Added: Nov-2021        *│   ********************************************************************************/└──> <!APM_BUILD_TYPE(APM_BUILD_AP_Periph><_board_orientation == ROTATION_CUSTOM_OLD>├──> _board_orientation.set_and_save(ROTATION_CUSTOM_1)├──> AP_Param::ConversionInfo info├──> <AP_Param::find_top_level_key_by_pointer(this, info.old_key)>│   ├──> info.type = AP_PARAM_FLOAT│   └──> <for (info.old_group_element=15 info.old_group_element<=17 info.old_group_element++)> <AP_Param::find_old_parameter(&info, &rpy_param)>│        └──> rpy[info.old_group_element-15] = rpy_param.get()└──> AP::custom_rotations().convert(ROTATION_CUSTOM_1, rpy[0], rpy[1], rpy[2])

3.2 update

AHRS更新过程:

  1. 配置及传感数据更新;
  2. EKF算法运算更新;
AP_AHRS::update││  // periodically checks to see if we should update the AHRS│  // orientation (e.g. based on the AHRS_ORIENTATION parameter)│  // allow for runtime change of orientation│  // this makes initial config easier│  /********************************************************************************│   * Configuration and sensor update                                              *│   ********************************************************************************/├──> update_orientation()├──> <!skip_ins_update>│   └──> AP::ins().update()  // tell the IMU to grab some data├──> WITH_SEMAPHORE(_rsem) // support locked access functions to AHRS data├──> <!_checked_watchdog_home>│   ├──> load_watchdog_home()  // see if we have to restore home after a watchdog reset:│   └──> _checked_watchdog_home = true││  // drop back to normal priority if we were boosted by the INS│  // calling delay_microseconds_boost()├──> hal.scheduler->boost_end()││  // update autopilot-body-to-vehicle-body from _trim parameters:├──> update_trim_rotation_matrices()│├──> <AP_AHRS_DCM_ENABLED>│   └──> update_DCM()││  // update takeoff/touchdown flags├──> update_flags()│├──> <AP_AHRS_SIM_ENABLED>│   └──> update_SITL()│├──> <HAL_EXTERNAL_AHRS_ENABLED>│   └──> update_external()││  /********************************************************************************│   * EKFx update                                                                  *│   ********************************************************************************/├──> <_ekf_type == 2>  // if EK2 is primary then run EKF2 first to give it CPU priority│   ├──> <HAL_NAVEKF2_AVAILABLE> update_EKF2()│   └──> <HAL_NAVEKF3_AVAILABLE> update_EKF3()├──> < else > // otherwise run EKF3 first│   ├──> HAL_NAVEKF3_AVAILABLE> update_EKF3()│   └──> <HAL_NAVEKF2_AVAILABLE> update_EKF2()├──> <AP_MODULE_SUPPORTED> // call AHRS_update hook if any│   └──> AP_Module::call_hook_AHRS_update(*this)│├──> <hal.opticalflow> // push gyros if optical flow present│   ├──> const Vector3f &exported_gyro_bias = get_gyro_drift()│   └──> hal.opticalflow->push_gyro_bias(exported_gyro_bias.x, exported_gyro_bias.y)│├──> <_view != nullptr> // update optional alternative attitude view│   └──> _view->update()│├──> update_AOA_SSA()  // update AOA and SSA││  /********************************************************************************│   * GCS notification                                                             *│   ********************************************************************************/├──> <HAL_GCS_ENABLED>│   ├──> state.active_EKF = _active_EKF_type()│   ├──> <state.active_EKF != last_active_ekf_type>│   │   ├──> last_active_ekf_type = state.active_EKF│   │   ├──> const char *shortname = "???"│   │   ├──> <case EKFType::DCM> <AP_AHRS_DCM_ENABLED>│   │   │   └──> shortname = "DCM"│   │   ├──> <case EKFType::SIM> <AP_AHRS_SIM_ENABLED>│   │   │   └──> shortname = "SIM"│   │   ├──> <case EKFType::EXTERNAL> <HAL_EXTERNAL_AHRS_ENABLED>│   │   │   └──> shortname = "External"│   │   ├──> <case EKFType::THREE> <HAL_NAVEKF3_AVAILABLE>│   │   │   └──> shortname = "EKF3"│   │   └──> <case EKFType::TWO> <HAL_NAVEKF2_AVAILABLE>│   │       └──> shortname = "EKF2"│   └──> GCS_SEND_TEXT(MAV_SEVERITY_INFO, "AHRS: %s active", shortname)│├──> update_state()  // update published state││  /********************************************************************************│   * add timing jitter to simulate slow EKF response                              *│   ********************************************************************************/└──> <CONFIG_HAL_BOARD == HAL_BOARD_SITL> //├──> const auto *sitl = AP::sitl()└──> <sitl->loop_time_jitter_us > 0>└──> hal.scheduler->delay_microseconds(random() % sitl->loop_time_jitter_us)

4. 外部AHRS传感模块

启动调用关系:

Copter::init_ardupilot└──> Copter::startup_INS_ground└──> AP_AHRS::init└──> AP_ExternalAHRS::init

循环更新关系

FAST_TASK(read_AHRS)└──> Copter::read_AHRS└──> AP_AHRS::update└──> AP_ExternalAHRS::update

4.1 init

支持以下两种类型:

  • AP_ExternalAHRS_VectorNav
  • AP_ExternalAHRS_MicroStrain5
AP_ExternalAHRS::init├──> <rate.get() < 50>│   └──> rate.set(50)  // min 50Hz├──> <case DevType::None>│   └──> return  // nothing to do├──> <case DevType::VecNav> <AP_EXTERNAL_AHRS_VECTORNAV_ENABLED>│   ├──> backend = new AP_ExternalAHRS_VectorNav(this, state)│   └──> return├──> <case DevType::MicroStrain5> <AP_EXTERNAL_AHRS_MICROSTRAIN5_ENABLED>│   ├──> backend = new AP_ExternalAHRS_MicroStrain5(this, state)│   └──> return└──> GCS_SEND_TEXT(MAV_SEVERITY_INFO, "Unsupported ExternalAHRS type %u", unsigned(devtype))

4.2 update

接下去又是front-end / back-end分层设计,本章节不再展开。

void AP_ExternalAHRS::update(void)└──> <backend>└──> backend->update()

5. 参考资料

【1】ArduPilot开源飞控系统之简单介绍
【2】ArduPilot之开源代码Task介绍
【3】ArduPilot飞控启动&运行过程简介
【4】ArduPilot之开源代码Library&Sketches设计
【5】ArduPilot之开源代码Sensor Drivers设计

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

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

相关文章

有趣的 scanf()

限制接收内容 这里的意思是直接收a、b、c作为ch的内容&#xff0c;遇到其它字符放入缓冲区中。 【scanf("%[...]",ch);只接收[]中的内容作为字符串的内容,将其它的内容放入缓冲区中】 这里将aaa后面的h放入缓冲区&#xff0c;但是没有抛弃掉&#xff0c;故而无法接收…

unity 实现拖动ui填空,并判断对错

参考&#xff1a;https://ask.csdn.net/questions/7971448 根据自己的需求修改为如下代码 使用过程中&#xff0c;出现拖动ui位置错误的情况&#xff0c;修改为使用 localPosition 但是吸附到指定位置却需要用的position public class DragAndDrop : MonoBehaviour, IBeginDr…

如何使用C/C++刷新在终端上已经打印的内容

写本文的起源是因为在安装一些工具的时候&#xff0c;发现在终端上并行安装的情况下&#xff0c;显示安装信息是会修改之前已经打印出来的内容&#xff0c;这是怎么做到的呢&#xff1f;抱着对这个问题的好奇我进行了一些探索。 终端是如何运行的 首先是最关键的问题&#xf…

算法通过村第十四关-堆|青铜笔记|堆结构

文章目录 前言堆的概念和特征堆的构成过程插入操作删除操作总结 前言 若执于空&#xff0c;空亦为障。 --彼得马西森《雪豹》 堆结构是一种非常重要的基础数据结构&#xff0c;也是算法的重要内容&#xff0c;很多题目甚至只能通过用堆来进行&#xff0c;所以我们必须明确什么类…

运维 | 如何在 Centos7.x 上安装 telnet 命令行工具

运维 | 如何在 Centos7.x 上安装 telnet 命令行工具 简介 Telnet 是用于通过TCP/IP网络远程登录计算机的协议。一旦与远程计算机建立了连接&#xff0c;它就会成为一个虚拟终端且允许你与远程计算机通信 快速安装 检测是否安装 rpm -qa telnet-server rpm -qa telnet执行安…

centos-apache-简易搭建静态网页服务器-总结

文章目录 1.XShell2.使用命令安装启动服务器3.上传静态文件4.配置文件5.总结 1.XShell 使用命令行工具连接目标CentOS服务器&#xff1a; 2.使用命令安装启动服务器 使用时注意不要复制注释&#xff08;#符号后面&#xff09; yum install httpd #安装 systemctl start htt…

android 与 flutter 之间的通信

文章目录 前言集成 flutter 混合开发android 与 flutter 之间的通信总结 一、前言 因为flutter 具有跨平台的属性&#xff0c;既可以在android上跑&#xff0c;也能在ios 上跑&#xff0c;所以为了节约开发的成本&#xff0c;减少人力&#xff0c;势必就会用到它。然而已有的…

Matlab地理信息绘图—数据诊断

文章目录 数据诊断分析&#xff08;均值方差&#xff09;Matlab代码实现结果展示 数据诊断分析&#xff08;均值方差&#xff09; 均值方差检测是一种简单但有效的异常检测方法&#xff0c;主要基于样本的均值和方差的统计信息。该方法的核心思想是假设正常的样本点应该聚集在…

Anaconda常用命令整理

概要 Anaconda常用命令整理 命令 1. 创建虚拟环境 conda create -n your_env_name pythonx.x # 在创建环境的同时安装必要的包 conda create -n your_env_name numpy matplotlib pythonx.x # 在指定的虚拟环境中安装额外的包 conda install -n your_env_name package_name 2…

CNN-generated images are surprisingly easy to spot... for now

CNN-generated images are surprisingly easy to spot… for now----《目前CNN生成的图像非常容易被发现》 背景&#xff1a; 研究者们发现&#xff0c;仅仅对一种由CNN模型生成的图像进行训练的分类器&#xff0c;也可以检测许多其他模型生成的结果。由此提出这样的观点&#…

中华人民共和国网络安全法

中华人民共和国网络安全法 《中华人民共和国网络安全法》已由中华人民共和国第十二届全国人民代表大会常务委员会第二十四次会议于2016年11月7日通过&#xff0c;现予公布&#xff0c;自2017年6月1日起施行。2022年9月12日&#xff0c;国家互联网信息办公室发布关于公开征求《…

Java面试题-Java核心基础-第二天(基本语法)

目录 一、注释有几种形式 二、标识符与关键字的区别 三、自增自减运算符 四、移位运算符 五、continue、break、return的区别 一、注释有几种形式 注释除了有其他编程语言有的单行注释和多行注释之外&#xff0c;还有其Java特有的文档注释 文档注释能够使用javadoc命令就…

C语言中的自定义类型详解(结构体 + 枚举 + 联合(共用体))

文章目录 1. 结构体1.1 结构体的声明1.2 结构体成员的访问1.3 匿名结构体1.4 结构体的自引用1.5 结构体内存对齐&#xff08;计算结构体的大小&#xff09;1.6 结构体传参1.6.1 传值传递1.6.2 传址传递&#xff08;使用指针&#xff09; 2. 位段2.1 什么是位段&#xff1f;2.2 …

Webpack 什么是loader?什么是plugin?loader与plugin区别是什么?

什么是loader&#xff1f;什么是plugin&#xff1f; loader 本质为一个函数&#xff0c;将文件编译成可执行文件。webpack完成的工作是将依赖分析与tree shinking对于类似.vue或.scss结尾的文件无法编译理解这就需要实现一个loader完成文件转译成js、html、css、json等可执行文…

铅华洗尽,粉黛不施,人工智能AI基于ProPainter技术去除图片以及视频水印(Python3.10)

视频以及图片修复技术是一项具有挑战性的AI视觉任务&#xff0c;它涉及在视频或者图片序列中填补缺失或损坏的区域&#xff0c;同时保持空间和时间的连贯性。该技术在视频补全、对象移除、视频恢复等领域有广泛应用。近年来&#xff0c;两种突出的方案在视频修复中崭露头角&…

LeetCode:1488. 避免洪水泛滥(2023.10.13 C++)

目录 1488. 避免洪水泛滥 实现代码与解析&#xff1a; 贪心 原理思路&#xff1a; 1488. 避免洪水泛滥 题目描述&#xff1a; 你的国家有无数个湖泊&#xff0c;所有湖泊一开始都是空的。当第 n 个湖泊下雨前是空的&#xff0c;那么它就会装满水。如果第 n 个湖泊下雨前是…

Android 13.0 蓝牙遥控器确认键弹不出输入法的解决方法

1.概述 在android13.0设备定制化开发时,遥控器是使用红外遥控器,也有使用蓝牙遥控器的,所以出现的问题不一定相同,今天遇到个问题就是蓝牙遥控器在输入数据时弹不出输入法的问题 首选排除输入法的问题,安装其他的输入法,也是同样的问题,这样就确定是系统EditText控件相关…

开源数据库MySQL 8.0 OCP认证精讲视频、环境和题库 之二

修改用户的初始密码&#xff1a; mysql>alteruserrootlocalhostidentifiedbyQaz1234&#xff1b; 或者&#xff1a; mysql>alteruseruser0identifiedbyQaz_1234; 在版本5.x中&#xff1a; mysql>setpasswordpassword(Qaz_1234); 可执行文件&#xff1a; 服务器端&…

miRNA测序数据生信分析——第四讲,未知物种的生信分析实例

miRNA测序数据生信分析——第四讲&#xff0c;未知物种的生信分析实例 miRNA测序数据生信分析——第四讲&#xff0c;未知物种的生信分析实例1. 下载测序数据2. 原始数据质控——软件fastqc3. 注释tRNA和rRNA&#xff0c;使用Rfam数据库——软件blast&#xff0c;Rfam_statisti…

监控系列(六)prometheus监控DMHS操作步骤

一、监控的操作逻辑 给操作系统安装expect命令expect脚本执行dmhs_console脚本执行 cpt / exec 命令用脚本进行过滤字符串过滤dm_export读取脚本与当前日期作比较&#xff0c;然后返回差值 二、安装步骤 1. linux中Expect工具的安装及使用方法 https://blog.csdn.net/wangta…