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.
2024-12-25 - Conductor 2: Activated Block Handling
Category Rtac
These two commits address the recent issue of spurious block activation breaking the automation.
Recently a new sensor-related issue arose with block B360. Last time, it was because some track was occupied somewhere else on the layout. This time, the issue is different: the automated passenger train is going to Summit (the top of the mountain), where it stops and returns back down. It goes through these blocks:
B370 (Summit) → B360 → B340 → B330 → B321 → B311 (Station)
The new problem with block B360: after the train has left block B360 and entered block B340, block B360 should register as “empty”. After all, the train isn’t on the block anymore. But from time to time -- very rarely -- the block will keep staying on, sometimes as long as a minute and half! Now two adjacent blocks can be active at the same time -- that happens when a train crosses a block boundary. But once the train reaches block B330, it is an error for block B360 to still be active.
When that happens, the automation enters the error mode, stops the train, and tries to do a recovery. Interestingly as soon as the train stops, that “frees” block B360 too. Thus the recovery mechanism notices that only block B330 is active, deduces the train must be there, and brings it back home. From a viewer point of view, that all happens almost instantly so it’s hard to notice visually that something went wrong. But from a software perspective, it was all wrong for sure.
The “fix” is an idea I had a while ago: right now the automation checks all the blocks on the route. If any block suddenly happens to activate anywhere on the route, that’s a sign something unexpected happens, and we better stop the automation. However, in this case, we don’t need to care about block B360 because it is behind the train. The change I made is to only look at the blocks “in front” of the train. If any of these suddenly become unexpectedly occupied, we better stop right away. If anything happens to blocks that we will not reach, then it’s fine and we can ignore them during this run -- if they are still active the next time the automation tries to start, then that will be a problem and the route won’t get activated, but it doesn’t need to stop the current train.
So that’s what the first commit does -- it computes only the forward-reachable nodes in the route’s node graph. It’s just your basic directed graph traversal algorithm, nothing fancy. The change is minimal, and the bulk of the commit is just a bunch of validation unit tests. The second commit is even smaller, and just checks the forward-reachable blocks instead of all the route blocks.
Once tested “in real life”, this behaved as expected.
The last piece of the puzzle isn’t software -- it’s to try to understand why that block B360 suddenly behaves like this -- why does it register as occupied (meaning the sensor detects current going through the power lead) when the train is two blocks away?
I just ordered and received two new IAScaled CKT-BD1 sensors. One will be used to replace the current NCE BD20 to see if it changes the behavior.
The other realization is that a lot of mountain track is just weird -- you might have noticed there’s no “B350” in the block list above. There is a section of track between 340 and 350, but despite my early attempts the track power lead for 350 never activated. Instead, the trains are detected on 340. I know that blocks B340 and B350 have been soldered together a while ago, because I previously fixed such a broken joint. I suspect originally B350 had its own power lead and maybe it broke or something like that and a quick repair was done by bridging it with the nearby B340 block. Now that I have more hands-on background on this layout, maybe it’s time I revisit this, yet it’s still a low-priority item as it works “good enough.”