學習如何為FPV戰斗無人機構建一個視頻模塊,該模塊能夠從模擬FPV攝像機捕獲視頻流,利用這些視頻流執行計算機視覺任務,并將圖像傳輸到飛行控制器進行進一步處理(OSD)以及通過VTX進行視頻傳輸。
本文是我一年多來一直在進行的研發工作的自然延續,該研發工作專注于為FPV戰斗無人機構建自動駕駛儀。
當我開始探索如何向FPV操作員通知自動駕駛儀的當前狀態和飛行參數時,我意識到在基于Betaflight固件的飛行控制器中沒有可用的軟件解決方案。這促使我考慮一個軟硬件結合的解決方案。
在評估不同選項時,有兩個關鍵因素脫穎而出:首先,保持與Betaflight固件和流行的FPV無人機配置的兼容性,而不改變它們,這一點很重要。其次,解決方案需要具備修改FPV視頻源和OSD(屏幕顯示)的能力,以顯示計算機視覺模型識別的目標,以及其他自動駕駛儀狀態和飛行參數。
在本文中,我將分享我在這一過程中發現的內容。
架構
最初的想法是在FPV攝像機和飛行控制器(FC)之間創建一個“中間人”,以便在FPV屏幕上疊加額外的控制和消息,同時處理圖像以執行人工智能驅動的計算機視覺任務。對于這個角色,我選擇了一臺樹莓派以及兩個加密狗:一個AV2USB加密狗(用于從FPV攝像機獲取數字MJPEG圖像)和一個HDMI2AV加密狗(用于以PAL/NTSC模擬格式將修改后的圖像傳輸到FC)。

視頻模塊接線圖
為了在FPV攝像機和飛行控制器之間實現“中間人”功能,我決定支持常用的接口,特別是JST 3針電纜。在此設置中,一條JST電纜將AV2USB加密狗連接到FPV攝像機,而另一條JST電纜則將飛行控制器連接到HDMI2AV加密狗。兩個加密狗都連接到伴侶計算機(在我們的例子中是樹莓派3),使其能夠獲取/傳輸帶有特定于計算機視覺任務的視頻疊加的FPV攝像機圖像。

AV2USB加密狗的焊接點
如上圖所示,我將USB電纜的紅色(5V)線焊接到加密狗上的5V焊盤上,同時還將JST電纜的紅色線也焊接上去。這種設置允許USB電纜同時為加密狗和FPV攝像機供電。
JST電纜的接地線(黑色)和視頻信號線(黃色)焊接到加密狗上的AV和G焊盤上。此外,USB電纜的接地線(灰色)也連接到加密狗上的G焊盤上。USB的藍色線焊接到DP(數據+)焊盤上,而USB的白色線則焊接到DM(數據-)焊盤上。
適當的焊接確保了電路板的可靠運行。
4極3.5毫米AV2PAL電纜,CVBS信號線焊接至3針JST連接器
為了將HDMI2AV加密狗連接到FC,我使用了CVBS線(PAL輸出中的黃色線),并將其連接到一條JST電纜上,該電纜通過用于FPV攝像機連接的相同3針JST線直接連接到FC板上。有關詳細信息,請參考上面的接線圖。
CVBS電纜中只有兩條線連接到3針JST連接器上。黃色線是信號線(CAM),連接到另一側的黃色線上。黑色線是接地線(GND),連接到另一側對應的接地線上。紅色線(5V)保持未連接狀態,因為它通常用于為FPV攝像機供電。然而,在我們的設置中,我們以不同的方式為FPV攝像機供電。
讓我們繼續探討軟件部分。
導入
為了實現視頻疊加功能,我們需要導入整個項目中將使用的兩個包:cv2(用于計算機視覺任務,如從FPV攝像機捕獲幀)和numpy(用于執行數組操作和數據操作)。
importcv2importnumpyasnp
如果你還沒有安裝它們,現在是時候安裝了。
定義和狀態
本節內容來源于Autopilot “BEE” 倉庫中的適當文件,包括definitions.py和autopilot.py,該倉庫針對FPV戰斗無人機(模擬器版本)的跟蹤目標功能。本節提供了應在FPV屏幕上顯示的自動駕駛儀設置及當前狀態這部分內容源自倉庫中Autopilot "BEE" with target following for FPV Combat Drone(模擬器版本)的definitions.py和autopilot.py文件,提供了應在FPV屏幕上顯示的自動駕駛儀的設置和當前狀態。
https://github.com/under0tech/autopilot_bee_sim
# definitionsvideo_source =0video_full =1video_message_limit =60camera_width =720camera_height =480camera_fps =1# statestate= { 'bee_state':'OFF',# OFF, READY, ... 'rssi':0, 'rssi_msg':'Strong signal', 'frame': {}, 'video_msg':'[Manual control is ON]', 'video_msg_countdown':0}
定義——視頻疊加模塊的設置:
video_source = 0,指的是通過樹莓派上的USB端口連接的攝像機,由于默認情況下沒有安裝攝像機,因此這是索引為0的第一個攝像機。
video_full = 1,表示視頻疊加將以全屏模式顯示。設為0用于調試。
video_message_limit = 60,限制在FPV屏幕上顯示video_msg的幀數為60幀。
camera_width和camera_height,將分辨率設置為720x480像素。
camera_fps = 1,使用OpenCV(cv2)每秒捕獲1幀。
自動駕駛儀的狀態(當前狀態):
rssi_msg,可以設置為“Strong signal”(強信號)或“No signal”(無信號)。根據此消息,RC標簽和圓形符號將以紅色或綠色顯示在FPV屏幕上,指示信號強度。
video_msg,可以包含要在FPV屏幕上顯示的任何消息,直到達到有限的幀數(在video_msg_countdown中計數)。
frame,保存當前幀,該幀可以由計算機視覺模型處理,以實現FPV無人機的自主操作。
當前狀態和所有字段狀態在自動駕駛儀運行期間由應用程序的其他組件更新。
視頻疊加
該子系統的核心是視頻疊加功能,這些功能會添加關于自動駕駛儀狀態的額外組件和消息,例如RC信號強度、自定義消息、縮放后的目標以及用于瞄準的中心十字線,所有這些都顯示在FPV屏幕上(FPV護目鏡或FPV顯示器)。
查看代碼及其在列表下方的描述。
# Autopilot's overlaydef draw_rc_auto_status(frame): color_green = (0,255,0) color_red = (0,0,255) color = color_greenifstate['rssi_msg'] =='Strong signal'elsecolor_red cv2.circle(frame, (50,50),7, color, -1) font = cv2.FONT_HERSHEY_SIMPLEX cv2.putText(frame,"RC", (65,55), font,0.5, color,2) ifstate['bee_state'] =='OFF': cv2.putText(frame,'MANUAL', (110,55), font,0.5, color_red,1) else: cv2.putText(frame,'AUTO', (110,55), font,0.5, color_green,2)def draw_dotted_line(frame, start, end, color, thickness, gap): x1, y1 = start x2, y2 = end length=int(np.sqrt((x2 - x1) **2+ (y2 - y1) **2)) fori in range(0,length, gap *2): start_x =int(x1 + (x2 - x1) * i /length) start_y =int(y1 + (y2 - y1) * i /length) end_x =int(x1 + (x2 - x1) * (i + gap) /length) end_y =int(y1 + (y2 - y1) * (i + gap) /length) cv2.line(frame, (start_x, start_y), (end_x, end_y), color, thickness)def draw_cross_target(frame): color_white = (255,255,255) height, width,_= frame.shape center_x, center_y = width //2, height //2 draw_dotted_line(frame, (center_x -50, center_y), (center_x +50, center_y), color_white,2,5) draw_dotted_line(frame, (center_x, center_y -50), (center_x, center_y +50), color_white,2,5)def draw_scaled_target(frame): color_white = (255,255,255) rect_size =50 height, width,_= frame.shape center_x, center_y = width //2, height //2 top_left_x = center_x - rect_size //2 top_left_y = center_y - rect_size //2 center_region = frame[top_left_y:top_left_y + rect_size, top_left_x:top_left_x + rect_size] scaled_region = cv2.resize(center_region, (rect_size *2, rect_size *2), interpolation=cv2.INTER_LINEAR) overlay_x_start = width - rect_size *2-20 overlay_y_start =20 frame[overlay_y_start:overlay_y_start + rect_size *2, overlay_x_start:overlay_x_start + rect_size *2] = scaled_region cv2.rectangle(frame, (overlay_x_start, overlay_y_start), (overlay_x_start + rect_size *2, overlay_y_start + rect_size *2), color_white,1)def draw_video_message(frame): font = cv2.FONT_HERSHEY_SIMPLEX color_white = (256,256,256) ifstate['video_msg'] !='': cv2.putText(frame,state['video_msg'], (43,80), font,0.5, color_white,1) countdown =int(state['video_msg_countdown']) ifcountdown < video_message_limit:? ? ? ? ? ? state['video_msg_countdown'] = countdown +?1? ? ? ? else:? ? ? ? ? ? state['video_msg'] =?''? ? ? ? ? ? state['video_msg_countdown'] =?0
draw_rc_auto_status(frame)函數在視頻疊加層上顯示RC信號強度和自動駕駛儀模式。它使用綠色或紅色圓圈來指示信號是強還是弱。如果自動駕駛儀關閉,它還會以紅色顯示“MANUAL”飛行模式;如果自動駕駛儀激活,則以綠色顯示“AUTO”。
draw_dotted_line(frame, start, end, color, thickness, gap)函數在幀上的兩點之間繪制一條虛線。它根據指定的間隔和厚度計算線段,繪制小線段以創建虛線效果。
另一個函數draw_cross_target(frame)在視頻幀的中心繪制一個十字線。它使用draw_dotted_line創建一對水平和垂直的虛線,在中心相交。這個視覺輔助工具有助于在FPV無人機操作期間跟蹤FPV屏幕的中心點(目標方向)。
draw_scaled_target(frame)函數提取并放大FPV視頻源的中心區域,將其作為插圖顯示在右上角。它捕獲一個方形區域,對其進行縮放,然后將其疊加到幀上。這提供了目標的更詳細視圖。
draw_video_message(frame)函數負責在視頻疊加層上顯示文本消息。如果在系統狀態的video_msg字段中存在消息,則將其顯示在RC信號強度下方。這包括一個倒計時計時器以控制消息的持續時間,并在計時器超過預設限制(默認:60)時清除它。此消息可以顯示由FPV護目鏡屏幕的視頻疊加功能檢索到的任何自定義文本。它對于顯示自動駕駛儀操作的各個階段非常有用。
運行點
main()函數實現了視頻疊加功能所需的所有操作,處理其他函數的初始化和執行,以便在FPV屏幕上繪制額外的控制和消息。
#Mainfunctiondefmain(): cap = cv2.VideoCapture(video_source) if not cap.isOpened(): print("Error: Could not access the camera.") exit() cap.set(cv2.CAP_PROP_FRAME_WIDTH, camera_width) cap.set(cv2.CAP_PROP_FRAME_HEIGHT, camera_height) cap.set(cv2.CAP_PROP_FPS, camera_fps) if video_full: cv2.namedWindow("BEE", cv2.WND_PROP_FULLSCREEN) cv2.setWindowProperty("BEE", cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN) print("Press 'q' to exit.") while True: ret, frame = cap.read() if not ret: print("Error: Could not read frame.") break # Save current frame to state for # Computer Vision tasks state['frame'] = frame draw_rc_auto_status(frame) draw_scaled_target(frame) draw_cross_target(frame) draw_video_message(frame) cv2.imshow('BEE', frame) if cv2.waitKey(1) &0xFF ==ord('q'): break cap.release() cv2.destroyAllWindows()
main()函數使用OpenCV初始化視頻捕獲設備(例如,我們之前連接的FPV攝像機),配置其分辨率和幀率。如果啟用了video_full(設為1),則可選地將顯示窗口設置為全屏模式。該函數進入一個循環以連續讀取視頻幀,為計算機視覺任務更新共享狀態字典中的當前幀。
它隨后應用幾個視頻疊加函數(draw_rc_auto_status、draw_scaled_target、draw_cross_target、draw_video_message)以在FPV屏幕上顯示控制和消息。
如上所述實現的main()函數僅適用于實驗目的。若要集成到自動駕駛儀中,此代碼將被移動到單獨的線程中,并由自動駕駛儀主進程管理。然而,那是另一個話題了。
啟動和使用
完成所有接線和焊接后,我啟動了FPV無人機以及安裝在其上的伴侶計算機。然后,我運行了一個Python腳本以驗證視頻模塊是否正常工作,成功地將FPV視頻源從FPV攝像機傳輸到飛行控制器,并隨后通過VTX傳輸到FPV護目鏡。
帶有視頻疊加和OSD屏幕的FPV顯示器
如上圖所示,包括OSD、視頻源和視頻疊加在內的所有內容都正確地顯示在FPV屏幕上。默認的PAL分辨率720x480像素導致圖像質量不太理想。然而,對于搭載模擬FPV攝像機的FPV無人機來說,這種分辨率水平是相當常見的。
-
無人機
+關注
關注
230文章
10746瀏覽量
185623 -
自動駕駛
+關注
關注
788文章
14212瀏覽量
169610 -
樹莓派
+關注
關注
121文章
1951瀏覽量
107012
發布評論請先 登錄
評論