ArduPilot开源代码之AP_MSP

ArduPilot开源代码之AP_MSP

  • 1. 源由
  • 2. Library设计
    • 2.1 启动代码
    • 2.2 支持特性
    • 2.3 MSP DisplayPort v.s. DJI FPV OSD
  • 3. 重要例程
    • 3.1 AP_MSP::init
    • 3.2 AP_MSP::loop
    • 3.3 AP_MSP::init_backend
  • 4. 实例理解
  • 5. 总结
  • 6. 参考资料

1. 源由

AP_MSP是处理MSP协议格式的报文数据应用类。

关于MSP协议格式,我们之前已经做过比较详细讨论,有兴趣具体了解,请查阅相关资料:

  • BetaFlight模块设计之三十二:MSP协议模块分析
  • iNavFlight之MSP DJI协议分析
  • iNavFlight之MSP DJI协议天空端请求报文
  • iNavFlight之MSP DJI协议飞控端请求应答
  • iNavFlight之MSP v2 Sensor报文格式
  • iNavFlight之RC遥控MSP协议

2. Library设计

2.1 启动代码

AP_Vehicle::setup└──> AP_MSP::init└──> hal.scheduler->thread_create(FUNCTOR_BIND_MEMBER(&AP_MSP::loop, void), "MSP", 1024, AP_HAL::Scheduler::PRIORITY_IO, 1)

整个应用框架通过以下两个函数实现:

  • AP_MSP::init //初始化
  • AP_MSP::loop //遍历轮训

2.2 支持特性

  • 支持SerialProtocol_MSP:通用MSP协议
  • 支持SerialProtocol_DJI_FPV:DJI FPV OSD协议
  • 支持SerialProtocol_MSP_DisplayPort:MSP Display Port

2.3 MSP DisplayPort v.s. DJI FPV OSD

MSP DisplayPort 和 DJI FPV OSD 协议之间的主要区别在于它们的应用领域和功能。以下是两者的详细对比:

  • MSP DisplayPort
    MSP(MultiWii Serial Protocol) DisplayPort 是一种用于传输飞行控制器和显示设备之间数据的协议。它主要用于发送实时飞行数据到显示器或OSD(On-Screen Display)。这是一个开源协议,广泛用于开源飞行控制器固件如Betaflight、iNav等。

特点:

  1. 开源协议:MSP 是开源的,允许开发者根据需要进行修改和扩展。
  2. 灵活性:可以传输各种类型的飞行数据,如GPS信息、电池状态、飞行模式等。
  3. 兼容性:与多种飞行控制器和OSD设备兼容,广泛应用于自制和定制无人机系统。
  • DJI FPV OSD
    DJI FPV OSD(On-Screen Display) 是由 DJI 提供的专有协议,专门用于其 FPV(First Person View)系统。这一协议用于在飞行时将实时飞行数据和视频传输到FPV眼镜或显示器上。

特点:

  1. 专有协议:DJI FPV OSD 是专有协议,专门为 DJI 的 FPV 产品设计。
  2. 集成性强:与 DJI 生态系统高度集成,提供无缝的用户体验。
  3. 功能丰富:提供高质量的视频传输和实时飞行数据,通常包括摄像头切换、飞行模式、GPS信息、电池状态等。
  • 主要差异
  1. 开放性

    • MSP DisplayPort 是开源协议,允许广泛的社区贡献和定制。
    • DJI FPV OSD 是闭源的,仅限于 DJI 设备使用。
  2. 应用范围

    • MSP DisplayPort 广泛应用于多种飞行控制器和显示设备。
    • DJI FPV OSD 专用于 DJI 的 FPV 系统。
  3. 兼容性

    • MSP DisplayPort 兼容多种设备和系统。
    • DJI FPV OSD 仅兼容 DJI 的产品。
  4. 功能与扩展性

    • MSP DisplayPort 提供了灵活的飞行数据传输,可以根据需要扩展。
    • DJI FPV OSD 集成了高质量的视频传输和各种飞行数据,但其扩展性受到限制,因为它是闭源的。

总体来说,MSP DisplayPort 更适合于那些需要灵活性和可定制性的开源无人机项目,而 DJI FPV OSD 则为使用 DJI 设备的用户提供了更集成和便捷的解决方案。

3. 重要例程

3.1 AP_MSP::init

AP_MSP::init
|
├── 获取串行管理器的引用 (const AP_SerialManager &serial_manager = AP::serialmanager())
|
├── 初始化 UART 指针 (AP_HAL::UARTDriver *uart = nullptr)
|
├── 初始化使用 MSP 线程的后端计数 (uint8_t backends_using_msp_thread = 0)
|
├── 定义支持的 MSP 协议数组 (static const AP_SerialManager::SerialProtocol msp_protocols[])
|   ├── AP_SerialManager::SerialProtocol_DJI_FPV
|   ├── AP_SerialManager::SerialProtocol_MSP
|   └── #if HAL_WITH_MSP_DISPLAYPORT
|       └── AP_SerialManager::SerialProtocol_MSP_DisplayPort
|       #endif
|
├── 遍历 MSP 协议数组 (for (const auto msp_protocol: msp_protocols))
|   ├── 遍历协议实例 (for (uint8_t protocol_instance=0; protocol_instance<MSP_MAX_INSTANCES-_msp_status.backend_count; protocol_instance++))
|       ├── 找到对应的串口 (uart = serial_manager.find_serial(msp_protocol, protocol_instance))
|       |
|       ├── 如果找到 UART 串口且初始化后端失败,则跳出当前循环 (if (uart != nullptr))
|       |   └── if (!init_backend(_msp_status.backend_count, uart, msp_protocol)) { break; }
|       |
|       ├── 如果后端使用 MSP 线程,增加使用 MSP 线程的后端计数 (if (_backends[_msp_status.backend_count]->use_msp_thread()))
|       |   └── backends_using_msp_thread++
|       |
|       └── 增加后端计数 (_msp_status.backend_count++)
|
└── 如果至少找到一个使用 MSP 线程的后端,启动协议处理线程 (if (backends_using_msp_thread > 0))└── if (!hal.scheduler->thread_create(FUNCTOR_BIND_MEMBER(&AP_MSP::loop, void), "MSP", 1024, AP_HAL::Scheduler::PRIORITY_IO, 1)) { return; }

3.2 AP_MSP::loop

AP_MSP::loop()
│
├── 初始化 UART (for loop)
│   ├── _backends[i] != nullptr && _backends[i]->use_msp_thread()
│   └── _backends[i]->init_uart()
│
├── 无限循环 while (true)├── 延迟 hal.scheduler->delay(10)├── 获取当前时间 const uint32_t now = AP_HAL::millis()├── 闪烁逻辑│   ├── (uint32_t(now * 0.00143) & 0x01) != _msp_status.flashing_on│   └── (uint32_t(now * 0.0005) & 0x01) != _msp_status.slow_flashing_on├── 检测飞行模式变化│   ├── AP::notify().flags.flight_mode != _msp_status.last_flight_mode│   └── now - _msp_status.last_flight_mode_change_ms > OSD_FLIGHT_MODE_FOCUS_TIME├── 屏幕变化检测 (if OSD_ENABLED)│   └── osd != nullptr│       └── _msp_status.current_screen != screen || !_msp_status.osd_initialized│           └── update_osd_item_settings()└── 处理后台数据 (for loop)├── _backends[i] != nullptr && _backends[i]->use_msp_thread()├── _backends[i]->hide_osd_items()├── _backends[i]->process_incoming_data()└── _backends[i]->process_outgoing_data()

3.3 AP_MSP::init_backend

AP_MSP::init_backend
|
|-- if (protocol == AP_SerialManager::SerialProtocol_MSP)
|   |-- 创建 AP_MSP_Telem_Generic 实例
|
|-- else if (protocol == AP_SerialManager::SerialProtocol_DJI_FPV)
|   |-- 创建 AP_MSP_Telem_DJI 实例
|
|-- #if HAL_WITH_MSP_DISPLAYPORT
|   |-- else if (protocol == AP_SerialManager::SerialProtocol_MSP_DisplayPort)
|       |-- 创建 AP_MSP_Telem_DisplayPort 实例
|
|-- else
|   |-- 返回 false
|
|-- if (_backends[backend_idx] != nullptr)
|   |-- 初始化后端实例
|   |-- 返回 true
|
|-- 返回 false

4. 实例理解

  • ArduPilot开源飞控之AP_Baro_MSP
  • TBD … … //后续补充

5. 总结

其实Ardupilot代码从框架设计的角度来看,非常透明、简洁、当然实际应用过程也存在一些资源剪裁问题。

总的来说,目前betaflight/inav开发航模生态下,MSP协议还是非常普及的。了解这块协议,对于兼容和集成会有很大的帮助。

6. 参考资料

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

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

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

相关文章

反向业务判断逻辑

业务功能需求&#xff1a; 根据id扣减用户余额 包括&#xff1a;判断用户状态是否正常判断用户余额是否充足 正向逻辑&#xff1a; 判断用户为正常下&#xff0c;判断用户余额充足&#xff0c;进行余额扣减&#xff1b; 》正向逻辑&#xff0c;多重嵌套&#xff0c;代码不美观…

✈️一文带你入门【NestJS】

✈️引言 在现代Web开发领域&#xff0c;框架和技术的迭代速度令人咋舌。其中&#xff0c;NestJS作为一款基于Node.js的后端框架&#xff0c;以其卓越的设计理念和强大的功能集&#xff0c;迅速吸引了众多开发者的眼球。本文将带你深入了解NestJS的起源、发展&#xff0c;以及…

SpringIOC原理

SpringIOC原理 1.概念 Spring通过一个配置文件描述Bean及Bean之间的依赖关系&#xff0c;利用Java语言的反射功能实例化Bean并建立Bean之间的依赖关系。Spring的IOC容器在完成这些底层工作的基础上&#xff0c;还提供了Bean实例缓存、生命周期管理、Bean实例代理、事件发布、…

AI提示词:AI辅导「数学作业」

辅导孩子作业对许多家长来说可能是一件头疼的事&#xff0c;但这部分工作可以在一定程度上交给AI来完成。 打开ChatGPT4,输入以下内容&#xff1a; # Role 数学辅导专家## Profile - author: 姜小尘 - version: 02 - LLM: Kimi - language: 中文 - description: 专门为小学生…

加密算法详解:对称加密、非对称加密、Hash算法

对称加密、非对称加密和哈希算法是信息安全中的三种主要加密技术&#xff0c;它们各自有不同的特点和用途&#xff1a; 对称加密&#xff08;Symmetric Encryption&#xff09; 工作原理&#xff1a;使用相同的密钥进行加密和解密。速度&#xff1a;通常非常快&#xff0c;适…

Elasticsearch:Node.js ECS 日志记录 - Morgan

这是之前系列文章&#xff1a; Elasticsearch&#xff1a;Node.js ECS 日志记录 - Pino Elasticsearch&#xff1a;Node.js ECS 日志记录 - Winston 中的第三篇文章。在今天的文章中&#xff0c;我将描述如何使用 Morgan 包针对 Node.js 应用进行日子记录。此 Morgan Node.j…

包装器 std::function

使用前&#xff0c;包头文件&#xff1a;#include <functional> std::function 是 C标准库 中的一个通用函数包装器&#xff1b; 它可以储存、复制、调用任何可调用的对象&#xff0c;包括&#xff1a;函数指针、成员函数、绑定的成员函数、lambda表达式、仿函数等。 1…

Selenium Grid- 让自动化分布式执行变得可能

什么是 Selenium Grid&#xff1f; Selenium Grid 是 Selenium 的三大组件之一&#xff0c;允许用户同时在不同的机器和系统上测试不同浏览器。 也就是说 Selenium Grid 支持分布式的测试执行。它可以让你的测试用例在一个分布式的执行环境中运行。 由上图可见&#xff0c;测试…

linux:基础知识及命令[图表]

lsof:查找文件 普通文件、目录、进程&#xff08;/proc&#xff09;、输入输出设备&#xff08;/dev&#xff09;、网络字节流socket、链接文件、管道文件 基本用法 lsof&#xff1a;列出所有打开的文件。lsof /path/to/file&#xff1a;列出打开指定文件的所有进程。lsof -…

大话光学原理:4.散射:瑞利、拉曼、米氏和布里渊

这是一缕柔和的光&#xff0c;在空气的舞台上轻盈地跳跃。它悠然自得&#xff0c;在宁静的空间中缓缓前行。然而&#xff0c;一片细薄透明的介质挡住了它的脚步&#xff0c;它毫无预兆地撞上了这片障碍。在这短暂的接触中&#xff0c;它被分解成无数微小的粒子&#xff0c;被迫…

增强现实(AR)与虚拟现实(VR)的区别?

随着科技的飞速发展&#xff0c;增强现实&#xff08;AR&#xff09;与虚拟现实&#xff08;VR&#xff09;技术在各个领域展现出巨大的潜力和应用前景。这两种技术虽然在体验和实现方式上有所不同&#xff0c;但都为用户提供了全新的感知体验。本文将详细解析AR和VR的概念、区…

机器视觉/自然语言/生成式人工智能综合应用实验平台-实训平台-教学平台

AIGC是人工智能1.0时代进入2.0时代的重要标志&#xff0c;MIT 科技评论也将Al合成数据列为2022年十大突破性技术之一&#xff0c;甚至将生成性Al(Generative Al) 称为是AI领域过去十年最具前景的进展。同时&#xff0c;AIGC领域岗位需求数量暴涨。高校方面在人工智能专业与机器…

javascript 处理###分隔的字符串

在 JavaScript 中&#xff0c;可以使用 split 方法将字符串按 ### 分隔成数组。以下是一个示例代码&#xff0c;展示了如何处理由 ### 分隔的字符串&#xff1a; 示例代码 // 示例字符串 let str "part1###part2###part3###part4";// 使用 split 方法按 ### 分隔字…

DEJA_VU3D - Cesium功能集 之 122-体元渲染(官方Voxels)

前言 编写这个专栏主要目的是对工作之中基于Cesium实现过的功能进行整合,有自己琢磨实现的,也有参考其他大神后整理实现的,初步算了算现在有差不多实现小140个左右的功能,后续也会不断的追加,工作原因可能无法像以前那样周更2-3篇,但是闲下来还是会不定期的更新,Cesium…

tensorflow张量生成以及常用函数

张量tensor&#xff1a;多维数组&#xff08;列表&#xff09; 阶&#xff1a;张量的维数 维数 阶 名字 例子 0-D 0 标量 scalar s 1&#xff0c; 2&#xff0c; 3 1-D 1 向量 vector…

How do I format markdown chatgpt response in tkinter frame python?

题意&#xff1a;怎样在Tkinter框架中使用Python来格式化Markdown格式的ChatGPT响应&#xff1f; 问题背景&#xff1a; Chatgpt sometimes responds in markdown language. Sometimes the respond contains ** ** which means the text in between should be bold and ### te…

Python数据分析-天气类型预测分析

一、研究背景 近年来&#xff0c;随着全球气候变化的加剧&#xff0c;天气预报和气象预测变得越来越重要。准确的天气预测不仅能够帮助人们做好日常生活的安排&#xff0c;还能在农业生产、防灾减灾等方面起到关键作用。随着大数据技术和机器学习算法的快速发展&#xff0c;利…

科普文:深入理解负载均衡(四层负载均衡、七层负载均衡)

概叙 网络模型&#xff1a;OSI七层模型、TCP/IP四层模型、现实的五层模型 应用层&#xff1a;对软件提供接口以使程序能使用网络服务&#xff0c;如事务处理程序、文件传送协议和网络管理等。&#xff08;HTTP、Telnet、FTP、SMTP&#xff09; 表示层&#xff1a;程序和网络之…

基于vue的地图特效(飞线和标注)

这段代码的主要功能是在页面加载完成后&#xff0c;初始化一个 echarts 地图图表&#xff0c;并配置了相关的地理数据、散点数据、线条数据以及样式效果&#xff0c;最后在指定的 div 元素中进行展示。 需要再vue中的框架实现&#xff0c;不能单独直接运行。 标注 type: effe…

Python30 使用Gensim库实现Word2Vec对文本进行处理

1.Word2Vec Word2Vec 是一种将词语表示为向量的技术&#xff0c;能够捕捉词语之间的语义关系。它由 Google 的 Tomas Mikolov 等人在 2013 年提出&#xff0c;广泛应用于自然语言处理任务中。其核心概念主要包括&#xff1a; 词嵌入&#xff08;Word Embeddings&#xff09; …