「ゆゆぽん☆退避/追越列車とか作っちゃうかMona-(11)−信号の灯火色を調べる(前編)」
VRMスクリプト禅問答
<<前回へ
前回までに実現した閉塞信号は、正しく区間閉塞動作をします。が、それは単に信号の色が変わるだけで、編成の運転に直接は影響しませんでした。
今回と次回に分けて、編成にこの信号を守らせる仕組みを解説します。つまり、運転の自動化です。なお、ゆゆぽん☆氏のリクエストは“手動で動かしても信号違反をしたら速度を下げる”でしたので、これに限定して解説します。
結論から参りましょう。
上図の“閉塞センサー”というのは、前回までに作った、閉塞信号と1つずつ対になっているセンサーのことです。編成に信号を守らせるには、これに加えて“換呼センサー”と便宜上呼ぶセンサーを、やはり閉塞信号に対して1つずつ配置します。
換呼センサーを配置する場所は、文字通り“信号を換呼すべき地点”です。つまり、そのセンサーを編成が通過する時点で、運転台から信号の灯火色がわかる場所であり、かつ、その信号を守るべく、信号までに減速なり停止なりをおこなうのに十分な距離のある場所でなくてはいけません。
では、どのようなスクリプトを書く必要があるか整理しましょう。VRMスクリプトに限らず、プログラミングというものは、キッカケになる原因とそれによって起こる結果が数珠繋ぎになったようなものです。そして、これをどのように書くべきかを考えるに際しては、モノにもよりますが、まずは達成されるべき結果を押さえ、それをするには何を原因に出来るか、というように、逆に考えていくと、さして難しい話ではありません。
まず第一に、起こるべき結果は
・編成はそのまま走行する。
・編成は減速する。
・編成は停車する。
のいずれか、です。そのまま走行する場合はさておき、編成を減速するなり停車するなりさせるには、つまり走行速度を変化させるには、編成スクリプトでSetVoltage命令(またはSetTimerVoltage命令)を使う必要があります。そのメソッドは、当然のことながら編成スクリプトに存在しなければなりません。
次に、起こるべき結果を3つ挙げましたが、これはもちろん信号の灯火色と対応しています。この3つのうちのどれか1つを選ぶワケですから、if系命令による条件判断をしなければなりません。
if系命令で条件判断をするというのは、具体的には ifeq {変数名}{値} によって、ある変数がある値になったかどうかをチェックし、一致すれば続く命令を実行する、ということに他なりません。
信号の灯火色を判定するのですから、{値}がSetSignal命令の赤=1/黄色=3/緑=6と対応することはわかりますね。問題となるのは{変数名}の方です。幸い、前回までに作った閉塞信号は、それぞれ信号オブジェクトのグローバル変数VarSignalColorにこの値が保存されるようになっていますから、これを付き合わせればいいことになります。が、この変数は信号オブジェクトに所属する変数ですから、編成スクリプトからこの値を調べるには、
ifeq {信号オブジェクト名}.VarSignalColor {値}
のように書く必要があります。
そして、レイアウト上には閉塞信号が複数ありますから、たとえばSIGNAL1からSIGNAL6まで6つの信号があるとして、
ifeq SIGNAL1.VarSignalColor 1
のようにしてしまうと、編成はどこを走行していても、常にSIGNAL1の灯火色を調べることになり、SIGNAL2〜6が無駄になります。
ということは、何らかの方法で、編成に対し“今、おまえが調べないといけない信号の名称はこれだよ”と教えてやる必要があります。VRM入道の熱心な読者であればピンと来るかと思いますが(来ない?・・・あ、そう)いわゆる
“動的オブジェクト参照”の出番です。
そして、動的オブジェクト参照において、参照すべきオブジェクト(この場合、進行方向にある閉塞信号の名称)を知っているのが換呼センサーであり、換呼センサーの編成検知がここまでに述べたすべての仕組みを実行する、という流れになります。
ここまでで、察しの良い人はスクリプトが書けるはずです。まだピンと来ないかたは次回をお楽しみに。