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研读系列
相关文章:
ArduPilot开源代码之AP_DAL_RangeFinder
ArduPilot开源代码之AP_DAL_RangeFinder 1. 源由2. 框架设计2.1 枚举 Status2.2 公有方法2.3 私有成员变量 3. 重要例程3.1 应用函数3.1.1 ground_clearance_cm_orient3.1.2 max_distance_cm_orient3.1.3 has_orientation3.1.4 get_backend 3.2 其他函数3.2.1 AP_DAL_RangeFind…...
SpringCloud教程 | 第九篇: 使用API Gateway
1、参考资料 SpringCloud基础篇-10-服务网关-Gateway_springcloud gateway-CSDN博客 2、先学习路由,参考了5.1 2.1、建了一个cloudGatewayDemo,这是用来配置网关的工程,配置如下: http://localhost:18080/aaa/name 该接口代码如…...
数据结构——hash(hashmap源码探究)
hash是什么? hash也称为散列,就是把任意长度的输入,通过散列算法,变成固定长度的输出,这个输出值就是散列值。 举例来说明一下什么是hash: 假设我们要把1~12存入到一个大小是5的hash表中,我们…...
国产麒麟、UOS在线打开pdf加盖印章
PageOffice支持两种电子印章方案,可实现对Word、Excel、PDF文档加盖PageOffice自带印章或ZoomSeal电子印章(全方位保护、防篡改、防伪造)。Word和Excel的盖章功能请参考:Word和Excel加盖印章和签字功能 (目前只支持win…...
破解反爬虫策略 /_guard/auto.js(二)实战
这次我们用上篇文章讲到的方法来真正破解一下反爬虫策略,这两个案例是两个不同的网站,一个用的是 /_guard/auto.js,另一个用的是/_guard/delay_jump.js。经过解析发现这两个网站用的反爬虫策略基本是一模一样,只不过在js混淆和生成…...
同样是人工智能 客户在哪儿AI和GPT等大模型有什么不同
书接上回。为了统一回答朋友们的疑惑,此前的两篇文章,着重讲述了客户在哪儿AI的企业全历史行为数据和企业信息查询平台上的数据的区别,以及客户在哪儿AI的ToB获客服务和AI外呼机器人的获客服务的不同。本期接着讲——客户在哪儿AI VS 大模型&…...
AES Android IOS H5 加密方案
前景: 1、本项目原有功能RSA客户端对敏感信息进行加密 2、本次漏洞说是服务端返回值有敏感信息,需要密文返回 3、最初只跟H5联调成功,后续APP联调失败(H5和APP的需求排期不一致),没关注到通用性 方案: 本次方案不…...
一文了解变阻器和电位器的定义、原理、应用及其对比
变阻器的定义 两端可变电阻器(称为变阻器)利用电阻来调节电流。电阻丝环绕在陶瓷或瓷器等绝缘芯上。当刮水器沿着电阻丝移动时,电路的有效电阻会发生变化。因此,它提供了精确的电流控制。调光器、电机速度控制器和加热元件使用变…...
WPF实现一个带旋转动画的菜单栏
WPF实现一个带旋转动画的菜单栏 一、创建WPF项目及文件1、创建项目2、创建文件夹及文件3、添加引用 二、代码实现2.ControlAttachProperty类 一、创建WPF项目及文件 1、创建项目 打开VS2022,创建一个WPF项目,如下所示 2、创建文件夹及文件 创建资源文件夹&…...
使用Dockerfile构建镜像
目录 1.使用Dockerfile构建tomcat镜像 1.1 通过ARG传参构建不同版本的tomcat 2.缩小镜像的体积大小 2.1 使用较小体积的基础镜像 2.2 多级构建减少体积 1.使用Dockerfile构建tomcat镜像 cd /opt mkdir tomcat cd tomcat/ 上传tomcat所需的依赖包 使用tar xf 解压三个压缩…...
概率论原理精解【3】
文章目录 向量值向量值函数导数对称矩阵定义性质例子应用 向量值理论基础定义性质应用示例 向量值函数的导数定义性质应用 向量值 向量值函数导数 D n ⊂ R n , 向量值函数 f : D n → R m D^n \subset R^n,向量值函数f:D^n\rightarrow R^m Dn⊂Rn,向量值函数f:Dn→Rm 1. 向量…...
[C/C++入门][循环]14、计算2的幂(2的n次方)
计算2的幂(即2的n次方)非常经典。你懂几种方法呢?很多人只会一种,我们来分析一下。 可以通过多种方式实现: 1、最简单的方法之一是使用位运算符<<,它本质上是在二进制表示下对2进行左移操作&#x…...
RPC与服务的注册发现
文章目录 1. 什么是远程过程调用(RPC)?2. RPC的流程3. RPC实践4. RPC与REST的区别4.1 RPC与REST的相似之处4.2 RPC与REST的架构原则4.3 RPC与REST的主要区别 5. RPC与服务发现5.1 以zookeeper为服务注册中心5.2 以etcd为服务注册中心 6. 小结参考 1. 什么是远程过程调用(RPC)?…...
3112. 访问消失节点的最少时间 Medium
给你一个二维数组 edges 表示一个 n 个点的无向图,其中 edges[i] [ui, vi, lengthi] 表示节点 ui 和节点 vi 之间有一条需要 lengthi 单位时间通过的无向边。 同时给你一个数组 disappear ,其中 disappear[i] 表示节点 i 从图中消失的时间点࿰…...
FastAPI 学习之路(五十二)WebSockets(八)接受/发送json格式消息
前面我们发送的大多数都是text类型的消息,对于text消息来说,后端处理出来要麻烦的多,那么我们可以不可以传递json格式的数据,对于前后端来说都比较友好,答案是肯定的,我们需要做下处理。 首先,…...
Go语言并发编程-案例_3
案例 并发目录大小统计 业务逻辑 统计目录的文件数量和大小(或其他信息)。示例输出: // 某个目录:2637 files 1149.87 MB 实现思路 给定一个或多个目录,并发的统计每个目录的size,最后累加到一起。 当…...
pikachu之跨站脚本攻击(x‘s‘s)
1get型 输入a看一下 接着输入<a> 发现<>没有被过滤当做标签处理了 尝试在表单提交的框里面,输入xss语句 尝试输入<script>alert(1)</script> 发现有长度限制 因为这里是get请求 get请求的特点是:传参是在url中的 所以我们可以在…...
Qt模型/视图架构——委托(delegate)
一、为什么需要委托 模型(model)用来数据存储,视图(view)用来展示数据。因此,模型/视图架构是一种将数据存储和界面展示分离的编程方法。具体如下图所示: 由图可知,模型向视图提供数…...
python3.11SSL: SSLV3_ALERT_HANDSHAKE_FAILURE
参考:python request包 版本不兼容 报错sslv3 alert handshake failure 解决方法-CSDN博客 修改:Python311\Lib\site-packages\urllib3\util\ssl_.py 新版本3.11里默认没有DEFAULT_CIPHERS 补回来: #__imported from 3.6.8 # A secure default. # So…...
[深度学习]基于yolov10+streamlit目标检测演示系统设计
YOLOv10结合Streamlit构建的目标检测系统,不仅极大地增强了实时目标识别的能力,还通过其直观的用户界面实现了对图片、视频乃至摄像头输入的无缝支持。该系统利用YOLOv10的高效检测算法,能够快速准确地识别图像中的多个对象,并标注…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
Spring数据访问模块设计
前面我们已经完成了IoC和web模块的设计,聪明的码友立马就知道了,该到数据访问模块了,要不就这俩玩个6啊,查库势在必行,至此,它来了。 一、核心设计理念 1、痛点在哪 应用离不开数据(数据库、No…...
《C++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
【Linux】自动化构建-Make/Makefile
前言 上文我们讲到了Linux中的编译器gcc/g 【Linux】编译器gcc/g及其库的详细介绍-CSDN博客 本来我们将一个对于编译来说很重要的工具:make/makfile 1.背景 在一个工程中源文件不计其数,其按类型、功能、模块分别放在若干个目录中,mak…...
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
摘要 本文是《Spring Boot 实战派》系列的第四篇。我们将直面所有 Web 应用都无法回避的核心问题:安全。文章将详细阐述认证(Authentication) 与授权(Authorization的核心概念,对比传统 Session-Cookie 与现代 JWT(JS…...
面试高频问题
文章目录 🚀 消息队列核心技术揭秘:从入门到秒杀面试官1️⃣ Kafka为何能"吞云吐雾"?性能背后的秘密1.1 顺序写入与零拷贝:性能的双引擎1.2 分区并行:数据的"八车道高速公路"1.3 页缓存与批量处理…...
Linux 下 DMA 内存映射浅析
序 系统 I/O 设备驱动程序通常调用其特定子系统的接口为 DMA 分配内存,但最终会调到 DMA 子系统的dma_alloc_coherent()/dma_alloc_attrs() 等接口。 关于 dma_alloc_coherent 接口详细的代码讲解、调用流程,可以参考这篇文章,我觉得写的非常…...
