「センサー1個で」シリーズ第四弾として、速度変化にも対応した編成長測定スクリプトを作ろうとしたのですが、これに悪戦苦闘しました(>_<)
センサー1個で編成長を測定する方法はセンサーに編成の前方台車と最後方台車を感知させ、通過時間と速度でもって計算します。距離=時間×速度ですのでシンプルな考え方は2つの時間の差を取って速度をかける方法ですがこれは速度が一定でないと使い物になりません。一方もう一つは単位時間に進んだ距離を足していく方法です。これだと速度が途中で変化しても距離が取れます。以下は両方を算出して表示するスクリプトです。
#OBJID=38
import vrmapi
def vrmevent_38(obj,ev,param):
di = obj.GetDict()
if ev == 'init':
obj.SetSNSMode(2)
di['train'] = 0
di['timerEID'] = 0
di['length'] = 0
di['t1'] = 0
di['t2'] = 0
elif ev == 'broadcast':
dummy = 1
elif ev == 'timer':
if param['eventUID'] == 100:
di['length'] = di['length'] + (0.185185 * di['train'].GetSpeed())
elif ev == 'time':
dummy = 1
elif ev == 'after':
dummy = 1
elif ev == 'frame':
dummy = 1
elif ev == 'catch':
if param['tire'] == 1:
di['t1'] = vrmapi.LAYOUT().SYSTEM().GetSystemTime()
di['train'] = obj.GetTrain()
di['timerEID'] = obj.SetEventTimer(0.1,100)
elif param['tire'] == 2:
di['t2'] = vrmapi.LAYOUT().SYSTEM().GetSystemTime()
length = (di['t2'] - di['t1']) * 1.85185 * di['train'].GetSpeed()
obj.ResetEvent(di['timerEID'])
vrmapi.LOG(' timerlength=' + str(di['length']))
vrmapi.LOG(' simplelength=' + str(length))
di['length'] = 0
もし定速であれば両者は同じ距離となるのですが
これが上手く同じにならないという状況が発生しました(>_<)
上記のように0.1秒刻みで測定すると
大体Timer計測側が1割短くなります。
0.01秒刻みで測定すると
とんでもない誤差になります(^_^;)
で1秒刻みで測定すると
速度が速いとすっ飛ばしがあるので誤差が出ますが、非常にゆっくりと計測すると大体合った数値になります。
このことからSetEventTimerは秒で指定するのですが、0.1秒、0.01秒と細かいステップで刻むと誤差がデカくなるという結論に至りました。何故他ではミリ秒を採択しているのにココはミリ秒じゃないんでしょうかね(#`Д´)
ということで、1秒単位じゃ流石に使えないし、0.1秒で1割増してやる方法で大体合ってるという程度にしようかなと思っています。今回はNXの仕様の部分であまり上手くはいかなさそうです。