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

ArduPilot开源飞控之AP_Baro_DroneCAN

ArduPilot开源飞控之AP_Baro_DroneCAN

  • 1. 源由
  • 2. back-end抽象类
  • 3. 方法实现
    • 3.1 probe
    • 3.2 update
    • 3.3 subscribe_msgs
    • 3.4 handle_pressure/handle_temperature
    • 3.5 CAN port
  • 4. 参考资料

1. 源由

鉴于ArduPilot开源飞控之AP_Baro中涉及Sensor Driver有以下总线类型:

  1. I2C
  2. Serial UART
  3. CAN
  4. SITL //模拟传感器(暂时并列放在这里)

ArduPilot之开源代码Sensor Drivers设计的front-end / back-end分层设计思路,AP_Baro主要描述的是front-end。

为了更好的从整体理解气压计这个传感器的嵌入式应用,这里深入到back-end驱动层,针对基于CAN协议的气压计设备,进行一个研读和理解。

2. back-end抽象类

AP_Baro_Backend驱动层需实现方法:

  • void update()
  • static AP_Baro_Backend *probe(AP_Baro &baro, AP_HAL::OwnPtr<AP_HAL::Device> dev)

注:通常来说使用ChibiOS的都有定时器,如果没有定时器,可以使用void accumulate(void)来实现传感器的数据定时获取。

class AP_Baro_Backend
{
public:AP_Baro_Backend(AP_Baro &baro);virtual ~AP_Baro_Backend(void) {};// each driver must provide an update method to copy accumulated// data to the frontendvirtual void update() = 0;// accumulate function. This is used for backends that don't use a// timer, and need to be called regularly by the main code to// trigger them to read the sensorvirtual void accumulate(void) {}void backend_update(uint8_t instance);//  Check that the baro valid by using a mean filter.// If the value further that filtrer_range from mean value, it is rejected.bool pressure_ok(float press);uint32_t get_error_count() const { return _error_count; }#if AP_BARO_MSP_ENABLEDvirtual void handle_msp(const MSP::msp_baro_data_message_t &pkt) {}
#endif#if AP_BARO_EXTERNALAHRS_ENABLEDvirtual void handle_external(const AP_ExternalAHRS::baro_data_message_t &pkt) {}
#endif/*device driver IDs. These are used to fill in the devtype fieldof the device ID, which shows up as BARO_DEVID* parameters tousers.*/enum DevTypes {DEVTYPE_BARO_SITL     = 0x01,DEVTYPE_BARO_BMP085   = 0x02,DEVTYPE_BARO_BMP280   = 0x03,DEVTYPE_BARO_BMP388   = 0x04,DEVTYPE_BARO_DPS280   = 0x05,DEVTYPE_BARO_DPS310   = 0x06,DEVTYPE_BARO_FBM320   = 0x07,DEVTYPE_BARO_ICM20789 = 0x08,DEVTYPE_BARO_KELLERLD = 0x09,DEVTYPE_BARO_LPS2XH   = 0x0A,DEVTYPE_BARO_MS5611   = 0x0B,DEVTYPE_BARO_SPL06    = 0x0C,DEVTYPE_BARO_UAVCAN   = 0x0D,DEVTYPE_BARO_MSP      = 0x0E,DEVTYPE_BARO_ICP101XX = 0x0F,DEVTYPE_BARO_ICP201XX = 0x10,DEVTYPE_BARO_MS5607   = 0x11,DEVTYPE_BARO_MS5837   = 0x12,DEVTYPE_BARO_MS5637   = 0x13,DEVTYPE_BARO_BMP390   = 0x14,};protected:// reference to frontend objectAP_Baro &_frontend;void _copy_to_frontend(uint8_t instance, float pressure, float temperature);// semaphore for access to shared frontend dataHAL_Semaphore _sem;virtual void update_healthy_flag(uint8_t instance);// mean pressure for range filterfloat _mean_pressure; // number of dropped samples. Not used for now, but can be usable to choose more reliable sensoruint32_t _error_count;// set bus ID of this instance, for BARO_DEVID parametersvoid set_bus_id(uint8_t instance, uint32_t id) {_frontend.sensors[instance].bus_id.set(int32_t(id));}
};

3. 方法实现

由于气压数据来自CAN总线,因此,其逻辑与MSP协议类似,相对简单,没有校准等复杂物理公式。

3.1 probe

实例初始化。

AP_Baro_DroneCAN::probe├──> WITH_SEMAPHORE(_sem_registry);├──> AP_Baro_DroneCAN* backend = nullptr;│├──> <for (uint8_t i = 0; i < BARO_MAX_DRIVERS; i++)>│   └──> <_detected_modules[i].driver == nullptr && _detected_modules[i].ap_dronecan != nullptr>│       ││       │    /********************************************************************************│       │     * Registered DroneCAN Baro Node                                                *│       │     ********************************************************************************/│       ├──> backend = new AP_Baro_DroneCAN(baro);│       ├──> <backend == nullptr>│       │   └──> AP::can().log_text(AP_CANManager::LOG_ERROR,LOG_TAG,│       │                  "Failed register DroneCAN Baro Node %d on Bus %d\n",│       │                  _detected_modules[i].node_id,│       │                  _detected_modules[i].ap_dronecan->get_driver_index());│       ├──> <else>│       │   ├──> _detected_modules[i].driver = backend;│       │   ├──> backend->_pressure = 0;│       │   ├──> backend->_pressure_count = 0;│       │   ├──> backend->_ap_dronecan = _detected_modules[i].ap_dronecan;│       │   ├──> backend->_node_id = _detected_modules[i].node_id;│       │   ├──> backend->_instance = backend->_frontend.register_sensor();│       │   ├──> backend->set_bus_id(backend->_instance, AP_HAL::Device::make_bus_id(AP_HAL::Device::BUS_TYPE_UAVCAN,│       │   │                                                                      _detected_modules[i].ap_dronecan->get_driver_index(),│       │   │                                                                      backend->_node_id, 0));│       │   └──> AP::can().log_text(AP_CANManager::LOG_INFO,LOG_TAG,│       │                  "Registered DroneCAN Baro Node %d on Bus %d\n",│       │                  _detected_modules[i].node_id,│       │                  _detected_modules[i].ap_dronecan->get_driver_index());│       └──> break;└──> return backend;

3.2 update

front-end / back-end数据更新。

AP_Baro_DroneCAN::update├──> float pressure = 0;├──> WITH_SEMAPHORE(_sem_baro);└──> <new_pressure>├──> <_pressure_count != 0>│   ├──> pressure = _pressure / _pressure_count;│   ├──>_pressure_count = 0;│   └──>_pressure = 0;├──> _copy_to_frontend(_instance, pressure, _temperature);├──> _frontend.set_external_temperature(_temperature);└──> new_pressure = false;

3.3 subscribe_msgs

CAN协议消息处理钩子。

AP_Baro_DroneCAN::subscribe_msgs├──> ap_dronecan == nullptr>│   └──> return;├──> <Canard::allocate_sub_arg_callback(ap_dronecan, &handle_pressure, ap_dronecan->get_driver_index()) == nullptr>│   └──> AP_BoardConfig::allocation_error("pressure_sub");└──> <Canard::allocate_sub_arg_callback(ap_dronecan, &handle_temperature, ap_dronecan->get_driver_index()) == nullptr>└──> AP_BoardConfig::allocation_error("temperature_sub");

3.4 handle_pressure/handle_temperature

处理CAN协议中气压数据。

AP_Baro_DroneCAN::handle_pressure├──> WITH_SEMAPHORE(_sem_registry);├──> driver = get_dronecan_backend(ap_dronecan, transfer.source_node_id, true);├──> <driver == nullptr>│   └──> return;└──> WITH_SEMAPHORE(driver->_sem_baro);├──> _update_and_wrap_accumulator(&driver->_pressure, msg.static_pressure, &driver->_pressure_count, 32);└──> driver->new_pressure = true;

处理CAN协议中温度数据。

AP_Baro_DroneCAN::handle_temperature├──> WITH_SEMAPHORE(_sem_registry);├──> driver = get_dronecan_backend(ap_dronecan, transfer.source_node_id, false);├──> <driver == nullptr>│   └──> return;└──> WITH_SEMAPHORE(driver->_sem_baro);└──> driver->_temperature = KELVIN_TO_C(msg.static_temperature);

3.5 CAN port

目前的官方文档有不一致的问题,希望后续能有完善和更新。

  • 【1】Inconsistent CAN startup documentation
  • 【2】Inconsistent CAN startup documentation #5475
init_ardupilot└──> AP_CANManager::init└──> AP_DroneCAN::init└──> AP_Baro_DroneCAN::subscribe_msgs

4. 参考资料

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

相关文章:

ArduPilot开源飞控之AP_Baro_DroneCAN

ArduPilot开源飞控之AP_Baro_DroneCAN 1. 源由2. back-end抽象类3. 方法实现3.1 probe3.2 update3.3 subscribe_msgs3.4 handle_pressure/handle_temperature3.5 CAN port 4. 参考资料 1. 源由 鉴于ArduPilot开源飞控之AP_Baro中涉及Sensor Driver有以下总线类型&#xff1a; …...

Supervised Contrastive Pre-training for Mammographic Triage Screening Model

方法 品红色箭头表示将生成的孪生编码器分别迁移到单视角学习模块和双视角学习模块...

JVM技术文档--JVM优化思路以及问题定位--JVM可调整参数汇总

阿丹&#xff1a; 一个优秀的程序员&#xff0c;是因为在线上的排查以及遇到的线上、生产事故较多所以定位问题以及解决问题会比普通程序员快很多&#xff0c;所以一个优秀的程序员要逐渐形成自己的方法论&#xff0c;来完善和解决问题。 我们是如何发现问题的呢&#xff1f; …...

Oracle10g数据库迁移方案

试验了很多次Oracle数据库迁移才成功&#xff0c;贴出来给大家参考一下&#xff0c;我看到有的地方写迁移之后还需要重新建立temp表空间&#xff0c;这个还没有研究。另外说一点的是两个数据库的版本一定要一致&#xff0c;之前失败过一次&#xff0c;就是因为两个数据库的版本…...

备忘录模式:对象状态的保存与恢复

欢迎来到设计模式系列的第十八篇文章&#xff0c;本篇将介绍备忘录模式。备忘录模式是一种行为型设计模式&#xff0c;它允许在不破坏封装性的前提下捕获一个对象的内部状态&#xff0c;并在之后恢复该状态。这种模式通常用于需要提供撤销操作的情况。 什么是备忘录模式&#…...

C# InvokeRequired线程安全

C# InvokeRequired线程安全 为了保证新家的线程可能要对主界面的控件元素的属性发生一些改变&#xff0c;此时防止此操作对于主线程的影响&#xff0c;就提出了 InvokeRequired方法&#xff0c;保证主线程的安全&#xff0c;同时新加的线程也可以改变主页面中元素的值。 定义…...

pdf怎么转成jpg图片格式

pdf怎么转成jpg图片格式&#xff1f;对于大家平时在工作或者生活中的图片使用习惯&#xff0c;经常需要将各种格式的文件转换成易于浏览和使用的JPG格式图片以便保存。如今&#xff0c;因为pdf文件具有更强的稳定性和设备兼容性&#xff0c;PDF文件在平时的电脑使用过程中可以说…...

React +ts + babel+webpack

babel babel/preset-typescript 专门处理ts "babel/cli": "^7.17.6", "babel/core": "^7.17.8", "babel/preset-env": "^7.16.11", "babel/preset-react": "^7.16.7", "babel/preset…...

红队专题-REVERSE二进制逆向反编译

红队专题 招募六边形战士队员IDA pro安装python2加入环境变量py2安装pip安装IDA 7.0 proIDAPython: importing "site" failed. 招募六边形战士队员 一起学习 代码审计、安全开发、web攻防、逆向等。。。 私信联系 IDA pro 安装python2 python-2.7.3.msi 加入环…...

Spring技术原理之Bean生命周期原理解析

Spring技术原理之Bean生命周期原理解析 Spring作为Java领域中的优秀框架&#xff0c;其核心功能之一是依赖注入和生命周期管理。其中&#xff0c;Bean的生命周期管理是Spring框架中一个重要的概念。在本篇文章中&#xff0c;我们将深入探讨Spring技术原理中的Bean生命周期原理…...

Unity实现设计模式——模板方法模式

Unity实现设计模式——模板方法模式 模板模式(Template Pattern)&#xff0c; 指在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现&#xff0c;但调用将以抽象类中定义的方式进行。 简单说&#xff0c; 模板方法模式定义一个操作中的算法的骨架&…...

C++实现高性能内存池(二)

文章目录 一、设计内存池二、实现MemoryPool::construct() 实现MemoryPool::deallocate() 实现MemoryPool::~MemoryPool() 实现MemoryPool::allocate() 实现三、与 std::vector 的性能对比一、设计内存池 在上节中,我们在模板链表栈中使用了默认构造器来管理栈操作中的元素内…...

沪深300期权一个点多少钱?

经中国证监会批准&#xff0c;深圳证券交易所于2019年12月23日上市嘉实沪深300ETF期权合约品种。该产品是以沪深300为标的物的嘉实沪深300ETF交易型指数基金为标的衍生的标准化合约&#xff0c;下文介绍沪深300期权一个点多少钱?本文来自&#xff1a;期权酱 一、沪深300期权涨…...

怎么防止重要文件夹丢失?文件夹安全如何保护?

我们在使用电脑的过程中&#xff0c;会将重要数据放在文件夹中&#xff0c;那么&#xff0c;我们该怎么防止重要文件夹丢失呢&#xff1f;下面我们就一起来了解一下。 EFS加密 EFS加密可以对于NTFS卷上的文件夹进行加密&#xff0c;加密后的文件夹将只允许加密时登录系统的用户…...

用于物体识别和跟踪的下游任务自监督学习-1-引言

一&#xff1a;引言&#xff1a; 图像和视频理解是计算机视觉应用中的基本问题&#xff0c;旨在使机器能够像人类一样解释和理解视觉数据。这些问题涉及识别图像和视频中的对象、人物、动作、事件和场景。如图1.1-&#xff08;a&#xff09;所示的图像识别任务包括对象检测[1]…...

式子表达ds类——多用位置/值域表示未知数+区间覆盖转区间加:CF407E

https://www.luogu.com.cn/problem/CF407E 多用位置/值域表示未知数 推出的式子中 n n n 表示长度&#xff0c;应该直接换成 r − l 1 r-l1 r−l1 区间覆盖转区间加 推出的式子有 m x , m n mx,mn mx,mn&#xff0c;朴素思路是用单调队列区间覆盖维护 那样就不能很方便…...

Python 实现秒表功能(比较好玩的题目)

以下实例使用 time 模块来实现秒表功能&#xff1a; import time print(按下回车开始计时&#xff0c;按下ctrlc停止计时) while True:input("")starttimetime.time()print(开始)try:while True:print(计时&#xff1a;,round(time.time()-starttime,0),秒)time.sle…...

DALL-E 3调参教程;百度新出的AI写小说神器;通义听悟看播客也太爽了;系列博文带你理解生成式AI | ShowMeAI日报

&#x1f440;日报&周刊合集 | &#x1f3a1;生产力工具与行业应用大全 | &#x1f9e1; 点赞关注评论拜托啦&#xff01; &#x1f525; 2023年诺贝尔奖全部揭晓&#xff0c;一文看完6类奖项花落谁家 https://www.nobelprize.org/prizes 随着最后一项「经济学奖」的揭秘&a…...

设计模式-享元模式

概念 共享内存&#xff08;主要考虑内存&#xff0c;而非效率&#xff09;相同的数据&#xff0c;共享使用&#xff08;JS中未找到经典应用场景&#xff09; 演示 <!-- 无限下拉列表&#xff0c;将事件代理到高层节点上 --> <!-- 如果都绑定到<a>标签&#x…...

中秋时节赏明月,五子棋戏月饼趣 — Flutter中秋限定版五子棋

前言 当中秋时节来临&#xff0c;我们都期待着与亲人朋友共度这个美好的节日。这个时候&#xff0c;除了传统的赏月和品尝美味的月饼&#xff0c;我还有一个特别的建议——尝试一款有趣的Flutter五子棋游戏&#xff01;这款五子棋游戏以中秋为主题&#xff0c;游戏的棋子也可爱…...

Scala第十九章节

Scala第十九章节 scala总目录 文档资料下载 章节目标 了解Actor的相关概述掌握Actor发送和接收消息掌握WordCount案例 1. Actor介绍 Scala中的Actor并发编程模型可以用来开发比Java线程效率更高的并发程序。我们学习Scala Actor的目的主要是为后续学习Akka做准备。 1.1 Ja…...

kafka与hbase的区别

Kafka 和 HBase 是两个不同的分布式数据存储系统&#xff0c;它们可以在大数据应用中发挥不同的作用。 Kafka 是一个高吞吐量的分布式发布订阅消息系统&#xff0c;主要用于处理实时数据流。它具有以下特点&#xff1a; 高性能&#xff1a;Kafka 能够以非常高的吞吐量和低延迟…...

出栈序列的合法性

给定一个最大容量为 M 的堆栈&#xff0c;将 N 个数字按 1, 2, 3, ..., N 的顺序入栈&#xff0c;允许按任何顺序出栈&#xff0c;则哪些数字序列是不可能得到的&#xff1f;例如给定 M5、N7&#xff0c;则我们有可能得到{ 1, 2, 3, 4, 5, 6, 7 }&#xff0c;但不可能得到{ 3, …...

unity操作_刚体 c#

刚体Rigidbody 首先在场景中创建一个Plane 位置重置一下 再创建一个Cube 充值 y0.5 我们可以看出创建的Cube 和 Plane都自带碰撞器 Plane用的是网格碰撞器 我们可以通过网格世界看到不同的网格碰撞器 发生碰撞&#xff08;条件&#xff09;&#xff1a; 两个物体都有碰撞器 …...

网络编程中套接字(socket)介绍(Python示例)

网络编程中套接字&#xff08;socket&#xff09;介绍&#xff08;Python示例&#xff09; 网络编程就是同一计算机的进程间或者不同的联网计算机之间的通信&#xff08;交换数据&#xff09;。 那么&#xff0c;这两台计算机之间用什么传输数据呢&#xff1f;首先你肯定先需要…...

d3dcompiler_43.dll是什么文件?缺失d3dcompiler_43.dll文件修复与解决方法

今天我要和大家分享的是关于d3dcompiler_43.dll丢失的解决方法。我相信很多网友在使用电脑时都遇到过这个问题&#xff0c;那么接下来就让我们一起来探讨一下如何解决这个问题吧&#xff01; 首先&#xff0c;让我们来了解一下d3dcompiler_43.dll文件的总体介绍。d3dcompiler_…...

YOLOv7改进:SPD-Conv,低分辨率图像和小物体涨点明显,涨点神器!!!

💡💡💡本文属于原创独家改进:SPD-Conv,优势:处理低分辨率图像和小物体等更困难的任务时性能更优 SPD-Conv | 亲测在多个数据集实现暴力涨点,尤其是小物体检测你值得拥有,强烈推荐,独家首发; 收录: YOLOv7高阶自研专栏介绍: http://t.csdnimg.cn/tYI0c ✨…...

iris(golang)连接mysql数据库

连接mysql数据库 安装依赖 go get github.com/go-sql-driver/mysqlfunc LinkMySQL(){DB,_ : sql.Open("mysql","root:123456tcp(127.0.0.1:3306)/webgo_accout")//设置数据库最大连接数DB.SetConnMaxLifetime(100)//设置上数据库最大闲置连接数DB.SetMaxId…...

C现代方法(第1、2章)笔记

文章目录 C现代方法笔记&#xff08;chapter1&2&#xff09;序言0.1 C标准0.2 现代方法 第1章 C语言概述1.1 C语言的历史1.1.1 起源1.1.2 标准化1.1.3 基于C的语言 1.2 C语言的优缺点1.2.1 C语言的优点1.2.2 C语言的缺点1.2.3 高效地使用C语言 第2章 C语言基本概念2.1 编写…...

练[CISCN2019 华东南赛区]Double Secret

[CISCN2019 华东南赛区]Double Secret 文章目录 [CISCN2019 华东南赛区]Double Secret掌握知识解题思路关键paylaod 掌握知识 ​ flask框架报错源码泄露&#xff0c;使用脚本进行RC4加解&#xff0c;ssti使用内置函数进行模板注入 解题思路 打开网站链接&#xff0c;页面就一…...