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

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、先学习路由&#xff0c;参考了5.1 2.1、建了一个cloudGatewayDemo&#xff0c;这是用来配置网关的工程&#xff0c;配置如下&#xff1a; http://localhost:18080/aaa/name 该接口代码如…...

数据结构——hash(hashmap源码探究)

hash是什么&#xff1f; hash也称为散列&#xff0c;就是把任意长度的输入&#xff0c;通过散列算法&#xff0c;变成固定长度的输出&#xff0c;这个输出值就是散列值。 举例来说明一下什么是hash&#xff1a; 假设我们要把1~12存入到一个大小是5的hash表中&#xff0c;我们…...

国产麒麟、UOS在线打开pdf加盖印章

PageOffice支持两种电子印章方案&#xff0c;可实现对Word、Excel、PDF文档加盖PageOffice自带印章或ZoomSeal电子印章&#xff08;全方位保护、防篡改、防伪造&#xff09;。Word和Excel的盖章功能请参考&#xff1a;Word和Excel加盖印章和签字功能 &#xff08;目前只支持win…...

破解反爬虫策略 /_guard/auto.js(二)实战

这次我们用上篇文章讲到的方法来真正破解一下反爬虫策略&#xff0c;这两个案例是两个不同的网站&#xff0c;一个用的是 /_guard/auto.js&#xff0c;另一个用的是/_guard/delay_jump.js。经过解析发现这两个网站用的反爬虫策略基本是一模一样&#xff0c;只不过在js混淆和生成…...

同样是人工智能 客户在哪儿AI和GPT等大模型有什么不同

书接上回。为了统一回答朋友们的疑惑&#xff0c;此前的两篇文章&#xff0c;着重讲述了客户在哪儿AI的企业全历史行为数据和企业信息查询平台上的数据的区别&#xff0c;以及客户在哪儿AI的ToB获客服务和AI外呼机器人的获客服务的不同。本期接着讲——客户在哪儿AI VS 大模型&…...

AES Android IOS H5 加密方案

前景&#xff1a; 1、本项目原有功能RSA客户端对敏感信息进行加密 2、本次漏洞说是服务端返回值有敏感信息&#xff0c;需要密文返回 3、最初只跟H5联调成功&#xff0c;后续APP联调失败(H5和APP的需求排期不一致)&#xff0c;没关注到通用性 方案&#xff1a; 本次方案不…...

一文了解变阻器和电位器的定义、原理、应用及其对比

变阻器的定义 两端可变电阻器&#xff08;称为变阻器&#xff09;利用电阻来调节电流。电阻丝环绕在陶瓷或瓷器等绝缘芯上。当刮水器沿着电阻丝移动时&#xff0c;电路的有效电阻会发生变化。因此&#xff0c;它提供了精确的电流控制。调光器、电机速度控制器和加热元件使用变…...

WPF实现一个带旋转动画的菜单栏

WPF实现一个带旋转动画的菜单栏 一、创建WPF项目及文件1、创建项目2、创建文件夹及文件3、添加引用 二、代码实现2.ControlAttachProperty类 一、创建WPF项目及文件 1、创建项目 打开VS2022,创建一个WPF项目&#xff0c;如下所示 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的幂&#xff08;即2的n次方&#xff09;非常经典。你懂几种方法呢&#xff1f;很多人只会一种&#xff0c;我们来分析一下。 可以通过多种方式实现&#xff1a; 1、最简单的方法之一是使用位运算符<<&#xff0c;它本质上是在二进制表示下对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 个点的无向图&#xff0c;其中 edges[i] [ui, vi, lengthi] 表示节点 ui 和节点 vi 之间有一条需要 lengthi 单位时间通过的无向边。 同时给你一个数组 disappear &#xff0c;其中 disappear[i] 表示节点 i 从图中消失的时间点&#xff0…...

FastAPI 学习之路(五十二)WebSockets(八)接受/发送json格式消息

前面我们发送的大多数都是text类型的消息&#xff0c;对于text消息来说&#xff0c;后端处理出来要麻烦的多&#xff0c;那么我们可以不可以传递json格式的数据&#xff0c;对于前后端来说都比较友好&#xff0c;答案是肯定的&#xff0c;我们需要做下处理。 首先&#xff0c;…...

Go语言并发编程-案例_3

案例 并发目录大小统计 业务逻辑 统计目录的文件数量和大小&#xff08;或其他信息&#xff09;。示例输出&#xff1a; // 某个目录&#xff1a;2637 files 1149.87 MB 实现思路 给定一个或多个目录&#xff0c;并发的统计每个目录的size&#xff0c;最后累加到一起。 当…...

pikachu之跨站脚本攻击(x‘s‘s)

1get型 输入a看一下 接着输入<a> 发现<>没有被过滤当做标签处理了 尝试在表单提交的框里面&#xff0c;输入xss语句 尝试输入<script>alert(1)</script> 发现有长度限制 因为这里是get请求 get请求的特点是&#xff1a;传参是在url中的 所以我们可以在…...

Qt模型/视图架构——委托(delegate)

一、为什么需要委托 模型&#xff08;model&#xff09;用来数据存储&#xff0c;视图&#xff08;view&#xff09;用来展示数据。因此&#xff0c;模型/视图架构是一种将数据存储和界面展示分离的编程方法。具体如下图所示&#xff1a; 由图可知&#xff0c;模型向视图提供数…...

python3.11SSL: SSLV3_ALERT_HANDSHAKE_FAILURE

参考&#xff1a;python request包 版本不兼容 报错sslv3 alert handshake failure 解决方法-CSDN博客 修改&#xff1a;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构建的目标检测系统&#xff0c;不仅极大地增强了实时目标识别的能力&#xff0c;还通过其直观的用户界面实现了对图片、视频乃至摄像头输入的无缝支持。该系统利用YOLOv10的高效检测算法&#xff0c;能够快速准确地识别图像中的多个对象&#xff0c;并标注…...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义&#xff08;Task Definition&…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

相机Camera日志实例分析之二:相机Camx【专业模式开启直方图拍照】单帧流程日志详解

【关注我&#xff0c;后续持续新增专题博文&#xff0c;谢谢&#xff01;&#xff01;&#xff01;】 上一篇我们讲了&#xff1a; 这一篇我们开始讲&#xff1a; 目录 一、场景操作步骤 二、日志基础关键字分级如下 三、场景日志如下&#xff1a; 一、场景操作步骤 操作步…...

【JVM】- 内存结构

引言 JVM&#xff1a;Java Virtual Machine 定义&#xff1a;Java虚拟机&#xff0c;Java二进制字节码的运行环境好处&#xff1a; 一次编写&#xff0c;到处运行自动内存管理&#xff0c;垃圾回收的功能数组下标越界检查&#xff08;会抛异常&#xff0c;不会覆盖到其他代码…...

零基础设计模式——行为型模式 - 责任链模式

第四部分&#xff1a;行为型模式 - 责任链模式 (Chain of Responsibility Pattern) 欢迎来到行为型模式的学习&#xff01;行为型模式关注对象之间的职责分配、算法封装和对象间的交互。我们将学习的第一个行为型模式是责任链模式。 核心思想&#xff1a;使多个对象都有机会处…...

【Oracle】分区表

个人主页&#xff1a;Guiat 归属专栏&#xff1a;Oracle 文章目录 1. 分区表基础概述1.1 分区表的概念与优势1.2 分区类型概览1.3 分区表的工作原理 2. 范围分区 (RANGE Partitioning)2.1 基础范围分区2.1.1 按日期范围分区2.1.2 按数值范围分区 2.2 间隔分区 (INTERVAL Partit…...

快刀集(1): 一刀斩断视频片头广告

一刀流&#xff1a;用一个简单脚本&#xff0c;秒杀视频片头广告&#xff0c;还你清爽观影体验。 1. 引子 作为一个爱生活、爱学习、爱收藏高清资源的老码农&#xff0c;平时写代码之余看看电影、补补片&#xff0c;是再正常不过的事。 电影嘛&#xff0c;要沉浸&#xff0c;…...

零知开源——STM32F103RBT6驱动 ICM20948 九轴传感器及 vofa + 上位机可视化教程

STM32F1 本教程使用零知标准板&#xff08;STM32F103RBT6&#xff09;通过I2C驱动ICM20948九轴传感器&#xff0c;实现姿态解算&#xff0c;并通过串口将数据实时发送至VOFA上位机进行3D可视化。代码基于开源库修改优化&#xff0c;适合嵌入式及物联网开发者。在基础驱动上新增…...

Vue 模板语句的数据来源

&#x1f9e9; Vue 模板语句的数据来源&#xff1a;全方位解析 Vue 模板&#xff08;<template> 部分&#xff09;中的表达式、指令绑定&#xff08;如 v-bind, v-on&#xff09;和插值&#xff08;{{ }}&#xff09;都在一个特定的作用域内求值。这个作用域由当前 组件…...

mac:大模型系列测试

0 MAC 前几天经过学生优惠以及国补17K入手了mac studio,然后这两天亲自测试其模型行运用能力如何&#xff0c;是否支持微调、推理速度等能力。下面进入正文。 1 mac 与 unsloth 按照下面的进行安装以及测试&#xff0c;是可以跑通文章里面的代码。训练速度也是很快的。 注意…...