RaspberryPi + ArdupilotでDroneを動かしたい(未完)

~~<font color="Red">申し訳ありません、まだ書いてる最中です</font>~~
~~<font color="Red">2019/11/26 研究で使うことがなくなったので、ここでやめます</font>~~


研究室でドローンを買ったのだけど使い方がよくわかんない。
飛行型と地上型の二種類があるんだけど、どっちも分からない上に地上型はもっとわかってない。
一番よくわかってなかったのはArdupilotをどう使えばいいのかということ。

~~**目標 :  ドローン(地上型)にラズパイを載せて、自動で運用したい**~~
研究でドローンを飛ばすことはなくなった

# Ardupilotのシステム構成

次のサイトでアーキテクチャを調べたら、図のような構成であることがわかった。
http://ardupilot.org/dev/docs/apmcopter-code-overview.html

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136973/7d545a2d-f0a6-5391-9a44-975dab444029.png)

この図の上側である「Companion Computer(以下CC)」や「Ground Station(以下GCS)」が手元やUAVにくっつけるPCで、MAVLinkを介してArdupilot(ソフトウェア)に情報伝達する仕組みらしい。

(ちなみにMAVLinkはDroneを制御するための軽量なメッセージングプロトコル。https://mavlink.io/en/)

# Companion Computer と制御ソフトウェア(API)

この図を見たときは、CC上で動かすソフトウェアはDroneKitの一択かな、と思っていたけどそうでもないみたい。

このページではArdupilotで使用可能なCCとソフトウェアの一覧が示されている。
http://ardupilot.org/dev/docs/companion-computers.html

例をあげると、としてRPiをUAVとかにつなげて、RPi上でDroneKitを動かしてUAVを制御する感じみたい。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136973/0b683942-71f4-91a5-38af-cd39a2cc492e.png)

|API|備考|
|----------------|------------------|
|**APSync** | ドローンでのネットワーク利用を前提とした制御ソフト。複雑なプログラミングには不向きそう?(eLABのページにはAPSyncの記載が全く無いような気がする)|
|**DroneKit** | UAVの制御アプリをPythonで実装するためのAPI(https://qiita.com/hsgucci/items/27fa33d7c7de505839da によれば、先行きが不明かもしれないらしい)。|

# 地上管理基地局 Ground Control Station

もちろん単純な操作はGCS(Ground Control Station:地上管理基地)を使ってもいいみたい。
だけどPCとDroneが無線であれ有線であれ接続している必要があるのがちょっとね(車タイプのドローンなら通信範囲外でも自動で運用したい時もあるから)。

主なGCSは次の2つ、GUIを持っていてPC上で直感的に地図を見ながら操作できるのが利点。

|GCS|備考|
|----------------|------------------|
|**MissionPlanner** <br>(Windows) | ファームウェアの書き換えや、センサやモータの初期設定・初期調整に必須。一番使いやすい。|
|**APMPlanner2** <br>(Windows/Linux/Mac) | 間違ってるかもしれないけど、MissionPlannerのクロスプラットフォーム版みたい。ほとんど同じだけど、なんか使い勝手が違うので一回しか使ってない。|
|**MAVProxy** <br>(Win/Lin/Mac) | 上２つよりもシンプルな画面で、GUIとCUIで命令を送信できる|

以上をまとめて図にわかりやすくするとこんな感じかも(間違ってるかもしれないが)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/136973/c17e6f20-e28f-c7ca-f672-d107223e5af4.png)

#使用機器

というわけで以下の構成で無人機を操作してみる

| Role             | Device            | Web Site           |
|:-----------------|:------------------|:------------------:|
|CC                | Raspberry Pi 3    | https://www.raspberrypi.org/|
|FC                | Pixhawk2(The Cube)| https://pixhawk.org/|
|UGV               | R1 UGV            | https://www.aionrobotics.com/|
|UAV               | LAB445            | http://elab.co.jp/|
|API               | Dronekit          | https://dronekit-python.readthedocs.io/en/latest/|

(APScyncは諦めた、公式ドキュメントが探しきれなかった。情けない。。。)

- 第一目標は屋内で前後左右の移動
- 第二目標は屋外で屋外でGPS座標を元に移動
- 第三目標はセンサなどのモジュールから取得したデータを元に経路を動的に変更



#DroneKit Pythonの準備
というわけでDroneKit-Python 2.0(DKPY 2.0)をRaspberryPi3にインストールしていきます。
[公式ドキュメント](https://dronekit-python.readthedocs.io/en/latest/)を参考に入れていきます。(ぶっちゃけ他の人もやってるから細かいところはそっちを見たほうがいいかも)

~~エラーがでる... pip install dronekit がうまく通らない~~


pipに関しては以下のサイトが参考になった
https://dronekit-python.readthedocs.io/en/latest/develop/installation.html#installing-dronekit
https://laboradian.com/cannot-import-name-main-when-upgrading-pip/

調べたらRaspberry Piではよくある問題らしい、外人さんも困ってた感じだった
自分の環境ではやる必要がなかったけれど、一度pipの環境を消してから再構築した。
（もしかしたらlibxslt周りをしっかりとインストールすればいいだけだったかも）

```
$ sudo apt-get install python-pip python-dev
$ sudo apt install libxml2-dev libxslt1-dev (libxslt-dev ではなく)
$ pip install dronekit
```

で通った(上手くいったかの保証はない)

```
$ pip list | grep drone
dronekit (2.9.2)
```

一応、pipの中にdronekitは入ってるみたいなので、ようやく下準備は完了。


#Pythonスクリプトを書く

以下のスクリプトが基本になるらしい。

```python:test_code_uav.py   
from dronekit import connect

# Connect to UDP endpoint.
vehicle = connect('/dev/ttyACM0,57600', wait_ready=True)
# Use returned Vehicle object to query device state - e.g. to get the mode:
print("Mode: %s" % vehicle.mode.name)
```

自分の環境ではPixhawk2 <-- USB- -> RraspberryPi なので/dev/ttyACM0に接続しました。
上記のスクリプトは、接続している無人機のModeが帰ってくる。
各モードはArdupilotのWebページを参照。
[Flight Mode : Copter](http://ardupilot.org/copter/docs/flight-modes.html) 
[Rover Control Modes : Rover](http://ardupilot.org/rover/docs/rover-control-modes.html) 

DroneKit-PythonのAPIによれば、

```
$ sudo python test_code_uav.py                                          
Mode: HOLD 
```

sudoじゃないと動かない(ユーザの権限によりけりだと思います)

ラズパイとardupilotの組み合わせはこの人の記事がすごく参考になる
https://qiita.com/hsgucci/items/7af8da302f80bf38de68

空中用のUAV[eLabの445,Pixhawk mini,[これ](https://store.shopping.yahoo.co.jp/elab-store/lab001.html)]ではTakeoffなどのコマンドを受け付けた。実際にモータも動きました。


##別の方法
pipでインストールできない場合はgitから直接ダウンロードするのも可能らしい

```
$git clone git@github.com:dronekit/dronekit-python.git
$cd dronekit-python
$sudo python setup.py install
```

***
#以下の問題が発生中


地上用のUGV[AION ROBOTICSのR1,Pixhawk2,[これ](https://store.aionrobotics.com/products/r1-ardupilot)]ではなぜかどのコマンドも受け付けない。
よくよく調べるとテレメトリーでも挙動が怪しい、、、もしかして初期設定にミス？
テレメトリーでもラズパイからのコマンドでも「Flight mode change failed」が発生している。

#現在の作業
下記のissueの解決策を試している。EKFとGPSが赤文字なので、もしかしたらそれが原因かも
https://discuss.ardupilot.org/t/flight-mode-failed/38907
https://discuss.ardupilot.org/t/flight-mode-change-failed-error-when-switching-to-auto/31206
https://discuss.ardupilot.org/t/flight-mode-change-failed-on-skit-steer-rover/43017

~~治らないのでSITL上でRoverを動かすことにする、これで動けば機器の問題、動かないなら別の問題の気がする。~~