# 簡介與環境設定
PX4為飛行控制軟體,提供機體自動穩定功能,並且原始碼為開源可以自行編輯。
本章節內容:
1. 安裝與設定開發環境
2. 編譯PX4並在模擬環境執行
3. 編譯自己的程式並執行
:::info
環境設定:
Ubuntu: 18.04
PX4 Firmware: v1.15.0
:::
# 1. 安裝與設定開發環境
將PX4開發環境安裝在Ubuntu環境。開發環境支援Ubuntu 18.04、Ubuntu 20.04、Ubuntu 22.04。本筆記以**Ubuntu 18.04配合ROS Medolic**為主。
## Step 1, 下載PX4原始碼:
從PX4官方環境抓原始碼。
```
$ git clone https://github.com/PX4/PX4-Autopilot.git --recursive
```
由於有很多submodule需要下載,注意要加入--recursive。
有加入--recursive的補救方式:
```
$ git submodule update --init --recursive –remote
```
## Step 2, 設定環境變數
執行PX4提供的bash script即可完成設定環境。
```bash=
sudo apt install python-pip libxml2-dev libxslt-dev python-dev python-setuptools
pip3 install lxml kconfiglib jinja2 pyserial empy==3.3.4 toml numpy pandas pyyaml pyros-genmsg packaging jsonschema future
bash ./PX4-Autopilot/Tools/setup/ubuntu.sh
```
(Ubuntu 18.04以外的OS)安裝過程出現E: Package 'python-dev' has no installaiton candidate 使用python3-dev
裝完之後看到Terminal顯示**Relogin or reboot computer before attempting to build NuttX targets**就完成環境設定。這時可以重開機。
過程中可能會遇到缺少tool或python版本不符合,提供下列Trouble shoot方式:
### Issue 1, python3版本
設定環境變數之前,由於sympy需要使用>=1.10.1的版本,先下載好python3.8,並把python alternative設定成python3.8
```
$ sudo apt install python3.8
$ sudo update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.8 1
```
手動升級python3會遇到apt update無法執行,重裝apt
```
$ sudo apt remove python3-apt
$ sudo apt autoclean
$ sudo apt install python3-apt
```
:::info
安裝失敗可以在remove python3-apt之後執行
```
$ sudo apt autoremove
```
但要注意這個動作可能會誤刪其他檔案
:::
### Issue 2, 安裝matplotlib
```
$ pip3 install pybind11 cmake numpy matplotlib
```
:::info
如果出現distro-info不符合規定的warning,使用下列語法更新
```
$ pip3 install --upgrade distro-info
```
:::
:::success
補充pip install和apt install差異
Both apt-get and pip are mature package managers which automatically install any other package dependency while installing. You may use anyone as you like. However, if you need to install a particular version of python-package, or install the package in a virtualenv, or install a package which is only hosted on PyPI; only pip would help you solve that issue. Otherwise, if you don't mind installing the packages in system-wide location it doesn't really matter whether you use apt-get or pip.
[Reference](https://askubuntu.com/questions/431780/apt-get-install-vs-pip-install)
:::
# 2. 編譯PX4並在模擬環境執行
目前只討論軟體模擬的執行方式。可以將gazebo替換成jmavsim,會開啟jmavsim作為模擬環境。
```
$ make px4_stil jmavsim
```
過程中如果有遇到python module沒有裝就使用pip或pip3裝即可。
執行過程中會編譯PX4並且開啟模擬器執行。可以使用console(左)對開起來的模擬環境(右)中的UAV下命令。

測試範例程式:
```
pxh> commander takeoff
pxh> commander land
```
可以看見無人機飛行跟降落。
# 3. 編譯自己的程式並執行
編譯方式分為靜態跟動態,靜態會將自己定義的module編譯成PX4裡面的一個module使用;動態則是可以讓編譯好的PX4連過去。目前使用靜態。
## 3.1 靜態
總共有下列幾個步驟:
1. 在PX4-Autopilot/src/examples建立module
2. module內容為
* souce code (.c)
* CMakeLists.txt
* Kconfig
3. 新增Kconfig key到PX4-Autopilot/boards/px4/sitl/default.px4board
Details as below:
### Step 1, 在PX4-Autopilot/src/examples新增自己的module
以hello_sky為例,在PX4-Autopilot/src/examples新增module,module name跟資料夾名稱相同。
```
$ cd ./PX4-Autopilot/src/examples
$ mkdir hello_sky
```
### Step 2, 撰寫c語言程式
撰寫c語言程式放在hello_sky,注意使用附檔名c。
```cpp=
#include <px4_platform_common/log.h>
__EXPORT int hello_sky_main(int argc, char *argv[]);
int hello_sky_main(int argc, char *argv[])
{
PX4_INFO("Hello Sky!");
return OK;
}
```
- px4_platform_common/log.h提供print out文字訊息(log)的function,腳色與<stdio.h> 與 printf()類似。提供的log分為不同level:PX4_INFO, PX4_WARN, PX4_ERR, PX4_DEBUG。在SITL中使用PX4_INFO會在sitl的console輸出。
- 一定要用這個固定的寫法命名main function並且要EXPORT
```
__EXPORT int <module_name>_main(...)
int <module_name>_main(...)
```
### Step 3, 撰寫cmake definition file CMakeLists.txt
```cmake=
px4_add_module(
MODULE examples__hello_sky
MAIN hello_sky
STACK_MAIN 2000
SRCS
hello_sky.c
DEPENDS
)
```
- px4_add_module()用來新增static library
- MODULE為這個module的unique name,常見的命名方式*路徑*__*module name*,路徑為src以下的路徑
- MAIN為module進入點,可以在SITL console以這個進入點/名稱呼叫這個module
- SRC為編譯module需要使用的source code
:::info
px4_add_module()定義在PX4-Autopilot/cmake/px4_add_module.cmake
:::
### Step 4, 撰寫Kconfig definition file Kconfig
有固定的寫法。
```Kconfig=
menuconfig EXAMPLES_HELLO_SKY
bool "hello_sky"
default n
---help---
Enable support for hello_sky
```
(tbd)
### 新增Kconfig key
新增Kconfig key到PX4-Autopilot/boards/px4/sitl/default.px4board
格式為
```
CONFIG_EXAMPLES_PX4_SIMPLE_APP=y
```
### Step 5, 編譯
```
$ make px4_stil jmavsim
```
編譯整個PX4,target為stil,模擬器為jmavsim。也可以使用Gazebo。
### Step 6, 執行
模擬器打開之後在pxh shell輸入hello_sky,可以看到執行程式在px4 shell顯示Hello Sky。
```
pxh> px4_simple_app
INFO [px4_simple_app] Hello Sky!
```
## 更多資料
根據[3]可以使用uORB/topics裡的library得到sensor資訊或送出資訊。
可以透過subscribe或是poblish topics來跟飛行器溝通。
更多資訊詳見[3]的example code。
# Trouble shoot
## PX4 正在執行導致build失敗
執行make px4_sitl_default jmavsim
出現INFO [px4] PX4 server already running for instance 0
ps找到px4還在執行中, kill -9 把PID砍掉即可
# More background knowledge needed
1. cmake基本與法
2. 上述軟體的執行PX4如何和模擬器傳訊息
# 參考資料
- [1][PX4-Autopilot (GitHub)](https://github.com/PX4/PX4-Autopilot)
- [2][PX4 User Guide(main)](https://docs.px4.io/main/en/)
- 建議從章節Development開始看
- [3][PX4 User Guide(main) / Development / Write your First Application](https://docs.px4.io/main/en/modules/hello_sky.html)