ArduPilot SITLからAirSimを操作するためのセットアップ

# 概要
AirSimとは、ドローン及び、都市や自然などの多様な環境を再現したシミュレータです。
ArduPilot SITLとは、ArduPilotの飛行制御ソフトウェアをPC上でシミュレーションするツールです。
この2つを連携させることで、PC上でドローンの本格的な飛行制御が実現出来るため、本記事にて、各ツールのセットアップ手順を記載します。

# 環境
本手順で取り扱う内容は、次の環境にて確認しています。
* NVIDIA GPU搭載 PC
* Ubuntu 24.04 Desktop
* Docker 28.1.1
* Docker Compose 2.35.1

# 手順
## ArduPilot SITLセットアップ
ArduPilot SITLのセットアップのためには様々なモジュールが必要となり、PC環境の汚染を防ぐためにDockerを使うことにします。
### DockerFile作成
以下の内容のDockerFileを作成してください。
```
FROM ubuntu:22.04

ENV DEBIAN_FRONTEND=noninteractive

# 必要なシステムパッケージ
RUN apt-get update && apt-get install -y \
    git \
    wget \
    ccache \
    g++ \
    pkg-config \
    libtool \
    libxml2-dev \
    libxslt-dev \
    curl \
    cmake \
    python3 \
    python3-tk \
    python3-pip \
    python3-dev \
    python3-wxgtk4.0 \
    build-essential \
    libgl1-mesa-glx \
    libglib2.0-0 \
    libxcb-xinerama0 \
    libsdl2-dev \
    libcanberra-gtk-module \
    libcanberra-gtk3-module \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

# 必要なPythonモジュール
RUN pip3 install --upgrade pip \
 && pip3 install \
    empy==3.3.4 \
    meson \
    ninja \
    pymavlink \
    pexpect \
    PyOpenGL \
    pyqt5 \
    pyqtwebengine \
    pyqt5-tools \
    matplotlib \
    pygame \
    opencv-python \
    opencv-contrib-python \
    MAVProxy

# ArduPilotを取得
RUN git clone https://github.com/ArduPilot/ardupilot.git /ardupilot
WORKDIR /ardupilot
RUN git submodule update --init --recursive

# wafによるSITL ビルド
RUN ./waf configure --board sitl && ./waf copter

# シミュレーションツールのPATHを追加
ENV PATH="/ardupilot/Tools/autotest:${PATH}"

# コンテナを常時起動
CMD ["tail", "-f", "/dev/null"]
```

Ardupilot-SITLのコンテナイメージを作成します。

```
$ docker build -t ardupilot .
```
ビルドが正常に完了すると、`docker images`コマンドで、`ardupilot`という名前のコンテナイメージが出来ているはずです。

### compose.yaml作成
以下の内容の`compose.yaml`を作成してください。
Ardupilot SITLにてMAPやコンソール画面を立ち上げることになるので、ディスプレイ表示関連の設定が入っています。
```
services:
  ardupilot-sitl:
    container_name: ardupilot-sitl
    image: ardupilot 
    environment:
      - DISPLAY=${DISPLAY}
      - NO_AT_BRIDGE=1
    volumes:
      - /tmp/.X11-unix:/tmp/.X11-unix
    network_mode: host
    stdin_open: true
    tty: true
```

以下のコマンドでArdupilot SITLコンテナを起動させます。
```
$ docker compose up -d
```
コンテナが起動することを確認してください。
実はまだコンテナが起動しただけで、中身のSITL自体は起動していません。
中身の起動は、この後のステップにて実行します。

## AirSimセットアップ
続いてAirSimをセットアップします。
AirSimについてはzipファイルの解凍だけで済むため、DockerではなくOS上にセットアップします。
[こちら](https://github.com/Microsoft/AirSim/releases)から、ご自身の環境に合うzipファイルをダウンロードしてください。私はUbuntuで作業しているので、v1.8.1 - Linux から選びました。また、ドローンを飛ばす環境として廃墟の公園やアフリカなど、利用可能なフィールドがいくつかあるのでお好きなzipファイルをダウンロードしてください。
私は今回 ZhangJiajie(中国の張家界市)を選びました。

zipファイルを任意のディレクトリにて解凍してください。
解凍後、`ZhangJiajie/LinuxNoEditor/ZhangJiajie.sh`のようなshファイルが存在しているので、それを実行してください。

実行後、"Would you like to use car simulation? Choose no to use quadrotor simulation."
Yes,Noの選択肢が表示されますが、今回はドローンをシミュレーションしたいので、Noを選択します。
ドローンやその背景が描写された画面が表示されるはずです。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510470/4e098bdb-b8f6-496b-9980-de09b7cb6ec8.png)
"F1"を押下するとヘルプが表示され、カメラの表示方法などが確認できます。

ただ、今の状態ではArduPilot SITLがまだ用意できていなくドローンが操作できないので、画面は一旦閉じてください。

ホームディレクトリ配下に、`Documents/AirSim/settings.json`というファイルが作成されているはずです。こちらがAirSimの設定ファイルです。
`Documents/AirSim/settings.json`を以下のように編集します。
[ArduCopterを使用する場合の設定](https://ardupilot.org/dev/docs/sitl-with-airsim.html#launch-copter-sitl)と同じサンプルの設定になります。


```
{
  "SettingsVersion": 1.2,
  "LogMessagesVisible": true,
  "SimMode": "Multirotor",
  "OriginGeopoint": {
    "Latitude": -35.363261,
    "Longitude": 149.165230,
    "Altitude": 583
  },
  "Vehicles": {
    "Copter": {
      "VehicleType": "ArduCopter",
      "UseSerial": false,
      "LocalHostIp": "127.0.0.1",
      "UdpIp": "127.0.0.1",
      "UdpPort": 9003,
      "ControlPort": 9002
    }
  }
}
```

## Ardupilot SITLからAirSimを操作
まず、コンテナからLinux上のディスプレイを利用するために、以下のコマンドを実行する必要があります。
```
$ xhost +local:docker
```
※もし実行し忘れた場合、SITL起動時に以下のエラーが出力されます。

```
Auhorization required, but no authorization protocol specified
Unable to access the X Display, is $DISPLAY set properly?
```

次に、Ardupilot SITLコンテナにログインして下さい。
```
$ docker exec -it ardupilot-sitl /bin/bash
```

次に、SITLの起動、およびMAPとMAVRroxyコンソールを表示する以下のコマンドを実行して下さい。
```
$ sim_vehicle.py -v ArduCopter -f airsim-copter --console --map
```
※sim_vehicle.pyのフルパスは、/aldupilot/Tools/autotest/sim_vehicle.pyになります。

実行後以下のように、MAPとMAVProxyコンソールが表示されるはずです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510470/25e6aa80-347a-45d4-8fd3-69f34f257d74.png)
左上がMAVProxyコンソール、左下がArduPilot SITL画面、右下がMAPです。

いまの状態だと、まだAirSimと接続していないので、MAVProxyコンソールには`link 1 down`と表示されているはずです。

その後、shを実行しAirSimを起動してください。AirSimの画面が表示されます。
また、少し時間が経過するとMAVProxyコンソール画面が`link 1 OK` となり、AirSimとの接続が完了したことを確認してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3510470/fdaf66f2-ecbc-44fb-a39f-92a8cb2bb7ba.png)

AirSimとArduPilot SITLが接続されれば、セットアップは完了です。
次に動作確認としてドローンを操作してみます。
今回はドローンが離陸＆着陸できることを確認します。
ArduPilot SITL画面にて、以下のコマンドを実行します。

```
# MAVProxy等の外部コマンドから制御できるモードにする
STABILIZE> mode GUIDED
```

```
# おまじない
GUIDED> param set ARMING_CHECK 0
```

```
# アーミング実行
GUIDED> arm throttle
```

```
# 飛行開始、高度10m上昇
GUIDED> takeoff 10
```

```
# 着陸
GUIDED> mode LAND
```

AirSimドローンが離陸＆着陸できたことを確認してください。

その他の操作もできるようです。詳細は以下の参考ページをご確認下さい。

# 参考
・コマンド集

https://ardupilot.org/mavproxy/docs/getting_started/cheatsheet.html?utm_source=chatgpt.com

https://ardupilot.org/dev/docs/copter-commands-in-guided-mode.html?utm_source=chatgpt.com


・セットアップ

https://ardupilot.org/dev/docs/sitl-with-airsim.html

・AirSimのsettings.json詳細

https://microsoft.github.io/AirSim/settings/