Model Train-related Notes Blog -- these are personal notes and musings on the subject of model train control, automation, electronics, or whatever I find interesting. I also have more posts in a blog dedicated to the maintenance of the Randall Museum Model Railroad.

2017-01-16 - Conductor Automation Software

Category Rtac

Conductor” is the name of the software that controls the automation on the Randall Museum Model Railroad. It’s written in Java and integrates into JMRI. The other part is the Android tablet display software. Combined, both create “RTAC” -- the Randall Train Automation Controller. I started the conductor project in mid-2016 and by the end of 2016 I had a working version deployed on the layout at the museum. Immediately after that, I started thinking about extending it already :-)

The RTAC / Conductor source can be found in this Bitbucket repo https://bitbucket.org/model-railroad/conductor with a GNU GPL v3 license.

--

Here's a rethink of the automation software.

Right now I have JMRI for sensor management and DCC throttles. Conductor acts as a plug-in that drives the automation purely on sensor+timer event based script.

One useful thing in RocRail is the notion of routes, which JMRI has too of course (but annoyingly complex to set up).

The idea is to describe the layout using a chain of blocks with turnouts on or between them.

The timer/sensor script remains the same, but the goal is to have the software know which engine number is on which block. This in turn will drive the display and make it possible to lock routes.

Example, for the Passenger and Branchline automation:

BL1 ⇒ BL2 [T324] ⇒ void ⇒ BL3 ⇒ BL4

B503b ⇒ B503a ⇒ [T504] ⇒ [T321] B321 [T322] [T326] ⇒ [T330] B330 ⇒ void ⇒ B360 ⇒ B370

[T322] ⇒ B322 [T324] ⇒ [T326]

B310 ⇒ [T320] B320 ⇒ [T330]

B311 [T311] ⇒ [T321]

One difficulty is to express the relation of turnouts and blocks. There are also some unknown blocks where the software has no visibility but can easily assume that the train is located there.

That's one thing that determinist software like JMRI or RocRail do not handle.

E.g. in the case of the passenger automation, right now the blocks B321 and B330 up to B350 are not detected, but once the automation has started we know that the train must be there somewhere till it reaches B360, at which point the train info can be transferred to B360.

Note that a train can be on two blocks at the same time if they are continuous. That's the case when crossing from one block to the next one, especially if there are lighted cars or push-pull engines.

What is this information good for?

First for display. One goal is to have a summary track representation on the tablet with the blocks and the train number should show up on that where the software think it is. That means if something is wrong, the viewer can notice it and act on it.

Second for emergency handling. When doing the Passenger automation, we expect the train leaving B503a to reach B330 in a specific amount of time, namely 50 seconds till we reduce the speed past the Sonora turnout. We can add some margin to it, e.g. say 60 seconds max. If we have not detected B330 turning on within 60 seconds, we can assume something is wrong.

Third for turnout protection. It would be ideal if the automation could prevent from aligning turnouts if their block or the next one is occupied. This would be only for automated routes. Manual operators could always realign turnouts.

Finally for automating train speed under automatic block control. E.g. if the passenger automation is returning to the station, the following would happen:

  • T330 (Sonora) needs to be aligned. However this can only be done if all of B330, B320 and B321 are not occupied.
  • If B330 is occupied or if T330 cannot be aligned, the train needs to stop before the occupied block. Luckily for us, blocks are long enough that if we stop a train just when it enters a block, it will stay in that block and not stop in the next one. Otherwise we would have to program it to stop 2 blocks before. Also in this example, "before B330" going down is that "void" block but that's OK since we know that a train that passes B360 going enters that void block.
  • Finally, when whatever is occupying block B330, B320  and B321 leaves and the 3 blocks are free, the automation can throw the T330 turnout and resume the train.

Knowing in which block the train is, it would not block itself from throwing a turnout. E.g. if the train is itself in B330, that should not prevent it from throwing T330.

One issue we have is that we have no real feedback on turnout position. We can only query JMRI to tell us what the turnout is likely to be at, unless an operator has manually changed it. JMRI has no knowledge of that. The NCE PH Pro command station does but I don't believe JMRI is querying that. (Update 2018-05-10: JMRI has a monitoring more specific to pull turnout state data from the NCE PH Pro. It's not fast and slows down the CS reportedly.)

Once we have all this, we could rewrite the automation in a completely different way. For example for the passenger automation, the events could be purely block based and their order forming a route, e.g. something like this:

State Station:

B503b & Stopped & Start ⇒ Align T504, T322, T321; State Up; Speed Fwd Normal; Expect B321 in 10s.

State Up:

B321 ⇒ Align T322, T326, T330; After 40s do F3; Expect B330 in 50s.

B330 ⇒ Speed Fwd Restricted; Expect void1

Void1 ⇒ Align T370; Expect B360; After 10s do Speed Fwd Normal; After 15s do Horn

B360 ⇒ Expect B370 in 10s

B370 ⇒ After 8s do Speed Fwd Restricted; After 11s do Stop; After 15s do State Down.

State Down:

B370 ⇒ Speed Rev Restricted; Expect B360

Etc.

So this describes the movement from block A to block B. Technically we don't even need to indicate which turnouts to throw, the software can compute that using the map described earlier.

One tricky part is that block "void1" since switching to that state relies on the block B330 going off instead of another sensor going on. Also calling it a "virtual block" instead of "void" may be better.

As far as the block graph is concerned, a train is thus located on a specific block (even if virtual) and with a specific direction within the block graph.

An end-goal of that is to allow "free" automated running. E.g. another train waiting at station track 2 could leave after the PA train once the blocks are free, or one could circle on the mainline and wait for the PA one when needed. For this we need to extend the concept of occupied block to occupied region -- e.g. B330 up to B370 is one region and can only have a single train at a time.


 Generated on 2024-12-21 by Rig4j 0.1-Exp-f2c0035