SSブログ
前の10件 | -

ポイントを含む区間のOBlock設定 [JMRI]

図のOB2のようにポイントを含む区間のOBlockは設定は通常のものと少し異なります。
030_blk_connection.001.png

ポイントが1つの場合、Pathが4つ(2ルート×往復)必要となり、さらに4つのPathそれぞれに対して「Turnouts」ボタンをクリックして表示されるTurnout Tableに、ポイント名と開通方向を設定します。
033_set_paths_turnout_table.png

Warrantで起点と終点を入力し、「Calculate」ボタンをクリックすると
034_def_warrant_root_location.png

正しくルートが表示されました。「Select」で確定します。
035_possible_root_table.png

後は今までと同様にスロットル操作を記録します。「Run」ボタンを押すと設定したルートに合わせてポイント切り替えも自動でやってくれるようになりました。

再びWarrant(2) [JMRI]

021_warrant_initial.png
Warrantウィンドウはルート設定とスロットル操作記録の表示が分離されました。

022_warrant_scripted.png
このバージョンでは2桁アドレスの車両を使ってスロットル操作の記録の記録ができませんでした(スロットルは表示されるものの操作できない)。4桁アドレスは大丈夫でした。
また、ブロックへの進入は記録されなくなってしまったようです。

023_warrant_fixed.png
あるブロックに入ったら車両を止める、などコマンドをブロックに進入したタイミングで実行したい場合、ブロック名を手動で書き換え、【Use block protection】を選択します。また2.7.9の時のWarrantが解放されない(idleに戻らない)問題は解消されているようです。

再びWarrant [JMRI]

JMRI2.9.6のリリースノートでWarrant周りの改善がアナウンスされていたので、再度触ってみました。まずぱっと見ではGUIが少し変わっている様子。

センサーテーブルでは一度に複数のセンサーを追加できるように。
011_multi_sensors_adding.png
こんな具合に。
012_multi_sensors_added.png

OBlocksウィンドウにはSignal Tableが追加されている。
013_oblock_initial.png
終端ブロックの処理の仕方が変わったようです。ブロックの終端側はPortalを設定する必要がなくなりました。(そのかわりPortalには接続するOBlockを必ず2つ設定する必要があるようです。)最初この変更に気づかず、以前の方法で設定したところ、Warrantでルート設定ができませんでした。
015_path_set.png

今日はここまで。次はWarrantウィンドウを見てみます。

Warrantで自動運転(3)−Warrantの設定 [JMRI]

最後にWarrantを設定します。ここで車両の走行ルートや動きを設定します。

Warrantを作成する


まず新しいwarrantを作成します。OBlocksの設定が終わっていればPanelウィンドウのメニューにWarrantsが追加されているはずなので、そこからCreate New Warrantを選択します。40_0_1.png
System NameとUser Name(任意)を入れてDoneを押します。40_01.png

ルートを作成する


最初に起点と終点のブロックを設定します。warrantウィンドウの右上に表示されているブロックから、起点となるブロックをOriginating LocationのBlock Nameにドラッグします。40_03_1.png
Path NameとExit Portal Nameが選択できるようになるので、車両の進行方向に応じて選択します。40_04_1.png
同様にDestination Locationに終点となるブロックをドラッグし、Path Nameを選択します。40_06_2.png
Calculateボタンをクリックすると、起点から終点までのブロックが計算されてTrain Routeに表示されます。40_08_1.png

車両の動きを記録する


次に車両を登録します。ロースターの登録があれば、Engine RosterにIDが表示されるので選択します。なければDCC Address欄に直接アドレスを入力することもできます。40_09_1.png
Learn ModeのStartボタンを押すと記録用のスロットルウィンドウが表示されます。(このときOriginating Locaitonの位置に車両があって、センサーがアクティブになっている必要があります)40_10_1.png
このスロットルを操作して車両を動かしていくと、経過時間、コマンドとその値、在線中のブロックがWarrantの「Throttle Commends」に逐次記録されていきます(画像は2.7.8のもので、2.7.9ではブロックに入るタイミングも記録されます。)40_11_1.pngStopボタンをクリックして記録を終了します。

warrantを保存する


まず「Save」ボタンをクリックしてwarrantを保存し、さらにメニューの「File」から「ストア」→「パネルと設定をファイルに保存」で保存します。

いよいよ自動制御


車両をOrigination Blockのブロックまで戻し、warrantウィンドウの「Run Train」→「Run」ボタンをクリックします。すると記録したのと同じ動きで車両が自動制御されました。
記録した通りに車両が動いてくれるのはちょっと感動的です。
ただし私の場合、制御が終わってもwarrantがidle状態に戻りませんでした。Loconet Simulatorではうまくいっているのですが。。。

Plone Siteがサイトルートのとき、Zopeのルートにアクセスする小ネタ [Zope/Plone]

tacacoさんよりZope/Ploneアドベントカレンダーのバトンが回ってきました。ここはほぼJMRIネタのみですが、他にブログがないのでこちらで。

さて、ApacheでサイトルートをPloneサイトとしているとき、コントロールパネルのProduct Managementでプロダクトがちゃんとインストールされてるかどうかチェックしたいとか、Placeless Translation Serviceでi18nがちゃんと効いているか確認したいとかいった場合に(また、i18nが効かないときにここの該当ファイルを消してからZopeを再起動するとうまく行くことがあります)、Zopeのルートフォルダにアクセスしたくなることがあります。

そんなときはアドレスバーの/manageの前に「aq_parent」を入れることで簡単に1階層上に行くことができます。

「/manage」zp1.png
「/aq_parent/manage」
zp2.png
ということでキャプチャでネタの薄さを取り繕いつつ、次のバトンは私のPython師匠のほかりさんにお願いします。

Warrantで自動運転(2)−OBlockの設定 [JMRI]

warrantを使った自動運転を試してみます。今回は図のような4ブロックの単線区間でA駅からB駅へ車両を動かしてみたいと思います。OBlocks_0_1.001.png最初に各ブロックの情報(ブロックの位置関係やセンサー/ポイントなどの情報)をJMRIに教えるために、Occupancy Blocks(OBlocks)を設定します。従来のBlockはLayoutEditorやスクリプトなどを使って設定する必要がありましたが、OBlocksは新たに追加されたOccupancy Blocksテーブルを使って、より簡単に設定することができるようになりました。
OBlocks_0_1.pngOblock, Portal, OPathの関係は図のような感じです。OBlockは従来のBlockと同様区間を表します。そしてPortalはOblock同士の接続点、OPathは各OBlock内での車両の進行方向を表します。

設定はPanel Proのツールバーの【ツール】→【Occupancy Blocks】で行います。39_oblock_0_1.png上がOBlockテーブル、下がPortalテーブルです。

まずOBlocksを設定します。テーブルにSystem Name, User Name, センサー名を入力していきます。(User Nameは必要に応じて入力します)System Name文頭の「OB」は入力しなくても勝手に入れてくれるみたいです。39_oblock_2_1.png
次にPortalsを入力します。39_portal_2_1.pngPortal Nameに任意の名前を、From Block NameとTo Block Nameに接続するブロック名を入力します。このときブロック名はOBlocks Tableからドラッグ&ドロップでコピーすることもできます。
Portalは起点・終点のブロックを含めて全てのブロックの両端に設定する必要があるようです。そのため両端のPortalはBlockの設定が1つしかできませんが、設定後頻繁に「Portal "##" needs have a Block specified on each side」と出るようになります。少し目障りですがそのままで問題はないようです。

最後に両端のブロックも含め各OBlockに対してOPathを設定します。Blocksテーブルの各ブロックの「Paths」ボタンをクリックするとPathテーブルが表示されます。39_path_0_1.png各進行方向について任意のPath NameとFrom Portal(入口)To Portal(出口)を入力します。またFrom/To PortalもPortal Tableからドラッグ&ドロップで入力することができます。
39_path_2_1.png
以上でOBlocks, Portals, OPathsの設定は完了です。

Warrantで自動運転 [JMRI]

最新のJMRI2.7.8から、Warrantという新機能が追加されています。この機能はGUIでルートや車両の動きが設定できるもので、これを使って車両の自動制御ができるそうです。
39_01.pngWarrantの設定には、まずOccupancy blockとそれに付随するPortals, Pathsを設定します。これらを設定するOccupancy Blocksウィンドウです。【ツール】→【テーブル】に追加されています。
39_02.pngルートや車両の動きを設定するWarrantウィンドウです。ここでスロットルの動きを記録できるようです。こちらはパネルウィンドウの【Warrants】→【Create New Warrant】で(2つ以上のOccupancy Blockが設定されていれば)表示されます。

今は使い方を勉強している最中ですが、GUIで設定できてしまうのはとても簡単そうですね。

ブロックトラッキング [JMRI]

JMRIでソフトウェアトラッキング(ブロックトラッキングというそうです)を実験しました。
ブロックトラッキングとはソフトウェア上でブロックとよばれる区間ごとに移動する車両の情報を追跡(移動先のブロックに情報を引き継ぐ、と言うほうが適切でしょうか)するものです。
ブロックトラッキングを使うためにはまずレイアウトエディタかスクリプトを使ってブロックを設定する必要がある(ブロックテーブルはブロックにPathとよばれる隣接ブロックの情報を設定できないため使えない)ようです。私はレイアウトエディタを使って設定しました。
37_01.png
まず【パネル】→【新規パネル】→【レイアウト編集】でレイアウトエディタを開きます。

37_03.png
【トラックノード】:【基準点】にチェックを入れて任意の場所で【Shift】+クリックしてブロック同士の接続点となる基準点を作成します。

37_04.png
次にブロックを作成します。【トラック】:【路線セグメント】にチェックを入れ、【ブロック】:【名称】に任意のブロック名(ユーザー名)を、【存在センサー】にあらかじめセンサーテーブル等で登録したセンサー名(こちらはシステム名)を入れてから基準点で【Shift】+クリックし、そのままもう一カ所の基準点までドラッグします。

すべてのブロックを作成後、【ツール】→【テーブル】→【ブロック】でブロックテーブルを開いてみます。レイアウトエディタで追加したブロックが表示されています。
37_05.png

37_6.png
ブロック1からブロック2へ車両が移動するとブロック2の【direction】に進行方向が表示されました。

車両が在線しているブロックの【value】に適当な文字を入れてみると、、、
37_07.png
37_08.png
車両の移動にあわせて移動しています。

ブロックのValueはメモリーに出力することができる(編集モードのパネルエディタでブロック中心の円のあたりで右クリック→編集...を選択し、【トラックセグメントを編集する】ウィンドウの【ブロック作成/編集】ボタンをクリック、【メモリー変数名】フィールドにメモリーのSystem Nameを入力)ので、Logixと組み合わせることで車両を識別して自動化(例えば車両ごと指定した方向にポイントを切り替えるとか、)できそうです。

祝!日本語化 [JMRI]

217.gif
JMRIバージョン2.7.4から表示言語に日本語が追加されました。今まで英語表示である上に日本語の情報も少なく若干敷居の高いイメージがあったのですが、これで一気に導入しやすくなったのではないでしょうか。最近メーリングリストも立ち上がり(http://www.freeml.com/jjmri)JMRI界隈はにわかに盛り上がりつつあるように感じます。
また、私自身もこの日本語化を機に最新版をインストールしてみました。今まで使っていたバージョン(2.0)から1年半ほどの期間でずいぶんと開発が進んでいて、様々な機能が追加されています。興味のあるところではまだドキュメントを読み進めている最中なのですが、どうやらデフォルト機能の組み合わせだけでソフトウェアトラッキングまでできそうな様子です。

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を実行するとスケジュール運転を開始します。


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

前の10件 | -

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