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.

2018-12-08 - Conductor 2: Route Sequences

Category Rtac

Above I mentioned the key features for Conductor 2 would be profiles, configuration language, and routes.

I should elaborate a bit on this, especially the routes.

First the profiles: A profile is simple a DCC address number and a map of variables values. Routes will defined variables for, e.g., timers and speeds. The profile will fill in these values to adjust them to a specific train.

Profiles should be dedicated to a specific route. For example: PA route, with 2 profiles (freight, amtrak, UP, etc.) There should probably be some kind of sanity check to ensure that a route with no profile cannot be started, and also that all the variables have a value.

To get started, profiles will be assigned via the script (“PA.profile = Amtrak506”). Later I’d like this to be on the tablet so that they can be changed, with the latest value persisted on disk.

Now let’s look at routes.

A route is a sequence of blocks and turnouts used by a specific engine/train, with events defined on how to move the train from one place to another.

There are 3 goals for routes:

  • Provide a way to do interlocking (globally or locally).
  • Define the sequence of movements required by the train.
  • Provide sanity checks on the train’s whereabout.

Let’s look at these individually.

Interlocking can be either global or local. A global interlock would validate that only one active route can use a given block / turnout at all times. A good example is the current passenger alternance animation: either the full Amtrak runs or the freight runs (on a limited portion of the same route). In the new system these would be defined as 2 separate routes, unaware of each other. One route could not be started if the other one is active as it would use at least one of the same blocks or turnouts.

Global interlocking is in a way a reservation mode. The whole set of blocks / turnouts are reserved for a particular route and cannot be changed by any other route.

The reservation is dynamic; it starts when the route becomes active, and ends when the route is no longer active. It’s important for the route events to determine when the route stops being active (e.g. when the train returned at the station and is known to be there). This way in case of error (e.g. derailment), the route stays active, and prevents further reservation.

Local interlocking would be a “smarter” way to do interlocking with a finer granularity. This is the simple ABS scheme used by railroads: check 2 blocks ahead in the desired sequence direction, and only advance into the next block if it is guaranteed to be free. There are some limitations:

  • In our case, we would need to enforce 2 free blocks ahead. Since typically we detect only a train engine, we do not know if the rest of the train overlaps the next or previous block; for automation purposes we can safely assume each train fits on a block.
  • The scheme does not work in a “dual shuttle” configuration, as is the case with the current Amtrak vs Freight automations, as it can create deadlocks if 2 trains are moving towards each other. They would typically stop 2 block away from each other, locked in their opposite direction and unable to resolve the deadlock. It’s possible to identify this and solve it but it’s extra finicky work which is a tad overkill here.

The ABS kind of interlock works well for trains running in a loop in the same direction. It means a faster train can follow a slower train and stop automatically when needed.

This kind of interlock works well when 2 routes need to cross through the same interchange block or turnout as this is a shared resource that is simply reserved by the first route to acquire the resource.

Global interlocking can be somewhat too overwhelming, reserving too many blocks in advance. There are 2 ways to work around this:

  • By using some kind of window, e.g. lock 2-3 resources around the current train position. That can result in the kind of contention explained in a dual shuttle setup.
  • By reserving all resources ahead of the train and progressively freeing resources behind the train if they are not used again in the route sequence.
  • By defining reservation sub-sequences (in essence “sub-routes” within the route).

The last one would work well in the Amtrak case:

  • Global reservation would lock all from B503b-B503a and B321 up to B370.
  • 2 sub-routes could be defined with T330 as the junction: B503b-B321 and B330-B370.

In that example, a free running train would be allocated a route of B320-B370, overlapping the second sub-route of the Amtrak, whereas the Freight would be allocated a route of B311-B321, overlapping the first sub-route.

Freeing global interlocked resources automatically behind a train would also work. In this case the Amtrak route would be defined as B503b-B321 | B330-B370 | B370-B330 | B321-B503b. Note that this is an ordered sequence, no longer just a set. When the train is going up, we can detect that it is going to use the same blocks again so they cannot be freed. When the train is going down, we can detect that the blocks are not used again and can be freed on the fly. This would allow a secondary train with a B320-B370 reservation to go through as soon as B330 + 1 block is freed.

In the case of sub-routes or automatic freeing, it’s important to realize we still want that extra one block of padding as we do not really control the location of the end of the train. In this regard, since we have fixed equipment for the automation, we could install wheel resistors. However we have no such requirement for regular non-automated trains.

Next we’ll discuss how to use a route sequence programmatically, events for it, and such.


 Generated on 2024-04-22 by Rig4j 0.1-Exp-e7e2d73