Ardupilotについて
1年ほど前に、ドローンのフライトコントローラ周りのOSSプロジェクトについてという記事を書きました。
その中で、Ardupilotというオープンソースプロダクトについて言及し、以下の図を載せました。
現在でも、ユーザプロセスやライブラリ、HAL、OSといったフレームワークの基本的構造は変わりません。
しかし、変わったことがあります。
それは、HALで抽象化の対象となるOSにLinuxも加わったということです。つまり、Linux + Ardupilotでドローンのフライトコントローラを制御できるようになったことである。
OS好きとして、Linuxをどう使っているのか非常に興味の湧くところです。また、Nuttx以外にもサポートされているOSもあるようです。こちらも興味がありますね。
Ardupilotの概要が書かれた資料はないの?
まず、ArdupilotのWeb Pageを読んでみましょう。OSSのドキュメントとしてはかなりわかりやすい部類です。
その上で、開発者向けのページを順に読むと多くを得ることができます。
しかし、それで終わってしまうと、書きたいことにつながらないので、簡単にユーザプロセスの実装について述べていきます。
http://ardupilot.org/dev/docs/learning-ardupilot-the-example-sketches.html
ソースを読む
よく言われるように、ユーザプロセス実装を理解するための早道はサンプルコードを読むことです。
Knowing the library API and conventions used in ArduPilot is essential to understanding the code. So using the library example sketches is a great way to get started. As a start you should read, build and run the example sketches for the following libraries
訳:Ardupilotで使われているLibrary APIとそのお約束事を知ることは、コードを理解する基本です。よってライブラリの実装例を使うことは、取っ掛かりとしてはとてもよい方法です。手始めに以下のライブラリ群の実装例を読んで、実際にビルドして走らせるのは良い考えです。
ここからgit cloneしましょう。
なお、読むソースコードは、「Copter-3.3.2」でタグ付けされているソースです。
あと、いくつか注意。
- ビルド環境やソースを読む環境はUbuntu14.04です。それ以外の方は適当に読み替えてください。
- 私も個人的な興味・趣味からソースを読んで勉強や調査をしております。なので、スゴいことを期待しないようお願いいたします(笑)。
機能追加をするもっとも基本的なやり方
ソースを読む前に、機能追加を行う最も基本的な方法についてみていきます。
ArdupilotのWeb Page(Learning ArduPilot — The Example Sketches)をざっと読むと色々わかりますが、基本となる部分は以下のとおりです。
- ユーザが追加するコードはSketchと呼ばれます。このプロジェクトがArduinoの影響を受けていることによります。よって、Arduinoを知っている人はイメージできるかもしれません。
- Sketchは起動時に一度だけ呼ばれるsetup()とsetup()呼び出し以降繰り返し呼ばれるloop()があります。
- halと呼ばれる変数があります。「これによってAP_HAL::HALオブジェクトへのアクセスが行える。このオブジェクトはすべてのハードウェア固有の関数にアクセスすることができ、これら関数にはコンソールへの出力関数、sleep、I2CやSPIバスを介した通信をする関数が含まれる。」
- sketchにはAP_HAL_MAIN()というマクロが必ず含まれます。
文章だけだとイメージしづらいですね。サンプルとなるsketchを書いてみます。
一番簡単なsketchは以下の通りになります。
// -*- tab-width: 4; Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil -*-
# include <AP_HAL_Linux/AP_HAL_Linux.h>
const AP_HAL::HAL& hal = AP_HAL_BOARD_DRIVER;
void setup(void)
{
hal.console->printf("setup\n");
}
void loop(void)
{
hal.console->printf("loop\n");
}
AP_HAL_MAIN();
ビルド手順
とりあえず、以下のようにやってみてください。
- libraries/AP_HAL_Linux/examples/ に skeltonというディレクトリを作って、上記のソースをコピペしてskelton.cppという名前で保存してください。
- libraries/AP_HAL_Linux/examples/BusTest からMakefileとmake.incを内容を変更せずにそのままlibraries/AP_HAL_Linux/examples/ にコピーしてください。
- make linux とタイプしてください。すると、ビルドが始まり、skelton.elfという実行形式ファイルが出来上がります。
- 環境によっては、「gawkがない!」などビルドに必要なツールが不足していることでビルドエラーになるケースがあります。その際はインストール願います。
さて、skelton.elfを実行しましょう。
最初の1回だけsetupと表示され、あとは延々loopという文字列行が表示されます。
setup
loop
loop
loop
loop
(以後続く)
フライトコントローラと呼ばれるハードウェア上で作成したソフトを動かす場合、もうひと手間かけないといけません。しかし、今回はArdupilotとLinuxについてソースを追ってみるのが主となります。よって、今回はフライトコントローラに関する記述は書きません。
今回のsketch作成でわかったこと
先に書いたとおりのことがわかりました。
- setup()は最初の一回だけ呼ばれる。
- setup()が呼ばれたあとで、loop()が繰り返し呼ばれる。
- 何か、halというグローバル変数がある。少なくともコンソールへの表示は何かのインスタンス経由で行われるようだ。
- AP_HAL_MAIN()という謎マクロがソースの一番下にある。
ここで、以下の疑問が湧いてきます。
- setup()とloop()は誰が呼び出すのか?
- AP_HAL_MAIN()とは何者か?
- halの具体的内容は?
- 一番最初の図には「ユーザプロセス」とある。今書いたsketchとプロセスの関係は?
次回以降、ソースを読んで疑問点を調べていきましょう。