今回開発した「自動追従ライントレースソフトウェア」を構成する主なファイルとその役割は以下のとおりです。
AutoFollwer └src ├Follower.c │ 「スタート待機中状態」「走行中状態」 │ 「停止中状態」を切り替えるライントレーサークラス ├RunController.c │ 「追従走行」「通常走行」を制御する走行コントローラクラス ├RunController_gen.c │ 「追従走行状態」「通常走行状態」を切り替えるクラス(ツールから自動生成) ├DriveController.c │ 駆動モータをコントロールするクラス ├initDevice.c │ デバイスの初期化を行うクラス ├prog.oil │ OSEK OSの設定ファイル └Makefile コード生成、ビルド、プログラム転送を定義したMakefile
このうち、ツールから自動生成されたファイルである「RunController_gen.c」について詳しく見ていきます。
/** 状態関連 */ #define FOLLOWER_LINETRACE 1 #define NORMAL_LINETRACE 2
ここでは、モデル上の状態名を取得して、マクロ定義しています。 |
/** * 状態を初期化する */ void AG_init(void) { AG_current_status = FOLLOWER_LINETRACE; AG_status_entry(); }
ここでは、「走行中」のサブ状態の開始状態である「追従走行中(follower_linetrace)」を設定しています。 |
/** * 状態のdo処理を行う */ static void AG_status_do(void) { switch (AG_current_status) { case FOLLOWER_LINETRACE: RC_fw_linetrace_run(); break; case NORMAL_LINETRACE: RC_us_linetrace_run(); break; } }
ここでは、状態ごとのモデルのdoアクティビティで定義された名前を、関数として呼び出しています。 |
/** * 次の状態を決定する */ static signed int AG_next_status(void) { signed int next_status = -1; /** 次の状態を決定する */ switch (AG_current_status) { case FOLLOWER_LINETRACE: if (touch_sensor_pressed()) { next_status = NORMAL_LINETRACE; } break; case NORMAL_LINETRACE: if (touch_sensor_pressed()) { next_status = FOLLOWER_LINETRACE; } break; } return next_status; }
ここでは、イベント「タッチセンサが押された(touch_sensor_pressed)」に応じて状態を切り替える処理を行っています。 |
なお、状態の数が増減するようなケース、イベントによる遷移先が変わるようなケースにおいても、モデルとソースコードを確実に同期させることができます。
では生成されたコードを、nxtOSEK上でクロスコンパイルして、ターゲットとなる教育用レゴ マインドストームNXTにアップロードしてみましょう。今度は「make build」でプログラムのビルドを、「make transfer」でNXTにプログラムのアップロードを行います。
アップロードが完了したら、自動追従ライントレースシステムを動作させてみましょう。ユースケース図に書いたとおりに動作するでしょうか? まずは、走行を開始させるために、スタートスイッチに割り当てられたタッチセンサを押下します。車輪が回り出したら、コース上で走らせてみましょう。
ステートマシン図を思い出してみてください。最初の走行状態は追従走行でしたので、走行体の超音波センサ付近に手を近づけてみると減速します。そして、手を離すと再び加速します。この状態で次に走行切り替えスイッチに割り当てられたタッチセンサを押下すると、通常走行に切り替わりますので、手を近づけたり離したりしても、今度は一定速度で走行します。最後に停止スイッチに割り当てられた停止ボタンを押下すると停止します。
いかがでしょうか。期待どおりに動作したと思います。これで無事、自動追従ライントレースシステムは完成しました。でもちょっと待ってください。何か気が付きませんでしたか? そう、追従走行ですが、これは障害物の有無であらかじめ設定された速度に単に加減速しているだけですよね。ちゃんと障害物との間隔に合わせて追従走行できないものでしょうか。それを解決するためには、制御の世界のモデルに足を踏み入れる必要があります。
今回、MDDの実践ということで、モデリングを行い、書いたモデルを解析・検証し、そしてモデルからコード生成を行いました。
MDDというと、「コードは書かずに自動生成されるから生産性が高い」とか、逆に「コードと同じ粒度の情報をモデルに書くので、モデルを書くのもコードを書くのも大差はない」といった話をよく耳にします。しかし、MDDの本質はコードの自動生成やモデルにコーディングレベルの情報を埋め込むことではありません。いかに開発するシステムの品質を高め、そしていかにそれを維持するかにあります。
システムの品質を高めるためには、コードよりも抽象度を上げ、システムをより広い視点から俯瞰(ふかん)することで、問題を解決することが必要であり、そのためにモデルという手段を用いることが効果的です。
そして、システムの品質を維持するためには、人の手や思考の介在する余地をなるべく減らすことが必要です。設計は文書やモデルで行い、実装は手でコーディングする場合、どうしてもこの間に人の手や思考の介在する余地が発生してしまいます。この余地こそが品質を落とす可能性となるため、それを避ける手段としてコードの自動生成があります。よって、MDDではモデルを活用して、そこからコードを自動生成しているのです。
以上、今回は簡単な自動追従ライントレースシステムを開発することを題材に、前回に引き続いて、ソフトウェアの世界のモデルに注目して、詳細設計と実装を行いました。次回からは、もう1つのモデルである「制御の世界のモデル」を用いて、この題材にさらに磨きを掛けていきたいと思います。(次回に続く)
Copyright © ITmedia, Inc. All Rights Reserved.