2023年12月9日發(作者:涉縣核桃)

Pixhawk系統架構介紹
前段時間導師叫我做撲翼無人機,工程上需要實現的,能夠通過程控飛起來,感覺難度挺大。先從研究PX4開始,打算一步步理解透整
個PX4的框架,機型的適配、旋翼、固定翼的姿態控制,新機型的添加等等。不知道能不能做成,這里先立個flag吧。
這篇文檔是我課程作業的一個報告,包含4個方面,硬件架構分析,Linux開發環境搭建,軟件架構分析,源代碼分析等。由于源代碼比
較龐雜,這里簡要分析下飛機的返航控制(RTL),旋翼的混控器,以及uORB的使用三個方面。
Pixhawk是一個獨立的項目,旨在以低成本和高可用性為學術界,業余愛好界和工業界提供高端行業標準自動駕駛儀硬件。由于其強大且豐
富的硬件而廣受無人機愛好者的好評。Pixhawk支持APM和PX4的固件,這里我們對原生的PX4固件做軟件架構分析。對于Pixhawk的系
統架構分析我將從四方面來展開,分別是:硬件架構介紹、PX4開發環境搭建、PX4軟件架構分析及總結。這里我們主要對軟件架構展開分
析,根據架構的層次性對PX4中的導航模塊、Mixer模塊和uORB模塊做分析和介紹。
關鍵詞:Pixhawk、PX4、硬件架構、軟件架構、uORB
1硬件架構分析
Pixhawk是一款基于ARM芯片的32位開源飛控,由ETH的computer vision and geometry group的博士生Lorenz Meier開發。最初
采用的是分體式的設計即px4(由px4fmu和px4io兩個組件組成),后合并成一個整體形成現在的pixhawk。其硬件和軟件都開源,因此
衍生出很多不同的軟硬件版本,最初的分銷商是美國的3D Robotics。PIXHAWK是一款高性能自動駕駛儀,適用于固定翼,多旋翼,直升
機,汽車,船只以及任何可移動的其他機器人平臺。它針對高端研究,業余和行業需求,并結合了PX4FMU + PX4IO的功能。Pixhawk的
外形如圖1所示:
圖1 Pixhawk外形及接口
Pixhawk的硬件架構整體框圖如圖2所示:
圖2 硬件框架 由圖中的內容可以看出硬件的大致框架,STM32F427芯片作為主控器承擔著全部傳感器的數據讀寫,姿態的結算及控制,以及其他信
息的處理和控制。電源系統不僅為電機電調提供電源,同時還承擔著主控制器器和所有模塊的電源供應。對于其它外圍系統以及和主控器的
通信方式分別如下所示:動力系統由主控器的四路PWM控制,調試系統通過microUSB接口和主控器交互,文件系統通過SDIO協議和主控
制器交互,數傳系統通過433M模塊和主控器交互,遙控系統通過SPI協議和主控制器交互,導航系統通過RTMC協議和主控器交互,定高
及姿態控制系統都是通過I2C協議和主控器交互。這里比較故障協處理器比較有趣,當飛機的主控制器跑飛或者發生其他錯誤導致無法對電
機進行控制時,可以由協控制器感知到,進而獲得電機的控制權,將電機控制在安全的模式下,直到檢測到主控器對電機的控制恢復正常。
協控制器不定時的讀取主控器的DMA計數寄存器,當這次計數寄存器的值和上去讀取到的值一致時說明主控器沒有對電機的PWM進行更
新,主控制器失去了對電機的控制,這時協控制器得知主控制器異常,開始接管對電機的控制,直到DMA計數器更新,主控制器恢復對電
機的控制。
2 PX4開發環境搭建
PX4代碼可以在 Mac OS,Linux 或者 Windows上進行開發,建議在Mac OS和Linux上進行開發,因為圖像處理和高級導航在
windows上不容易開發。如果不確定,新的開發者應默認用Linux和當前Ubuntu長期支持版本(Ubuntu LTS edition)。如果對Docker
熟悉,你可以使用其中一個容器來安裝開發環境。
我們使用Debian /Ubuntu LTS 作為Linux的標準支持版本,在這里我的Linux版本為Ubuntu 16.04。
2.1 權限設置
為了便于開發,我們需要把用戶添加到用戶組”dialout”中,執行:
sudo urmod -a -G dialout $USER
然后注銷后,重新登錄,因為重新登錄后所做的改變才會有效。注意:永遠不要使用sudo來修復權限問題,否則會帶來更多的權限問
題,需要重裝系統來解決。
2.2 安裝PX4的依賴包
更新包列表,安裝下面編譯PX4的依賴包。先安裝cmake,執行:
sudo add-apt-repository ppa:george-edison55/cmake-3.x -y
sudo apt-get update
安裝必備的軟件,比如python、git、qtcreator等等:
# 必備軟件
sudo apt-get install python-argpar git-core wget zip
python-empy qtcreatorcmake build-esntial genromfs -y
安裝一些仿真工具:
# 仿真工具
sudo add-apt-repository ppa:openjdk-r/ppa
sudo apt-get update
sudo apt-get install openjdk-8-jre
sudo apt-get install ant protobuf-compiler libeigen3-devlibopencv-dev openjdk-8-jdk openjdk-8-jre clang-3.5 lldb-3.5 -y
2.3 安裝交叉編譯工具鏈
Ubuntu配備了一系列代理管理,這會嚴重干擾任何機器人相關的串口(或usb串口),卸載掉它也不會有什么影響,我們這里把它卸載:
sudo apt-get remove modemmanager
更新包列表和安裝下面的依賴包:
sudo apt-get install python-rial openocd flex bison libncurs5-devautoconf texinfo build-esntial
libftdi-dev libtoolzlib1g-dev
python-empy -y
安裝arm-none-eabi編譯工具鏈,在添加arm-none-eabi工具鏈之前,請確保刪除殘余:
sudo apt-get remove gcc-arm-none-eabi gdb-arm-none-eabibinutils-arm-none-eabi gcc-arm-embedded
sudo add-apt-repository --remove ppa:team-gcc-arm-embedded/ppa
如果需要在樹莓派上開發則需要安裝樹莓派上對于的工具鏈。樹莓派開發者應該從下面地址下載樹莓派Linux工具鏈。安裝腳本會自動安裝
交叉編譯工具鏈:
cd rpi_toolchain
./install_
在工具鏈安裝過程中需要輸入密碼。如果不想把工具鏈安裝在默認位置/opt/rpi_toolchain,可以執行./install_
本傳入其它地址。安裝腳本會自動配置需要的環境變量。最后,運行以下命令更新環境變量:
source ~/.profile
2.4 代碼編譯
開發環境搭建好之后,就可以開始下載代碼并編譯了,PX4可以在控制臺或者圖形界面/IDE開發。在這里我們對控制臺的開發進行簡要
介紹。
先建立工作目錄,然后從git上下載代碼:
mkdir -p ~/src
cd ~/src
cd Firmware
git submodule update --init --recursive
cd ..
現在可以通過編譯源代碼來構建二進制文件。在直接使用硬件前,推薦先進行仿真。然后就可以對代碼進行編譯并下載了:
cd Firmware
make px4fmu-v2_default
注意到“make”是一個字符命令編譯工具,“px4fmu-v2”是硬件/ardupilot版本,“default”是默認配置,所有的PX4編譯目標遵
循這個規則。通過在命令后面添加‘upload’,編譯的二進制程序就會通過USB上傳到飛控硬件。下載成功后的情況如下所示:
當然這樣編譯后的代碼是無法直接讓飛行器飛起來的,如果希望下載能夠讓自己飛機飛起來的代碼建議下載QGroundControl地面站軟
件,按照軟件的提示來選擇自己的機型,校正傳感器,鏈接遙控器,調試參數等操作。
3 PX4軟件架構分析
PX4的軟件架構將會從4方面來展開陳述,分別是:軟件框架的劃分,代碼文件結構,飛行控制流程以及源代碼分析。其中源代碼分析將
挑選具有代表性的返航控制模塊,混控器以及uORB中間件來分析,這三部分分別隸屬于軟件框架層次中的應用程序框架,庫和操作系統。
3.1軟件框架的劃分
圖3 軟件框架
根據PX4軟件的運作,同時為了便于我們更好的理解,它可以劃分成四個層次:
1) 應用程序的API:這個接口提供給開發人員,比如使用ROS(實時操作系統)或DroneAPI(DroneAPI是一個用于控制無人機的Python
庫,可以單獨的運行在機載電腦或者其他設備上,通過串口或者無線的方式與飛控板通信),這一層旨在盡可能的精簡、扁平及隱藏其復雜
性。
2) 應用程序框架: 這是為操作基礎飛行控制的默認程序集(節點)。比如旋翼的控制、直升機的控制、固定翼的控制等,還有位置估計、
命令控制、導航控制等。
3) 庫: 這一層包含了所有的系統庫和基本交通控制的函數。比如數學庫、控制庫、MAV庫等等。
4) 操作系統: 最后一層提供操作系統支持,比如任務的調度,硬件驅動程序,網絡,UAVCAN和故障安全系統等功能。
3.2 文件結構
分析完了整體的框架,對源代碼文件結構的分析也同樣重要,源代碼的目錄結構如圖4所示。在firmware文件夾下有很多文件夾,我們
按照圖片中的順序來講解每個文件夾中代碼的功能。其中cmake是編譯工具;build_px4fmu-v2_default是在編譯后產生中間靜態文件和
最終生成的下載文件;src包含飛行控制的主要代碼;nuttx-config是nuttx的配置文件;tools文件夾下包含一些工具,比如下載工具;
Nuttx里面則是Nuttx操作系統的源代碼;ROMFS里面包含的是飛控板的啟動代碼。
下面介紹非常重要的src文件夾里面包含的內容。systemcmds:主要放置了系統工具,能夠通過啟動文件啟動或在nsh中去調用的工具。
其中包括控制I2C,查看修改參數,查看軟件版本,校準電調、查看系統性能、bootloader升級等工具;drivers里面包含的主要是和硬件相
關的驅動代碼,比如stm32文件夾下面包括adc的基類、高精度定時器、伺服控制的驅動程序,device文件夾下面包含外設的基類定義,比
如I2C和SPI等,boards目錄下定義了這個型號的板子的接口配置以及相應配置接口(LED、PWM、USB、定時器等的配置);examples
下面包含一些簡單的實例程序,如果有一些實驗性的代碼可以放到這下面;include目錄和lib目錄包含其他代碼需要用到的頭文件和庫;
platforms下面定義了px4平臺的系統接口方便和nuttx操作系統分離,這樣方便移植到其他平臺;modules下面分了很多文件夾,這些文
件夾各自是不同的模塊,這就是最上層的功能模塊包括commder、navigator、mc_att_control、mc_pos_control等。
圖4 文件結構
3.3 飛行控制流程
飛行控制的流程如圖5所示。圖中的左邊是飛控系統的控制功能實現,我們從上往下,從左往右依次分析。
1) 用戶通過地面站或者遙控器發出模式切換以及搖桿操作對飛行器進行控制,commander根據飛行器的當前狀態對用戶想要切換到的狀
態main_state進行判斷:是否能夠切換到目標狀態,確定最終狀態。stickmapper見名知意,搖桿映射,參見px4io.c、文
件。
2) navigator決定飛行器最終會怎么做飛行模式nav_state的轉換,以及對應模式下飛機的飛行控制。3) 位置控制提取local postion(光流+IMU)或global postion(GPS)數據根據導航狀態進行串級PID控制。外環輸入位置差輸出速度,內
環輸出推力。
4) 姿態控制采用傾轉分離的解耦合控制方式,先對齊Z軸再對齊偏航角。同樣采用串級PID的控制方式,外環輸入姿態角誤差,輸出姿態
角速率,內環最后輸出所需的力矩。
5) mixer混控器根據機型進行力矩分配。根據葉素理論,螺旋槳旋轉產生的s升力/扭矩與轉速的平方以及拉力系數/扭矩系數相關。構造
力矩分配矩陣。
6) motor_driver驅動電機,控制飛行器飛行。
左邊是位置估計算法的實現,GPS確定global postion,optical flow確定local postion,二者有其一才能進入到POSCTL模式。姿態估計
是一切的基礎,通過融合慣性傳感器(和光流)各自優點解算出飛行器的當前姿態信息。
圖5飛行控制流程
3.4 源代碼分析
在這里我們將結合源代碼分析3個模塊的功能及實現,分別是RLT(Return to launch返航控制)模塊,mixer(混控器模
塊),uORB(Micro Object Request Broker,微對象請求代理器)消息中間件。
3.4.1 RTL
RTL(return to launch,返航模式)是應用程序框架Navigator中的一部分。它的功能顧名思義就是提供返航功能,返回并降落到“家”的
位置。當飛行模式切換到返航模式時,飛行器會先爬升到返航設定的最低的高度,然后再家的上方懸停幾秒(可設定),最后降落到“家”的
位置,即飛行器起飛的位置或者說是飛行器解鎖時的位置。在RTL控制中,把返航飛行劃分成了7個部分,如圖6所示。
圖6 返航飛行的劃分
飛行模式相對應的控制函數存儲在的數組里面,如圖7所示,比如RTL模式的控制函數存放在第3個位置,在導航函數中對定期的檢查當
前的模式,然后運行當前模式的代碼,如圖8所示。當第一次運行_rtl函數時需要先調用on_activation()函數,非第一次運行_rtl函數則運行
on_active函數,因為在第一次運行時需要對飛機進安全性檢查,具體可以看圖9的on_activation()函數,將依次進行如下判斷:
1) 如果當前已經著陸,不執行。
2) 如果當前正在執行降落命令,則直接切換到RTL_STATE_RETURN。
3) 如果高度小于最小返航高度,則爬升到設定高度,如果大于最小高度,則以當前高度返航。
4) 其他情況直接切換到RTL_STATE_RETURN。
5) 最后執行t_rtl_item函數,為不同狀態執行不同的控制。
圖7 _navigation_mode_array
圖8 導航模式的輪詢
圖9 on_activation()函數
3.4.2 mixer
混控器)是根據機型進行力矩分配的庫,有了混控器使得PX4架構保證了核心控制器中不需要針對機身布局做特別處理?;炜刂傅氖前演斎?/p>
指令(例如:遙控器打右轉)分配到電機以及舵機的執行器(如電調或舵機PWM)指令。對于固定翼的副翼控制而言,每個副翼由一個舵
機控制,那么混控的意義就是控制其中一個副翼抬起而另一個副翼落下。同樣的,對多旋翼而言,俯仰操作需要改變所有電機的轉速。將混
控邏輯從實際姿態控制器中分離出來可以大大提高復用性。Mixer簡要的控制流程是這樣的,一個特定的控制器(如姿態控制器)發送特定
的歸一化(-1..+1)的命令到給混合(mixing),然后混合后輸出獨立的PWM到執行器(電調,舵機等).在經過輸出驅動如(串
口,UAVCAN,PWM)等將歸一化的值再轉回特性的值(如輸出1300的PWM等)。在混控器中每個機架都會有自己對于的混控文件,
比如旋翼對于的混控文件是mixer_。
這里拿四旋翼的X模式來舉例說明一下,機架的軸向及力矩分配矩陣如圖10所示:
圖10 機架軸向及力矩分配矩陣
力矩分配矩陣中,每一行代表一個電機,并且和它們的編號順序相同,第1列到第三列分別代表的是Roll、Pitch和Yaw軸的輸入。比如
當前需要加大Roll軸的角度,其他軸的的角度保持不變,那么2,3號的電機轉速應該增加,1,4號電機的轉速應該較小,對比在力矩分配矩陣
上你可以看到,第2,3行的第一列是正值,表示轉速和Roll的期望角度正相關,第1,4行是負值,代表和Roll的角度負相關。
在混控器文件中,首先會得到某個通道在對應軸向的力矩輸入,比如說來自飛機姿態控制器的輸入,或者是控制器的輸入等,范圍會控制
在-1~1之間,得到輸入后,混控器會把輸入力矩的大小混合映射到每個電機上,同樣每個電機得到幅度為0~1范圍內的輸出(0代表停轉,1
代表滿轉),最后把這個輸出值計算出PWM的占空比,然后通過電調來調節電機的轉速?;炜仄鞯目刂屏鞒谭譃橄旅鎺撞剑?/p>
1) 讀取控制通道的輸入。2) 先對Roll、Pitch的輸入通道進行計算,得到輸出值,因為姿態調節中首先考慮的是Roll和Pitch是否穩定,相對于Yaw則沒有那么重
要,然后根據計算得到的最大最小值判斷是否飽和。飽和的意思就是說每個電機的的輸出是否超過了0~1的范圍,如果超過和0~1的范圍但
是最大最小值之間沒有超過1,則可以通過平移來解決,如果幅度超過了1,則需要通過縮放解決。
3) 確定Roll和Pitch軸可以滿足輸出要求后,這時加入Yaw,再次計算是否飽和,如果飽和適當調節油門來響應Yaw。
4) 最后得到每個電機的輸出,判斷改變幅度是否過大,做一個限幅。
源代碼分別如圖11,12,13,14所示:
圖11 得到通道0的輸入
圖12 對Roll和Pitch軸進行疊加計算
圖13 記錄下電機相差的的最大幅度
圖14 對電機的輸出進行評議或縮放操作
3.4.3 uORB分析
uORB(Micro Object Request Broker,微對象請求代理器)是PX4/Pixhawk系統中非常重要且關鍵的一個模塊,它肩負了整個系統的數
據傳輸任務,所有的傳感器數據、GPS、PPM信號等都要從芯片獲取后通過uORB進行傳輸到各個模塊進行計算處理。實際上uORB是一套
跨「進程」 的IPC通訊模塊。在Pixhawk中,所有的功能被獨立以進程模塊為單位進行實現并工作。而進程間的數據交互就由為重要,必須
要能夠符合實時、有序的特點。
Pixhawk使用的是NuttX實時ARM系統,uORB實際上是多個進程打開同一個設備文件,進程間通過此文件節點進行數據交互和共享。
進程通過命名的總線交換的消息稱之為主題(topic),在Pixhawk 中,一個主題僅包含一種消息類型,通俗點就是數據類型。每個進程可以
訂閱或者發布主題,可以存在多個發布者,或者一個進程可以訂閱多個主題,但是一條總線上始終只有一條消息,如圖15所示。
圖15 uORB訂閱發布示意圖
在uORB中訂閱或者發布主題的流程如圖16所示,首先使用orb_subscribe訂閱某個主題,訂閱后獲得一個句柄,對句柄初始化化,比
如說初始化為檢測POLLIN事件,之后使用poll函數來監視文件描述符,如果對應的實際發生,使用orb_copy來獲得對應的消息。
圖16 uORB訂閱/發布數據流程
接下來對一些常用的uORB函數進行介紹。
1) int orb_subscribe(const structorb_metadata *meta)
功能:訂閱主題(topic);
說明:即使訂閱的主題沒有被公告,但是也能訂閱成功;但是在這種情況下,卻得不到數據,直到主題被公告;
參數:
meta:uORB元對象,可以認為是主題id,一般是通過ORB_ID(主題名)來賦值;
返回值:
錯誤則返回ERROR;成功則返回一個可以讀取數據、更新話題的句柄;如果待訂閱的主題沒有定義或聲明則會返回-1,然后會將errno賦值為ENOENT;
eg:
int fd =orb_subscribe(ORB_ID(topicName));
2) int poll(struct pollfd fds[],nfds_t nfds, int timeout)
功能:監控文件描述符(多個);
說明:timemout=0,poll()函數立即返回而不阻塞;timeout=INFTIM(-1),poll()會一直阻塞下去,直到檢測到return > 0;
參數:
fds:struct pollfd結構類型的數組;
nfds:用于標記數組fds中的結構體元素的總數量;
timeout:是poll函數調用阻塞的時間,單位:毫秒;
返回值:
>0:數組fds中準備好讀、寫或出錯狀態的那些socket描述符的總數量;
==0:poll()函數會阻塞timeout所指定的毫秒時間長度之后返回;
-1:poll函數調用失敗;同時會自動設置全局變量errno;
3) intorb_copy(const struct orb_metadata *meta, int handle, void *buffer)
功能:從訂閱的主題中獲取數據并將數據保存到buffer中;
參數:
meta:uORB元對象,可以認為是主題id,一般是通過ORB_ID(主題名)來賦值;
handle:訂閱主題返回的句柄;
buffer:從主題中獲取的數據;
返回值:
返回OK表示獲取數據成功,錯誤返回ERROR;否則則有根據的去設置errno;
eg:
struct nsor_combined_s raw;
orb_copy(ORB_ID(nsor_combined),nsor_sub_fd, &raw);
4)orb_advert_t orb_adverti(const struct orb_metadata *meta, const void *data)
功能:公告發布者的主題;
說明:在發布主題之前是必須的;否則訂閱者雖然能訂閱,但是得不到數據;
參數:
meta:uORB元對象,可以認為是主題id,一般是通過ORB_ID(主題名)來賦值;
data:指向一個已被初始化,發布者要發布的數據存儲變量的指針;
返回值:錯誤則返回ERROR;成功則返回一個可以發布主題的句柄;如果待發布的主題沒有定義或聲明則會返回-1,然后會將errno賦值為ENOENT;
eg:
struct vehicle_attitude_s att;
memt(&att, 0, sizeof(att));
intatt_pub_fd = orb_adverti(ORB_ID(vehicle_attitude), &att);
5) int orb_publish(const structorb_metadata *meta, orb_advert_t handle, const void *data)
功能:發布新數據到主題;
參數:
meta:uORB元對象,可以認為是主題id,一般是通過ORB_ID(主題名)來賦值;
handle:orb_adverti函數返回的句柄;
data:指向待發布數據的指針;
返回值:OK表示成功;錯誤返回ERROR;否則則有根據的去設置errno;
eg:
orb_publish(ORB_ID(vehicle_attitude),att_pub_fd, &att);
4 總結
Pixhawk硬件的功能已經能夠滿足絕大部分飛行器的硬件需求了,同時由于硬件開源的特點,相信以后的硬件功能也會越來越強大。PX4軟
件代碼建立在Nuttx操作系統上,穩定性可以得到很大的保障,其使用的uORB消息中間件技術也大大的簡化了開發,同時PX4模塊化的編
程思想也為開發人員的閱讀和二次開發提供了很大的便利。
本文發布于:2023-12-09 21:34:11,感謝您對本站的認可!
本文鏈接:http://www.newhan.cn/zhishi/a/1702128852241139.html
版權聲明:本站內容均來自互聯網,僅供演示用,請勿用于商業和其他非法用途。如果侵犯了您的權益請與我們聯系,我們將在24小時內刪除。
本文word下載地址:Pixhawk系統架構介紹.doc
本文 PDF 下載地址:Pixhawk系統架構介紹.pdf
| 留言與評論(共有 0 條評論) |