ArduPilotのSITLを動かす

ドローンエンジニア会議in加賀で更新作業をするようになってきた。。(--;;

（2024年07月27日）ドローンエンジニア会議in加賀で更新しました。

（2023年07月29日）ドローンエンジニア会議in加賀で講義を聞きながら修正しました。

（2020年7月9日）ラズパイ４でArduPilot SITLを動かす方法の記事を書きました～

[ArduPilot SITLをラズパイ4で動かそう](https://qiita.com/hsgucci/items/2b65b205b0834089a54e)

# はじめに
Ardupilot系のフライトコントローラをPythonで動かす場合，**dronekit**を使うのが簡単です．
また，dronekitをテストするシミュレーション環境として**dronekit-sitl**が準備されています．
しかし，このdronekit-sitl，

- CopterやRoverのファームウェアバージョンがちょっと古い
- Planeはなんでか飛ばない
- **更新されなくなって、そもそも動かなくなった！**  <font color=red>**(New!)**</font> 

<!-- - ログが`/tmp`に溜まっていって，複数台を数日飛ばすとHDDがスグ一杯になる．-->

など，あまり良い面がありません．
**まあ，あくまでdronekitの「お試し用」ですから．**

そこで，<font color="blue"> **Ardupilot本来のシミュレーション環境である「SITL Simulator」を試したい** </font>と思います．

本ページでは,このArduPilot純正シミュレータをdronekit-sitlと区別して，
「Ardupilot-SITL」と呼んで記事を書いていこうと思います．

(2024年7月27日追記)
Windows用のArdupilotの設定ソフトである **「MissionPlanner」** にもシミュレーション機能があります。
これはArdupilot-SITLと同じものなので、最初に使い方を覚えるには最適です。
その後、レベルアップしたらUbuntu上でArdupilot-SITLをインストールして色々試すと良いでしょう。

# 概要
公式ページ　[SITL Simulator (Software in the Loop)](http://ardupilot.org/dev/docs/sitl-simulator-software-in-the-loop.html)
にインストールの方法が記載されています．

本ページでは，公式ページを日本語訳しつつ，
個人的に便利な使い方を紹介していきます．

# 準備するもの

・Ubuntu Linuxの動くインテル系ＰＣ
　　古いＰＣやラップトップをLinuxパソコンとして復活させると良いでしょう．
　　dronekit-sitlの方は「x86系のみ，ARM系非サポート」と明記されていました．
　　上位互換であるArdupilot-SITLも同じ条件になります．
　　~~今回は一応インテル系ＰＣを使っておきましたが，Raspberry Piでも起動できるのでしょうか？~~
　　※Raspberry Piで試しました．~~依存関係でエラーになりました．~~ 動きました．
　　　　 [ArduPilot SITLをラズパイ4で動かそう](https://qiita.com/hsgucci/items/2b65b205b0834089a54e)


　動作確認済みＯＳ：
  Ubuntu-MATE 18.04(64bit), Ubuntu-MATE 20.04(64bit), Ubuntu-MATE22.04(64bit)

# SITL Simulatorのインストール

[Setting up SITL on Linux](http://ardupilot.org/dev/docs/setting-up-sitl-on-linux.html)　にも書かれていますが，
実は **Ardupilot sitlのビルド環境は，APM/Pixhawkに書き込むファームウェアのビルド環境の一部** です．

つまり，Ardupilot-SITLを動かそうとすると，実機のファームウェアも作れちゃうという一粒で二度美味しい環境が出来上がります．

## aptの更新
まずはaptのリポジトリのリストを最新のものに更新(update)し，
更新のあるものをupgradeします．

```bash:システムの更新
sudo apt update
sudo apt upgrade
```

## gitのインストール
gitがインストールされていなかったら，インストールします．

```bash:gitのインストール
sudo apt install git
```
## ArduPilotのクローン
ホームフォルダにArdupilot本体をクローンします．
また，必要なサブモジュールもダウンロードしておきます．

```bash:Ardupilotのクローン
cd ~
git clone https://github.com/ArduPilot/ardupilot
cd ardupilot
git submodule update --init --recursive
```


## 必要なパッケージのインストール
gitでcloneしたフォルダの中に，ビルドに必要な依存パッケージをインストールしてくれるシェルファイルがあるので，実行します．
(`sudo`を使うので，途中でパスワードを聞かれることがあります．)

```bash:依存関係のインストールシェルを実行
~/ardupilot/Tools/environment_install/install-prereqs-ubuntu.sh -y
```

このシェルファイルが，ビルドに必要な環境設定を`.profile`に書き込んでくれるので，
以下のように入力して，再読込しておきましょう．

```bash:設定ファイルの再読込
source ~/.profile
```

再起動時後は，`.profile`は自動的に読み込まれます．
従って，上記のコマンドを再度打つ必要はありません．
参考：[[Linux]環境変数の読み込み順番](https://qiita.com/yunzeroin/items/480a3a677f78a57ac52f)

`source`コマンドで環境を再設定するのは，`.bashrc`を書き換えたときと同じですね．

以上で，SITL Simulatorの開発環境がインストールできました．
(SITLだけじゃなくて全部だけど)

# SITL Simulatorのビルド＆簡易実行

Ardupilot-SITLのビルドと簡易的な実行は，`sim_vehicle.py`というコマンドでできます．
`sim_vehicle.py`は，ArdupilotのPythonベースのビルドコマンド`waf`のラッパーで，
`waf`でのビルドと，シミュレータの起動を一度に行ってくれます．

`sim_vehicle.py`の使い方は非常に簡単で，
**<font color="blue">自分のビルドしたいドローンタイプのフォルダに入って，コマンドを打ちます．</font>**

従って，最も簡易的な`-w`オプションでの起動で示すと，以下のようになります．
なお，シミュレータを終了する際は，Ctrl+c　です．

## ArduCopterの場合
コプターのSITLを実行したいとき

```bash:ArduCopterのSITL
cd ~/ardupilot/ArduCopter
sim_vehicle.py -w
```

## ArduRoverの場合
ローバーのSITLを実行したいとき

```bash:ArduRoverのSITL
cd ~/ardupilot/APMrover2
sim_vehicle.py -w
```

## ArduPlaneの場合
固定翼機のSITLを実行したいとき

```bash:ArduPlaneのSITL
cd ~/ardupilot/ArduPlane
sim_vehicle.py -w
```

# (補足)ドローンのフォルダに入らずに起動したい場合

いちいち`ArduCopter`や`ArduPlane`のフォルダに入るのが面倒だという方は、直接起動することもできます。

```
sim_vehicle.py -v copter -w
```
細かい解説は　[こちら](https://qiita.com/hsgucci/items/9037835f9c25ce04c38d#vehicle%E3%82%AA%E3%83%97%E3%82%B7%E3%83%A7%E3%83%B3)　でしています。


## sim_vehicle.pyのオプション

```bash:最も単純な-wでの実行
sim_vehicle.py -w
```
でビルド＆実行した場合，SITLが起動するだけでなく，

SITLのメッセージウィンドウが立ち上がります．
![message2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/689af449-2679-df65-c7a3-6ff1714c6d07.png)

また，`mavproxy.py`も勝手に立ち上がってSITLに接続してくれます．
キー入力待ちになっているので，対話的にドローンを動かせます．

---
以降は，引数につけるオプションの解説です．
オプションはたくさんありますが，**よく使う代表的な物だけ** 紹介します．
オプションは，
```bash
sim_vehicle.py --help
```
で出せます。

## シミュレーション関連のオプション

### wipe-eepromオプション
`--wipe-eeprom`は省略形で`-w`とも書けます．
EEPROMを消去し，デフォルトパラメータでSITLを起動します．
初期状態という事です．

### instanceオプション

`--instance=インスタンス番号`を指定すると，SITLの起動時のポート番号が変わります．

デフォルト(インスタンス番号=0)は5760,5762,5763ポートなのに対して，
番号=1だと5770,5772,5773，
番号=2だと5780,5782,5783，

のように10ずつ増えていきます．

1つのインスタンスに対して、3つのポートが有るのは、
1つのフライトコントローラにTelem1, Telem2, Telem3/4などがあるのと同じです。
もし、1つしかなかった場合、mavproxyがそれを専有してしまうと、Pythonなどの他のプログラムが接続する口がなくなってしまいます。
(もちろんmavproxyを使えば１つのポートを更に複数に分岐することもできるけど)

このインスタンス番号を使うことで，SITLの複数起動が可能になります．
Swarm(集団行動や群知能)の研究にはこのオプションを使います．

### locationオプション

`--location=地名`では，
　ardupilot/Tools/autotest/locations.txt
に予め記載されている地点をホームにして離陸できます．

例えば`Kawachi`を指定すると，茨城県稲敷郡河内町の「ドローンフィールド KAWACHI」で起動します．

```bash:ドローンフィールドKAWACHI
sim_vehicle.py --location=Kawachi --map
```
`Karuizawa`だとJapanDronesの会社の緯度・経度．
`KazakoshiPark`は軽井沢風越公園グラウンド.ドローンエンジニア養成塾かな？

日本の事前登録地点はそのくらいです．

### custom-locationオプション

`--location=`だと事前登録した地点のみです．
任意地点をホームにする場合は，`--custom-location=緯度,経度,高度,方位`で指定します．

```bash:例：柏の葉キャンパス駅前を指定・地図表示あり
sim_vehicle.py --custom-location=35.894087,139.952447,17,353 --map
```
![custom-location_map.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/dc7dd719-9ece-d8a1-cf98-ab47d322575f.png)

### no-mavproxyオプション

普段はSITLの起動と同時にmavproxyも自動で起動しますが，
`--no-mavproxy`を指定すると，mavproxyをOFFにできます．

dronekitやpymavlinkで接続したいときなどは，このオプションを使うと良いでしょう．
あるいは，5760番をmavproxyが使うので，5762や5763にdronekitで接続するのもアリです．



## ビルド関連オプション

### no-rebuildオプション

最初に`sim_vehicle.py`を実行するときには、プログラム全体をビルドしてくれますが，
シミュレーションする度に毎回ビルド作業をされると少しイラッときます．

`--no-rebuild`を指定すると，リビルドせずに，ビルド済みのバイナリで実行してくれます．
なのですぐにシミュレータが立ち上がります．


## MAVProxy関連オプション

### consoleオプション
`--console`を指定すると，機体の姿勢やステータスを表示する別ウィンドウが立ち上がります．
![console.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/c1e3401f-5acb-9df2-96cf-48f33d680de2.png)

### mapオプション
`--map`を指定すると，機体の位置を地図上で見ることのできるウィンドウが立ち上がります．
![map.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/c1d6b8f9-608c-0d0c-84cc-56a4d255663d.png)

## 機体関連オプション

### vehicleオプション

`--vehicle=ドローンタイプ`を指定すれば，ArduCopterやArduPlaneのフォルダへ移動する必要がなくなります．
ドローンタイプには，`ArduCopter`，`AntennaTracker`，`APMrover2`，`ArduSub`，`ArduPlane`が指定できます．
単純に`copter`, `rover`, `plane`などのように書いても大丈夫です。

### frameオプション

`--frame=フレームタイプ`を指定すると，具体的なドローンの形状を指定できます．

筆者は全て試していませんが，以下のようなタイプがあるそうです．

ArduCopterのとき
　　`+` `Callisto` `IrisRos` `X` `airsim-copter`
　　`bfx` `calibration` `coaxcopter` `cwx` `deca`
　　`deca-cwx` `djix` `dodeca-hexa` `freestyle`
　　`gazebo-iris` `heli` `heli-blade360` `heli-dual`
　　`heli-gas` `hexa` `hexa-cwx` `octa-dji`
　　`octa-quad` `octa-quad-cwx` `quad` `quad-can`
　　`scrimmage-copter` `singlecopter` `tri` `y6`

Helicopterのとき
　　`heli` `heli-blade360` `heli-dual` `heli-gas`

Blimpのとき
　　`Blimp`

ArduPlaneのとき
　　`CRRCSim` `calibration` `firefly` `gazebo-zephyr`
　　`glider` `jsbsim` `last_letter` `plane` `plane-3d`
　　`plane-dspoilers` `plane-elevon` `plane-ice`
　　`plane-jet` `plane-soaring` `plane-tailsitter`
　　`plane-vtail` `quadplane` `quadplane-can`
　　`quadplane-cl84` `quadplane-copter_tailsitter` `quadplane-ice`
　　`quadplane-tilthvec` `quadplane-tilttri`
　　`quadplane-tilttrivec` `quadplane-tri`
　　`scrimmage-plane` 

APMrover2のとき
　　`airsim-rover` `balancebot` `calibration`
　　`gazebo-rover` `motorboat` `rover` `rover-skid`
　　`rover-vectored` `sailboat` `sailboat-motor`

ArduSubのとき
　　`gazebo-bluerov2` `vectored` `vectored_6dof`

AntennaTrackerのとき
　　`tracker`

sitl_periph_gpsのとき
　　`gps`




# (おまけ)Pixhawkのファームウェアのビルド方法

`waf`の話が出たので，ついでにファームウェアのビルド方法も記載しておきます．
参考：[Building ArduPilot](https://github.com/ArduPilot/ardupilot/blob/master/BUILD.md)

まずは，`waf`のある`ardupilot`フォルダ直下へ移動します．

```bash:gitでcloneしたフォルダへ
cd ~/ardupilot
```
sitlと違って，コプターやローバーのフォルダに入る必要はありません．

次に，ビルドしたいフライトコントローラを指定します．

```bash:configure書式
./waf configure --board ボードタイプ
```
`--board`の後ろに書くボードタイプは，Mission Plannerで確認すると良いでしょう．
[フライト・データ]画面のHUDの下のタブを，[メッセージ]にするとボードタイプが書かれています．
例えばPixhawk1のコピー品では，以下の様に書かれていました．
![board.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/256470/f724753b-1b44-ad3c-a2a7-03ac138c5b85.png)
従って，

```bash:設定
./waf configure --board fmuv2
```
と書きます．
ボードを指定したら，ビルドしたいドローンタイプを決めてコマンドを打ちます．
主な引数として，`copter`，`rover`，`rover`，`antennatracker`があります．

```bash:ビルド
./waf copter
```

より細かな使い方は，先程のリンクを参照してください．

## SITLのwafビルド
なお，SITLのビルドもwafだけ使って手動で行うことも可能です．

```bash:SITLのwafによるビルド
./waf configure --board sitl
./waf copter
```

## SITLの単独起動
例えばsim_vehicle.pyで以下の様にSITLを起動すると，

```bash:sim_vehicle.pyの起動
sim_vehicle.py --custom-location=35.894087,139.952447,17,353
```
起動中に画面に表示される文字列に以下のような部分があります．

```bash:SITL本体の起動コマンド
/home/(ユーザ名)/ardupilot/build/sitl/bin/arducopter -S -I0 --home 35.894087,139.952447,17,353 --model + --speedup 1 --default /home/(ユーザ名)/ardupilot/Tools/autotest/default_params/copter.parm
```
これは，wafでビルドされたarducopterを使ってSITLを起動するコマンドです．

したがって，`sim_vehicle.py`を使わずとも，自力でSITLを起動させることも出来ます．
sim_vehicle.pyはmavproxyの起動や，事前登録したホームで起動などの親切設計がありますが，むしろ邪魔な場合は直接起動させてしまいましょう．


# おわりに

dronekit-sitlではなく，ArduPilotオリジナルのSITLのビルド＆起動方法を示しました．
次回は，dronekitでArduPilot-SITLに接続してみたいと思います．

先行き不透明なdronekitだけど，行けるところまで行くぞ〜