SSブログ

JMRIでスケジュール運転(1) [JMRI]

BDL168/RX4を使ったスケジュール運転のスクリプトを作ってみました。
センサーとレポーターの反応をトリガーに、トランスポンディングで取得した車両アドレスに対応する車両制御スクリプトを起動する方法で自動制御します。

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(レポーター)のアドレス')
という風に記述します。
pic1.gif
この例ではアドレス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を実行するとスケジュール運転を開始します。


現状では瞬停対策(同じスケジュールが再度実行されてしまう)や、スケジュールが終了しないうちに次のスケジュールが実行されてしまうことがあるなど、まだまだ改良の余地がありそうです。

nice!(0)  コメント(0)  トラックバック(0) 
共通テーマ:趣味・カルチャー

nice! 0

コメント 0

コメントを書く

お名前:
URL:
コメント:
画像認証:
下の画像に表示されている文字を入力してください。

トラックバック 0

この広告は前回の更新から一定期間経過したブログに表示されています。更新すると自動で解除されます。