keimei main -> キハポスト@VRM -> VRM4スクリプト -> VRM4スクリプト〜ポイント制御応用編

VRM4スクリプト(4)〜ポイント制御応用編

この文章を書いた時点でのVRM4のバージョンは「4.0.0.4」です。これ以前のバージョンではうまく動作しません。また、今後のバージョンアップによって仕様が変更される可能性もあります。

基礎編が十分に理解できれば、スクリプトについては、ほぼ習得したと言ってもいいでしょう。あとは、その応用だけです。今回はもう少し実用的な制御に挑戦します。

前回の実験用のレイアウトをそのまま使います。基礎編ではポイントを人間がキーを押すことによって切り替えましたが、今回は、編成によって「自動で」切り替わるようにします。レイアウトの左側からやってきた列車がポイントで上下に振り分けられる、という仕様にしましょう。VRM3では、列車番号とポイントの設定で行っていたことですが、VRM4では自分でスクリプトを書かないといけないのですね。

レイアウトの左側に2つの編成:「TE253」と「TE751」を用意します。この名前は編成エディタで設定しますが、前回ポイントに名前を付けたのと同じく、名前を変更するなら、この準備段階で行ってください。ここでは、形式名にTrainを表すTを付けてみました。

そして、この編成を自動検出するために「センサ」を設置します。マニュアルによると、センサはポイントの手前「十分」な距離をとって設置せよ、とありますが、具体的にどのくらいの距離におけばいいのか分からなかったので、上図の位置に置いてみました。列車のスピードとポイント-センサ間の通過時間の兼ね合いが問題だと思われます。

●結果=ポイントの設定●

基礎編で書いたプログラムがそのまま使えます。というか、ここでも使えるようにするために、基礎編でそういう仕様にした訳ですね。ブラックボックスという訳ですから、誰から呼び出されてもきちんと動作してくれる筈です。というわけで、ポイント側はいじる必要はありません、やったね。

●原因=センサの設定●

今回、原因(トリガー)となる要素はセンサですね。センサ上を通過する編成を検出する「GetSenseTrain」という命令がありますので、これを用います。ここでお断りなのですが、本来、センサからポイントの切り替えメソッドを直接呼び出せばいいのですが、それではなぜかうまくいきませんでした(注1)ので、センサから編成を呼び出して、編成にあるスクリプトでポイント切り替え命令を呼び出すという二段構えになってしまいました。まあ、センサから見ると、自分の上を通過した編成が何かを教えてやるから、あとは、その編成で行きたい方向を設定しろ、って感じで、却って自然な処理かもしれません。

注1:if文でTrain変数同士が比較できない。

まず、センサを右クリックして、「センサ設定」の「スクリプトエディター」に以下を入力します。なお、名称は「SNS00」に変更し、認識距離はデフォルトのままです。

//Sensor00

Var snsID0
VarTrain SnsTrain

SetEventSensor kenshutu snsID0

BeginFunc kenshutu
  GetSenseTrain SnsTrain
  call SnsTrain kirikae
EndFunc

基本的には、SetEventKeyと同じですので、命令の詳しい働きはマニュアルを見てください。 SetEventSensor命令で「kenshutu」メソッドを呼び出すことを設定します。「kenshutu」メソッドで、GetSenseTrainでセンサ上を通過した編成名を文字通りゲットして、callでその編成を呼び出しています。kirikaeは、編成のスクリプトにこれからプログラミングするメソッドの名前です。

//Train E253
BeginFunc kirikae
  call "PNT01" P_ue
EndFunc
//Train E751
BeginFunc kirikae
  call "PNT01" P_sita
EndFunc

編成は2つありますので、それぞれの編成エディタの「スクリプトエディター」に上記を入力します。TE253は上方向に行きたいので、「PNT01」の「P_ue」メソッドを呼び出します。TE751は「P_sita」です。ここで、両方も同じ「kirikae」という名前になっていますが、これは「TE253」の「kirikae」か、「TE751」の「kirikae」かで区別できます。逆に同じ名前にしておかないと、さっきのセンサスクリプトで呼び出す時に話がややこしくなってしまいます。

これで、編成の上下振り分けが出来ました。取り敢えずビューアーで動作確認してみましょう。

●応用の応用●

ついでにもう一頑張りしてみましょう。左から来た列車が見事、上下に振り分けられましたが、これを再び左側に帰らせてあげます。ここで、問題となるのは、VRM3とVRM4でのポイントの仕様の違いです。VRM3では、ポイントの背向(レイアウト右方向)から列車が侵入する場合、たとえ、そちら方向にポイントが開いていなくても強制的に通過することが出来ました。しかし、VRM4ではこれが出来ません。列車のいる方向にポイントが開いていないと手前で強制停止してしまいます。つまり、現実の鉄道と同じように、列車に合せてポイントをいちいち切り替えてあげないといけないのです(スプリングポイントという訳にもいきません)。これは面倒くさいので、ぜひスクリプトで自動切り替えしたいところです。

実は、これは大して難しくありません。ポイントの右側にセンサを2つ追加します。このセンサもポイントから十分距離をとって設置します(最初のレイアウト図参照)。こちらは、編成が何であるかを検出する必要もなく、センサ上に列車が乗っかったら、自分の方向にポイントを切り替えるだけです。

//Sensor01
Var snsID1
SetEventSensor ken1 snsID1

BeginFunc ken1
  call "PNT01" P_ue
EndFunc
//Sensor02
Var snsID2
SetEventSensor ken2 snsID2

BeginFunc ken2
  call "PNT01" P_sita
EndFunc

ここまで出来たら、もう天下無敵ですね。2本の列車を右へ左へ自由に走らせることができます。そう、単線での列車交換や、駅で急行が各停を追い抜く、なんてことが自動で出来るのです。という訳で宿題(?)にしますので、そういったレイアウトをぜひご自分で作ってみてください。

厳密にやるなら、フェイルセーフとかフールプルーフとかセマフォとかを考えないといけません。マニュアルには、列車通過中にポイントを切り替えないで下さいとあります。この例だと、TE751がポイントを通過中に、TE253が右からやってきてセンサ02に達するとポイントが上方向に切り替わってしまって、TE751は脱線転覆大惨事ってことになります(実際にはそんな酷いことにはならないようですが)。

しかし、そういうフールプルーフのルーチンを追加すると、プログラムが複雑かつ大きくなりセンサの追加も必要かもしれません。VRM4ではスクリプトの処理がかなり負担になり、マシンパワーによってはうまく実行できない可能性もあるとありますので、スクリプトは必要最小限の簡単なものにして、安全管理は人間が行った方がいいかもしれません。(将来、信号機などが追加されれば、もう少し面白い事ができるかも。)

では、ここまで読んで下さった人の為に、ここで使ったレイアウトをプレゼントしましょう。もちろん、スクリプトも記述済みです。 スクリプトの動作確認はしていますが、保証はしません。というか、あくまで参考程度に留めて、自分流のスクリプトに挑戦されることをお薦めします。

ダウンロード(point1.lzh)