それでは、私たちのチームが、どのように提出用のモデルを作っていったのかを紹介していきます。
私たちのチームのコンセプトは、「コースをセグメントに分割し、走行方法を切り替える」というものです(前回のFusion&Futuresチームと似ています)。こうしたコンセプトで、インコースやアウトコース、難所をどのように走らせるのかを話し合い、走らせ方を図に表してみました(図5)。これがDSLの原型ともいえます。なお、この段階で必要な走行方法などもある程度ピックアップしました。
こうして考えた走らせ方に加え、走ること以外に必要な機能(キャリブレーションなど)をユースケースで分析しました。また、DSLの開発プロセスの説明であったように、DSLを作る上では「固定部(どのバリエーションでも変更がない部分)」と「可変部(バリエーションごとに変更の可能性がある部分)」を識別する必要がありますので、私たちは「フィーチャーモデル」を使用して、固定部・可変部の切り出しを行いました(図6)。
フィーチャーモデルによる分析も初めてで、随分試行錯誤しました。やり方としては、まず各所の走行方法の切り替え方を図5のような図や「ユースケースシナリオ」を用いて記述し、要素を洗い出しました。次に、要素間の関係と、必須か選択(オプショナル)かを分析していきました。これらの作業により、ドメインの分割と、走り方にかかわらず必要となる部分(固定部)と、走り方を変えることによって変わる部分(可変部分)がどこであるかという切り分けができました。固定部分に関しては、共通な振る舞いとしてフレームワークで実現し、可変部に関してはDSLで組み換えを行うように以降の作業を進めました。
次に、フィーチャーモデルや図で書いていた走らせ方をベースに、コース戦略(スタートからゴールまで、走り方を組み合わせたもの)がどのような構成になっているかということを「分析クラス図」で記述しました(図7)。
この際、フィーチャーモデル上の走行に関する部分(走行方法を1つから選択する部分。図6の【1】)に関しては多重度を「1」に(図7の【1】)、セグメント走行条件(オプショナルとした部分。図6の【2】)に関しては多重度を「0..*」とし(図7の【2】の部分)、フィーチャーモデルで考えた構成が取れるようにしました。
勉強しながらの作業でおのおのの理解が不十分なこともあり、議論がなかなか収束せず、分析クラス図を作るまでに相当な時間を使ってしまいました。ここまでできた段階でモデル提出まで1週間程度しかありませんでした。
提出用モデルを作成するため、分析クラス図をベースにDSL定義と設計モデルの作成に取り掛かりました。
DSLを作成するためのツールは幾つかありますが(注1)、今回私たちが使用したのは「Microsoft Visual Studio」の「DSL Tools」です。Visual Studio DSL Toolsでは、DSLデザイナーを使って作成するDSLの意味的構造・制約、そして図的表現とのマッピングを定義できます。また、DSLモデルにアクセスし、データを取得してそれを基にコードを生成するテンプレートエンジンも用意されています(テンプレートはC#、またはVisual Basicで記述)。DSLデザイナーで定義を行うとDSLエディタが生成されます(図8)。
DSLを定義する際、まず分析モデルをベースにDSLのメタモデルを定義しました。DSL Toolsでのメタモデル定義は、UMLのクラス図そのものではありませんが、構造はほぼ変わりません。分析クラス図をしっかり作っていれば、あまり変えることなく入力することができます。多重度も分析クラス図と同じものを入力しました。こうすることで、例えば、“セグメント走行方法には走行が1つ以上関連付けられない”といった制約が、自動的にDSLエディタで実現されます。さらに、図とマッピングを行い、表示の調整やツールボックスの定義などを行うことでDSLエディタを生成することができます。DSLの作り方に関しては、書籍「ドメイン特化型開発―Visual StudioとDSLによる次世代モデル駆動開発(日経BPソフトプレス)」が参考になりますので、作ってみたい方はそちらを参照していただくとよいでしょう。
設計モデルは、主にフィーチャーモデル上で固定部として切り出した「セグメント走行切り替え」部分を、フレームワークとして設計しました。その際、フレームワークが可変部の個別の要素に影響されないように注意しました。その結果、Fusion&Futuresチームと同様、Strategyパターンを用いた構造となりました(前回のFusion&Futuresチームの設計モデルを参照願います)。
提出用モデルとしては「フィーチャーモデル」「非機能要件」「分析クラス図」「設計クラス図」「シーケンス図」「状態図」などを記述しました。また、DSLを使って、各難所をどのようにクリアするかというシナリオなども入れました。
私たちのチームはモデル提出までは、サンプルコードを修正して走行や検知などのアルゴリズムを少しずつ試していました。モデル提出後にようやくフレームワークやフレームワークI/Fに合わせたアルゴリズムごとの実装、DSLの骨組みの作成を行いました。実装はC言語で行いました。フレームワークに関しては、Fusion&Futuresチームとおおむね同様の仕組みになりました。また、コース戦略は、“1コース戦略1ファイル”の形でテーブル形式のコードとして記述できるようにしました。ただし、走行中に検出する事象を複数(図7の【2】の部分。多重度が0..*)とした関係で、要素間はFusion&Futuresチームのようなリスト形式ではなく、ネットワーク形式となり、記述がより複雑になっている点が異なります。
走行部門で良い成績を残すには、より速く正確にコースを走れるように、戦略と戦略パラメータ(アルゴリズムのパラメータ)をチューニングし、洗練させていくことが必要です(実際に作ったいろいろな戦略をロボットでテストすることにより行います)。
私たちが最終的に目指したのは、DSLモデルからこの戦略コードを生成することで、「パラメータのチューニングを素早くできるようにすること」でした。それには戦略コードを生成するために、DSL定義フェーズにてテンプレートを作成する必要があったのですが、テンプレート作成の作業が遅れたため、完成するまでの間、戦略コードを手書きで記述してテストを行う必要がありました。戦略をリスト形式で記述していたFusion&Futuresチームでも記述ミスが問題になっていましたが、私たちの場合も同様で、特に戦略の記述がネットワーク形式で複雑になっている分、ある部分を変更するとそれに併せて変更しなくてはならない点が幾つもあり、戦略で使用する要素を追加するだけでも非常に苦労しました。
その後、テンプレートが完成してDSLモデルから戦略コードが生成できるようになると状況は一変しました。
これまでの手書きの戦略コード作成による苦労が全くなくなり、短時間で幾つもの戦略を作成し、試すことができるようになりました。また、それまではフレームワークの構造を知っているメンバーしか戦略を作ることができませんでしたが、DSLを使うことで説明もなく戦略を作ることができるようになりました。このことにより、私たちの戦略コードを作り上げる時間が大幅に短縮され、出来上がったプログラムの走行を試したいメンバーによってロボットの順番待ちが生じるほどになりました。この結果、ライントレースのみのコース完走もおぼつかない状態から、難所を通ってもかなりの確率で完走できるようになりました。
私たちの作成したDSLの一例を図9に、そこから生成されるコードの例を図10に示します。
今回の方法で連載第2回「ETロボコンに向けた具体的な全体活動」で紹介した各ドメインがどのように実現されているかを図11に示します。足回り、フレームワークドメインに関してはMDDツールを使わなかったFusion&Futuresチームと同じ構成です。戦略の部分をDSLモデルで記述できるようにしたという点が異なります。
今回行ったDSLによる開発のメリットとデメリットを紹介したいと思います。
まずメリットですが、前述のようにDSLができてしまうとその後の生産性が非常に上がります。特に、手で書くことによるつまらないミスがなくなるとともに、DSLエディタ上で各種の禁則(例えば、事象の検知間には線が引けないなど)がチェックされるので、モデルを作る時点でのミスもなくすことができます。さらに、分かりやすい表記を使うことで中身を知らない人でも直感的にDSLモデルを作ることができ、学習コストを下げることができます。また今回、新しいアルゴリズムを作成した場合や修正した場合には、DSL定義にも要素の追加や修正を行うようにしたため、開発者は戦略作成をする際、常に新たなアルゴリズムを使える状態となっていました。このようにすることで、自然とソフトウェアの再利用を促すことができるのではないかと思います。
次にデメリットですが、DSLを構築するためには、DSLを作成するためのツールの知識、メタモデルを作成するためのモデリングスキル、テンプレートを作成するための言語(今回はC#を利用)の知識など多くの要素が必要になります。私たちも、メタモデルとなる分析モデルは作成したものの、ツールの知識習得が間に合わず、DSL定義の多くをチームメンバーで作成することができませんでした(事務局の経験者にベースを作ってもらいました)。DSL定義を行うためには、計画的な学習期間と参考文献が必要ですが、参考文献はあまり多くなく、経験者の知見に頼るところが大きいのが実情です。こうした課題があるため、業務に適用を検討している場合には、いきなり導入するのではなく、事前に小さな対象で経験を積んだのち、掛かるコストに見合うかどうかを分析してから使う必要があると思います。適用対象としては、派生開発のように少しずつ異なるバリエーションの製品を作るのに向いている手法ではないかと思います。
大会の結果は、モデルの評価が「B-」と振るいませんでしたが、走行は4位と上位に食い込むことができました。総合は5位だったのですが、試走会での振る舞い審査(注2)までの作りこみが甘かったなどの要因があり、惜しくもチャンピオンシップ大会に出ることはできませんでした。しかし、実装に掛けた開発期間が短い中、走行上位に食い込むことができたのは、DSLを使うことで、さまざまな戦略を試すことができたおかげだと思います。また、大会直前は足回り要素(走行方法や検知方法)の新たな作り込みや大きな変更を行わないようにし、安定した足回り要素を使って走行戦略のテストとチューニングに徹したことも、良い結果につながったと思います。モデルの評価に関しては、分析までに時間を使ってしまったため、最終的に審査員の方に見てもらえるような、見やすい資料に仕上げることができなかったのが大きな要因の1つだと思います。分析や設計といった中身の部分ももちろん重要なのですが、ETロボコンの提出モデルに関しては“見てもらう資料”として仕上げるための時間もあらかじめ計画しておく必要があったというのが反省点です。
今回、DSLを使った開発を行うことで、その効果を実感できました。そういった意味では目標は達成できたといえます。しかし、DSLを定義するには、まだまだ知識やスキルが足りておらず、今後さらなる勉強が必要だと考えています。また、チーム活動の進め方にも課題は多く、スケジューリングや進捗管理、会議運営や情報共有など、いろいろな点で気付きを得ることができました。今後はこうした点を改善できるようにしたいと思っています。
その他の取り組みとして、モデル提出後は作るものが明確になったため、スクラム(アジャイルソフトウェア開発手法の一種)の手法を取り入れ、毎日15分でタスク確認や各自の所有時間から作業分担(担当はメイン、サブの2人)を行いました。結果、非常に効果があることが確認できました。大会を通じ、成果を出すには“チーム力”が重要な要素であり、メンバーがうまくモチベーションを保ち、全員が連携できれば非常に大きな成果を生むことができることが分かりました。そのためには、目的や計画、やるべきことをうまく共有し、各自の良いところを生かせるようにすることが重要だと実感しました。
次回は「BridgePoint」による開発を行った「みんなとみらい2」チームの活動をチームリーダーの田村が紹介する予定です。お楽しみに! (次回に続く)
Copyright © ITmedia, Inc. All Rights Reserved.