2005/9/10

目指せ完全自動運転(6)−赤信号停止からの回復  VRMスクリプト禅問答
難易度:☆☆☆☆

前々回紹介したスクリプトで、メソッドStdMtdSignalRの中にコメントアウトされていた部分がありました。今回はそれに関するお話です。このスクリプトを組み込むことで、分岐のないエンドレスループの中で完全自律型自動運転をおこなうための要素がすべて出揃うことになります。

まずは、お手元の編成に組み込み済みのメソッドStdMtdSignalR内のSetEventAfter命令の頭についているコメント記号(//)を削除してください。続いて、以下のスクリプトを編成スクリプトに加えてください。
[編成スクリプト]
//
//閉塞出発待ちメソッド
//
BeginFunc MtdWaitRestart
Var TmpSignal
Var TmpSpeed
//現在速度を評価
GetCurrentSpeed TmpSpeed
ifzero TmpSpeed
//信号灯火色を取得
mov TmpSignal StdObjSignal.StdVarSignalPosition
ifeq TmpSignal 1
//R現示の場合、このメソッドを再度タイマー登録
SetEventAfter this MtdWaitRestart TimerID 1000
else
//閉塞信号喚呼メソッドを実行=再出発
call this StdMtdCheckSignal
endif
else
//現在速度がゼロでない場合、このメソッドを再度タイマー登録
SetEventAfter this MtdWaitRestart TimerID 1000
endif
EndFunc
このメソッドの動作を要約すると「現在速度が0km/h=停止中であり、かつ、オブジェクト変数StdObjSignalが指し示す信号の灯火色が赤でなければ、閉塞信号喚呼メソッドを実行する」というものになります。
このメソッドはメソッドStdMtdSignalRが列車の停止を開始(SetTimerVoltage 0.0)した直後にSetEvnetTimer命令によってタイマー登録されます。この時点でオブジェクト変数StdObjSignalには、列車を停止させた信号機が記録されていますから、これを参照し続けることによりその灯火色が赤以外になる=先行列車と十分距離が開いたので再出発が可能になる、のを待つことが可能です。

最初にGetCurrentSpeed命令で現在速度を取得しています。これは、R現示に対してはなにはともあれ一旦列車が停止すべきであるという考えから、速度が0Km/hにならない限り、信号灯火の再評価をおこなわないようにするためです。
一旦速度が0Km/hになれば、続くifeq命令によりオブジェクト変数StdObjSignalが示す信号のグローバル変数(=公開プロパティ)VarStdSignalPositionが評価されるようになります。この値1であるということは、すなわち信号が赤であることを意味しており、列車の再出発は許可されません。
これは何もしなくて良いという意味ではありません。適度な間隔を空けて(サンプルでは1,000ミリ秒になっていますが、これは適当に調整して構いません)もう1度、厳密に言えば、信号が赤でなくなるまで同じことを繰り返す必要があります。これを実現するために、SetEventTimer命令で「自分自身(MtdWaitRestart)を1,000ミリ秒後に実行する」というタイマー定義をおこなうわけです。
信号が赤でない場合、メソッドStdMtdCheckSignalが実行されます。この時点で信号はY現示かG現示のはずですから、結果的にこれは注意/巡航速度で再出発することを意味します。また、この場合はSetEventAfter命令が実行されないので、メソッドMtdWaiRestartが実行されるのはこれが最後(厳密には次に列車が赤信号につかまるまでの間に限って、ですが)ということになります。

ここで使われている「ある条件が整うまで待つ」というテクニックは、今後も完全自律型自動運転シリーズで頻出する予定です。このテクニックについて改めて、もう少し一般化しその基本的な考え方や応用について説明します。が、思うに飽和状態の方がほとんどだと思いますので、少し間を空けます。

質問やご要望があれば気軽にコメント欄に書き込んでください。特に「ここの意味がよくわからないのでもっと詳しく」という指摘は大歓迎です、なぜわかりにくいのかの理由が添えられていると特に。
0

コメントを書く

この記事にはコメントを投稿できません




teacup.ブログ “AutoPage”
AutoPage最新お知らせ