轉發多臺px4仿真UDP數據到地面站

轉發腳本的任務需求

仿真采用UDP通信方式,在 wsl 中仿真三臺飛機,項目需要將一臺電腦中的三臺飛機的數據打包發送到另一臺飛機的地面站,但地面站是無法直接訪問另一臺主機的 wsl 中的端口的,wsl 中的端口需要本機才能訪問,接收數據,因此,需要編寫一個腳本在主機運行,接收 wsl 中仿真飛機的數據,通過主機的 ip 與端口發送給 app 的主機 ip 與端口(),并且,接收 app 的命令,轉發給三臺飛機(命令中會包含飛機id,因此腳本不需要做篩選,直接轉發給三個即可)。

目標端口與本機都需要在同一個局域網下(連接同一個wifi),整體框圖如下:

腳本編寫的注意點

仿真飛機的發送端口

仿真飛控在沒有收到地面站心跳包時,是往 14550 端口發送數據的,只有在收到自己預先配置的接收端口接收到數據后,才會往配置的接收端口發送數據,一般配置的端口都是 18570,多臺飛機就往后順延,18571,18572

地面站發送心跳也是必須往飛機配置的端口發送心跳才行,例如飛機是18570,那么必須往這個端口發心跳,飛控才會改為往18570發送數據。

代碼:

#! /usr/bin/env python
# -*-coding:utf-8-*
import socketimport socket
import threading
import time# 監控gcs發送的心跳包并轉發給飛機的心跳端口 14550 (心跳端口為多機共用端口)
def udp_listen_gcs_to_uav(gcs_sock, uav1_sock, uav2_sock, uav3_sock, uav_ip, uav1_port, uav2_port, uav3_port):# print("listen GCS UDP port") while True:# 接收數據        buffer_size = 255  #緩沖區大小        gcs_data, gcs_addr = gcs_sock.recvfrom(buffer_size)  #讀取gcs發送過來的數據包,轉發給wsl的飛控 print("addr:", gcs_addr, "data:", gcs_data)#發送數據到wsl的飛機地址與端口        uav1_sock.sendto(gcs_data, (uav_ip, uav1_port))uav2_sock.sendto(gcs_data, (uav_ip, uav2_port))uav3_sock.sendto(gcs_data, (uav_ip, uav3_port))# 監控uav1 18570 端口發送的消息并轉發給gcs端口
def udp_listen_uav_to_gcs(uav_sock, gsc_sock, gcs_ip, gcs_port):# print("listen uav UDP port:") while True:# 接收數據        buffer_size = 255  #緩沖區大小        uav_data, uav_addr = uav_sock.recvfrom(buffer_size)  #讀取gcs發送過來的數據包,轉發給wsl的飛控 # print("uav_addr:", uav_addr, "uav_data:", uav_data)  # 發送數據到wsl的飛機地址與端口        gsc_sock.sendto(uav_data, (gcs_ip, gcs_port))def main():self_UDP_IP = "172.16.20.86"  # 本機IP UDP通信可以不使用此字段    gcs_tx_ip = "172.16.20.16"    # gcs發送ip    gcs_tx_port = 14650  # gcs發送端口    gcs_rx_ip = "172.16.20.16"   # gcs接收ip    gcs_rx_port = 14650  # gcs接收端口    uav_ip = "172.27.21.175"  # 飛機的ip都是相同的    uav1_port = 18570   # 飛機1的端口號  在發送了心跳包后,需要與飛機在此端口進行通信    uav2_port = 18571   # 飛機1的端口號  在發送了心跳包后,需要與飛機在此端口進行通信    uav3_port = 18572   # 飛機1的端口號  在發送了心跳包后,需要與飛機在此端口進行通信    #創建與地面站以及與飛機通信的sock,之后傳入各個線程    gcs_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)gcs_sock.bind(('', gcs_tx_port))# 綁定使用哪個端口發送  要讓飛機往18570發送數據,因此心跳包也要從18570發送,飛控從18570接收到心跳包后,就會往18570發送自身數據    uav1_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)uav1_sock.bind(('', uav1_port))uav2_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)uav2_sock.bind(('', uav2_port))uav3_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)uav3_sock.bind(('', uav3_port))# 創建線程 監聽gcs的包之后轉發給飛控心跳端口 14550    listen_gcs_to_uav_thread = threading.Thread(target=udp_listen_gcs_to_uav, args=[gcs_sock, uav1_sock, uav2_sock, uav3_sock, uav_ip, uav1_port, uav2_port, uav3_port])# 創建線程 監聽wsl中的uav1,2,3端口消息 18570,18571,18572  并轉發給gcs端口    listen_uav1_to_gcs_thread = threading.Thread(target=udp_listen_uav_to_gcs, args=[uav1_sock, gcs_sock, gcs_rx_ip, gcs_rx_port])listen_uav2_to_gcs_thread = threading.Thread(target=udp_listen_uav_to_gcs, args=[uav2_sock, gcs_sock, gcs_rx_ip, gcs_rx_port])listen_uav3_to_gcs_thread = threading.Thread(target=udp_listen_uav_to_gcs, args=[uav3_sock, gcs_sock, gcs_rx_ip, gcs_rx_port])listen_gcs_to_uav_thread.start()listen_uav1_to_gcs_thread.start()listen_uav2_to_gcs_thread.start()listen_uav3_to_gcs_thread.start()# 等待線程結束    listen_gcs_to_uav_thread.join()  # 等待心跳包發送完成后就啟動下一個任務    listen_uav1_to_gcs_thread.join()listen_uav2_to_gcs_thread.join()listen_uav3_to_gcs_thread.join()# Press the green button in the gutter to run the script.
if __name__ == '__main__':main()

在上述代碼中,UDP 在接收時是用不到此ip的,也就是 gcs_sock.bind(('', gcs_tx_port)),函數中的 ip 可以不填,只需要將端口號填對即可,但在發送時,需要指定 ip,而且在給飛控發送心跳時,需要綁定端口號為飛機的端口號

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/79801.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/79801.shtml
英文地址,請注明出處:http://en.pswp.cn/web/79801.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

FPGA圖像處理(五)------ 圖片水平鏡像

利用bram形成雙緩沖,如下圖配置所示: wr_flag 表明 buffer0寫 還是 buffer1寫 rd_flag 表明 buffer0讀 還是 buffer1讀 通過寫入邏輯控制(結合wr_finish) 寫哪個buffer ;寫地址 進而控制ip的寫使能 通過狀態緩存來跳轉buffer的…

微服務八股(自用)

微服務 SpringCloud 注冊中心:Eureka 負載均衡:Ribbon 遠程調用:Feign 服務熔斷:Hystrix 網關:Gateway/Zuul Alibaba 配置中心:Nacos 負載均衡:Ribbon 服務調用:Feign 服務…

ESP32_IDF_OTA_HTTP升級固件

ESP32_IDF_OTA_HTTP升級固件 前言:一個項目的主控使用的是ESP32,因為封裝外殼的原因,所以需要采用OTA的方式進行升級,因為之前有對WIFI的OTA有所了解,所以在此基礎上,使用官方提供的native_ota_example例程…

MySQL表結構化:數據類型與表生命周期詳解

引言 各位數據庫學習者大家好!今天我們將深入探討MySQL中最核心的對象——表(Table)的各類操作 🎯。表是存儲數據的基石,就像Excel中的工作表一樣,但功能要強大得多!無論是電商網站的用戶信息&…

React中的狀態管理Dva總結

在 React 開發中,隨著應用的復雜度增加,如何高效地管理應用狀態成為了一個非常重要的問題。為了解決這一問題,很多開發者選擇了 Redux,然而 Redux 的學習曲線較陡,且需要配置較多的樣板代碼。為此,Ant Desi…

數據結構中的高級排序算法

希爾排序 你可以將希爾排序理解成——先通過幾次分組的、較小的組間插入排序將原數組變得有序&#xff0c;最后再進行一次序列基本有序的完整插入排序。 #include <stdio.h>#define ARR_LEN(arr) (sizeof(arr) / sizeof(arr[0]))void print_arr(int arr[], int len) {for…

計算機視覺最不卷的方向:三維重建學習路線梳理

提到計算機視覺&#xff08;CV&#xff09;&#xff0c;大多數人腦海中會立馬浮現出一個字&#xff1a;“卷”。卷到什么程度呢&#xff1f;2022年秋招CV工程師崗位數下降了16%&#xff0c;但求職人數增加了23%&#xff0c;求職人數與招聘崗位的比例達到了恐怖的15:1&#xff0…

【Docker】Docker環境下快速部署Ollama與Open-WebUI:詳細指南

Docker環境下快速部署Ollama與Open-WebUI&#xff1a;詳細指南 在本篇文章中&#xff0c;我們將深入探討如何在Docker中高效部署 Ollama 和 Open-WebUI&#xff0c;并解決在實際使用中常見的問題&#xff0c;確保你的模型服務穩定高效地運行。 一、Ollama 和 Open-WebUI 快速部…

Vue3學習(組合式API——Watch偵聽器詳解)

目錄 一、Watch偵聽器。 &#xff08;1&#xff09;偵聽單個數據。 &#xff08;2&#xff09;偵聽多個數據。&#xff08;數組寫法&#xff1f;&#xff01;&#xff09; &#xff08;3&#xff09;immediate參數。(立即執行回調) &#xff08;3&#xff09;deep參數。(深層監…

SARIMA-LSTM融合模型對太陽黑子數量預測分析|附智能體數據代碼

全文智能體鏈接&#xff1a;https://tecdat.cn/?p41969 分析師&#xff1a;Peng Fan 本研究以太陽黑子活動數據為研究對象&#xff0c;旨在幫助客戶探索其未來走勢并提供預測分析。首先&#xff0c;通過對數據的清洗和處理&#xff0c;包括離群值的識別與處理以及時間序列的建…

簡單易懂的JavaScript中的this指針

文章目錄 默認綁定 / 隱式綁定如何調整this1.用變量固定this2.箭頭函數2.bind3.call/apply&#xff08;一次性&#xff09; 默認綁定 / 隱式綁定 要找this指針指向誰&#xff0c;我們首先要做的是&#xff1a;找到一個明確的對象&#xff0c;這個對象調用了含有this指針的函數…

Spring MVC數據綁定和響應 你了解多少?

數據綁定的概念 在程序運行時&#xff0c;Spring MVC接收到客戶端的請求后&#xff0c;會根據客戶端請求的參數和請求頭等數據信息&#xff0c;將參數以特定的方式轉換并綁定到處理器的形參中。Spring MVC中將請求消息數據與處理器的形參建立連接的過程就是Spring MVC的數據綁…

BMS工具箱用來執行貝葉斯模型平均(BMA)計算模塊

貝葉斯模型平均&#xff08;Bayesian Model Averaging&#xff0c;BMA&#xff09;是一種用于處理模型不確定性的統計方法&#xff0c;通過結合多個模型的預測結果來提高預測的準確性和魯棒性。在 MATLAB 中&#xff0c;可以使用專門的工具箱&#xff08;如 BMS 工具箱&#xf…

Java內存馬的檢測與發現

【網絡安全】Java內存馬的檢測與發現 一、Java內存馬的現象二、檢測思路三、重點關注類四、檢測方法1. 檢查方法&#xff08;FindShell&#xff09;2. 檢查方法&#xff08;sa-jdi&#xff09;3. 檢查方法&#xff08;arthas-boot&#xff09;4. 檢查方法&#xff08;cop.jar&a…

ISP有感自發

一、黑電平 由于傳感器&#xff0c;即便在無光的情況下&#xff0c;依然會產生微小的暗電流&#xff0c;這些暗電流可能是噪點會影響后期的調試。因此&#xff0c;我們便將這些電流處理為0&#xff0c;成為純黑的顏色。可以在源頭消除這些誤差。 如何矯正黑電平&#xff1a; …

數字信號處理-大實驗1.1

MATLAB仿真實驗目錄 驗證實驗&#xff1a;常見離散信號產生和實現驗證實驗&#xff1a;離散系統的時域分析應用實驗&#xff1a;語音信號的基音周期&#xff08;頻率&#xff09;測定 目錄 一、常見離散信號產生和實現 1.1 實驗目的 1.2 實驗要求與內容 1.3 實驗…

【SSL證書系列】https雙向認證中客戶端認證的原理

HTTPS雙向認證&#xff08;也稱為雙向SSL/TLS認證&#xff09;是一種增強安全性的機制&#xff0c;其中客戶端和服務器都需要驗證彼此的數字證書&#xff0c;以確保雙方身份的真實性。以下是其核心原理和步驟的詳細解析&#xff1a; 一、雙向認證的核心目標 雙向身份驗證&#…

Linux系統編程——fork函數的使用方法

在 Linux 系統編程 中&#xff0c;fork() 函數是創建新進程的關鍵系統調用。fork() 在當前進程&#xff08;父進程&#xff09;中創建一個幾乎完全相同的子進程。子進程和父進程從調用 fork() 的位置繼續執行&#xff0c;但它們是兩個獨立的進程&#xff0c;每個進程都有自己的…

LLMs之ChatGPT:《Connecting GitHub to ChatGPT deep research》翻譯與解讀

LLMs之ChatGPT&#xff1a;《Connecting GitHub to ChatGPT deep research》翻譯與解讀 導讀&#xff1a;這篇OpenAI幫助文檔全面介紹了將GitHub連接到ChatGPT進行深度代碼研究的方法、優勢和注意事項。通過連接GitHub&#xff0c;用戶可以充分利用ChatGPT強大的代碼理解和生成…

flutter 視頻通話flutter_webrtc

flutter 比較熱門的庫 flutter_webrtc | Flutter package agora_rtc_engine | Flutter package 我使用的是flutter_webrtc 下面是官方推薦的demo庫 GitHub - flutter-webrtc/flutter-webrtc-demo: Demo for flutter-webrtc 其中 https://demo.cloudwebrtc.com:8086/ 已經停…