OpenIPC開源FPV之Adaptive-Link天空端代碼解析

OpenIPC開源FPV之Adaptive-Link天空端代碼解析

  • 1. 源由
  • 2. 框架代碼
    • 2.1 消息機制
    • 2.2 超時機制
  • 3. 報文處理
    • 3.1 special報文
    • 3.2 普通報文
  • 4. 工作流程
    • 4.1 `Profile` 競選
    • 4.2 `Profile` 研判
      • 4.2.1 回退策略
      • 4.2.2 保持策略
    • 4.3 `Profile` 應用
  • 5. 總結
  • 6. 參考資料
  • 7. 補充資料
    • 7.1 RSSI 和 SNR 的物理含義
    • 7.2 信號質量加權的理論依據
    • 7.3 實際應用中的加權方法
    • 7.4 加權方法的優化
    • 7.5 綜合考慮信號質量的模型
    • 7.6 8812EU WiFi模塊

1. 源由

在《OpenIPC開源FPV之Adaptive-Link工程解析》中,已經有了整個工程的大體概念,接下來再對代碼進行逐步分析。

首先,對天空端的代碼進行分析:ALink42n.c

2. 框架代碼

ALink42n.c相對來說,代碼量最少,也是最為基本的一份代碼。

目前,尚不太清楚具體n/p/q之間的差異,邏輯上看應該是關于切換配置profile的條件計算方式不太一樣,對于穩定性、可靠性方面應該有所差異。

  • The relationship between .c and binary files #7

注:感興趣的朋友,可以跟下帖子,不過隨著代碼的深入了解,以及性能測試數據,也能慢慢明晰之間的差異。

2.1 消息機制

  • 加載配置 - “/etc/alink.conf”
  • 加載Profile - “/etc/txprofiles.conf”
  • majestic:80
  • wfb-cli:8000
  • Terminal:bash
  • 綁定默認IP - 10.5.0.10:9999

n/p/q只有q寫的是10.5.0.10,其他是10.5.0.2,應該有筆誤。

  • 接受兩種UDP報文:special報文和普通報文
main├──> load_config(CONFIG_FILE); // "/etc/alink.conf"├──> load_profiles(PROFILE_FILE); // "/etc/txprofiles.conf"├──> bind DEFAULT_IP(10.5.0.10) DEFAULT_PORT(9999)├──>loop recvfrom│   ├──> <special:> special_command_message(message);│   └──> process_message(message);└──> close(sockfd);

2.2 超時機制

當長時間未收到報文,則進行最大功率設置。

count_messages (void *arg)
│
├──> while (1)                                   // Infinite loop
│   ├──> usleep(fallback_ms * 1000);              // Sleep for 'fallback_ms' milliseconds
│   │
│   ├──> pthread_mutex_lock(&count_mutex);       // Lock the count_mutex to safely access shared data
│   │   ├── local_count = message_count;        // Store current message count into local_count
│   │   ├── message_count = 0;                  // Reset the message count to 0
│   │   └── pthread_mutex_unlock(&count_mutex); // Unlock the count_mutex after accessing shared data
│   │
│   ├──> pthread_mutex_lock(&pause_mutex);       // Lock the pause_mutex to safely check and change 'paused'
│   │   ├──> if (local_count == 0 && !paused) {  // If no messages received and not paused:
│   │   │   ├──> printf("No messages received in %dms, sending 999\n", fallback_ms);
│   │   │   └──> start_selection(999, 1000);    // Call start_selection with parameters 999 and 1000
│   │   ├──> else {                              // If messages are received or paused:
│   │   │   ├──> if (verbose_mode) {             // If verbose mode is enabled:
│   │   │   │   └──> printf("Messages per %dms: %d\n", fallback_ms, local_count);
│   │   │   └──> }                               // End of verbose_mode check
│   │   └──> }                                   // End of else block
│   └──> pthread_mutex_unlock(&pause_mutex);     // Unlock the pause_mutex after checking 'paused' status
│
└──> return NULL;                                 // Return NULL from the function (indicates thread termination)

3. 報文處理

+--------------+---------------+-------------+
|              | special? (8B) | Msg content |
| Msg len (4B) |---------------+-------------|
|              | RF Signal Estimated Values  |
+--------------+---------------+-------------+

3.1 special報文

  • 報文格式:
+--------------+---------------+-------------+
| Msg len (4B) | special? (8B) | Msg content |
+--------------+---------------+-------------+
  • 代碼流程:

處理pause_adaptive/resume_adaptive/request_keyframe命令

special_command_message├──> "pause_adaptive"│   └──> paused = true├──> "resume_adaptive"│   └──> paused = false├──> "drop_gop"│   └──> // 已經注釋掉,代碼暫時保留├──> "request_keyframe"│   └──> < > request_keyframe_interval_ms> `idrCommand`└──> "Unknown"

3.2 普通報文

  • 報文格式:
+--------------+------------------+-----------------+----------------+-----------+------+-------+-------+---------------+
| Msg len (4B) | transmitted_time | link_value_rssi | link_value_snr | recovered | lost | rssi1 | rssi2 | rssi3 | rssi4 |
+--------------+------------------+-----------------+----------------+-----------+------+-------+-------+---------------+
  • 代碼流程:

解析地面端報文反饋的RF信號參數,比如:RSSI/SNR等

process_message├──> [index/token parse]│   ├──> <0> transmitted_time = atoi(token);│   ├──> <1> link_value_rssi = atoi(token);│   ├──> <2> link_value_snr = atoi(token);│   ├──> <3> recovered = atoi(token);│   ├──> <4> lost = atoi(token);│   ├──> <5> rssi1 = atoi(token);│   ├──> <6> rssi2 = atoi(token);│   ├──> <7> rssi3 = atoi(token);│   ├──> <8> rssi4 = atoi(token);│   └──> <.> Ignore extra tokens├──> <!time_synced> settimeofday(&tv, NULL)└──> <!paused> start_selection(link_value_rssi, link_value_snr);

4. 工作流程

4.1 Profile 競選

2.1 paused 為 false 時,滿足觸發條件則進行 start_selection

start_selection├──> <selection_busy> return├──> <rssi_score == 999> value_chooses_profile(999); // Default settings│   └──> return├──> int combined_value = floor(rssi_score * w_rssi + snr_score * w_snr);├──> constrain(1000, 2000, combined_value)├──> float percent_change = fabs((float)(value - baseline_value) / baseline_value) * 100;└──> <percent_change >= hysteresis_percent>└──> <time_diff_ms >= min_between_changes_ms> value_chooses_profile(value); // apply new settings

注:這里采用了 rssisnr 權重方式。

4.2 Profile 研判

Profile 競選成功后,在實際應用時,需要檢查觸發條件,比如:如果當前為需要切換的 Profile則無需觸發。

value_chooses_profile├──> Profile* selectedProfile = get_profile(input_value);├──> [Find the index of the selected profile]├──> <previousProfile == currentProfile> return // no changes├──> <previousProfile == 0 && timeElapsed <= hold_fallback_mode_s> return // first profile in fallback time├──> <(currentProfile - previousProfile == 1) && timeElapsed <= hold_modes_down_s> // just one step difference in hold time└──> apply_profile(selectedProfile)

無縫的觸發場景判斷,能夠確保信號的穩定傳輸和平滑切換:

  • what’s the difference between hold_fallback_mode_s and hold_modes_down_s? #9

4.2.1 回退策略

滿足下面條件,無需觸發回退策略;反之,則進入最大發射效率模式。

  • 前一次 Profile 已經指向 index=0
  • 最近一次檢測時間沒有超過 hold_fallback_mode_s 設置
    if (previousProfile == 0 && timeElapsed <= hold_fallback_mode_s) {if (verbose_mode) {puts("Holding fallback...");}return false;}

原因:回退策略是確保無接收端信號時,保持最大發射效率(Do the Best)。

4.2.2 保持策略

滿足下面條件,觸發保持策略;反之,則進入執行當前 Profile 切換。

  • 前一次 Profile 比當前競選 Profile發射效率更大
  • 最近一次檢測時間沒有超過 hold_modes_down_s 設置
    if (previousProfile < currentProfile && timeElapsed <= hold_modes_down_s) {if (verbose_mode) {puts("Holding mode down...");}return false;}

原因:發射效率降低時,保持并不影響信號傳輸質量(信號傳輸并非功率敏感應用)。

4.3 Profile 應用

這里需要注意幾個細節:

  • 功率增加/減小其命令執行順序不一致
  • 綜合信號質量來選擇不同的GI/MCS/FecK/FecN/Bitrate/Gop/Power/ROIqp
apply_profile
├──> Local Variables Initialization
│   └──> Command Templates and Time Calculation
├──> Load Profile Variables into Local Variables
│   └── Copy values from `profile` into local variables
├──> Profile Comparison (currentProfile vs previousProfile)
│   ├──> If currentProfile > previousProfile:
│   │   ├──> Execute Power Command if changed      // "iw dev wlan0 set txpower fixed %d"
│   │   ├──> Execute GOP Command if changed        // "curl -s 'http://localhost/api/v1/set?video0.gopSize=%f'"
│   │   ├──> Execute MCS Command if changed        // "wfb_tx_cmd 8000 set_radio -B 20 -G %s -S 1 -L 1 -M %d"
│   │   ├──> Execute FEC Command if changed        // "wfb_tx_cmd 8000 set_fec -k %d -n %d"
│   │   ├──> Execute Bitrate Command if changed    // "curl -s 'http://localhost/api/v1/set?video0.bitrate=%d'"
│   │   ├──> Execute ROI Command if changed        // "curl -s 'http://localhost/api/v1/set?fpv.roiQp=%s'"
│   │   └──> Execute IDR Command if enabled        // "curl localhost/request/idr"
│   └──> Else (if currentProfile <= previousProfile):
│       └──> Execute commands in different order
└──> Display Stats (msposdCommand)└──> Execute `msposdCommand`                   // "echo '%ld s %d M:%d %s F:%d/%d P:%d G:%.1f&L30&F28 CPU:&C &Tc %s' >/tmp/MSPOSD.msg"
rangeMinrangeMaxsetGIsetMCSsetFecKsetFecNsetBitratesetGopwfbPowerROIqp
999999long0121533321.0610,0,0,0
10001150long0121533331.0600,0,0,0
11511300long1121566671.05912,12,12,12
13011700long21215100001.05812,8,8,12
17011850long31215125001.0568,0,0,8
18512001short31215140001.0564,0,0,4
  • rangeMin: Starting value of the range.

  • rangeMax: Ending value of the range.

  • setGI: 是無線通信系統中的 保護間隔(GI,Guard Interval)短GI(400 ns)和長GI(800 ns)是兩種常見的保護間隔設置,用于管理OFDM(正交頻分復用)符號之間的時間間隔。選擇短GI或長GI會影響性能和抗干擾能力。它通常在無線通信協議的 物理層(PHY) 中進行設置,比如Wi-Fi(802.11標準)。

  • setMCS: 定義了用于數據傳輸的調制和編碼方案MCS決定了數據是如何編碼的(調制類型),以及為錯誤糾正添加了多少冗余數據(編碼率)。在Wi-Fi(802.11n/ac/ax)中,MCS值通常從0到9(或更高,取決于Wi-Fi版本)。MCS索引是802.11協議標準的一部分,并且可以根據鏈路質量和信號強度進行調整。

  • setFecK: 指的是前向錯誤糾正(FEC)方案,特別是表示在應用錯誤糾正之前的數據位數(K值)FEC用于通過添加冗余數據來提高無線通信的可靠性,從而使接收方能夠糾正噪聲或干擾引起的錯誤。K值通常是Reed-Solomon編碼卷積編碼中的一個參數。

  • setFecN: 表示應用FEC后的總位數(包括數據位和校驗位)。 K/N的比率給出了編碼率,這決定了為錯誤糾正添加的冗余程度。較低的FEC值(例如1/2)表示更多的冗余和錯誤糾正能力,而較高的值(如3/4或5/6)則提供更高的吞吐量,但錯誤糾正能力較弱。

  • setBitrate: 表示通過無線鏈路傳輸數據的速度,通常以Mbps(兆比特每秒)為單位。該值受到調制方案編碼率信號強度的影響。在Wi-Fi網絡中,通常會根據這些因素動態調整比特率,以優化吞吐量,同時保持穩定的連接。

  • setGop: GOP設置與視頻編碼相關,尤其是在像H.264H.265這樣的壓縮方案中。定義了關鍵幀(I幀)之間的間隔。短GOP意味著更頻繁的關鍵幀(更高的視頻質量,較低的壓縮),而長GOP意味著較少的關鍵幀(更高的壓縮,較低的質量)。在無線通信中,這個設置對于視頻流的傳輸有很大影響。

  • wfbPower: 指的是無線前端(WFB)硬件的發射功率發射功率是無線通信中的一個關鍵參數,影響無線信號的范圍和質量。在Wi-Fi設備中,功率通常可以根據法規限制、設備能力和網絡狀況進行調整。wfbPower值可能用于配置設備中射頻(RF)部分的放大器

  • ROIqp: ROI QP values as a comma-separated string (e.g., 0,0,0,0).

5. 總結

  • Profile 是一個經驗值(測試值),依賴于具體場景應用。
  • 配置參數(如:hold_fallback_mode_s/hold_modes_down_s) 也是一個經驗參數,依賴于具體應用場景。
  • RSSI SNR 權重 RF信號質量計算模型,也是一個經驗方法,可以調整更優的算法。

基于上述邏輯,對于這些內容的優化,就能更好的將FPV視頻無縫的應用于實際環境 - 取決于大量的測試和優化。

注:這里感覺缺少心跳報文丟失的處理,以應對極端情況。

6. 參考資料

【1】OpenIPC開源FPV之Adaptive-Link工程解析

7. 補充資料

RSSI(接收信號強度指示)和SNR(信噪比)是衡量信號質量的常用指標。

加權 RSSI 和 SNR 以綜合評估信號質量的做法,基于以下幾個理論依據:

  1. RSSI 反映信號強度,而 SNR 反映信號與噪聲的比率,兩者結合能夠更全面地評估信號質量。
  2. 加權方式可以根據應用場景和環境的變化,動態調整各個參數的影響,優化信號質量的評估。
  3. 加權系數的調整通常是基于實際的應用需求和實驗數據優化的。

通過加權結合這兩個指標,可以更準確地反映無線通信中的實際信號質量,進而為系統做出更合理的決策(如選擇最佳基站、調整發射功率、優化資源分配等)。

7.1 RSSI 和 SNR 的物理含義

  • RSSI:表示接收到的信號強度,是衡量信號功率強度的一個指標。通常情況下,RSSI 越高,表示信號接收的質量越好。然而,RSSI 只反映了信號的強度,并不直接考慮噪聲的影響。

  • SNR:表示信號與噪聲的比值,是衡量信號質量的一個重要指標。SNR 越高,意味著信號在噪聲背景下越清晰,通信質量越高。高的 SNR 值通常意味著信號更容易被準確解碼,而低的 SNR 值則容易導致誤碼或通信失敗。

7.2 信號質量加權的理論依據

  • 信號強度與噪聲的相對重要性
    單獨依賴 RSSI 來衡量信號質量可能會產生誤導。因為高強度的信號也可能伴隨著較強的噪聲,而高噪聲水平會影響信號的清晰度。因此,SNR 提供了一個更全面的衡量標準,考慮了信號的強度與噪聲的關系。加權方式結合了這兩個指標,能夠更準確地反映實際信號質量。

  • 加權的數學模型
    一種常見的做法是將 RSSI 和 SNR 作為輸入參數,通過某種加權函數或線性組合來得到一個綜合的信號質量指標。可以根據具體場景的需求調整權重值。例如:
    Q = w 1 ? RSSI + w 2 ? SNR Q = w_1 \cdot \text{RSSI} + w_2 \cdot \text{SNR} Q=w1??RSSI+w2??SNR
    其中,$ w_1 $ 和 $ w_2 $ 是 RSSI 和 SNR 的權重系數,表示它們在信號質量計算中的相對重要性。

    • 選擇合適的權重系數
      權重的設置需要根據具體的應用需求和實驗數據來優化。在一些應用中,SNR 可能更為關鍵,因為它直接影響到數據傳輸的錯誤率,而在其他場景中,RSSI 可能更重要,因為信號強度直接決定了通信的覆蓋范圍。

7.3 實際應用中的加權方法

  • 無線通信系統:在無線通信中,RSSI 和 SNR 都是評估信號質量的重要指標。將兩者加權后,系統可以更好地判斷信號的穩定性和傳輸質量。例如,在 Wi-Fi 或移動通信中,基站或接入點會同時考慮這兩個參數,以確保數據傳輸的可靠性。

  • 動態信號質量評估:無線環境通常是動態變化的,信號強度和噪聲水平可能隨時間和位置變化。通過加權方式,可以更靈活地反映當前信號的質量,特別是在復雜的多徑傳播和干擾環境中。

7.4 加權方法的優化

  • 信道的特性:在不同的無線信道中,RSSI 和 SNR 對信號質量的影響可能不同。例如,在高干擾環境下,SNR 的作用更為突出,因此可以為 SNR 分配更大的權重。而在信號強度較好的環境中,RSSI 可能會更重要。

  • 基于經驗的調整:通過實際測試和仿真,可以根據不同的環境條件和通信需求,調整 RSSI 和 SNR 的權重。例如,在一個需要長距離傳輸的場景中,可能會更側重于 RSSI;而在一個要求高數據速率和低錯誤率的場景中,可能會更關注 SNR。

7.5 綜合考慮信號質量的模型

在一些高級的信號質量評估模型中,除了直接的 RSSI 和 SNR 之外,可能還會考慮其他因素,比如:

  • 路徑損耗:信號在傳播過程中的衰減。
  • 干擾:來自其他無線設備或環境的噪聲。
  • 調制方式:不同的調制方式對信號質量的敏感度不同。

這些因素也可能在加權過程中作為附加的輸入,進一步提升信號質量評估的準確性。

7.6 8812EU WiFi模塊

  • M8812EU2 2T2R 802.11a/n/ac WiFi Module
  • Using BL-M8812EU2 (or other RTL8812EU-based) Wi-Fi Module

功率設置兩個方法: WIP: Add support for RTL8812EU-based Wi-Fi adapters for FPV firmware #1344

  • driver_txpower_overridein /etc/wfb.conf. The range is 0~63
  • iw dev <wlan0> set txpower fixed <mBm>. The range is 0~3150, and can be set dynamically when transmitting.
    在這里插入圖片描述
    在這里插入圖片描述

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

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

相關文章

labelme標簽批量轉換數據集json_to_dataset

文章目錄 labelme標簽批量轉換數據集json_to_dataset轉換原理單張圖片轉換多張圖片批量轉換bat腳本循環法 標注圖片提取標注圖片轉單通道 labelme標簽批量轉換數據集json_to_dataset 轉自labelme批量制作數據集教程。 轉換原理 在安裝了labelme的虛擬環境中有一個labelme_js…

Apache Kylin最簡單的解析、了解

官網&#xff1a;Overview | Apache Kylin 一、Apache Kylin是什么&#xff1f; 由中國團隊研發具有濃厚的中國韻味&#xff0c;使用神獸麒麟&#xff08;kylin&#xff09;為名 的一個OLAP多維數據分析引擎:&#xff08;據官方給出的數據&#xff09; 亞秒級響應&#xff…

01云計算HCIA學習筆記

筆者今年7月底考取了華為云計算方向的HCIE認證&#xff0c;回顧從IA到IE的學習和項目實戰&#xff0c;想整合和分享自己的學習歷程&#xff0c;歡迎志同道合的朋友們一起討論&#xff01; 第一章 云計算概述 ICT&#xff1a;ICT是世界電信協會在2001年的全球會議中提出的一個綜…

php生成圖片

前提 開啟dg2庫 去掉前面的;注釋&#xff0c;有的可能會帶.dll后綴影響不大 extensiongd2代碼 <?php $file imagecreate(100,50); //先生成圖片資源$color imagecolorallocate($file,255,255,255); //白色$c imagecolorallocate($file,0,100,255);imagefill($file,0…

免費GIS工具箱:輕松將glb文件轉換成3DTiles文件

在GIS地理信息系統領域&#xff0c;GLB文件作為GLTF文件的二進制版本&#xff0c;主要用于3D模型數據的存儲和展示。然而&#xff0c;GLB文件的使用頻率相對較低&#xff0c;這是因為GIS系統主要處理的是地理空間數據&#xff0c;如地圖、地形、地貌、植被、水系等&#xff0c;…

為何VisualRules更適合技術人員使用

什么是規則引擎 規則引擎是一種軟件組件&#xff0c;它允許將業務規則從應用程序的核心代碼中分離出來&#xff0c;以一種更加靈活、易于管理和維護的方式來定義、存儲和執行這些規則。簡單來說&#xff0c;它就像是一個專門處理規則的 “大腦”&#xff0c;可以根據預先設定的…

prometheus 搭建監控

prometheus 下載 prometheus-3.0.0.linux-amd64.tar.gztar -zxvf prometheus-3.0.0.linux-amd64.tar.gzmv prometheus-3.0.0.linux-amd64 prometheus-3vim /etc/systemd/system/prometheus.serviceprometheus.service [Unit] DescriptionPrometheus Wantsnetwork-online.t…

游戲何如防抓包

游戲抓包是指在游戲中&#xff0c;通過抓包工具捕獲和分析游戲客戶端與服務器之間傳輸的封包數據的過程。抓包工具可實現攔截、篡改、重發、丟棄游戲的上下行數據包&#xff0c;市面上常見的抓包工具有WPE、Fiddler和Charles Proxy等。 抓包工具有兩種實現方式&#xff0c;一類…

RestTemplate實時接收Chunked編碼傳輸的HTTP Response

學習調用AI接口的時候&#xff0c;流式響應都是使用的 Transfer-Encoding: chunked&#xff0c;圖方便想用RestTemplate&#xff0c;但是平時用到的都是直接返回響應對象的類型。使用bing搜索到一種方式&#xff0c;使用下面的代碼來讀取&#xff0c;于是掉這個坑里了&#xff…

request.setAttribute()和session.setAttribute()的區別

request.setAttribute() 作用&#xff1a;request.setAttribute()是在一次請求內共享數據 解釋&#xff1a;例如將一個數據保存request域中&#xff0c;然后請求轉發至前端頁面&#xff0c;則數據轉發至前端頁面后會被自動銷毀。簡單點說就是&#xff0c;數據只能用一次就不能…

Java中的Consumer接口應該如何使用(通俗易懂圖解)

應用場景&#xff1a; 第一次程序員A寫好了個基礎的遍歷方法&#xff1a; public class Demo1 {public static void main(String[] args) {//假設main方法為程序員B寫的,此時需要去調用A寫好的一個遍歷方法//1.如果此時B突然發現想將字符串以小寫的形式打印出來&#xff0c;則…

【常微分方程講義1.1】方程的種類發展與完備

方程在數學歷史中不斷發展&#xff0c;逐步趨于完備。從最初的簡單代數方程到包含函數、算子甚至泛函的更復雜方程&#xff0c;數學家通過不斷的擴展和深化&#xff0c;逐漸建立起更為豐富和多元的方程類型體系。方程的種類之所以不斷演變&#xff0c;部分是因為解決實際問題的…

通過移除 -march=native 解決 Ubuntu 20.04 程序運行“段錯誤 (核心已轉儲)”問題的詳解

通過移除 -marchnative 解決 Ubuntu 20.04 程序運行“段錯誤 (核心已轉儲)”問題的詳解 在Ubuntu 20.04系統中&#xff0c;開發和編譯C/C程序時&#xff0c;常見的編譯選項可能會影響程序的穩定性和兼容性。特別是在使用CMake構建系統時&#xff0c;某些編譯標志可能導致程序在…

Linux下學【MySQL】表的必備操作( 配實操圖和SQL語句)

緒論? “Patience is key in life &#xff08;耐心是生活的關鍵&#xff09;”。本章是MySQL中非常重要且基礎的知識----對表的操作。再數據庫中表是存儲數據的容器&#xff0c;我們通過將數據填寫在表中&#xff0c;從而再從表中拿取出來使用&#xff0c;本章主要講到表的增…

深度學習之目標檢測篇——殘差網絡與FPN結合

特征金字塔多尺度融合特征金字塔的網絡原理 這里是基于resnet網絡與Fpn做的結合&#xff0c;主要把resnet中的特征層利用FPN的思想一起結合&#xff0c;實現resnet_fpn。增強目標檢測backone的有效性。代碼實現如下&#xff1a; import torch from torch import Tensor from c…

游戲AI實現-尋路算法(BFS)

廣度優先搜索算法&#xff08;英語&#xff1a;Breadth-first search&#xff0c;縮寫&#xff1a;BFS&#xff09;&#xff0c;又譯作寬度優先搜索&#xff0c;或橫向優先搜索&#xff0c;是一種圖形搜索算法。 尋路地圖搭建&#xff1a; 游戲AI實現-尋路地圖搭建-CSDN博客 …

CMake的INSTALL FILES和INSTALL DIRECTORY有什么區別

在 CMake 中&#xff0c;install() 命令用于安裝構建的目標文件、頭文件、庫等到指定的目標路徑。install(FILES ...) 和 install(DIRECTORY ...) 都是 install() 命令的具體用法&#xff0c;它們的功能和適用場景不同。 以下是兩者的詳細區別和用法說明&#xff1a; 1. insta…

主流網絡安全產品

目前市場上也出現了品類豐富的安全產品&#xff0c;如“防火墻、抗D、負載均衡、WAF、數據庫審計、漏掃、網頁防篡改、上網行為管理、堡壘機等”這些產品由于功能不同在網絡中部署的位置也有區別。下面來簡單聊一下每類產品的功能和部署位置。 &#xff08;1&#xff09;防火墻…

利用git上傳項目到GitHub

GitHub是基于git實現的代碼托管。git是目前最好用的版本控制系統了&#xff0c;非常受歡迎&#xff0c;比之svn更好。 GitHub可以免費使用&#xff0c;并且快速穩定。 利用GitHub&#xff0c;你可以將項目存檔&#xff0c;與其他人分享交流&#xff0c;并讓其他開發者幫助你一…

《Vue3實戰教程》13:Vue3偵聽器

如果您有疑問&#xff0c;請觀看視頻教程《Vue3實戰教程》 偵聽器? 基本示例? 計算屬性允許我們聲明性地計算衍生值。然而在有些情況下&#xff0c;我們需要在狀態變化時執行一些“副作用”&#xff1a;例如更改 DOM&#xff0c;或是根據異步操作的結果去修改另一處的狀態。…