六自由度建模與視覺路徑規(guī)劃仿真實(shí)踐)
簡介本資源是一套面向高校自動(dòng)化、航空航天及控制工程專業(yè)學(xué)生的Matlab小型固定翼無人機(jī)建模與仿真完整實(shí)踐方案聚焦飛行動(dòng)力學(xué)建模、實(shí)時(shí)圖像顯示與多策略路徑規(guī)劃三大核心能力訓(xùn)練。壓縮包共34個(gè)文件含28個(gè).m主控與算法腳本如dubinsParameters、planRRTDubins、autopilot等、3個(gè)Simulink系統(tǒng)模型文件mavsim.slx等用于動(dòng)力學(xué)與控制閉環(huán)仿真、2幅環(huán)境/傳感器圖像predator.jpg、batcam.png及1張說明圖整體僅540KB輕量易部署。已有1086人學(xué)習(xí)下載資源結(jié)構(gòu)清晰從參數(shù)配置param.m、氣動(dòng)建模forces_moments.m、狀態(tài)估計(jì)estimate_states.m到路徑生成planCoverRRTDubins.m、航跡跟蹤path_follow.m及可視化drawEnvironment.m、drawPathError.m全覆蓋所有模塊均可獨(dú)立運(yùn)行或協(xié)同調(diào)試配套注釋詳實(shí)是理解固定翼無人機(jī)自主飛行系統(tǒng)設(shè)計(jì)與驗(yàn)證的理想入門級工程范例。1. 項(xiàng)目緣起從零開始構(gòu)建一個(gè)“看得見”的無人機(jī)仿真世界幾年前當(dāng)我第一次接觸無人機(jī)項(xiàng)目時(shí)面對的是一堆冰冷的代碼和一堆抽象的數(shù)學(xué)公式??刂破髡{(diào)參像是在黑箱里摸索飛行動(dòng)力學(xué)模型是否準(zhǔn)確只能等真機(jī)試飛時(shí)才能驗(yàn)證成本高、風(fēng)險(xiǎn)大。那時(shí)候我就在想如果能有一個(gè)“數(shù)字孿生”的沙盤在電腦里就能把飛機(jī)飛起來看到它的姿態(tài)、軌跡甚至模擬它“眼中”的世界那該多好。這就是我動(dòng)手搭建這個(gè)Matlab小型固定翼無人機(jī)建模與仿真程序的初衷。這個(gè)程序遠(yuǎn)不止是一個(gè)簡單的動(dòng)力學(xué)模型。它的核心價(jià)值在于構(gòu)建了一個(gè)從“物理內(nèi)核”到“視覺感知”再到“智能決策”的完整閉環(huán)仿真環(huán)境。你不僅能看到無人機(jī)按照六自由度方程在空中飛行還能通過一個(gè)虛擬的“機(jī)載攝像頭”觀察地面并讓無人機(jī)基于這些圖像信息或預(yù)設(shè)地圖自主規(guī)劃出一條從A點(diǎn)到B點(diǎn)的最優(yōu)或可行路徑。對于學(xué)生來說它是理解無人機(jī)原理、學(xué)習(xí)控制算法和路徑規(guī)劃理論的絕佳實(shí)驗(yàn)平臺對于工程師它可以作為算法前期驗(yàn)證、降低實(shí)物試錯(cuò)成本的得力工具對于研究者它提供了一個(gè)高度可定制、模塊化的框架便于快速實(shí)現(xiàn)和測試新的想法。整個(gè)項(xiàng)目完全基于Matlab/Simulink環(huán)境構(gòu)建充分利用了其強(qiáng)大的數(shù)值計(jì)算、圖形顯示和工具箱生態(tài)。下面我將毫無保留地拆解這個(gè)系統(tǒng)的每一個(gè)模塊分享從建模、仿真到集成的完整過程以及那些在文檔里找不到的“踩坑”經(jīng)驗(yàn)。2. 基石小型固定翼無人機(jī)的六自由度非線性動(dòng)力學(xué)建模仿真系統(tǒng)的靈魂在于模型。一個(gè)失真的模型無論后續(xù)的控制器和規(guī)劃器多精妙得出的結(jié)論都可能是空中樓閣。對于固定翼無人機(jī)我們必須建立其六自由度6-DoF非線性動(dòng)力學(xué)模型這包括了在三維空間中的三個(gè)平移自由度和三個(gè)旋轉(zhuǎn)自由度。2.1 坐標(biāo)系定義與轉(zhuǎn)換一切計(jì)算的起點(diǎn)建模的第一步是明確坐標(biāo)系。這里主要涉及兩個(gè)機(jī)體坐標(biāo)系Body Frame, B-frame和地面慣性坐標(biāo)系Earth Frame, E-frame通常為NED北-東-地。機(jī)體坐標(biāo)系 (B-frame): 原點(diǎn)在無人機(jī)質(zhì)心。X軸指向機(jī)頭Y軸指向右翼Z軸根據(jù)右手定則指向機(jī)身下方。在這個(gè)坐標(biāo)系下我們定義無人機(jī)的線速度[u, v, w]對應(yīng)X,Y,Z軸速度和角速度[p, q, r]滾轉(zhuǎn)、俯仰、偏航角速度。地面慣性坐標(biāo)系 (E-frame): 這是我們觀察無人機(jī)運(yùn)動(dòng)的全局坐標(biāo)系。通常采用北-東-地NED約定。無人機(jī)的位置[X_n, Y_e, Z_d]和姿態(tài)歐拉角滾轉(zhuǎn)角 Φ俯仰角 Θ偏航角 Ψ都是在這個(gè)坐標(biāo)系下描述的。兩者之間的轉(zhuǎn)換至關(guān)重要。線速度通過方向余弦矩陣DCM或旋轉(zhuǎn)矩陣進(jìn)行轉(zhuǎn)換。而角速度與歐拉角變化率之間的關(guān)系則由一個(gè)非線性微分方程描述其中包含著名的“歐拉角奇異點(diǎn)”當(dāng)俯仰角Θ±90°時(shí)。在仿真中我選擇了四元數(shù)來表示姿態(tài)它沒有奇異點(diǎn)計(jì)算也更高效最后再轉(zhuǎn)換為歐拉角用于顯示和理解。注意很多初學(xué)者會(huì)直接使用Simulink Aerospace Blockset里的“6DOF (Euler Angles)”模塊這很方便但要小心它的奇異點(diǎn)問題。對于可能做大機(jī)動(dòng)如特技飛行的仿真強(qiáng)烈建議使用“6DOF (Quaternion)”模塊或者自己用四元數(shù)實(shí)現(xiàn)姿態(tài)更新。2.2 力與力矩的構(gòu)成氣動(dòng)、重力、推力作用在無人機(jī)上的合外力與合力矩決定了其運(yùn)動(dòng)狀態(tài)。它們主要由三部分組成重力: 始終沿地面坐標(biāo)系的Z軸指向地心方向。需要在機(jī)體坐標(biāo)系下表示F_gravity_B DCM * [0; 0; mg]其中m是質(zhì)量g是重力加速度DCM是從地面系到機(jī)體系的旋轉(zhuǎn)矩陣轉(zhuǎn)置。推力: 由螺旋槳發(fā)動(dòng)機(jī)產(chǎn)生。假設(shè)推力沿機(jī)體X軸方向其大小通常建模為油門指令δ_t的函數(shù)例如T T_max * δ_t線性模型或更復(fù)雜的包含空速影響的模型。推力作用點(diǎn)如果不在質(zhì)心還會(huì)產(chǎn)生俯仰力矩。氣動(dòng)力與力矩: 這是最復(fù)雜也最核心的部分。它們?nèi)Q于無人機(jī)的氣動(dòng)外形、飛行狀態(tài)空速、迎角、側(cè)滑角和控制面偏轉(zhuǎn)。迎角 (α)和側(cè)滑角 (β)這是連接機(jī)體速度與氣動(dòng)力的關(guān)鍵橋梁。α arctan(w/u),β arcsin(v/V)其中V sqrt(u^2v^2w^2)為空速。氣動(dòng)系數(shù): 力與力矩通常被無量綱化為系數(shù)。例如升力系數(shù)C_L阻力系數(shù)C_D俯仰力矩系數(shù)C_m等。這些系數(shù)是α, β, 馬赫數(shù)、控制面偏轉(zhuǎn)角升降舵δ_e副翼δ_a方向舵δ_r以及它們的變化率如俯仰角速度q的復(fù)雜函數(shù)。工程化處理對于小型固定翼無人機(jī)我們通常采用“系數(shù)線性化查表”的方式。在常規(guī)飛行包線內(nèi)可以假設(shè)C_L C_L0 C_Lα * α C_Lq * (q * c? / (2V)) C_Lδe * δ_e。其中C_L0, C_Lα等為氣動(dòng)導(dǎo)數(shù)可以通過計(jì)算流體力學(xué)CFD或風(fēng)洞試驗(yàn)獲得對于學(xué)習(xí)目的也可以參考公開的模型如Aerosonde UAV數(shù)據(jù)。對于非線性較強(qiáng)的區(qū)域則使用基于α, β等參數(shù)預(yù)計(jì)算好的多維查表Lookup Table。在我的實(shí)現(xiàn)中我將氣動(dòng)力計(jì)算封裝成了一個(gè)獨(dú)立的Matlab函數(shù)模塊。輸入是當(dāng)前狀態(tài)u,v,w, p,q,r, 控制面偏角和氣動(dòng)參數(shù)輸出是機(jī)體坐標(biāo)系下的三個(gè)氣動(dòng)力X_a, Y_a, Z_a和三個(gè)氣動(dòng)力矩L, M, N。這樣在Simulink中調(diào)用非常清晰。% 示例簡化的氣動(dòng)力計(jì)算函數(shù)框架 function [F_aero_B, M_aero_B] calculateAeroForces(state, delta, aero_params) % state: [u, v, w, p, q, r] 在機(jī)體坐標(biāo)系下的速度與角速度 % delta: [delta_e, delta_a, delta_r] 控制面偏轉(zhuǎn)角 % aero_params: 結(jié)構(gòu)體包含翼面積S、翼展b、平均氣動(dòng)弦長c_bar、氣動(dòng)導(dǎo)數(shù)等 V norm(state(1:3)); % 空速 alpha atan2(state(3), state(1)); % 迎角 beta asin(state(2) / V); % 側(cè)滑角注意V0時(shí)的處理 % 1. 計(jì)算氣動(dòng)系數(shù)這里以線性模型示例 C_L aero_params.C_L0 aero_params.C_L_alpha * alpha aero_params.C_L_q * (state(5) * aero_params.c_bar / (2*V)) aero_params.C_L_delta_e * delta(1); C_D aero_params.C_D0 aero_params.C_D_alpha * alpha; % 簡化阻力模型 C_Y aero_params.C_Y0 aero_params.C_Y_beta * beta aero_params.C_Y_delta_r * delta(3); C_l aero_params.C_l_beta * beta aero_params.C_l_p * (state(4) * aero_params.b / (2*V)) aero_params.C_l_delta_a * delta(2); C_m aero_params.C_m0 aero_params.C_m_alpha * alpha aero_params.C_m_q * (state(5) * aero_params.c_bar / (2*V)) aero_params.C_m_delta_e * delta(1); C_n aero_params.C_n_beta * beta aero_params.C_n_r * (state(6) * aero_params.b / (2*V)) aero_params.C_n_delta_r * delta(3); % 2. 計(jì)算氣動(dòng)力與力矩在機(jī)體軸系 Q 0.5 * aero_params.rho * V^2 * aero_params.S; % 動(dòng)壓 F_aero_B Q * [-C_D; C_Y; -C_L]; % 注意通常Z軸向下為正所以升力為負(fù) M_aero_B Q * [aero_params.b * C_l; aero_params.c_bar * C_m; aero_params.b * C_n]; end2.3 運(yùn)動(dòng)方程集成與Simulink實(shí)現(xiàn)有了力與力矩我們就可以根據(jù)牛頓-歐拉方程寫出完整的6-DoF運(yùn)動(dòng)方程。在Simulink中我采用“基于模型設(shè)計(jì)”的思路使用基本的數(shù)學(xué)運(yùn)算模塊加、乘、積分和函數(shù)調(diào)用模塊如上述氣動(dòng)力函數(shù)來搭建模型而不是完全依賴現(xiàn)成的6DOF模塊。這樣做的好處是模型完全透明便于調(diào)試和修改。核心的積分環(huán)路是這樣的上一時(shí)刻的狀態(tài)位置、速度、姿態(tài)、角速度 - 計(jì)算當(dāng)前所受合外力/力矩 - 通過運(yùn)動(dòng)微分方程 - 得到狀態(tài)變量的導(dǎo)數(shù) - 經(jīng)過積分器 - 更新為當(dāng)前時(shí)刻的狀態(tài)。這個(gè)環(huán)路由Simulink的求解器自動(dòng)推進(jìn)。實(shí)操心得仿真步長的選擇至關(guān)重要。對于固定翼無人機(jī)動(dòng)力學(xué)其模態(tài)頻率較高如短周期模態(tài)需要較小的步長才能準(zhǔn)確捕捉。我通常從0.01秒開始嘗試。使用變步長求解器如ode45可以兼顧精度和速度但在有離散控制器或規(guī)劃器時(shí)固定步長如ode4即四階龍格庫塔更穩(wěn)定。務(wù)必在仿真后檢查狀態(tài)量的變化是否平滑有無異常的數(shù)值振蕩。3. 讓無人機(jī)“看見”三維可視化與虛擬相機(jī)圖像生成一個(gè)只有數(shù)據(jù)曲線的仿真是枯燥且不直觀的。讓無人機(jī)“看見”是連接物理模型與高層智能路徑規(guī)劃的關(guān)鍵橋梁也是驗(yàn)證感知算法的基礎(chǔ)。3.1 基于MATLAB Robotics System Toolbox的三維場景搭建我選擇使用MATLAB的Robotics System Toolbox來創(chuàng)建三維環(huán)境。它提供了robotics.OccupancyGrid用于二維路徑規(guī)劃和robotics.VectorFieldHistogram等工具但其三維可視化能力更適合我們構(gòu)建一個(gè)簡單的虛擬世界。首先創(chuàng)建一個(gè)三維的axes對象并設(shè)置好視角和光照。然后用基本的圖形對象patch,surf,plot3來繪制地形、障礙物和無人機(jī)模型。地形可以用meshgrid生成網(wǎng)格點(diǎn)再通過一個(gè)函數(shù)如peaks或自定義的高度圖賦予Z值最后用surf繪制。為了增加真實(shí)感可以根據(jù)高度映射不同的顏色。無人機(jī)模型為了可視化姿態(tài)我們不能只畫一個(gè)點(diǎn)。我創(chuàng)建了一個(gè)簡單的三維“飛機(jī)”圖形由幾個(gè)patch對象組成機(jī)身、機(jī)翼、尾翼。這個(gè)圖形對象的頂點(diǎn)坐標(biāo)定義在機(jī)體坐標(biāo)系下。在每一幀更新時(shí)根據(jù)無人機(jī)當(dāng)前的位置X_n, Y_e, Z_d和姿態(tài)旋轉(zhuǎn)矩陣R將機(jī)體坐標(biāo)系下的頂點(diǎn)坐標(biāo)變換到地面坐標(biāo)系V_earth pos (R * V_body)然后更新patch對象的Vertices屬性。軌跡用一個(gè)plot3對象來實(shí)時(shí)繪制無人機(jī)質(zhì)心的歷史位置形成飛過的軌跡線。3.2 模擬機(jī)載攝像頭與圖像生成這是項(xiàng)目的亮點(diǎn)之一。我們不僅要從第三人稱視角看無人機(jī)還要模擬第一人稱的機(jī)載視圖。思路是在三維場景中我們放置一個(gè)虛擬的相機(jī)其位置和朝向與無人機(jī)綁定比如安裝在機(jī)頭下方。然后獲取這個(gè)相機(jī)視角下的“快照”生成一幅圖像。相機(jī)參數(shù)標(biāo)定在MATLAB中我們可以用cameraIntrinsics對象來定義相機(jī)的內(nèi)參焦距、主點(diǎn)、畸變。對于仿真我們可以假設(shè)一個(gè)理想的針孔相機(jī)模型。focalLength [800, 800]; % 像素單位下的焦距 [fx, fy] principalPoint [320, 240]; % 圖像中心 [cx, cy] imageSize [480, 640]; % 圖像尺寸 [高度 寬度] intrinsics cameraIntrinsics(focalLength, principalPoint, imageSize);相機(jī)姿態(tài)設(shè)置相機(jī)的外參即相對于機(jī)體坐標(biāo)系的位置和朝向需要定義。例如相機(jī)安裝在機(jī)頭前下方0.1米光軸指向機(jī)體前方并略微下傾比如-10度俯仰。% 相機(jī)相對于機(jī)體坐標(biāo)系的位置和姿態(tài)旋轉(zhuǎn)矩陣 T_body_to_cam [eye(3), [0.1; 0; -0.05]; 0 0 0 1]; % 假設(shè)安裝在(0.1, 0, -0.05)m R_body_to_cam eul2rotm([0, deg2rad(-10), 0]); % 繞Y軸旋轉(zhuǎn)-10度俯仰向下 T_body_to_cam(1:3, 1:3) R_body_to_cam;渲染圖像這是最具挑戰(zhàn)的一步。純Matlab的圖形渲染并非為實(shí)時(shí)圖像生成設(shè)計(jì)。我探索了兩種方法方法A使用getframe和vision.AlphaBlender簡易但慢將三維axes的CameraPosition和CameraTarget設(shè)置為虛擬相機(jī)的位置和看向的點(diǎn)然后使用getframe(gca)捕獲當(dāng)前視圖作為圖像。但這種方法捕獲的是整個(gè)圖形窗口包含坐標(biāo)軸等需要裁剪且?guī)屎艿?。方法B使用pcplayer與自定義投影推薦更接近真實(shí)創(chuàng)建一個(gè)點(diǎn)云播放器pcplayer但將其用于顯示我們自定義的三維場景點(diǎn)云。首先將地形和障礙物的表面點(diǎn)采樣為點(diǎn)云。然后在每一仿真步根據(jù)無人機(jī)和相機(jī)姿態(tài)計(jì)算這些點(diǎn)在該相機(jī)視角下的投影坐標(biāo)。利用相機(jī)內(nèi)參將三維點(diǎn)投影到二維圖像平面。最后根據(jù)深度進(jìn)行簡單的可見性判斷如Z-buffer生成一幅“深度圖”或“特征圖”。雖然這不是真實(shí)的光照渲染圖像但對于許多路徑規(guī)劃算法如基于特征的視覺導(dǎo)航、障礙物檢測來說這種二維投影信息已經(jīng)足夠。我最終采用了方法B的變種。我創(chuàng)建了一個(gè)簡化的三維網(wǎng)格地圖占用網(wǎng)格每個(gè)網(wǎng)格單元有一個(gè)屬性如空地、障礙物、目標(biāo)點(diǎn)。虛擬相機(jī)的任務(wù)就是“看到”前方一定錐形范圍內(nèi)的網(wǎng)格并將其渲染成一張從上往下的二維俯視圖類似于一個(gè)高度壓縮的二維激光雷達(dá)掃描圖這非常適合用于后續(xù)的局部路徑規(guī)劃。踩坑實(shí)錄最初我試圖用getframe實(shí)現(xiàn)實(shí)時(shí)圖像流仿真速度立刻從實(shí)時(shí)降到了十分之一。原因是getframe和圖形重繪開銷巨大。教訓(xùn)是在仿真中視覺模塊的“逼真度”需要與“效率”權(quán)衡。除非專門研究圖像處理算法否則用簡化的幾何投影來提供必要的環(huán)境信息往往是更高效的選擇。將圖像更新頻率設(shè)置為比動(dòng)力學(xué)仿真步長低一個(gè)數(shù)量級如動(dòng)力學(xué)步長0.01s圖像更新0.1s也能顯著提升性能。4. 大腦從全局到局部的路徑規(guī)劃算法集成有了能“飛”的模型和能“看”的眼睛最后一步就是為無人機(jī)裝上“大腦”讓它能自主規(guī)劃路徑。我的程序集成了兩層規(guī)劃基于已知地圖的全局路徑規(guī)劃和基于機(jī)載“視覺”的局部實(shí)時(shí)避障。4.1 全局路徑規(guī)劃A*算法在三維空間的應(yīng)用全局規(guī)劃假設(shè)我們擁有一張先驗(yàn)的二維或二維半地圖即每個(gè)XY位置有高度或通行代價(jià)。我選擇了經(jīng)典的A*A-Star算法因?yàn)樗诰W(wǎng)格地圖上非常高效且能保證找到最優(yōu)路徑如果存在。地圖表示使用一個(gè)二維矩陣map表示全局代價(jià)地圖。值0代表可通行空地1代表障礙物也可以使用0~1之間的值表示不同地形的通行代價(jià)如草地、水域。節(jié)點(diǎn)與啟發(fā)函數(shù)將地圖網(wǎng)格化每個(gè)網(wǎng)格中心是一個(gè)節(jié)點(diǎn)。A*算法需要定義移動(dòng)代價(jià)g(n)和啟發(fā)函數(shù)h(n)。對于無人機(jī)我通常允許八方向移動(dòng)包括對角對角移動(dòng)代價(jià)設(shè)為sqrt(2)。啟發(fā)函數(shù)使用歐幾里得距離或曼哈頓距離。為了考慮高度可以將節(jié)點(diǎn)擴(kuò)展為三維(x, y, z)但搜索復(fù)雜度會(huì)立方增長。一個(gè)折中方法是在二維XY平面上規(guī)劃但將高度變化爬升/下降的代價(jià)融入到g(n)中例如增加一個(gè)與高度差成正比的懲罰項(xiàng)這樣規(guī)劃出的路徑會(huì)傾向于選擇平緩的路線。MATLAB實(shí)現(xiàn)雖然MATLAB沒有內(nèi)置的A*函數(shù)但實(shí)現(xiàn)起來很直接。需要維護(hù)openSet和closedSet以及每個(gè)節(jié)點(diǎn)的gScore,fScore和parent。MATLAB的矩陣操作優(yōu)化能讓代碼比較簡潔。規(guī)劃出的路徑是一系列連續(xù)的網(wǎng)格坐標(biāo)點(diǎn)(x_i, y_i)。% 簡化版A*算法核心框架偽代碼 function path aStar(start, goal, map) [rows, cols] size(map); openSet priorityQueue(); % 需要實(shí)現(xiàn)一個(gè)優(yōu)先隊(duì)列按fScore排序 gScore inf(rows, cols); fScore inf(rows, cols); cameFrom cell(rows, cols); % 記錄父節(jié)點(diǎn) gScore(start(1), start(2)) 0; fScore(start(1), start(2)) heuristic(start, goal); openSet.insert(start, fScore(start(1), start(2))); while ~openSet.isEmpty() current openSet.pop(); % 取出fScore最小的節(jié)點(diǎn) if isequal(current, goal) path reconstructPath(cameFrom, current); return; end neighbors getNeighbors(current, map); % 獲取8鄰域可通行節(jié)點(diǎn) for i 1:length(neighbors) neighbor neighbors(i); tentative_gScore gScore(current(1), current(2)) cost(current, neighbor); if tentative_gScore gScore(neighbor(1), neighbor(2)) cameFrom{neighbor(1), neighbor(2)} current; gScore(neighbor(1), neighbor(2)) tentative_gScore; fScore(neighbor(1), neighbor(2)) tentative_gScore heuristic(neighbor, goal); if ~openSet.contains(neighbor) openSet.insert(neighbor, fScore(neighbor(1), neighbor(2))); else openSet.update(neighbor, fScore(neighbor(1), neighbor(2))); end end end end path []; % 未找到路徑 end4.2 局部實(shí)時(shí)避障人工勢場法APF的快速響應(yīng)全局路徑給出了一個(gè)粗略的參考但無人機(jī)飛行中可能會(huì)遇到未預(yù)料的障礙物動(dòng)態(tài)障礙或地圖誤差。這就需要局部實(shí)時(shí)規(guī)劃。我選擇了人工勢場法Artificial Potential Field因?yàn)樗?jì)算量小適合在線運(yùn)行。其核心思想是為目標(biāo)和障礙物分別構(gòu)造勢場引力場由目標(biāo)點(diǎn)產(chǎn)生勢能大小與到目標(biāo)的距離成正比引力方向指向目標(biāo)。U_att 0.5 * k_att * (distance_to_goal)^2對應(yīng)的引力F_att -gradient(U_att) k_att * (goal_position - current_position)。斥力場由障礙物產(chǎn)生只在障礙物周圍一定范圍內(nèi)有效勢能大小與到障礙物距離成反比斥力方向遠(yuǎn)離障礙物。U_rep 0.5 * k_rep * (1/distance_to_obs - 1/influence_distance)^2(if distance influence_distance)對應(yīng)的斥力F_rep gradient(U_rep)。無人機(jī)所受的虛擬合力F_total F_att ΣF_rep。將這個(gè)合力的方向作為期望的加速度或速度方向輸入給底層的飛行控制器。在我的實(shí)現(xiàn)中局部障礙物信息就來源于第3節(jié)中虛擬相機(jī)生成的二維局部地圖。算法每隔一個(gè)規(guī)劃周期如0.1秒就根據(jù)當(dāng)前位置、全局路徑的下一段子目標(biāo)、以及局部障礙物柵格圖計(jì)算出一個(gè)即時(shí)的期望航向角或橫向加速度指令傳遞給控制器。注意事項(xiàng)人工勢場法有個(gè)著名的問題——局部極小值。當(dāng)引力和斥力平衡時(shí)無人機(jī)可能會(huì)被困在某個(gè)點(diǎn)無法動(dòng)彈。我的解決方法是結(jié)合全局路徑。當(dāng)檢測到無人機(jī)速度持續(xù)低于閾值且未到達(dá)目標(biāo)時(shí)就觸發(fā)一次局部重規(guī)劃或者在勢場函數(shù)中加入一個(gè)“切向力”或“隨機(jī)擾動(dòng)”來幫助逃逸。更魯棒的方法是結(jié)合D* Lite等動(dòng)態(tài)重規(guī)劃算法但計(jì)算開銷會(huì)增大。5. 系統(tǒng)集成與仿真循環(huán)讓一切協(xié)同工作將動(dòng)力學(xué)模型、可視化、圖像生成、路徑規(guī)劃器集成到一個(gè)流暢的仿真循環(huán)中是最后的挑戰(zhàn)。我采用Simulink作為主引擎結(jié)合MATLAB Function塊和S-Function來實(shí)現(xiàn)混合系統(tǒng)仿真。5.1 Simulink模型架構(gòu)整個(gè)系統(tǒng)是一個(gè)典型的“感知-規(guī)劃-控制”閉環(huán)。Plant Model被控對象即第2節(jié)搭建的6-DoF無人機(jī)非線性動(dòng)力學(xué)模型。輸入是控制面偏角[δ_e, δ_a, δ_r]和油門δ_t。輸出是所有狀態(tài)量位置、姿態(tài)、速度等。Flight Controller飛行控制器這是一個(gè)內(nèi)環(huán)控制器負(fù)責(zé)穩(wěn)定無人機(jī)姿態(tài)。我通常設(shè)計(jì)為串級PID控制。外環(huán)位置/高度/航向產(chǎn)生期望的俯仰角、滾轉(zhuǎn)角和空速指令內(nèi)環(huán)姿態(tài)角根據(jù)期望姿態(tài)和當(dāng)前姿態(tài)的偏差計(jì)算出所需的控制面偏轉(zhuǎn)角和油門量。這部分可以用Simulink的PID模塊搭建參數(shù)需要仔細(xì)整定。Path Follower路徑跟蹤器它接收規(guī)劃器給出的路徑點(diǎn)一系列[X, Y, Z]并計(jì)算出當(dāng)前無人機(jī)應(yīng)該執(zhí)行的“目標(biāo)狀態(tài)”比如目標(biāo)高度、目標(biāo)航向、目標(biāo)空速然后傳遞給飛行控制器。常用的跟蹤算法有純追蹤法Pure Pursuit或線性二次型調(diào)節(jié)器LQR。Global Local Planner規(guī)劃器這是一個(gè)由觸發(fā)事件或固定周期驅(qū)動(dòng)的模塊。全局規(guī)劃器在仿真開始時(shí)運(yùn)行一次給出全局路徑。局部規(guī)劃器以更高頻率如10Hz運(yùn)行它從Visualization Image Module可視化與圖像模塊獲取當(dāng)前的局部障礙物信息并對全局路徑進(jìn)行微調(diào)或生成緊急避障指令。Visualization Image Module可視化與圖像模塊這是一個(gè)MATLAB Function塊或S-Function在每個(gè)仿真步或每N個(gè)步被調(diào)用。它從Plant Model讀取當(dāng)前無人機(jī)狀態(tài)更新三維動(dòng)畫和虛擬相機(jī)圖像。圖像信息被傳遞給局部規(guī)劃器。5.2 仿真流程與參數(shù)調(diào)試心得啟動(dòng)仿真后流程如下初始化加載無人機(jī)參數(shù)、地圖、設(shè)置初始狀態(tài)。全局規(guī)劃根據(jù)起點(diǎn)和終點(diǎn)運(yùn)行A*算法得到全局路徑點(diǎn)序列。Simulink求解器開始推進(jìn)時(shí)間 a. 動(dòng)力學(xué)模型根據(jù)當(dāng)前控制輸入更新狀態(tài)。 b. 可視化模塊更新3D視圖和虛擬相機(jī)圖像。 c. 在規(guī)劃周期到達(dá)時(shí)局部規(guī)劃器根據(jù)當(dāng)前圖像和位置計(jì)算局部路徑指令。 d. 路徑跟蹤器綜合全局和局部指令生成目標(biāo)狀態(tài)。 e. 飛行控制器根據(jù)目標(biāo)狀態(tài)和當(dāng)前狀態(tài)差計(jì)算新的控制輸入。 f. 控制輸入作用于動(dòng)力學(xué)模型進(jìn)入下一個(gè)仿真步。仿真結(jié)束分析數(shù)據(jù)軌跡跟蹤誤差、控制量變化、圖像序列等。調(diào)試經(jīng)驗(yàn)分享“分而治之”不要試圖一次性集成所有模塊并跑通。我的步驟是先讓動(dòng)力學(xué)模型在開環(huán)下給定固定舵面能飛出一個(gè)合理的軌跡如平飛。然后關(guān)閉環(huán)控制器讓無人機(jī)能穩(wěn)定懸停或跟蹤簡單的指令如階躍高度變化。接著單獨(dú)測試路徑跟蹤器用一條預(yù)設(shè)的直線或圓弧路徑看無人機(jī)能否跟上。再單獨(dú)測試規(guī)劃器輸入一個(gè)簡單地圖看規(guī)劃出的路徑是否合理。最后再把所有模塊像拼圖一樣連接起來。參數(shù)整定順序控制器參數(shù)整定從內(nèi)環(huán)開始。先整定角速率環(huán)p, q, r再整定姿態(tài)環(huán)Φ, Θ, Ψ最后整定外環(huán)位置/速度環(huán)。使用Simulink的PID Tuner工具或手動(dòng)調(diào)整時(shí)觀察階躍響應(yīng)的超調(diào)量、穩(wěn)定時(shí)間和穩(wěn)態(tài)誤差??梢暬菑?qiáng)大的調(diào)試工具當(dāng)無人機(jī)飛行動(dòng)作怪異時(shí)仔細(xì)觀察三維動(dòng)畫。是姿態(tài)劇烈振蕩還是根本朝錯(cuò)誤方向飛結(jié)合繪制出來的狀態(tài)曲線如歐拉角、控制量能快速定位問題是出在控制器、規(guī)劃器還是模型本身。虛擬相機(jī)圖像也能幫你確認(rèn)局部規(guī)劃器“看到”的世界是否和你設(shè)想的一致。性能瓶頸如果仿真速度很慢使用Profiler工具分析耗時(shí)最多的函數(shù)。往往是可視化渲染或規(guī)劃算法尤其是搜索算法占了大頭。對于非關(guān)鍵模塊可以降低其更新頻率。對于A*算法如果地圖很大可以嘗試使用更高效的啟發(fā)函數(shù)如Diagonal distance或者采用跳點(diǎn)搜索JPS等優(yōu)化算法。通過這個(gè)完整的建模與仿真程序你獲得的不再是一個(gè)黑盒工具而是一個(gè)透明、可干預(yù)、可擴(kuò)展的無人機(jī)系統(tǒng)研發(fā)沙盤。它允許你以極低的成本深入理解從底層動(dòng)力學(xué)到高層智能決策的每一個(gè)環(huán)節(jié)并安全、高效地測試你的算法創(chuàng)意。無論是用于教學(xué)、科研還是工程預(yù)研這套框架都提供了一個(gè)堅(jiān)實(shí)的起點(diǎn)。本文還有配套的精品資源點(diǎn)擊獲取