列車を停車させた後6秒後に発車させる

今回は列車がセンサーを踏んだら停車し、6秒後に発車するスクリプトを作っていきます。


まず「停車しろ」と命令させるセンサーと制御する編成を用意して下さい

列車の速度を制御する(発車、停車、減速・・・etc)命令文は全部で2つしかありません。(細かく言うとまだありますが、今回は実用的でないので省きます)
一つは"何秒後に時速○○km/hにしろ"という命令文で、もう一つは"何mm進んだらに時速○○km/hにしろ"という命令文です。

今回は扱いが簡単な"何秒後に時速○○km/hにしろ"という命令文を使っていきます。

この"何秒後に時速○○km/hにしろ"というのはSetTimerVoltageという命令文です。
この命令文はありとあらゆる速度制御に使えます。

スクリプトマニュアルの"編成"の欄にあるこの命令文の内容を見てみると。
SetTimerVoltage 変数1 変数2
version 4.0.0.0

変数2の時間後に変数1で表される電圧まで変化させます。電圧は、0.0から1.0の値をとります。変数2は、ミリ秒で設定します。

とあります。
これを見る限り

変数1=電圧

変数2=時間(ミリ秒)

とりあえずこのことが言えますね。

時間(ミリ秒)とは?
ミリ秒とは1000ミリメートル=1メートルや1000ミリリットル=1リットルなどに用いられるように1000ミリ秒=1秒で表せられます。
つまり3秒を表したいときは3000ミリ秒になります。
よくワカラン人は書くときはとりあえず最後に0を3つ付け、読むときは0を3つ消せばOKです

電圧とは?
解説泣かせのI.MAGICめ!
ちょっとややこしくなりますので注意して読んで下さい。(ややこしいだけで難しくはないです)

VRMではビュワーにあるような○○km/hという速度の表し方の他に、スクリプトなどでよく使う電圧という速度の表し方があります。
つまり"速度"を2通りで表すことができるのです。

第3号収録の103系を例にとって考えてみます。(何色でも可)
コイツの最高速度は何も設定をいじっていなければ時速100km/hです。

このときの電圧と速度の関係は
MAXスピード=100km/h=電圧1.0
となります。

次に停車しているとき(0km/h)の電圧と速度の関係は
停車中=0km/h=電圧0.0
となります。

そして中くらいのスピードで走っているとき(50km/h)の電圧と速度の関係は
中くらいのスピード=50km/h=電圧0.5
となります。

そして中くらいのスピードより若干遅く走っているとき(30km/h)の電圧と速度の関係は
中くらいよりも若干遅いスピード=30km/h=電圧0.3
となります。

そして中くらいのスピードより若干速く走っているとき(80km/h)の電圧と速度の関係は
中くらいよりも若干速いスピード=80km/h=電圧0.8
となります。

と、このように○○km/hによって電圧も変化していきます。

正確に言うと

現在の電圧=現在速度÷最高速度

というふうになりますが、ぶっちゃけこんなことイチイチ考えるのはアホらしいので、簡単にまとめると。

電圧0.0=停車中
電圧0.3=中くらいよりも若干遅いスピード
電圧0.5=中くらいのスピード
電圧0.8=中くらいよりも若干速いスピード
電圧1.0=MAXスピード

こんな感じに見てもらえればOKです。

ちなみに、何故速度と電圧が関係しているのかというと、Nゲージを含む小型鉄道模型の殆どはレールから電気を得て走っています。
そしてその電圧を変化させて列車の速度を調節しているのです。
つまり直流12Vで最高速度になり0Vで列車は停止します。I.MAGICはどうもこれを意識しているみたいです。


ちょっと一息、トワイライト

さて、実際にSetTimerVoltageを使ってみます。

走ってきた列車が10秒後に停車するとしましょう。
すると命令文はこうなります。

SetTimerVoltage 0.0 10000

最初の0.0は電圧0.0つまり速度を0km/hにしろ(=停車しろ)となるわけです。

2つ目の10000は10000ミリ秒、これを普通の秒にするには1000で割ればいいので10000÷1000=10となり、10秒を表します。

これで10秒後に速度0km/hにしなさいと命令しているわけです。

具体的に例を挙げて言うと時速20km/hで走ってきた列車がこのセンサーを踏んだ場合、1秒間に2km/hずつ減速して10秒後に停車します。

ではさっそくこの命令を組み込みますが、これ1行だけ書いてもビュワー起動時に1回だけ”停車しろ”と命令するだけなのでBeginFunc-EndFuncで固めます。

この機能(BeginFunc-EndFunc=メゾット)の名前は”停車しろ”という内容ですのでstopとでもしておきます。

●編成のスクリプト
BeginFunc stop
SetTimerVoltage 0.0 10000
EndFunc

この命令を列車がセンサーを踏んづけたときに発動すればいいわけです。
というわけでセンサーのスクリプトを書いていきます。

先回のスクリプトが”列車がセンサーを踏んだときに警笛を鳴らす”であったので、これを改造すれば簡単にできそうです。

先回のスクリプト
Var evid
SetEventSensor snsev, evid

BeginFunc snsev

VarTrain ressya
GetSenseTrain ressya

call ressya keiteki

EndFunc


一部記述を変更しています。

つまり"列車がセンサーを踏んだときに警笛を鳴らす"を"列車がセンサーを踏んだときにstopを発動する"に変えてやればいいわけです。
するとスクリプトは次のようになります。

●センサーのスクリプト
Var evid
SetEventSensor snsev, evid

BeginFunc snsev

VarTrain ressya
GetSenseTrain ressya

call ressya stop

EndFunc


ressyaのkeitekiを発動しなさいという命令をressyaのstopを発動しなさいに変えるだけです。
この辺の細かいことは先回を参照して下さい。

それではこれを編成、センサーに書き込みます。
これでビュワーを起動し、列車を発車させセンサーを踏んづけると・・・


ちゃんとセンサーを踏んだら列車が停車しました。

さて、列車が停車した後は”6秒後に発車しろ”という命令文を書けばいいわけです。
はじめに”6秒後”という命令はとりあえず無視して”発車しろ”という命令文から書いていきます。 発車しろという命令文は、"何秒後に時速○○km/hにしろ"を使えばできそうです。
今回は"10秒後に中くらいよりも若干遅いスピードにしろ"という感じに進めていきます。

停車しろというスクリプト
BeginFunc stop
SetTimerVoltage 0.0 10000
EndFunc

をいじっていきます。
中くらいよりも若干遅いスピードにする命令文なのでメゾット名はlowとでもしておきます。

●編成のスクリプト
BeginFunc low
SetTimerVoltage 0.3 10000
EndFunc

こうすれば列車は10秒後に中くらいよりも若干遅いスピードになります

この機能も付け足せばいいので最終的に編成のスクリプトは以下のようになります。

停車、発車の2つの機能を持った編成のできあがり

 

つぎに、センサーのスクリプトを記述します。
さっきのセンサー
Var evid
SetEventSensor snsev, evid

BeginFunc snsev

VarTrain ressya
GetSenseTrain ressya

call ressya stop

EndFunc


これに、発車しろと付け加えたものは
Var evid
SetEventSensor snsev, evid

BeginFunc snsev

VarTrain ressya
GetSenseTrain ressya

call ressya stop
call ressya low

EndFunc


となりますが、これではセンサーを踏んだ瞬間に「停車しろ」と「発車しろ」の2つが発動され、編成は大変困ってしまいます。

そこで次に「6秒後に」という部分を作っていきます。
スクリプトマニュアルのイベントの欄にある”SetEventAfter”をクリックして下さい。
そこに次のようなことが書かれています。
SetEventAfter オブジェクト参照 メソッド イベントIDを受け取るグローバル変数 時間
version 4.0.0.2

この命令を実行した時点から指定時間後に発生するイベントです。ただし、鉄道模型シミュレーターは、実行しているパソコンの性能によってループ速度がことなるため、厳密に一定の時間で発生することはなく、指定時間を経過した時点でコールされるイベントとして扱ってください。

ビュワーは、データの準備が整いレイアウトが走行可能になった時点でスタートする内部時計をもっています。時計は、1/1000秒=1ミリ秒でカウントされます。このイベントで設定する時間は、ミリ秒単位です。

イベントを登録すると、イベントハンドラーを識別するためのイベントIDが変数に設定されます。


とまぁぱっと見ただけではかなり難しそうなな内容ですが、一つずつ整理していくと分かり易くなります。
1行目SetEventAfterの右に書かれている単語に注目して下さい。
つまり、これら”オブジェクト参照 メソッド イベントIDを受け取るグローバル変数 時間”の4つのものを用意すれば良いわけです。

まず、”イベントIDを受け取るグローバル変数”はとりあえず無視して下さい。
必要になってくるのは
オブジェクト参照、メソッド、時間
の3つです。

”時間”の部分は”何秒後に・・・”の部分なのでここはOKですね。
6秒後に発車なので6秒=6000ミリ秒より6000が入ります。

つぎに”オブジェクト参照、メソッド”の部分ですが、ここでcallの内容を思い出して下さい。
スクリプトマニュアルによると

call オブジェクト名またはオブジェクト変数 メソッド名

とあるようにほとんと同じ内容になっております。

つまり
callが必要とするもの
オブジェクト名またはオブジェクト変数、メソッド名

SetEventAfterが必要とするもの
オブジェクト参照、メソッド、時間

ここでオブジェクト名またはオブジェクト変数=オブジェクト参照、メソッド名=メソッドなので
(厳密な意味だと違うのか、それとも単にI.MAGICの表記揺れなのか・・・・!?)
もっと言い換えるなら

callが必要とするもの
オブジェクト参照、メソッド

SetEventAfterが必要とするもの
オブジェクト参照、メソッド、時間

とこのようにSetEventAfterが必要とするもの=callが必要とするもの+時間となっております。

つまり
call ressya low

これに”6秒後に”という部分を付け足すにはSetEventAfterを使って

SetEventAfter ressya low 6000

こうしてやれば”6秒後にressyaのlowという機能を発動しろ”となるわけです。
これが重要な基礎部分になります

さて、とりあえず無視したイベントIDを受け取るグローバル変数をこれに付け加えていきます。
”イベントIDを受け取るグローバル変数”と難しそうな内容ですが、要は”変数”なんです。
つまり、”変数”をぶち込めばいいわけです。

まずtievは変数だと宣言します(tiev:time eventの略記)
Var tiev
SetEventAfter ressya low 6000

んで、このtievをメゾット(=low)と時間(=6000)の間に入れてくれとマニュアルに書かれているので、最終的に
Var tiev
SetEventAfter ressya low tiev 6000

これでressyaのメゾットlowを6秒後に発動しろという命令文になるのです。

ちなみにこのtievはセンサーのときのやつとおなじくKillEvent系列で使うもので、とりあえずいる物と考えて下さい。

さてさて、これでセンサーのスクリプトはこのようになりました。

●センサーのスクリプト
Var evid
SetEventSensor snsev, evid

BeginFunc snsev

VarTrain ressya
GetSenseTrain ressya

call ressya stop

Var tiev
SetEventAfter ressya low tiev 6000

EndFunc


これをセンサーのスクリプトに書けば晴れて自動運転の完成・・・・・・・


列車が止まってくれません・・・

一旦は減速しはじめるのですが再び加速しだしてしまいます。
これは一体何故でしょうか。

ここでまず、停車するメゾットstopの中身を思い出して下さい。

BeginFunc stop
SetTimerVoltage 0.0 10000
EndFunc

これは”10秒後”に速度が0になる命令文でした。
んで、さっきは”6秒後”に加速しろという内容でした。

さっきセンサー書いたスクリプトはセンサーを踏んだ瞬間に”stop発動”と”6秒後にlow発動”が同時に命令されたわけです。
つまり停車しきる前に”加速しろ”という命令が発動したため再び加速してしまったのです。
なので6秒後に加速しろではなく停車しきるまでの時間10秒をたした”16秒後に加速しろ”としなければなりません。

というわけでセンサーのスクリプトは以下のようになります。
●センサーのスクリプト
Var evid
SetEventSensor snsev, evid

BeginFunc snsev

VarTrain ressya
GetSenseTrain ressya

call ressya stop

Var tiev
SetEventAfter ressya low tiev 16000

EndFunc



列車が停車した後発車しました。

これで自動運転ができました。
今回のスクリプトはこれにて完了です。お疲れ様でした。

次回は自動折り返し運転に挑戦します。
次回へ>>>>>>


前へ戻る

inserted by FC2 system