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.pswp.cn/web/42930.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/42930.shtml
英文地址,請注明出處:http://en.pswp.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; …