JMRIでスケジュール運転(1) [JMRI]
BDL168/RX4を使ったスケジュール運転のスクリプトを作ってみました。
センサーとレポーターの反応をトリガーに、トランスポンディングで取得した車両アドレスに対応する車両制御スクリプトを起動する方法で自動制御します。
setup.py
setup.pyはセンサー/レポーターの設定とスケジュールファイルの登録を行います。locoaddressの()中に制御対象の(スケジュールを作成した)車両のアドレスを記述し、またsectionaddressの()中にスケジュールを実行するセンサーとレポーターのアドレスを
('センサーのアドレス(ただしレポーターの場合は'0')','所属するzone(レポーター)のアドレス')
という風に記述します。
この例ではアドレス1のBDL168のzoneA(レポーターアドレス1)に所属するアドレス2,3,4のセンサーとアドレス1のレポーター反応自体に対してスケジュールを実行しますが、ここでセンサー1を使用しないのはzoneに進入した際の最初のセンサー反応よりレポーターの反応が遅くセンサー1の反応時には車両のアドレスがとれないので、レポーター反応時に最初のスケジュールを実行するためです。
よってこのスクリプトは現在センサー1→センサー4の片方向運転用となり、逆方向の場合はセンサー4のかわりにレポーターを使います。
schedule64.py
スケジュールファイルは上のように「schedule + 車両アドレス + .py」のファイル名にします。このファイルはスケジュール運転する車両の数(setup.pyのlocoaddressに記述したアドレスの数)だけ必要です。また任意のアドレスに対して実行するためには各行のschedule64、Schedule64を「schedule+アドレス」、「Schedule+アドレス」に変更し、また最終行を「schedules['アドレス'] = schedule + アドレス」に変更します。なお、このサンプルでは、レポーター1反応時にアドレス64の車両を0.1まで減速し、センサー4反応時にさらに減速→停止、3秒停車ののちスピード0.3まで加速します。
以上のファイルを「jython」フォルダ内に入れ、PanelPro(またはDecorderPro)の「Panels」→「Run script...」よりsetup.pyを実行するとスケジュール運転を開始します。
現状では瞬停対策(同じスケジュールが再度実行されてしまう)や、スケジュールが終了しないうちに次のスケジュールが実行されてしまうことがあるなど、まだまだ改良の余地がありそうです。
センサーとレポーターの反応をトリガーに、トランスポンディングで取得した車両アドレスに対応する車両制御スクリプトを起動する方法で自動制御します。
setup.py
schedules = sections = {} sep = java.io.File.separator #スケジュール制御する車両アドレス locoaddress = ('64',) #センサー/レポーター(トランスポンダ)のアドレス sectionaddress =(('0','1'),('2','1'),('3','1'),('4','1')) ### 車両アドレス設定/スケジュールファイル登録 ### class LoadThrottle(jmri.jmrit.automat.AbstractAutomaton) : def init(self): global throttle throttle = {} for address in locoaddress: isLong = address > 127 throttle[address] = self.getThrottle(int(address), isLong)ます if throttle[address] == None: print "Couldn't assign throttle" execfile("jython" + sep + "schedule" + address + ".py") return def handle(self): return False LoadThrottle().start() ### レポーター/センサー設定 ### # レポーターリスナー class LrListener(java.beans.PropertyChangeListener): def __init__(self, address): self.address = address def propertyChange(self, event): value = event.newValue.split(" ") if value[1] == 'enter': schedules[value[0]][self.address].start() # センサーリスナー class LsListener(java.beans.PropertyChangeListener): def __init__(self, address, lraddress): self.address = address self.lraddress = lraddress def propertyChange(self, event): if event.newValue == 2: lrstat = reporters.provideReporter(self.lraddress).getState() schedules[str(lrstat)][self.address].start() # レポーター/センサーオブジェクトを生成 for address in sectionaddress: if address[0] == '0': lrlistener = LrListener(address[1]) sections[address[1]] = reporters.provideReporter(address[1]) sections[address[1]].addPropertyChangeListener(lrlistener) else: lslistener = LsListener(address[0],address[1]) sections[address[0]] = sensors.provideSensor(address[0]) sections[address[0]].addPropertyChangeListener(lslistener)
setup.pyはセンサー/レポーターの設定とスケジュールファイルの登録を行います。locoaddressの()中に制御対象の(スケジュールを作成した)車両のアドレスを記述し、またsectionaddressの()中にスケジュールを実行するセンサーとレポーターのアドレスを
('センサーのアドレス(ただしレポーターの場合は'0')','所属するzone(レポーター)のアドレス')
という風に記述します。
この例ではアドレス1のBDL168のzoneA(レポーターアドレス1)に所属するアドレス2,3,4のセンサーとアドレス1のレポーター反応自体に対してスケジュールを実行しますが、ここでセンサー1を使用しないのはzoneに進入した際の最初のセンサー反応よりレポーターの反応が遅くセンサー1の反応時には車両のアドレスがとれないので、レポーター反応時に最初のスケジュールを実行するためです。
よってこのスクリプトは現在センサー1→センサー4の片方向運転用となり、逆方向の場合はセンサー4のかわりにレポーターを使います。
schedule64.py
schedule64 = {} #アドレス64の車両がレポーター1に差し掛かったときに実行されるスケジュール class Schedule64_1(jmri.jmrit.automat.AbstractAutomaton): def init(self): return def handle(self): currentSpeed = throttle["64"].getSpeedSetting() while currentSpeed > .10: currentSpeed -= .02 if currentSpeed < .10: currentSpeed = .10 throttle["64"].speedSetting = currentSpeed self.waitMsec(250) schedule64['1'] = Schedule64_1() #アドレス64の車両がセンサー2に差し掛かったときに実行されるスケジュール class Schedule64_2(jmri.jmrit.automat.AbstractAutomaton): def init(self): return def handle(self): return False schedule64['2'] = Schedule64_2() #アドレス64の車両がセンサー3に差し掛かったときに実行されるスケジュール class Schedule64_3(jmri.jmrit.automat.AbstractAutomaton): def init(self): return def handle(self): print 'sc64_3' return False schedule64['3'] = Schedule64_3() #アドレス64の車両がセンサー4に差し掛かったときに実行されるスケジュール class Schedule64_4(jmri.jmrit.automat.AbstractAutomaton): def init(self): return def handle(self): currentSpeed = throttle["64"].getSpeedSetting() while currentSpeed > .0: currentSpeed -= .02 if currentSpeed < .0: currentSpeed = .0 throttle["64"].speedSetting = currentSpeed self.waitMsec(250) self.waitMsec(3000) while currentSpeed < .30: currentSpeed += .02 if currentSpeed > .30: currentSpeed = .30 throttle["64"].speedSetting = currentSpeed self.waitMsec(250) schedule64['4'] = Schedule64_4() schedules['64'] = schedule64
スケジュールファイルは上のように「schedule + 車両アドレス + .py」のファイル名にします。このファイルはスケジュール運転する車両の数(setup.pyのlocoaddressに記述したアドレスの数)だけ必要です。また任意のアドレスに対して実行するためには各行のschedule64、Schedule64を「schedule+アドレス」、「Schedule+アドレス」に変更し、また最終行を「schedules['アドレス'] = schedule + アドレス」に変更します。なお、このサンプルでは、レポーター1反応時にアドレス64の車両を0.1まで減速し、センサー4反応時にさらに減速→停止、3秒停車ののちスピード0.3まで加速します。
以上のファイルを「jython」フォルダ内に入れ、PanelPro(またはDecorderPro)の「Panels」→「Run script...」よりsetup.pyを実行するとスケジュール運転を開始します。
現状では瞬停対策(同じスケジュールが再度実行されてしまう)や、スケジュールが終了しないうちに次のスケジュールが実行されてしまうことがあるなど、まだまだ改良の余地がありそうです。
コメント 0