SOAを支える2本柱「ポート」と「ハンドラ」Robotics Studio活用術 はじめて作るサービス(4)(2/2 ページ)

» 2007年10月26日 00時00分 公開
[大川 善邦 工学博士 日本大学工学部非常勤講師/大阪大学名誉教授,@IT MONOist]
前のページへ 1|2       

新しいメッセージの作成

 メッセージGetのプログラミング作法の解析が完了しましたので、このパターンをまねして新しいメッセージを作成していきましょう。

 すでに述べましたが、新規にメッセージを作る際には“最初にそのメッセージのクラスを作る”必要があります。

 MSRS内に、すでにいくつかのメッセージ(例えば、Replace、Updateなど……)が定義されているので、今回はMSRSの「Replace」を使って新たにメッセージを作成することにします。ちなみに、Replaceとはサービスの状態を変更するメッセージです。


※注:
新規にメッセージを作成することを「メッセージのカスタマイズ」といいます。メッセージをカスタマイズする際には、そのメッセージを定義するクラスを作成する必要があります。今回は、入門段階なのでカスタマイズは行いません。MSRSにおいて定義されているメッセージのクラスを使います。


状態の実装

 Replaceはサービスに対して働き掛けるメッセージなので、“状態”が必要になります。まず、MyProj2Types.csファイルに対して、ソース5のように状態を定義します。

状態の定義 ソース5 状態の定義

 ここでは状態のプロパティとして、

  • _destination (ロボットが移動する場所)
  • _rotVelocity (モーターの回転速度)
  • _bumper (バンパーのON/OFF信号)

を定義します。

※注:
現在の段階では、サービスとロボットは物理的に接続されていません。これらのプロパティは仮想的なプロパティと考えてください。


ポートセットへの記入

 ソース6のようにポートセットに対して、新規にReplaceを追記します。

ポートセットへの書き込み ソース6 ポートセットへの書き込み

 これで、MyProj2Operationsというポートセットに対して、Replaceというメッセージが投函可能になりました。

メッセージのクラスの定義

 ポートセットMyProj2Operationsに対して投函するReplaceメッセージのクラスをソース7のように定義します。

Replaceのクラス ソース7 Replaceのクラス

 ソース7を見てお分かりのとおり、MSRSのReplaceをそのまま継承しています。

ハンドラの作成

 ポートセットのインスタンスの生成は、テンプレートに手を入れる必要はありません。

 Replaceのハンドラは、ソース8のように記述します。

Replaceのハンドラ ソース8 Replaceのハンドラ

 属性の部分は、

[ServiceHandler(ServiceHandlerBehavior.Exclusive)] 

とします。

 ここで、ServiceHandlerBehaviorはExclusiveとします。ここはとても重要なポイントです。ソース4のGetのハンドラを見てください。Getの属性において、ServiceHandlerBehaviorはConcurrentとなっています。Getは、サービスの状態を読み出すメッセージです(一般に、データを読み出す処理は複数のプログラムを同時並行的に実行することができます)。

 ところが、Replaceはサービスの状態を書き換える処理です。例えば、2つ以上のプログラムが、同時にデータを書き換える処理を行うと、結果がどのようになるか予想できません。このような処理をクリティカル セクション(critical section)といいます。

 このような問題を回避する手段として、ServiceHandlerBehaviorをExclusiveとしています。このようにすることで、このハンドラが処理を行っている間、ほかのプログラムはこのデータにアクセスできなくなります。つまり、排他制御が行われるのです。

 Replaceの処理はGetとは異なり、

_state = replace.Body; 

によってメッセージの中身を状態へセットして、

replace.ResponsePort.Post(DefaultReplaceResponseType.Instance); 

により処理の終了をポストします。

VPLによる検証

 プログラムの作成は以上で終了です。それでは、MyProj2をビルドしてください。

 ビルドが無事に成功したら、VPLを起動します。

 [Basic Activities]のツールボックスから、画面1のように、3つの[Data]をドラッグし、状態のプロパティに合わせてデータを設定します。

3つの[Data] 画面1 3つの[Data]

 次に、[Basic Activities]のツールボックスから、画面2のように[Join]をドラッグし、[Data]と接続します。

要素の追加 画面2 要素の追加

 [Join]の入力ポートは2口なので、3つ目の[Data]が接続できないように思えます。しかし、3つ目の[Data]から強引に[Join]へ線を引っ張ると、画面3のように入力ポートが3口に拡張され、3つのメッセージをまとめる[Join]が作成できます。

3つのメッセージをまとめる[Join] 画面3 3つのメッセージをまとめる[Join]

 続いて、[Services]のツールボックスから[MyProj2]をドラッグして、[Join]と接続します。

 画面4のように、[Connections]ダイアログが開くので、[To]ペインで[Replace]を選択します。

[Connections]ダイアログ 画面4 [Connections]ダイアログ

 続いて、[Data Connections]ダイアログが開くので、画面5のように入力とプロパティの関連付けを行います。

[Connections]ダイアログ 画面5 [Connections]ダイアログ

 これで、MyProj2の状態は変更されました。

 変更をチェックするためにもう1つ[MyProj2]をドラッグして、2つの[MyProj2]を接続します。すると、画面6のように[Connections]ダイアログが開くので、[From]ペインで[Replace - Success]を選択し、[To]ペインで[Get]を選択します。設定が完了したら[OK]ボタンをクリックします。

[Connections]ダイアログ 画面6 [Connections]ダイアログ

 最後に、画面7のように3つのダイアログをドラッグして、[MyProj2]と接続します。

完成したダイヤグラム 画面7 完成したダイヤグラム

 このときに、[Connections]と[Data Connections]ダイアログにおいても、連載第3回「サービスはロボットの状態と連動して動くもの」を参考にして、正しい設定を行ってください(注)。

※注:
[Connections]と[Data Connections]のダイアログが、自動的に開かない場合はブロックを結ぶ線を右クリックして、ダイアログを表示し、パラメータを設定します。デフォルトでは、入力は“null”になっているので、設定を行わないと正しい結果は得られません。


 以上でダイヤグラムは完成です。

 これを実行してみると意図したとおり、3つのダイアログが開くはずです(画面8)。

実行の結果 画面8 実行の結果


 「ポート」と「ハンドラ」の解説は以上です。それでは、最後に今回の内容の理解度をチェックしてみましょう。以下に演習問題を2つ用意しました。ぜひチャレンジしてください。(次回に続く)


演習問題1:

今回、MyProj2でメッセージの名前を「Replace」としましたが、メッセージの名前を「SetState」としてプログラムを作ってください。


演習問題2:

メッセージの名前「Replace」を「SetVelocity」に変更して、状態のプロパティの「rotVelocity」だけを変更するプログラムを作ってください。ちなみに、ほかのプロパティは変更してはいけません。


前のページへ 1|2       

Copyright © ITmedia, Inc. All Rights Reserved.