ArduPilot开源代码之AP_DAL_RangeFinder

ArduPilot开源代码之AP_DAL_RangeFinder

  • 1. 源由
  • 2. 框架设计
    • 2.1 枚举 `Status`
    • 2.2 公有方法
    • 2.3 私有成员变量
  • 3. 重要例程
    • 3.1 应用函数
      • 3.1.1 ground_clearance_cm_orient
      • 3.1.2 max_distance_cm_orient
      • 3.1.3 has_orientation
      • 3.1.4 get_backend
    • 3.2 其他函数
      • 3.2.1 AP_DAL_RangeFinder
      • 3.2.2 start_frame
      • 3.2.3 handle_message
  • 4. 总结
  • 5. 参考资料

1. 源由

AP_DAL_RangeFinder用于管理和操作测距仪的数据和状态。

它提供了一些方法来获取测距仪的高度和距离信息,检查测距仪的方向,启动数据收集帧,并处理日志消息。私有成员变量则用于存储日志信息和管理后端实例。

2. 框架设计

2.1 枚举 Status

这个枚举定义了测距仪的各种状态,包括:

  • NotConnected: 测距仪未连接。
  • NoData: 测距仪没有数据。
  • OutOfRangeLow: 测距仪数据超出下限。
  • OutOfRangeHigh: 测距仪数据超出上限。
  • Good: 测距仪状态良好。

2.2 公有方法

  • int16_t ground_clearance_cm_orient(enum Rotation orientation) const;

    • 根据给定的方向返回地面净空高度,单位是厘米。
  • int16_t max_distance_cm_orient(enum Rotation orientation) const;

    • 根据给定的方向返回最大距离,单位是厘米。
  • bool has_orientation(enum Rotation orientation) const;

    • 检查是否存在具有指定方向的测距仪,返回布尔值。
  • AP_DAL_RangeFinder();

    • 构造函数,用于初始化类的实例。
  • void start_frame();

    • 开始一个新的帧,可能用于初始化或重置测距仪的数据收集过程。
  • AP_DAL_RangeFinder_Backend *get_backend(uint8_t id) const;

    • 根据给定的ID获取对应的后端实例,返回指向后端实例的指针。
  • void handle_message(const log_RRNH &msg);

    • 处理 log_RRNH 类型的日志消息。
  • void handle_message(const log_RRNI &msg);

    • 处理 log_RRNI 类型的日志消息。

2.3 私有成员变量

  • struct log_RRNH _RRNH;

    • 一个 log_RRNH 结构体实例,用于存储相关的日志信息。
  • struct log_RRNI *_RRNI;

    • 一个指向 log_RRNI 结构体的指针,用于存储相关的日志信息。
  • AP_DAL_RangeFinder_Backend **_backend;

    • 一个指向 AP_DAL_RangeFinder_Backend 实例数组的指针,可能用于管理多个后端实例。

3. 重要例程

enum Rotation : uint8_t {ROTATION_NONE                = 0,ROTATION_YAW_45              = 1,ROTATION_YAW_90              = 2,ROTATION_YAW_135             = 3,ROTATION_YAW_180             = 4,ROTATION_YAW_225             = 5,ROTATION_YAW_270             = 6,ROTATION_YAW_315             = 7,ROTATION_ROLL_180            = 8,ROTATION_ROLL_180_YAW_45     = 9,ROTATION_ROLL_180_YAW_90     = 10,ROTATION_ROLL_180_YAW_135    = 11,ROTATION_PITCH_180           = 12,ROTATION_ROLL_180_YAW_225    = 13,ROTATION_ROLL_180_YAW_270    = 14,ROTATION_ROLL_180_YAW_315    = 15,ROTATION_ROLL_90             = 16,ROTATION_ROLL_90_YAW_45      = 17,ROTATION_ROLL_90_YAW_90      = 18,ROTATION_ROLL_90_YAW_135     = 19,ROTATION_ROLL_270            = 20,ROTATION_ROLL_270_YAW_45     = 21,ROTATION_ROLL_270_YAW_90     = 22,ROTATION_ROLL_270_YAW_135    = 23,ROTATION_PITCH_90            = 24,ROTATION_PITCH_270           = 25,ROTATION_PITCH_180_YAW_90    = 26, // same as ROTATION_ROLL_180_YAW_270ROTATION_PITCH_180_YAW_270   = 27, // same as ROTATION_ROLL_180_YAW_90ROTATION_ROLL_90_PITCH_90    = 28,ROTATION_ROLL_180_PITCH_90   = 29,ROTATION_ROLL_270_PITCH_90   = 30,ROTATION_ROLL_90_PITCH_180   = 31,ROTATION_ROLL_270_PITCH_180  = 32,ROTATION_ROLL_90_PITCH_270   = 33,ROTATION_ROLL_180_PITCH_270  = 34,ROTATION_ROLL_270_PITCH_270  = 35,ROTATION_ROLL_90_PITCH_180_YAW_90 = 36,ROTATION_ROLL_90_YAW_270     = 37,ROTATION_ROLL_90_PITCH_68_YAW_293 = 38, // this is actually, roll 90, pitch 68.8, yaw 293.3ROTATION_PITCH_315           = 39,ROTATION_ROLL_90_PITCH_315   = 40,ROTATION_PITCH_7             = 41,ROTATION_ROLL_45             = 42,ROTATION_ROLL_315            = 43,///// Do not add more rotations without checking that there is not a conflict// with the MAVLink spec. MAV_SENSOR_ORIENTATION is expected to match our// list of rotations here. If a new rotation is added it needs to be added// to the MAVLink messages as well.///ROTATION_MAX,ROTATION_CUSTOM_OLD          = 100,ROTATION_CUSTOM_1            = 101,ROTATION_CUSTOM_2            = 102,ROTATION_CUSTOM_END,
};

3.1 应用函数

3.1.1 ground_clearance_cm_orient

获取指定方向安全距离

int16_t AP_DAL_RangeFinder::ground_clearance_cm_orient(enum Rotation orientation) const
{
#if !APM_BUILD_TYPE(APM_BUILD_AP_DAL_Standalone)const auto *rangefinder = AP::rangefinder();if (orientation != ROTATION_PITCH_270) {// the EKF only asks for this from a specific orientation.  Thankfully.INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);return rangefinder->ground_clearance_cm_orient(orientation);}
#endifreturn _RRNH.ground_clearance_cm;
}

3.1.2 max_distance_cm_orient

获取指定方向最大距离

int16_t AP_DAL_RangeFinder::max_distance_cm_orient(enum Rotation orientation) const
{
#if !APM_BUILD_TYPE(APM_BUILD_AP_DAL_Standalone)if (orientation != ROTATION_PITCH_270) {const auto *rangefinder = AP::rangefinder();// the EKF only asks for this from a specific orientation.  Thankfully.INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);return rangefinder->max_distance_cm_orient(orientation);}
#endifreturn _RRNH.max_distance_cm;
}

3.1.3 has_orientation

指定方向测距仪是否有效

bool AP_DAL_RangeFinder::has_orientation(enum Rotation orientation) const
{for (uint8_t i=0; i<_RRNH.num_sensors; i++) {if (_RRNI[i].orientation == orientation) {return true;}}return false;
}

3.1.4 get_backend

获取后台驱动实例

AP_DAL_RangeFinder_Backend *AP_DAL_RangeFinder::get_backend(uint8_t id) const
{if (id >= RANGEFINDER_MAX_INSTANCES) {INTERNAL_ERROR(AP_InternalError::error_t::flow_of_control);return nullptr;}if (id >= _RRNH.num_sensors) {return nullptr;}return _backend[id];
}

3.2 其他函数

3.2.1 AP_DAL_RangeFinder

构造函数,初始化实例序号

  • _RRNH //Replay Data Rangefinder Header
  • _RRNI //Replay Data Rangefinder Instance
  • _backend
AP_DAL_RangeFinder::AP_DAL_RangeFinder()
{
#if !APM_BUILD_TYPE(APM_BUILD_AP_DAL_Standalone) && !APM_BUILD_TYPE(APM_BUILD_Replay)_RRNH.num_sensors = AP::rangefinder()->num_sensors();_RRNI = NEW_NOTHROW log_RRNI[_RRNH.num_sensors];_backend = NEW_NOTHROW AP_DAL_RangeFinder_Backend *[_RRNH.num_sensors];if (!_RRNI || !_backend) {goto failed;}for (uint8_t i=0; i<_RRNH.num_sensors; i++) {_RRNI[i].instance = i;}for (uint8_t i=0; i<_RRNH.num_sensors; i++) {// this avoids having to discard a const...._backend[i] = NEW_NOTHROW AP_DAL_RangeFinder_Backend(_RRNI[i]);if (!_backend[i]) {goto failed;}}return;
failed:AP_BoardConfig::allocation_error("DAL backends");
#endif
}

3.2.2 start_frame

AP_DAL::start_frame└──> AP_DAL_RangeFinder::start_frame
void AP_DAL_RangeFinder::start_frame()
{const auto *rangefinder = AP::rangefinder();  // 获取距离传感器对象的指针if (rangefinder == nullptr) {return;  // 如果传感器对象为空,直接返回}const log_RRNH old = _RRNH;  // 备份旧的 RRNH 对象状态// EKF 只需要这个值 *向下*。_RRNH.ground_clearance_cm = rangefinder->ground_clearance_cm_orient(ROTATION_PITCH_270);  // 设置地面间隔高度,使用 ROTATION_PITCH_270 方向_RRNH.max_distance_cm = rangefinder->max_distance_cm_orient(ROTATION_PITCH_270);  // 设置最大测距距离,使用 ROTATION_PITCH_270 方向WRITE_REPLAY_BLOCK_IFCHANGED(RRNH, _RRNH, old);  // 如果 RRNH 对象改变,则写入重放块// 遍历所有传感器for (uint8_t i = 0; i < _RRNH.num_sensors; i++) {auto *backend = rangefinder->get_backend(i);  // 获取第 i 个传感器的后端对象指针if (backend == nullptr) {continue;  // 如果后端对象为空,跳过当前传感器}_backend[i]->start_frame(backend);  // 调用对应传感器的后端对象的 start_frame 函数}
}

3.2.3 handle_message

AP_DAL::handle_message└──> AP_DAL_RangeFinder::handle_message
void AP_DAL_RangeFinder::handle_message(const log_RRNH &msg)
{_RRNH = msg;if (_RRNH.num_sensors > 0 && _RRNI == nullptr) {_RRNI = NEW_NOTHROW log_RRNI[_RRNH.num_sensors];_backend = NEW_NOTHROW AP_DAL_RangeFinder_Backend *[_RRNH.num_sensors];}
}void AP_DAL_RangeFinder::handle_message(const log_RRNI &msg)
{if (_RRNI != nullptr && msg.instance < _RRNH.num_sensors) {_RRNI[msg.instance] = msg;if (_backend != nullptr && _backend[msg.instance] == nullptr) {_backend[msg.instance] = NEW_NOTHROW AP_DAL_RangeFinder_Backend(_RRNI[msg.instance]);}}
}

4. 总结

AP_DAL_RangeFinder主要功能是用于管理和操作测距仪的数据和状态,并提供访问接口进行直接状态访问。

5. 参考资料

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

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

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

相关文章

git config

文章目录 1.简介2.格式3.选项4.示例参考文献 1.简介 安装完 Git 后&#xff0c;需要对 Git 环境进行一次配置&#xff0c;且只需要配置一次。程序升级时会保留配置信息。 你可以在任何时候再次通过运行命令来修改它们。 Git 自带一个 git config 的工具来设置控制 Git 外观和…

AI(Adobe lliustrator)教程+软件包

简介&#xff1a; 软件主要应用于印刷出版、海报书籍排版、专业插画、多媒体图像处理和互联网页面的制作等&#xff0c;也可以为线稿提供较高的精度和控制&#xff0c;适合生产任何小型设计到大型的复杂项目。 通常用于创建LOGO(商标或徽标)&#xff0c;图标&#xff0c;插图…

【数据结构】线性结构——数组、链表、栈和队列

目录 前言 一、数组&#xff08;Array&#xff09; 1.1优点 1.2缺点 1.3适用场景 二、链表&#xff08;Linked List&#xff09; 2.1优点 2.2缺点 2.3适用场景 三、栈&#xff08;Stack&#xff09; 3.1优点 3.2缺点 3.3适用场景 四、队列&#xff08;Queue&#xff09; 4.1优点…

根目录满迁移docker文件

在 Ubuntu 下&#xff0c;迁移 Docker 的数据存储位置到另一个挂载点需要按照以下步骤进行操作。确保在操作之前备份重要数据&#xff0c;以防止意外情况发生。 步骤概述 停止 Docker 服务&#xff1a; bash sudo systemctl stop docker创建新的存储位置&#xff1a; 假设你有…

递归式函数

在java中&#xff0c;函数递归是会报编译错误的。比如我定义一个斐波那契函数&#xff1a; public class RecursiveFunction {public static void main(String[] args) {fibonacci x -> x < 3 ? 1 : fibonacci.apply(x - 1) fibonacci.apply(x - 2);} }它就报了这个错…

设计模式-三大分类

软件七大设计原则 1、单一职责 定义&#xff1a;每个类应该只有一个引起它变化的原因。 解释&#xff1a;一个类只负责一个功能&#xff0c;这样可以减少类之间的耦合&#xff0c;提高系统的可维护性和可扩展性。 2、开闭原则 定义&#xff1a;软件实体&#xff08;类、模块…

使用Dockerfile构建镜像

通过基础镜像 centos:7&#xff0c;在该镜像中安装 jdk 和 tomcat 以后将其制作为一个新的镜像 mscentos:7 创建目录 mkdir -p /kong/docker/dockerfile编写 Dockerfile 文件 vim DockerfileDockerfile 文件内容如下&#xff1a; # 指明构建的新镜像是来自于 centos:7 基础…

广义可加模型和光滑曲线拟合的R代码

&#x1f3c6;本文收录于《CSDN问答解答》专栏&#xff0c;主要记录项目实战过程中的Bug之前因后果及提供真实有效的解决方案&#xff0c;希望能够助你一臂之力&#xff0c;帮你早日登顶实现财富自由&#x1f680;&#xff1b;同时&#xff0c;欢迎大家关注&&收藏&…

jvm-并发-java基础-数据结构小测

这篇文章是一些练习题&#xff0c;答案后续更新。 请简述银行家算法 请简述死锁产生的条件 解决死锁的几种方式 简述synchronized锁的膨胀 什么是cas cas 的问题如何解决 jmm 简单理解 volatile 单例模式 线程安全的两种代码 懒汉&恶汉 线程池的7个参数分别是什么…

ABAQUS细观混凝土周期性边界(PBC)表征体元(REV)界面层(ITZ)及砂浆塑性损伤(CDP)模拟

混凝土的细观结构决定着其宏观破坏行为&#xff0c;对混凝土在结构尺度上采用细观模型将导致巨大的计算量而难以实现&#xff0c;表征体元&#xff08;‌REV&#xff09;‌方法可选取一定的平均范围来描述混凝土的性质和行为&#xff0c;这对于理解和模拟混凝土的损伤机理至关重…

构建高可用应用的设计模式与实践

高可用性&#xff08;High Availability, HA&#xff09;是现代分布式系统中必不可少的特性之一。高可用应用能够在面对系统故障、网络分区或资源压力等多种情况下&#xff0c;依然保证服务的连续性和稳定性。本文将介绍构建高可用应用的常见设计模式与实践&#xff0c;并提供J…

测试用例的设计方法

等价类 等价类概念&#xff1a;在所有测试的数据中&#xff0c;具有某种共同特征的数据子集 边界值 边界值分析是对程序输入或输出的边界值进行测试的一种黑盒测试方法 边界值是作为等价类的补充&#xff0c;其主要区别是&#xff1a; 边界值测试设计不是从某一个等价类中…

nacos注释配置未生效?

遇到的问题 Nacos中修改配置将配置的key 的注释&#xff0c;配置未发生变更问题 NacosValueAnnotationBeanPostPorcessor中有&#xff0c;获取key&#xff0c;是获取的所有注解上的值&#xff0c;而values是enviroment中的属性值 当我们注释掉nacos中的属性时&#xff0c;ke…

15. 【C++】详解搜索二叉树 | KV模型

目录 1.定义 初始化 插入 查找 删除 完整代码 2.运用 K 模型和 KV 模型详解 K 模型 KV 模型 代码解释 为了更好地理解 map 和 set 的特性&#xff0c;和后面讲解查找效率极高的平衡搜索二叉树&#xff0c;和红黑树去实现模拟&#xff0c;所以决定在这里对搜索二叉树…

Google资深工程师深度讲解Go语言-课程笔记

课程目录&#xff1a; 第1章 课程介绍 欢迎大家来到深度讲解Go语言的课堂。本课程将从基本语法讲起&#xff0c;逐渐深入&#xff0c;帮助同学深度理解Go语言面向接口&#xff0c;函数式编程&#xff0c;错误处理&#xff0c;测试&#xff0c;并行计算等元素&#xff0c;并带…

(vue)Vue读取public中的json文件,打包后只需更改包文件

(vue)Vue读取public中的json文件,打包后只需更改包文件 背景&#xff1a;增加账号需求。原本是在页面&#xff0c;每次都需技术人员添加再打包部署&#xff0c;现在放到json里&#xff0c;以后直接服务器改json就行。 旧版&#xff1a; let userArr [{username:aaa,password:…

VLAN 划分案例详解

vlan 的应用在网络项目中是非常广泛的&#xff0c;基本上大部分的项目都需要划分 vlan&#xff0c;这里从基础的 vlan 的知识开始&#xff0c;了解 vlan 的划分原理。 为什么需要 vlan&#xff1a; 1、什么是 VLAN&#xff1f; VLAN&#xff08;Virtual LAN&#xff09;&…

springboot 之 使用easyexcel导出数据时数据格式转换问题

背景 导出数据库中的数据&#xff0c;有些字段格式为LocalDateTime需要转化为String. 软件版本 springboot 2.7.17 easyexcel 3.0.5 代码 //实现相关接口&#xff0c;进行格式转化 import com.alibaba.excel.converters.Converter; import com.alibaba.excel.metadata.Globa…

Python数据分析实战:利用ARIMA模型洞察股市规律

在股市中&#xff0c;数据的波动与变化风云莫测&#xff0c;难以捉摸。然而&#xff0c;借助科学的分析方法和工具&#xff0c;我们或许能够找到一些数据规律。今天&#xff0c;我们聊聊如何使用Python编程语言&#xff0c;结合ARIMA模型来洞察股市的变幻&#xff0c;为我们的投…

精确控制Conda环境:使用conda install命令安装特定版本的包

精确控制Conda环境&#xff1a;使用conda install命令安装特定版本的包 在Python项目开发中&#xff0c;依赖管理是确保项目可复现性和稳定性的关键环节。Conda作为Anaconda发行版中的包管理器&#xff0c;提供了强大的依赖管理功能&#xff0c;允许用户安装和管理不同版本的包…