難易度:☆☆☆☆
VRM4第2号で待望の灯火する信号機が登場しました。完全自律型自動運転を目指すからには、信号の灯火と連動して走る列車を実現したいものです。今回はその前段階として、その肝となる「区間閉塞」を理解しておくことにしましょう。スクリプトは次回示します。

<区間閉塞の考え方>
大雑把に言えば、区間閉塞は列車の追突防止の仕組みです。話を単純化するために三灯式信号に話を限定しますが、原理はすべて同じです。閉塞信号機で区切られた区間に列車が進入するとその区間が「閉塞」となり、区間入り口の信号機はR現示(赤灯火)になります。
同時に、それまで閉塞していた区間が開放され信号機の灯火が遷移します。ここでは三灯式を前提としているのでY現示(黄灯火)となります。これは「1つ先の区間が閉塞しているので停止にそなえて注意(減速)せよ」という意味ですね。さらに1つ前の区間(直前までY現示だった信号)は「少なくとも1つ先は閉塞していないので安心して進行してよろしい」という意味でG現示(青灯火)になります。
これを整理すると、以下のようになります。
@閉塞信号を列車が通過すると、その信号はR現示となる。
A同時に、1つ前の信号はY現示となる。
B同時に、2つ前の信号はG現示となる。
これをVRMスクリプトで実現しようと言うわけです。@についてはイメージしやすいですね。「列車が通過すると」は、すなわち「センサーが編成を検知すると」ということです。
ピンと来ないのはAとBです。これをもう少し整理しましょう。
改めて上の図を見てください。この瞬間(列車が左から3番目の区間から2番目の区間に進入した瞬間)何が起こるのでしょうか。@については、信号機のところにセンサーがあり、これが同じ場所にある信号機をR現示に変化させたのだ、と考えればよろしい。
ではAについては?
これは、R現示になった信号が自分の1つ前の信号を知っていて、これをY現示に変えたのだ、と考えましょう。VRMスクリプト的に言うと「call {1つ前の信号}{Y現示にするメソッド}」です。
ではBも「call {2つ前の信号}{G現示にするメソッド}」でしょうか?
これでも良いのですが、この方式を採用するとそれぞれの信号が自分の1つ前の信号、2つ前の信号(四/五灯式信号ならばもっと)を知っていなければならず、管理が面倒です。
そこでちょっと発想を変えます。上図でR現示に切り替わった(左から2番目の)信号は、1つ前の信号を知っていて、それに「Y現示になれ」と命じます。こうして黄灯火になった(左から3番目の)信号ですが、考えてみるとコイツは少し前に同じことをさらに1つ前の(一番右の)信号にしているはずです。つまり、コイツも「1つ前の信号を知っている」はずなのです。そこでこれを利用します。つまり・・・
(i)センサーは編成を検知すると自分の担当している信号のR現示メソッドを実行する。
(ii)R現示メソッドは信号を赤にすると同時に、1つ前の信号のY現示メソッドを実行する。
(iii)Y現示メソッドは信号を黄にすると同時に、1つ前の信号のG現示メソッドを実行する。
(iv)G現示メソッドが信号を青にする(これ以上は連鎖しない)。
という仕組みにします。
これにより「センサーが信号のR現示メソッドを実行する」「R現示メソッドが1つ前の信号のY現示メソッドを実行する」「(1つ前の信号の)Y現示メソッドが1つ前の(つまり2つ前の)信号のG現示メソッドを実行する」が連鎖発生し、一気に信号が切り替わります。
この方法の最大のメリットは、すべての信号、すべてのセンサーが基本的にはまったく同じスクリプトで良い、という点です。唯一異なるのは、それぞれのセンサーは
自分の担当している信号を、それぞれの信号は、
1つ前の信号を知っていなければならない点です。逆に言うと、これさえしっかり管理してやれば、何百と信号機があっても正しく動作する、ということです。そして、たとえば10個信号機が並んでいるとして「1番信号の1つ前は10番信号である」としてやれば、エンドレスループを閉じることが出来ます。
次回は、この理屈をスクリプト実装したサンプルコードを紹介しましょう。
質問やご要望があれば気軽にコメント欄に書き込んでください。特に「ここの意味がよくわからないのでもっと詳しく」という指摘は大歓迎です、なぜわかりにくいのかの理由が添えられていると特に。