2005/9/22

目指せ完全自動運転(12)−前回の解答と連載終了宣言  VRMスクリプト禅問答
難易度:☆☆☆☆☆☆☆

前回示した例題の回答例です。
要点は(i)本線を列車が通過したことを知る方法、(ii)必ずしも同時におこらない2つの本線列車通過をSIGNAL5のG現示への切り替えに連動する方法、の2つです。まず、下に示す概念図をご覧ください。

クリックすると元のサイズで表示します
<概念図・・・余計に混乱しますか、そうですか>

図中の四角の枠はメソッドを、丸囲みは信号機を示しています。これらを結ぶ矢印は、実線が他のメソッドの実行を開始するcall命令で、色が付いているものは特に信号機をその灯火色に設定することを意味しています。破線はメソッドが矢印が向かっている信号機の灯火色を確認し、矢印の色でなければ前回紹介した「自分自身をSetEventAfterする」方法でその色になるまで待つことを意味します。たとえば、一番上の四角=MtdStopTrainから下に伸びる3つの白い矢印実線は、MtdStopTrainから3つのメソッドMtdWaitSignalG、MtdChkSignal1a、MtdChkSignal2aが実行開始されることを意味しています。

次に、先に示した2つの要点の解決策を説明します。

(i)本線を列車が通過したことを知る方法は、(a)ある信号がR現示になるのはその信号の担当する閉塞区間に列車が進入したことを意味している、(b)同じくY現示になるのはその列車が次の閉塞区間に移ったことを意味している、を利用します。SIGNAL1だけに着目すると、メソッドMtdChkSignal1aは信号機SIGNAL1がR現示になるまで自分自身を実行し続けます。そしてR現示になったら、自分を実行するのを止め、その代わりにSIGNAL1がY現示になるまで待つメソッドMtdSignal1bの実行を開始します。
まったく同じことを信号機SIGNAL3に対しても、メソッドMtdChkSignal2a、MtdChkSignal2bがおこないます。こうすることでメソッドMtdChkSignal1bの繰り返しが終わることはすなわち信号機SIGNAL1が担当する閉塞区間を列車が通過したことと等しくなり、メソッドMtdChkSignal2bは信号機SIGNAL3に対して同じことになります。これが、本線を列車が通過したことを知る方法、の答えです。

(ii)必ずしも同時におこらない2つの本線列車通過をSIGNAL5のG現示への切り替えに連動する方法、は、新たに二灯式信号機を2つ、「作業用信号機」として設置することで解決します。なお、この信号機は高度を地面よりも低く(たとえば対地-100mmに)設定し、レイアウト的には見えなくしてしまいます。
この信号機SIGNAL5_1、SIGNAL5_2は、それぞれメソッドMtdChkSignal1b、MtdChkSignal2bが繰り返しを終了するタイミングでG現示に切り替えます。つまり、SIGNAL5_1がG現示になったということはSIGNAL1が担当する閉塞区間を列車が通過したことと等しくなります。SIGNAL5_2がSIGNAL3のそれに当たることはもうおわかりですね。必ずしも信号機を使う必要はないのですが、こうしておくことでどちらの条件が成立/不成立なのかが地面に潜って信号を見ればわかるので、動作テスト時に有利です。
あとは、この2つの信号機が両方共にG現示になるまで繰り返し実行するメソッドMtdWaitSignalGを作り、これが繰り返しを終えるタイミングでSIGNAL5をG現示に切り替えてやれば、結果的に2つの本線の列車の通過を待って待避線からの進入を許可したことになります。これが、必ずしも同時におこらない2つの本線列車通過をSIGNAL5のG現示への切り替えに連動する方法、の答えです。

以下はこれをスクリプトとして記述したものです。
[停車用センサースクリプト]

//制御対象信号
VarSignal ObjCtrlSignal
VarSignal ObjCtrlSignal1
VarSignal ObjCtrlSignal2
get ObjCtrlSignal "SIGNAL5"
get ObjCtrlSignal1 "SIGNAL1"
get ObjCtrlSignal2 "SIGNAL3"
//作業用信号
VarSignal ObjWorkSignal1
VarSignal ObjWorkSignal2
get ObjWorkSignal1 "SIGNAL5_1"
get ObjWorkSignal2 "SIGNAL5_2"
//理変数&センサーイベント設定
VarTrain ObjTrain
Var EventID
Var TimerID
Var TimerID1
Var TimerID2
SetEventSensor MtdSenseTrain EventID
//
//編成検知イベント
//
BeginFunc MtdSenseTrain
GetSenseTrain ObjTrain
call this MtdStopTrain
EndFunc
//
//編成駅停車メソッド
//
BeginFunc MtdStopTrain
get ObjTrain.StdObjSignal ObjPartnerSignal
call ObjTrain StdMtdStationStop
SetEventAfter this MtdWaitSignalG TimerID 3000
call ObjWorkSignal1 StdMtdSignalR
call ObjWorkSignal2 StdMtdSignalR
call this MtdChkSignal1a
call this MtdChkSignal2a
EndFunc
//
//出発信号制御メソッド
//
BeginFunc MtdWaitSignalG
ifeq ObjWorkSignal1.StdVarSignalPosition 6
ifeq ObjWorkSignal2.StdVarSignalPosition 6
call ObjCtrlSignal StdMtdSignalG
else
SetEventAfter this MtdWaitSignalG 1000 TimerID
endif
else
SetEventAfter this MtdWaitSignalG 1000 TimerID
endif
EndFunc
//
//SIGNAL1がRになるのを待つメソッド
//
BeginFunc MtdChkSignal1a
ifeq MtdCtrlSignal1.StdVarSignalPosition 1
call this MtdChkSignal1b
else
SetEventAfter this MtdChkSignal1a TimerID1 1000
endif
EndFunc
//
//SIGNAL1がYになるのを待つメソッド
//
BeginFunc MtdChkSignal1b
ifeq ObjCtrlSignal1.StdVarSignalPosition 3
call ObjWorkSignal1 StdMtdSignalG
call ObjCtrlSignal1 StdMtdSignalR
else
SetEventAfter this MtdChkSignal1b TimerID1 1000
endif
EndFunc
//
//SIGNAL3がRになるのを待つメソッド
//
BeginFunc MtdChkSignal2a
ifeq ObjCtrlSignal2.StdVarSignalPosition 1
call this MtdChkSignal2b
else
SetEventAfter this MtdChkSignal2a TimerID2 1000
endif
EndFunc
//
//SIGNAL3がYになるのを待つメソッド
//
BeginFunc MtdChkSignal2b
ifeq ObjCtrlSignal2.StdVarSignalPosition 3
call ObjWorkSignal2 StdMtdSignalG
call ObjCtrlSignal2 StdMtdSignalR
else
SetEventAfter this MtdChkSignal2b TimerID1 1000
endif
EndFunc
細かい部分としては、SIGNAL1/3がY現示になった時点でこれをR現示に切り替えSIGNAL5から進入してくる列車との衝突を回避するだとか(ここで以前仕掛けたR→Y、Y→G以外の遷移を禁止する措置が活きてくる)、SIGNAL5_1/2をMtdStopTrainが実行された時点でR現示にして初期化するだとか、ここには出てきませんが、SIGNAL5から進入した列車が本線を横切り終わった時点でSIGNAL1/3を強制的にG現示に切り替えて後続列車のために区間を開放するという後始末があったりしますが、ここまでの議論を理解できた方には最早説明は不要でしょう。

唐突ですが、どうにもこのシリーズは不評のようなので、ここいらで一旦連載を終了します。ここまでに説明したこと、また、VRMスクリプト禅問答で取り上げたネタを精読いただければ、自律的自動運転に必要なテーマはほとんど網羅されているはずです。あとは、読者諸兄でいろいろ試行錯誤してみてください。何か解決出来ない問題が発生した場合は、適当にコメントを残してください。ちょっと出かけるのでお返事はしばらく後になりますが、大抵のことは解決できると思いますのでアテにしていただいて結構です。
0

2005/10/3  18:21

投稿者:ghost
まぁ「不評」っつーのは言葉のアヤです。なんと言うか、意図していた見返りが得られないのでやめた、という感じで。拙者、実利主義者なので。

#スイスにはまだ飯の種が御座候わず。それさえあればとっくにおさらばしてます(ぉぃ

2005/9/26  11:39

投稿者:Gallagher
このシリーズ不評なんですか。少なくとも自分には大好評でしたが…コメントはなくとも、愛読者はたくさんいると思いますよ。

#いくら待っても侍の更新がないと思ったら、いつのまにかスイスに定住してた、なんてナシですよ。

コメントを書く

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




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