APM飛控學習之路:1 無人機的分類與發展

   “舊時王謝堂前燕,飛入尋常百姓家”。無人機也像那堂前燕,從以前爲軍事所專屬,負責偵查和戰鬥,飛入民用領域,在航拍、植保、快遞、救災、巡檢、拍攝等行業大顯身手,無人機+的應用遍地開花,成爲智能時代機器人領域的尖兵。

        無人機,顧名思義,即不載人的飛行器。目前飛行器主要分爲3類:固定翼(fixed wing);直升機(helicopter);多旋翼(multi-rotor)。最近風頭最熱、也最有前景的,當屬多旋翼大家族的主力軍——四旋翼無人機(quadcopter),大大小小的無人機廠商如雨後春筍般冒出來。大的有DJI、零度、億航、極飛等,小的就數不勝數了,最近京東也衆籌了一款PowerEgg無人機,無人機行業的繁榮可見一斑。各飛行器的特點簡介如下:

 

飛行器分類

固定翼

直升機

多旋翼

穩定性

自穩定

不穩定,完整驅動

不穩定,欠驅動

續航時間

飛行效率

載荷

其他

起飛助跑,降落滑行

可垂直起降,機械結構複雜

可垂直起降,機械結構簡單        

         本系列博客的重點也是四旋翼無人機。四旋翼含4個螺旋槳,即4個電機,4個自由度,而三維空間的位姿有6個自由度,4<6,因而稱欠驅動。受控的自由度可以從遙控器的輸入看出端倪:左邊的搖桿控制上下的高度和機頭的朝向(Yaw),右邊的搖桿控制飛機的前後和左右,共4個自由度。而欠驅動的2個自由度爲飛機的俯仰(Pitch)和橫滾(Roll),和飛機的前後、左右是耦合的,因此也可以說右邊的搖桿控制飛機的俯仰和橫滾。無人機在前後左右運動時機身會產生一定傾斜的原因即在於此。

        上表大致總結了各飛行器的特點,那麼問題來了,多旋翼各項指標落後仍受大衆青睞到底爲哪般?讓我們走近科學,探祕多旋翼。由於多旋翼系統不穩定、欠驅動,需要自動控制器來控制飛行器的姿態,而要取得姿態,就不得不提慣性導航系統(Inertial Navigation System,以下簡稱INS)。INS的主要原理是利用加速度計和陀螺儀,對時間積分獲得速度,進而獲得飛行器的位置和姿態。INS最初用於導彈、火箭等軍事領域,十幾公斤的大鐵疙瘩對於按噸計的巨型鐵疙瘩來說那都不算事兒。但要放到多旋翼頭上,這可是泰山壓頂,愚公有心也無力,多旋翼的研究一度停滯。

 

        到了上世紀90年代,隨着微機電系統(Micro-Electro-Mechanical System,以下簡稱MEMS)的發展,幾克重的mm級INS被開發出來,多旋翼的自動控制器又重新擡頭。但是條件還不夠,傳感器的噪聲、多傳感器的數據融合、多旋翼的非線性系統結構、飛行控制算法等問題仍像一座座大山,等待探路者去征服。到了2005年,穩定靠譜的多旋翼自動控制器才正式面世。四旋翼作爲多旋翼無人機中最簡潔的一種,開始受到廣泛關注和研究。由於其結構簡單、控制靈活、成本較低,也逐漸進入了商業領域和大衆視野。

 

        之後的歷史,諸君都是見證者。2009年,《三傻大鬧寶萊塢》中Geek的小四軸,把新鮮感帶給了大衆。2010年,法國Parrot公司發佈AR.Drone——世界首款流行的四旋翼,上能飛天拍大地,下可懸停擺造型,成爲人們的天空之眼。此時的四旋翼,還是小衆人羣的玩具。直到2013年,DJI的Phantom與GoPro結合,讓四旋翼從一個玩具變身成了航拍精靈。先手優勢一發不可收,至今DJI已成爲世界上首屈一指的無人機廠商,成爲中國智造的驕傲,也成功幫汪峯求婚,新娘頭條雙豐收!除了DJI,國際的3D Robotics、AscTec,國內的零度、億航也加入戰局,羣雄爭霸,硝煙四起。

 

        一個Interesting&Exciting的無人機時代正在拉開序幕,讓我們拭目以待。

 

APM飛控學習之路:2 四旋翼的工作原理與系統組成

2016年10月31日 20:48:47

閱讀數:8807

        “一葉障目,不見泰山”。在研究四旋翼飛行器之前,有必要從整體介紹其工作原理、主要部件、技術名詞等基礎知識。不然就像羊入虎口,陷入一大堆不同層次的資料,難覓出口。接下我就拋磚引玉,儘自己所能,介紹四旋翼的工作原理和主要部件。餘雖不敏,然餘誠也。

 

工作原理

 

        四旋翼飛行器,通過4個對稱佈置的電機,改變螺旋槳的轉速,實現升力的變化,進而控制飛行器的姿態和位置。姿態具體指3個歐拉角:橫滾(Roll)、俯仰(Pitch)、偏航(Yaw)。位置具體指1個高度油門(Throttle)和2個位置(X和Y)。歐拉角是一種描述物體姿態的常見方式,廣泛應用於慣性導航、機器人等領域。爲了方便大家理解,在網上找了3個歐拉角的動圖,分別爲Roll、Pitch、Yaw,讓我們致敬製作者3秒鐘。

        橫滾:Roll,控制四旋翼左右運動。

        俯仰:Pitch,控制四旋翼前後運動。

        偏航:Yaw,控制四旋翼的朝向。

        無人機的姿態和位置共有6個自由度,每個自由度的控制如下圖所示。4個電機2個正轉(電機2和4),2個反轉(電機1和3),對稱佈置。電機正反轉配合正反槳,可使螺旋槳的風都往下刮以平衡重力,同時抵消因槳葉旋轉帶來的空氣阻力扭矩。由於輸入只有4個自由度,因此多出的2個自由度是不完全受控的,其中俯仰運動和前後運動耦合,滾轉運動和側向運動耦合。

        座標系:標準右手系。規定X軸正方向爲前向。螺旋槳的箭頭向上↑:電機轉速上升。螺旋槳的箭頭向下↓:電機轉速下降。

        (a) 垂直運動(Throttle):4個電機均加大馬力,螺旋槳產生的升力大於重力,飛機便垂直上升。當升力與重力平衡時,飛機便懸停。懸停是考驗算法的重要一環,靠的是PID不斷反饋,調整轉速。

        (b) 俯仰運動(Pitch):電機1加大馬力,電機3減小馬力,二者的變化量相同。1處升力變大,3處升力減小,重力仍保持平衡,但對Y軸產生一個力矩,機身繞Y軸旋轉,實現俯仰。

        (c) 滾轉運動(Roll):與 (b) 原理相同,只是Y軸換成了X軸。

        (d) 偏航運動(Yaw):電機1、3加大馬力,電機2、4減小馬力,二者的變化量相同。重力和繞X、Y軸的扭矩仍保持平衡,但要注意的是,根據作用力和反作用力原理,由於2個正轉的速度>2個反轉的速度,空氣阻力產生的扭矩不平衡了,使得機身繞Z軸旋轉,實現偏航。

        (e) 前後運動:與 (b) 耦合,機身繞Y軸旋轉一定角度後,使得升力沿水平方向有了分量,實現前後運動。

        (f) 側向運動:與 (c) 耦合,原理與 (e) 相同。

        如果有朋友接觸過麥克納姆輪,也稱“全向輪”,那就更容易理解四旋翼的工作原理了。麥克納姆輪通過4個對稱佈置的電機和輪盤,可實現車身水平任意方向的移動和原地旋轉,無比靈活。

 

主要部件

 

        以S500爲例,S500是一架入門級的四旋翼飛機,這裏的500指的是軸距(對角2個電機之間的距離),單位 :mm。對於開源愛好者而言,如果想一站式玩四旋翼,在某寶上選購一架S500是個不錯的選擇。下面我就從上表出發,詳細介紹四旋翼的主要部件和技術名詞。

四旋翼本體

        四旋翼分2種模式,1種是+模式:飛行方向(機頭)與旋翼重合;1種是X模式:飛行方向(機頭)平分旋翼。

        +模式:直觀,簡單,驅動弱,調參容易。

        X模式:複雜,穩定,驅動好,調參麻煩。

        對於四旋翼,穩定和驅動是第一位的,調參可以站在巨人的肩膀上,因此一般採用X模式。

飛行控制器

        飛行控制器簡稱飛控,是無人機的大腦。目前主要分開源和閉源兩派,開源飛控的鼻祖來自Arduino,著名的WMC飛控和APM飛控都是Arduino飛控的直接衍生品,APM全稱ArduPilotMega,其中的Ardu代表的就是Arduino。APM飛控是目前成熟度最高的開源飛控,但由於容量和計算量有限,在不久的將來一定會被更強大的PIX4、PIXHAWK所超越,成爲一個時代的縮影。還有一些較爲初級的飛控,如KK、QQ、玉兔等,在這就不贅述了。閉源飛控主要由商業公司推出,如DJI的工業級飛控A2、A3,入門級飛控Naza系列,還有零度的S4、X4和雙子星GEMINI。值得一提是其中的雙子星,是國內首個雙餘度安全飛行控制系統。隨着安全性的重視和提高,冗餘度設計也將成爲無人機的標配。

螺旋槳

        4個螺旋槳,2正槳(順時針轉)2反槳(逆時針轉),正反槳的風都向下吹,正反的目的主要是抵消螺旋槳的自旋。安裝的時候,無論正反槳,有字的一面均向上。槳型中1045這4位數字,前2位10代表槳的直徑(單位:英寸inch),後2位45代表槳的角度(單位:度°)。

電機

        4個無刷電機,2正轉2反轉。2212這4位數字,前2位22代表電機轉子直徑,後2位12代表電機轉子高度,單位:毫米mm,注意均指電機轉子而非外殼。如果大家留心的話,電機外殼上一般會並註明這4位數字,除此之外,還會看到一個KV值,代表外加1V電壓時電機每分鐘空轉轉速。如“KV:900”代表外加1V電壓時,電機空轉時每分鐘轉900圈。常見的電機品牌有新西達(XXD)、朗宇(SunnySky)等,並且很多外殼上會有一串神祕字符:MADE IN CHINA。

電調

        說完電機說電調,電調和電機配套使用,是飛控和電機之間的橋樑。電調全稱電子調速器(Electronic Speed Control),負責將飛控的控制信號(PWM波)轉變爲電流的大小,進而控制電機轉速。除了明面上的轉換功能,還能承載電機所需的大電流,以及將11.1V轉爲5V供飛控和遙控模塊使用(BEC輸出)。電調的主要參數是電流輸出能力,單位A,如30A代表電調能提供的最大電流爲30A。常見的電調品牌有新西達(XXD)、中特威(ZTW)、好盈(HobbyWing)等。

電池

        一般爲鋰電池,因爲同等電池容量鋰電池最輕。大家可以看到有3個參數:3200mAh 11.1V 30c。和手機電池一樣,3200mAh代表以3200mA電流放電,可持續1小時。11.1V代表電壓,一般由3節標準鋰電池組成(3.7V×3=11.1V),相應標識爲3S。30c代表放電能力,在航模中是個重要參數,意味着可以3200mA×30的電流強度放電。說完了放電,還有充電,一般爲2c充電,即充電電流可爲3200mA×2。由於航模鋰電池採用多節標準鋰電池組成,而各節標準鋰電池之間存在充放電性能差異,因此充電器一般採用平衡充,避免某節電池過充。

遙控器

        主要分美國手和日門手,美國手的油門在左邊,日本手的油門在右邊。在四旋翼的控制中,一般採用美國手。怎麼判斷油門呢?很簡單,遙控器左右2個搖桿中,推上去不回彈的是油門。也很好理解,油門一般穩定在一個位置就好了,回彈的話飛手會流淚。遙控器中也有1個神祕數字,6代表6通道,即遙控器可控的動作路數。因爲四旋翼有4個自由度,所以遙控器至少需要4通道,剩餘的通道用於控制飛行模式等。

        至此四旋翼的主要部件和技術名詞介紹完畢,還有一些可選部件,如數傳、OSD、雲臺、相機、圖傳等,待大家入門後即可自行挖掘。最後附上一個Exciting的TED視頻,震撼你的眼球。拉菲羅·安德烈:四軸飛行器靈活的運動性

   

APM飛控學習之路:3 APM系統介紹與開發環境搭建

置頂2016年11月03日 11:08:55

閱讀數:31859

        “工欲善其事,必先利其器”。在進行無人機飛控開發時,選擇一個合適的軟硬件平臺以及IDE是十分重要的。目前,APM飛控成熟度高,開發工具齊全,社區建設完善,開發者文檔豐富,適合開源選手入門和二次開發。因此,本系列博客以APM飛控作爲切入點,在Windows環境下介紹其代碼結構和開發應用。

 

APM系統介紹

 

        APM全稱ArduPilotMega,Ardu源自Arduino,Pilot意指飛行,Mega代表主芯片爲ATMEGA2560(Atmel公司的8位AVR單片機)。是的,沒有看錯,一個簡單8位單片機竟完成了如此複雜的飛控任務! 51單片機表示哭暈在廁所,同爲8位出身,命運截然不同。筆者大概是2011年接觸的單片機,當時也同大多數初學者一樣,從經典的51單片機入門,一個個模塊、寄存器的學習,曲線雖說不上陡峭,但至少不那麼友好。反觀Arduino,近3年在國內迅速崛起,除了Geek文化和開源文化的普及,一個很關鍵的原因在於Arduino讓不懂硬件電路的普通人(甚至小學生)也能輕鬆上手硬件了。沒有了煩人的寄存器,沒有了紛繁的頭文件,一個setup()和一個loop(),再加一個自帶教程的簡潔IDE,Arduino名副其實——源自意大利的男姓用名,意爲“強壯的朋友”。世界如此美好,我想和Arduino做朋友。

        APM內置六軸MEMS傳感器MPU6000,氣壓計MS-5611,三軸磁力計HMC5883,一般還會配置GPS模塊,以便更精確的慣性導航。其中,MPU6000整合了三軸陀螺儀和三軸加速度計,積分可得速度和位姿。MS-5611通過測量氣壓得到高度,輔助GPS定位。HMC5883通過測量地磁場得到方位,輔助無人機定向。飛控採集並融合多種傳感器的數據,計算並校正無人機的位姿。給APM一張正面裸板特寫!

 

APM與PIXHAWK的關係        

        說到APM,就不得不提它的進化版:PX4和PIXHAWK,來自蘇黎世聯邦理工大學。“PX4是一個軟硬件開源項目(遵守BSD協議),目的在於爲學術、愛好和工業團體提供一款低成本、高性能的高端自駕儀。PX4FMU自駕儀模塊運行高效的實時操作系統(RTOS),Nuttx提供可移植操作系統接口(POSIX)類型的環境。由3DR聯合APM小組與PX4小組於2014年推出的PIXHAWK飛控是PX4飛控的升級版本,擁有PX4和APM(ArduPilot)兩套固件和相應的地面站軟件,也是目前全世界飛控產品中硬件規格最高的產品。”

        好了說人話,目前主流就2種:APMPIXHAWK。有時指硬件,有時指軟件(固件),爲了明確,在此做個區分。硬件分2種:APM和PIXHAWK。APM的版本有2.5,2.6和2.8,PIXHAWK的版本有v1和v2。軟件也分2種:APM和PX4。軟件版本就多了去了,詳見github。APM硬件由於存儲空間有限,最高支持到3.2.1的APM軟件。PIXHAWK硬件是STM32F4,存儲空間大,對APM軟件(3.2.1之後的版本也支持)和PX4都支持。

        APM和PIXHAWK都開源,不過二者遵守的開源協議不同。APM多用於DIY和小型產品,某寶上大量的無人機就採用APM,成本低。公司商用一般採用PIXHAWK。目前很多PIXHAWK裏跑的還是APM固件,個人認爲有幾大原因:1. APM固件出來的更早,使用人羣習慣的延續;2. APM固件成熟度更高、資料更全。3. APM固件走開源路線更徹底,遵守GPL V3協議,PX4更傾向商業和實驗用途,遵守BSD協議。目前APM小組已和PX4小組分道揚鑣,詳見新聞:ArduPilot脫離Dronecode真相

APM固件下載

 

        剛提到APM硬件的最高版本爲2.8,現在說說APM固件(源碼)的版本。既然是開源項目,那麼在github上肯定有倉庫。曾經的APM源碼存於code.google.com,後來github席捲全球,成爲廣泛接受的代碼倉庫,於是谷歌把自己的倉庫關了(反正國內也上不去:-()。github上的源頭在此:https://github.com/ArduPilot/ardupilot。其中的ArduCopter支持多旋翼、直升機等,四旋翼源碼即在其中,但是別急着下載,先點擊release看看源碼版本。可以看到帶Copter的最新版本是“Copter-3.4.0”,帶ArduCopter的最新版本是“ArduCopter-3.2.1-apm-px4”,很多朋友直接參照網上的《通過Arduino給APM編譯下載最新固件》用git克隆代碼到本地,發現無法使用,問題就在於git獲取的是最新版,而APM支持的最高版本是“ArduCopter-3.2.1-apm-px4”,從命名也可以發現,該版本固件同時支持APM和PX4。

 

        獲取ArduCopter-3.2.1版本的源碼有2種方式:I. 在github頁面點擊release,往下翻幾頁,找到“ArduCopter-3.2.1-apm-px4”下載即可。II. 喜歡git的朋友在克隆最新代碼後,也可以回退到3.2.1的版本,與第一種方法獲得的源碼無異。

 


 
  1. git clone https://github.com/ArduPilot/ardupilot.git

  2. cd ardupilot/

  3. git branch -a

  4. git checkout -b arducopter-3.2.1 origin/ArduCopter-3.2.1

 

        使用方法解壓之後就可以看到源碼啦,結構如下。其中,APMrover2支持地面車輛,ArduPlane支持固定翼,ArduCopter支持多旋翼和直升機。對於四旋翼的開發,就對應ArduCopter文件夾。值得一提的是,打開ArduCopter文件夾後,可以看到一大波.pde文件,.pde爲Arduino文件的舊版後綴,新版的爲.ino(Arduino的後3個字母),可以簡單類比成.cpp文件。熟悉C++的朋友可能會想去找main文件,這回改頭換面了,主文件叫ArduCopter.pde。

 

 

APM開發環境

 

        巧婦難爲無米之炊”,現在米有了,用什麼工具做飯呢。先把火備好,即編譯的工具鏈和驅動:MHV_AVR_Tools_20121007.exe(AVR單片機編譯和下載程序用)和MissionPlanner-latest.msi(飛控地面站,含APM的USB接口驅動)。接下來就是用什麼竈臺做飯了,以Windows平臺爲例,竈臺根據方便程度有2種:I. 土竈:ArduPilot-Arduino-1.0.3-gcc-4.7.2-windows(爲ArdupPilot定製的Arduino IDE)。II. 電磁爐:Visual Studio配合Visual Micro插件(Arduino for Visual Studio插件)。二者本質沒有區別,可以看到都是調用gcc工具鏈,Visual Studio只是通過Visual Micro在上層封裝了操作接口,便於程序員查看和編寫代碼。強烈建議使用Visual Studio!!!

 

環境I(輕量). Arduino IDE

 

        先介紹Arduino派的IDE:ArduPilot-Arduino-1.0.3-gcc-4.7.2-windows,此IDE不同於普通的Arduino IDE,而是爲ArdupPilot定製的。解壓之後,打開“arduino.exe”,一張白板撲面而來。唯一和飛控有關的就在菜單欄上,相比通用ArduinoIDE多了“ArduPilot”一項。工具欄的“√”是編譯,“→”是下載。

        點擊“文件->參數設置”,可設置程序庫的位置,即APM源碼位置,注意不要勾選“啓動時檢查更新”,因爲本IDE專爲ArduPilot定製。其他選項可根據個人喜好設置。

        設置完成後退出再重開,以保證程序庫位置生效。點擊“文件->程序庫->ArduCopter”,源代碼一覽無餘。之後配置APM固件,主芯片:“工具->板卡->Arduino Mega 2560 or Mega ADK”,串口:“工具->串口->相應USB串口”(確保驅動已安裝),編程器:“工具->編程器->AVRISP mkll”(默認),APM硬件型號:“ArduPilot->HALBoard->ArduPilot Mega 2.x”。

 

        至此,Arduino IDE的完畢,可以點擊編譯了。等待3分鐘左右,編譯完畢,生成一個hex文件用於下載到APM板。

        切記:不要下載!不要下載!不要下載!下載會變磚!

 

環境II(推薦). Visual Studio&Visual Micro

 

        Arduino IDE編譯APM的代碼還可以,但要是用來瀏覽和編寫代碼,那就是千絲萬縷扭不清了,所以ArduinoIDE的設置裏也機智地留下一條後路:“□使用外部編輯器”。

        Visual Studio(以下簡稱VS)作爲宇宙最強IDE,怎麼能不支持下Arduino,感謝微軟救民於水火。以VS2012爲例,點擊“工具->擴展和更新->聯機”,搜索“Visual Micro”,下載安裝即可。順便推薦下Visual Assist,VS下最好的代碼補全工具,以前寫1行代碼的功夫,現在可以寫3行~

        安裝好之後,VS的菜單欄多了一些振奮人心的東西。“VMICRO”中可設置Arduino的選項,點擊“VMICOR->Visual Micro Explorer”,如下圖所示。對比Arduino IDE可發現,編譯、下載、COM口應有盡有,還可適配不同的Arduino 版本。

        點擊“Configure”進行配置,選擇Arduino版本:1.0,配置Arduino目錄,筆者的是:D:\Fly\ArduPilot-Arduino-1.0.3-windows,即ArduPilot-Arduino-1.0.3-gcc-4.7.2-windows解壓後的文件夾。注意此插件的名字是“Arduino IDE for Visual Studio”,並不是專爲Ardupilot/APM定製,因此還需適配apm硬件信息(點擊藍字鏈接下載,解壓後爲一名爲apm的文件夾,內僅含boards.txt)。將該apm文件夾放入D:\Fly\ArduPilot-Arduino-1.0.3-windows\hardware中。配置完成之後,可在“Installed”選項卡中查看支持的硬件類型,如所需的“Arduino Mega 2560 HAL (Apm 2)”,插上APM後在COM口選擇對應的串口號。此外,在“Examles”選項卡中可查看Arduino和ArduCopter的例程。

        重啓VS,點擊“文件->打開->Arduino Project”,選擇ArduCopter文件夾中的ArduCopter.pde打開,即可在“解決方案資源管理器”中看到APM的源碼結構。解釋一下,ArduCopter.pde相當於平時常見的Main.cpp,在ArduCopter.pde的最後一行是真正的main函數。

AP_HAL_MAIN();

        除此之外,有一點需要注意,在“VMICRO”中,“Debugger”取消勾選“Automatic Debug(Release/Debug)”,否則會編譯失敗。因爲APM2.8不支持在線Debug,同時對於“多線程”程序,Debug本身意義不大,一般採用串口print進行調試以便觀察程序流程。對於普通Arduino板(如nano)可以勾選,下載後會自動進入調試狀態。

        至此,Visual Studio&Visual Micro的配置完畢,又可以愉快地編譯了。同樣等待大概3分鐘左右,可以看到編譯完成,生成一個hex文件用於下載到APM板。對於編譯,第1次會較慢,修改代碼再次編譯就很快了。

        切記:不要下載!不要下載!不要下載!下載會變磚!

        在此給出筆者用VS2012編譯的工程:APM3.2.1固件-VS2012工程,打開ArduCopter文件夾中的ArduCopter.sln即可使用。如果你好奇心太重點了下載,也沒關係,筆者會在下一篇博客讓板磚起死回生:)

 

APM資料說明

 

        有關APM的資料,首推ArduPilot官網:http://ardupilot.org/ardupilot/。如果是開發四旋翼,左側的“Copter”和“Developers”是你經常要去逛的。裏面詳細介紹了APM的方方面面,值得反覆咀嚼。網上的APM資料,很多就是翻譯自ArduPilot官網,但是良莠不齊。不要懼怕英文而選擇逃避,蔡康永有一段很有名的話,“15歲覺得游泳難,放棄游泳,到18歲遇到一個你喜歡的人約你去游泳,你只好說"我不會耶”。18歲覺得英文難,放棄英文,28歲出現一個很棒但要會英文的工作,你只好說“我不會耶”。人生前期越嫌麻煩,越懶得學,後來就越可能錯過讓你動心的人和事,錯過新風景。”萬事開頭難,但也不要放大開頭的困難,跨過去就好了。

        國內的資料,主要推薦“模友之吧”裏“泡泡老師”的視頻教程,教你一步步上手APM2.8:[泡泡老師教程] 新手課堂:APM2.8的使用方法

        個人收集的2個資料:新編APM-2.8.0中文入門手冊APM2.8接口介紹

 

  “月盈則虧,水滿則溢”。當博主編譯完成,以爲離成功更近一步準備下載的時候,殊不知陷阱也早已準備好,等待我的踏入。連上USB線,下載,timeout...,timeout...,timeout...,留下博主一臉懵逼,和一塊已然變磚的APM板。遂作此文,爲廣大APM開發者避開下載的坑。

        下載環境:APM2.8,固件版本3.2.1,通過USB下載。

 

原因定位

 

        事出突然,案發現場只留下了一張截圖,代表着下載失敗。

        從這張截圖開始分析:avrdude是AVR系列單片機的下載模塊,負責將hex文件寫入APM板的ROM和EEPROM。寫入文件之後,avrdude向APM板Send數據,估計用於校驗,卻等不到迴應:“programmer is not responding”,只能向電腦返回:timeout,順便不忘問候博主:“avrdude done. Thank you.”

        由此看來下載完程序之後,APM板直接變磚,已無法和PC端取得有效通信。博主經過多種嘗試,如重新編譯並下載、通過地面站(Mission Planner)刷固件、下載老版本固件,皆因timeout或無法連接而告終。痛定思痛,想到安卓手機刷機時也可能變磚,變磚後還能刷回來,靠的是什麼?Bootloader!難道是因爲程序過大,把APM板中的Bootloader,也就是引導程序給覆蓋了?!

        回過頭來看編譯結果:編譯之後,程序大小爲256258bytes,也就是250KB的樣子,佔用了總容量的99%!很可能把Bootloader給佔用了。就好比把一個很大的文件往電腦的C盤塞,把C盤塞爆了,順便把系統也弄崩了。果不其然,查閱資料可知,APM 程序存儲容量爲256KB,其中8KB被Bootloader佔用。如果程序大於248KB,當程序燒寫進APM中時,會破壞APM的Bootloader。Bootloader破壞之後的現象就是:APM板上電後只有電源燈亮,且無法連接地面站。正是如此!

 

刷寫Bootloader

 

        雖然Bootloader被博主無意中破壞,但天無絕人之路,從哪裏弄壞,就從哪裏修好。當自己買電子元器件和電路板,根據開源的APM硬件焊接APM板時,也需要給APM板重新燒寫Bootloader。

硬件準備

 

        AVR單片機的USBASP或USBISP下載器×1。

軟件準備

 

        1. 下載器配套軟件,推薦progisp1.72。

        2. AVR的USB自編程軟件:Flip。

        3. 32u2的驅動程序。

        4. 三個hex文件:Atmega2560的bootloader文件、32u2的bootloader文件和32u2的ppm程序文件。

        燒寫過程概述:先給Atmega2560燒寫bootloader,然後給Atmega32u2燒寫bootloader,最後給32u2寫入PPM解碼通訊程序。

        燒寫的視頻教程(含驅動和hex文件下載):[泡泡老師教程] 新手課堂,如何給修復或空板APM燒寫 Bootloader

        燒寫的文字教程:燒寫APM板的Bootloader

        按照視頻教程操作即可,可以不用轉接線,直接用幾根杜邦線連接,注意線序。

 

程序裁剪與下載

 

        既然程序容量有限,就需要對程序進行裁剪,比如拿剪刀把APM板剪掉一角。好了正經一點,所謂裁剪,最簡單的就是將部分程序註釋或刪除,使編譯之後的程序容量變小。要想裁剪APM,首先需要對飛控程序的結構有個大致的瞭解,才能在註釋或刪除代碼的同時保證飛控的穩定性。先看看官網是怎麼介紹飛控程序的:“The ArduPilot code base is quite large (about 700k lines for thecore ardupilot git tree) and can be quite intimidating to a new user.”,翻譯過來就是飛控代碼太太太多了,足足70萬行估計你這小白搞不定。

        “他強任他強,清風撫山崗。他橫由他橫,明月照大江。”雖然飛控代碼多,但是程序員有兩板斧子,一看代碼結構,二看主函數。

        根據上篇博文所述,使用VS2012配合VM插件查看APM3.2.1工程代碼,其代碼主要由多個pde文件組成,可簡單理解爲cpp文件。根據pde文件的命名,博主將代碼分爲6類:(1)主函數ArduCopter;(2)各種飛行模式,佔了大部分程序,如control_acro、control_althold、control_auto等;(3)系統初始化system;(4)Mavlink通信GCS_Mavlink;(5)用戶程序UserCode;(6)其他雜項。既然飛行模式的程序最多,博主就準備拿它開刀。

        要裁剪飛行模式,就得看主函數是如何調用各飛行模式的。看大型代碼一定要帶着目的去看,既然通過遙控可以切換飛行模式,那麼判斷處於飛行模式的代碼一定是在某個循環中。這樣一來就好辦了,從ArduCopter.pde的fast_loop()函數入手,可以看到其代碼不多,列出如下。


 
  1. static void fast_loop()

  2. {

  3.  
  4. // IMU DCM Algorithm

  5. // --------------------

  6. read_AHRS();

  7.  
  8. // run low level rate controllers that only require IMU data

  9. attitude_control.rate_controller_run();

  10.  
  11. #if FRAME_CONFIG == HELI_FRAME

  12. update_heli_control_dynamics();

  13. #endif //HELI_FRAME

  14.  
  15. // write out the servo PWM values

  16. // ------------------------------

  17. set_servos_4();

  18.  
  19. // Inertial Nav

  20. // --------------------

  21. read_inertia();

  22.  
  23. // run the attitude controllers

  24. update_flight_mode();

  25.  
  26. // optical flow

  27. // --------------------

  28. #if OPTFLOW == ENABLED

  29. if(g.optflow_enabled) {

  30. update_optical_flow();

  31. }

  32. #endif // OPTFLOW == ENABLED

  33.  
  34. }

        細心的朋友可能注意到了,顧名思義,update_flight_mode()就是更新飛行模式的函數。右鍵轉到定義或按快捷鍵F12,可查看update_flight_mode()中是一串熟悉的switch-case語句,根據不同的case切換不同的飛行模式。以常見的自穩模式stabilize爲例,可一直追蹤下去,如高度控制,電機控制等。醉翁之意不在酒,在乎“飛行模式”也。

        目前已瞭解飛行模式如何調用,那麼裁剪也就很自然了——註釋掉暫時不同的飛行模式。博主將APM所支持的飛行模式列舉如下,用的最多的當屬自穩STABILIZE和懸停LOITER,因此可將其他的一些飛行模式註釋掉。博主所用S500無人機的遙控器爲6通道,開關SWC撥到上爲自穩模式,撥到中爲懸停模式,因此博主在代碼中只保留了自穩STABILIZE、定高ALT_HOLD、懸停LOITER和降落LAND共4種模式。

        將飛行模式裁剪後,重新編譯代碼,驚喜出現了,程序容量從99%降到了89%。現在自信地下載代碼,成功!快給博主點個贊~

        溫馨提示:下載源碼不會改變APM中傳感器的參數,如加速度計、羅盤等,其參數在APM板的EEPROM中,通過地面站的一系列校準步驟寫入。有關地面站的使用,詳見新編APM-2.8.0中文入門手冊

 

APM飛控學習之路:5 串口概述與收發調試

2016年11月23日 20:11:23

閱讀數:9558

        “雲中誰寄錦書來,雁字回時,月滿西樓”。當無人機在空中飛翔時,從APM飛控到飛手之間有幾條看不見的“風箏線”——(1)2.4GHz的遙控;(2)433/915MHz的數傳;(3)5.8GHz的圖傳;(4)osd(on-screen display)。其中遙控是大家最爲熟知的,用於控制飛行和切換模式。數傳說白了是一個披着射頻的皮的無線串口,波特率57600,連接地面站可實時觀測飛行數據和在線調參。圖傳是FPV(First Person View)必備,傳輸視頻信號用於航拍。osd是錦上添花的部件,將飛行數據疊加到視頻信號上一起傳回地面接收機。

        遙控、圖傳和osd都是很成熟的產品,對於開源用戶來說定製性不強,而數傳可以傳回用戶感興趣的任何數據以及在線調參,實爲居家必備之良品。如果選購與APM適配的3DR數傳,無需任何修改,插上APM即可在地面站(Mission Planner)監測無人機的飛行數據。從功能上看,數傳與下載程序兼具串口功能的USB線別無二致,只是形態上有線無線而已。二者的技術基礎是串口以及基於串口的Mavlink通信,本文主要討論如何使用APM中的串口並進行二次開發。

 

APM2.8串口概述


        串口的英文名是UART,全稱Universal Asynchronous Receiver/Transmitter,即通用異步接收/發送機,只要一對傳輸線(RX-TX)即可實現雙向通信。串口通過USB轉TTL模塊可插在電腦的USB口,在設備管理器上體現爲COM口,是單片機調試和通信的重要接口。

        對於APM2.8飛控,其主控芯片爲Atmega2560,有4個串口,分別爲UART0~UART3,在APM中起作用的只是前3個,即UART0、UART1和UART2。UART0接USB,UART1接GPS,UART2接數傳。

        APM3.2.1源碼爲適應除APM之外的不同硬件(如PIXHAWK),在硬件抽象層HAL(Hardware Abstraction Layer)提供了通用的外設接口。在HAL.h中可以查看HAL類的聲明,串口方面保留了_uartA~_uartE共5個。


 
  1. class AP_HAL::HAL {

  2. public:

  3. HAL(AP_HAL::UARTDriver* _uartA, // console

  4. AP_HAL::UARTDriver* _uartB, // 1st GPS

  5. AP_HAL::UARTDriver* _uartC, // telem1

  6. AP_HAL::UARTDriver* _uartD, // telem2

  7. AP_HAL::UARTDriver* _uartE, // 2nd GPS

  8. AP_HAL::I2CDriver* _i2c,

  9. AP_HAL::SPIDeviceManager* _spi,

  10. AP_HAL::AnalogIn* _analogin,

  11. AP_HAL::Storage* _storage,

  12. AP_HAL::UARTDriver* _console,

  13. AP_HAL::GPIO* _gpio,

  14. AP_HAL::RCInput* _rcin,

  15. AP_HAL::RCOutput* _rcout,

  16. AP_HAL::Scheduler* _scheduler,

  17. AP_HAL::Util* _util)

  18. :

  19. uartA(_uartA),

  20. uartB(_uartB),

  21. uartC(_uartC),

  22. uartD(_uartD),

  23. uartE(_uartE),

  24. i2c(_i2c),

  25. spi(_spi),

  26. analogin(_analogin),

  27. storage(_storage),

  28. console(_console),

  29. gpio(_gpio),

  30. rcin(_rcin),

  31. rcout(_rcout),

  32. scheduler(_scheduler),

  33. util(_util)

  34. {}

  35.  
  36. virtual void init(int argc, char * const argv[]) const = 0;

  37.  
  38. AP_HAL::UARTDriver* uartA;

  39. AP_HAL::UARTDriver* uartB;

  40. AP_HAL::UARTDriver* uartC;

  41. AP_HAL::UARTDriver* uartD;

  42. AP_HAL::UARTDriver* uartE;

  43. AP_HAL::I2CDriver* i2c;

  44. AP_HAL::SPIDeviceManager* spi;

  45. AP_HAL::AnalogIn* analogin;

  46. AP_HAL::Storage* storage;

  47. AP_HAL::UARTDriver* console;

  48. AP_HAL::GPIO* gpio;

  49. AP_HAL::RCInput* rcin;

  50. AP_HAL::RCOutput* rcout;

  51. AP_HAL::Scheduler* scheduler;

  52. AP_HAL::Util* util;

  53. };

        落實到APM2.8飛控板上,從HAL_AVR_APM2_Class.cpp中可以查看串口的對應關係,同樣可以得出只用了前3個,且UART0接USB,UART1接GPS,UART2接數傳。源碼與飛控板,一個底層,一個上層,“默契”地達成了一致。

 


 
  1. HAL_AVR_APM2::HAL_AVR_APM2() :

  2. AP_HAL::HAL(

  3. &avrUart0Driver, /* phys UART0 -> uartA */

  4. &avrUart1Driver, /* phys UART1 -> uartB */

  5. &avrUart2Driver, /* phys UART2 -> uartC */

  6. NULL, /* no uartD */

  7. NULL, /* no uartE */

  8. &avrI2CDriver,

  9. &apm2SPIDriver,

  10. &avrAnalogIn,

  11. &avrEEPROMStorage,

  12. &avrUart0Driver,

  13. &avrGPIO,

  14. &apm2RCInput,

  15. &apm2RCOutput,

  16. &avrScheduler,

  17. &avrUtil )

  18. {}

 

        如果大家仔細觀察上面APM2.8的方框圖,可以發現數傳和USB接口都是走的UART0,這是爲何?因爲APM2.8採用了一種MUX複用的方式,使得當數傳與USB同時接上的時候,USB會把數傳屏蔽,即UART0占主導地位。在此祭出硬件原理圖,TS5A23157是一個模擬開關,3DR代表數傳。當USB和數傳同時接上時,模擬開關會將3DR_RX與RX0接上,3DR_TX與TX0接上,即串口0把數傳給屏蔽了。

 

串口源碼分析

 

        一個串口要發揮作用,首先需要初始化,即配置波特率、設置起始位等操作。對於STM32單片機(用於PIXHAWK),還有串口中斷等配置。APM中的Arduino單片機比較簡單,只需配置好波特率,其餘保持默認即可。

        Arduino程序的初始化,一般在setup()函數中。不出所料,串口的初始化也在其中,見ArduCopter.pde的setup()函數,可以看到初始化函數init_ardupilot()。


 
  1. void setup()

  2. {

  3. cliSerial = hal.console;

  4.  
  5. // Load the default values of variables listed in var_info[]s

  6. AP_Param::setup_sketch_defaults();

  7.  
  8. // setup storage layout for copter

  9. StorageManager::set_layout_copter();

  10.  
  11. init_ardupilot();

  12.  
  13. // initialise the main loop scheduler

  14. scheduler.init(&scheduler_tasks[0], sizeof(scheduler_tasks)/sizeof(scheduler_tasks[0]));

  15. }

        在Visual Studio+VMICRO的環境下,按F12或鼠標右鍵可轉到init_ardupilot()的定義,在system.pde的init_ardupilot()中摘出與uartA有關的代碼以便分析。


 
  1. hal.uartA->begin(map_baudrate(g.serial0_baud), 512, 128);,

  2.  
  3. //gcs[0].init(hal.uartA);

  4.  
  5. hal.uartA->set_blocking_writes(false);

        第1行和第3行很好理解,分別是uartA設置波特率(115200)和非阻塞模式,第2行的gcs[0]容易讓人迷惑。gcs的全稱爲Ground Control Station,即地面工作站。再轉到gcs的定義,可發現其數據類型爲GCS_MAVLINK,由此可斷定該行代碼的作用是綁定Mavlink和uartA,將數據以Mavlink協議與地面站通信。爲單獨測試串口收發,可取消uartA與Mavlink的綁定,即註釋掉gcs所在行的代碼。

 

串口數據收發


        初始化搞定之後,就可以進行簡單的串口收發測試——串口助手發數據給飛控,飛控返回原數據。串口的接收一般有2種方式:查詢或中斷。Arduino中的串口中斷函數爲SerialEvent,是一種軟中斷,博主將Arduino nano板中測試通過的串口中斷代碼移植到APM源碼中,發現並不起作用。原因尚不明確,或許 APM板本身並不支持,也可能是博主移植的地方不合適。期待有心人進行嘗試,歡迎留言討論。
        爲了推進測試進程,轉向查詢方式。有2種方式:1.在ArduCopter.pde的fast_loop中查詢;2.在UserCode.pde中添加代碼。如果要使用UserCode.pde,需在ArduCopter.pde添加相應的宏,才能將UserCode.pde加入編譯。爲了方便,博主在fast_loop()中添加串口接收查詢代碼:


 
  1. static void fast_loop()

  2. {

  3.  
  4. // IMU DCM Algorithm

  5. // --------------------

  6. read_AHRS();

  7.  
  8. // run low level rate controllers that only require IMU data

  9. attitude_control.rate_controller_run();

  10.  
  11. #if FRAME_CONFIG == HELI_FRAME

  12. update_heli_control_dynamics();

  13. #endif //HELI_FRAME

  14.  
  15. // write out the servo PWM values

  16. // ------------------------------

  17. set_servos_4();

  18.  
  19. // Inertial Nav

  20. // --------------------

  21. read_inertia();

  22.  
  23. // 串口接收查詢 by--嶽小飛

  24. while (hal.uartA->available())

  25. {

  26. uint8_t data = (uint8_t)hal.uartA->read();

  27. hal.uartA->write(data);

  28. }

  29.  
  30. // run the attitude controllers

  31. update_flight_mode();

  32.  
  33. // optical flow

  34. // --------------------

  35. #if OPTFLOW == ENABLED

  36. if(g.optflow_enabled) {

  37. update_optical_flow();

  38. }

  39. #endif // OPTFLOW == ENABLED

  40.  
  41. }

        打開串口,APM飛控會發出一串提示字符,包括版本信息,如“Init ArduCopter V3.2.1”。博主發送“YueXiaoFei”,飛控原樣返回,測試通過。基於這個簡單的收發測試,大家可自定義數據協議,發送和接收感興趣的飛行數據,也可學習基於串口的Mavlink協議。

        PS:無人機系列的第5篇至此結束,系列博客也隨之告一段落。就應用方面而言,從入門到編譯,從編譯到調試,博主儘可能地將問題講清楚,所有資料免積分下載,也算是爲開源貢獻自己的一份力吧。博客中可能存在一些小錯誤,也歡迎大家在評論區批評指正。力有不逮,敬請見諒~

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章