APM飛控學習之路:4 源碼裁剪與下載

        “月盈則虧,水滿則溢”。當博主編譯完成,以爲離成功更近一步準備下載的時候,殊不知陷阱也早已準備好,等待我的踏入。連上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()函數入手,可以看到其代碼不多,列出如下。

static void fast_loop()
{

    // IMU DCM Algorithm
    // --------------------
    read_AHRS();

    // run low level rate controllers that only require IMU data
    attitude_control.rate_controller_run();
    
#if FRAME_CONFIG == HELI_FRAME
    update_heli_control_dynamics();
#endif //HELI_FRAME

    // write out the servo PWM values
    // ------------------------------
    set_servos_4();

    // Inertial Nav
    // --------------------
    read_inertia();

    // run the attitude controllers
    update_flight_mode();

    // optical flow
    // --------------------
#if OPTFLOW == ENABLED
    if(g.optflow_enabled) {
        update_optical_flow();
    }
#endif  // OPTFLOW == ENABLED

}
        細心的朋友可能注意到了,顧名思義,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中文入門手冊
        PS:無人機系列的第4篇至此結束,編譯和下載終於告一段落,使用者至此可以愉快地二次開發了。說到開發就有調試,有關二次開發中利用串口調試的問題,且看下回分解。




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