Multiple Junction Semaphores
Build #102 introduced some new features for signal route setting, including Route tags and route limits.
See Also Scripting.Signals
You can download the demo layout referred to in this article from http://www.rail3d.net/layouts/SemaphoreJunction.trp
Previously, a signal has only been able to display three routes: the main route and two diverging routes. In some situations we need to display more possible routes, we can now use the route tag markers and script features to build signals with more route possibilites.
The signal(s)
Included in the demo package (above) are several new signal models, two five arm junction signals (one with a distant arm) and some four arm junction signals. These models are also available from the rail3d model library.
To keep things simple, all the models use the same components, and the signal arms have the same id’s from left to right: The extreme left arm has id=1, the main arm has id=3 and the extreme right arm has id=5. This distant arm has id=10. Where there are only four arms, the arms have the same ids as they would in the five arm case, but with one of the arms missing. Thus the signal on the right of the above picture has arms with ids 2,3,4 and 5 (the left most arm, id 1 is missing).
It would be a good idea to use this numbering convention in all multiple arm semaphore signals.
By keeping the ids the same in each case, the same script throughout - at the moment I have put the script in the model file - but it would make sense to put it in a seperate file and reference it from each signal model.
The arms are in seperate files, and only differ by the id parameter. Since the arms are going to be controlled by the script, none of the arms actually need a state table.
Setting the routes.
The signal will be driven by the route tags.
Tags are applied to nodes from the Feature: New Route Tag menu item. Tags are free form text and may be applied to any node as required. In my example I have tagged the platforms “P1″, “P2″, “P3″, “P4″ and the freight loop “Loop”.
The advantage of this system is that we can apply meaningful names to the tags and by using the signal tag mapping map these to the signal arms.
Tag mapping
Signal tag mapping is a simple mapping function taking the applied route tags and converting them to values recognised by the script.
In my script I am going to look for routes “Left1″, “Left2″, “Main”, “Right1″ and “Right2″. “Left2″ and “Right2″ are the extreme outermost arms, “Left1″ and “Right1″ are the inner arms and “Main” the main central arm. So for each of the multiple arm junction signals (there are three used in the demo layout), I need to map the specific routes of the signal to the standard naming Left1/Left2 etc.
The route mapping can be found by right clicking the signal node and selecting the map from the signal sub-menu.
For the five arm junction at one end of the station (the one at the top of this page) the map needs to translate “P1″ to the rightmost arm “Right2″, “P2″ to the second right arm “Right1″, “P3″ to the main arm “Main” etc. So the mapping table looks like this:
P1>Right2
P2>Right1
P3>Main
P4>Left1
Loop>Left2
Thus if the route selected is into platform 2, the tag will be “P2″, and the mapping table will translate this to “Right1″. In my script I can use the GetRouteLabel()
function to retrieve this value and set the arms accordingly.
Because I have used the same arm ids for each signal the same script can apply to all of the signal variations:
OnSetLamps()
{
Signal.SetArm(1,0);
Signal.SetArm(2,0);
Signal.SetArm(3,0);
Signal.SetArm(4,0);
Signal.SetArm(5,0);
if(!Signal.IsOn())
{
string sTag=Signal.GetRouteLabel();
if(sTag=="Right2")
Signal.SetArm(5,-45);
else
{
if(sTag=="Right1")
Signal.SetArm(4,-45);
else
{
if(sTag=="Left1")
Signal.SetArm(2,-45);
else
{
if(sTag=="Left2")
Signal.SetArm(1,-45);
else
Signal.SetArm(3,-45); // Default is to set the main arm
}
}
}
}
}
I only need one function - the OnSetLamps()
function: this is called when the lamps (or in this case arms) need to be set.
Firstly, we set all the arms to the normal position (angle=0).
Next we test if the signal is on or not: if it is on we don’t need to do anything else.
If the signal is not on, then we can retrieve the route tag using the GetRouteLabel()
function and we test for each of the routes “Right2″, “Right1″ etc and set the appropriate arm if we find the right label.
There is no test for “main” as I want this to be the default, ie if none of the other routes are found then the main arm is cleared.
And that’s about it!
import