Rail3D*


 

Express Selection



Introduction

On this page…

  1. 1 Background
  2. 2 Setup of solution
    1. 2.1 Diagram
    2. 2.2 Overview
  3. 3 The script

Signalling at stations is often set up so that nearby level crossings aren’t kept closed to road traffic for an unnecessarily long amount of time while trains call at the station. However, the same signalling must also ensure that express trains aren’t held at signals while the crossing booms/gates are being closed.

In these cases, the signalling system is designed to remember if a train is “Express” or “Stopping”. This article demonstrates one way to script this.

1 Background

Stations often have level crossings (a.k.a. public crossing roads, or pcrs) adjacent to them, but trains stopping at the station can cause the level crossing gates or booms to be closed for an unnecessarily long time. To prevent this, signals protecting the crossing are often configured to remain at stop until approaching trains have actually arrived at the station, at which time the crossing is activated. Once the crossing is activated and the booms or gates are closed, the signal can be cleared.

Such a setup might look like this (only one line is shown):

This works well for stopping trains, however express trains not intending to stop at the station would be brought almost to a stand at the station while the booms/gates closed and the signal cleared. To avoid this, the crossing is activated earlier if the train is known to be express. While this can be achieved already by having express trains trigger a release for the signal earlier than stopping trains, some problems can arise:

  • If the “Express” release and the “Stopping” release are both in the same signal section immediately in rear of the level crossing signal, express trains will still pass the signal in rear of the station at caution. This may be undesirable, as express trains will still have to slow down.
  • You can shift the “Express” release further in advance of the level crossing, so that there are at least two signals in between it and the pcr (three signals for 4-position/4-aspect signalling). This can help ensure that express trains don’t have to pass signals at anything other than an all clear aspect. However, an express train can trigger the release for the pcr as intended, but a stopping train might be in front and have the crossing released for it by the express train behind, causing the booms/gates to close earlier than necessary.

This solution could also be adapted for the approach release of any other signals on your layout.

2 Setup of solution

2.1 Diagram

For this scripted solution, I’ll be referring to the following diagram:

Some extra things to note:

  • I have shown just one line, but in reality the other line for the other direction would be there also.
  • Trains travel from left to right.
  • There are three labelled Location markers, shown with blue dots on the track.
  • Signals 14 and 18 protect the two crossings (pcr1 and pcr2), and have their Controlled and Hold flags set. These signals are also linked to releases set for all trains, as shown by the dotted lines connected to light blue dots on the track.
  • All other signals are automatic.

2.2 Overview

Here is a brief description of what we’re going to do. Using Rail 3D’s document scripts, we’re going to maintain a “queue” (or a “buffer”) of trains “registered” to pass through each pcr.

  1. When a train passes the SpeedDetection location marker, a script will decide if that train is express or stopping.
  2. The script will then “register” this express/stopping selection with each pcr by adding the selection to the end of the pcr’s “queue”.
  3. Each pcr’s queue is examined each time a train passes one of the three location markers shown, and the signal protecting the pcr has its Hold flag unset if the next entry in the queue is for an express train. The Hold flag is restored if the entry is for a stopping train.
  4. When a train clears a pcr, its selection is removed from that pcr’s queue. The pcr’s queue is then re-examined for the next entry in preparation for the next train.

3 The script

This requires just the one script, which is to be put in the document’s script (accessible from File > Document Script). I’ll go through it in parts.

This first part declares the string variables strPCR1 and strPCR2. These are our “queues”:

Init()
{
	persistent string strPCR1="";
	persistent string strPCR2="";
}

We declare some more variables specific for when a train passes a location marker, including some references to the signals protecting the pcrs:

OnLocation()
{
	string Location;
	string Route=Train.GetRoute();

	string strPCR1Next;
	string strPCR2Next;
	int intTempLen;

	signal sigPCR1=Document.GetSigByID("14");
	signal sigPCR2=Document.GetSigByID("18");

When a train passes the “SpeedDetection” location marker, the script determines whether it is an express train or a stopping train based on its speed:

 
	if(Location=="SpeedDetection")
	{
//		if(Route=="Express")
		if(Train.GetSpeed()>10)
		{
			strPCR1=strPCR1+"E";
			strPCR2=strPCR2+"E";
		}
		else
		{
			strPCR1=strPCR1+"S";
			strPCR2=strPCR2+"S";
		}
	}

This happens just after a station, so it is assumed that any stopping train departing the station will be under the threshold of 10 m/s (36 km/h, or 23 mph) and therefore deemed a stopping train by the script. You can adjust this yourself, or substitute it for the commented line so that the train’s route determines whether it is considered express or stopping.

If the train is determined to be an express train, the letter “E” for express is added to the queues of both the pcrs. Otherwise, the letter “S” for stopping is added.

The next part of our script deals with removing the “E” or the “S” from a pcr’s queue once the train has cleared the pcr:

	intTempLen=Len(strPCR1);
	intTempLen=intTempLen-1;
	strPCR1Next=Right(strPCR1,intTempLen);
	intTempLen=Len(strPCR2);
	intTempLen=intTempLen-1;
	strPCR2Next=Right(strPCR2,intTempLen);

	if(Location=="ClearedPCR1")
	{
		if(Len(strPCR1)==1)
		{
			strPCR1="";
		}
		else
		{
			strPCR1=strPCR1Next;
		}
		sigPCR1.ResetHoldCount();
	}

	if(Location=="ClearedPCR2")
	{
		if(Len(strPCR2)==1)
		{
			strPCR2="";
		}
		else
		{
			strPCR2=strPCR2Next;
		}
		sigPCR2.ResetHoldCount();
	}

Don’t get too caught up in the detail above — there is a bit of messing around with variables going on, but all that’s happening is that the first character from the pcr’s queue is being removed.

(Technical note: the relevant signal also has its release count reset because express trains will still add one to the release count even when the signal is not designated as a hold signal, causing all following trains to be treated as express even if they are not.)

Nearly there! The final part of the script is the bit that examines the pcrs’ queues and sets the holds on the signals accordingly:

	strPCR1Next=Left(strPCR1,1);
	strPCR2Next=Left(strPCR2,1);

	if((Location=="SpeedDetection")||(Location=="ClearedPCR1")||(Location=="ClearedPCR2")
	{
		if(strPCR1Next=="E")
		{
			sigPCR1.SetHold(0);
		}
		else
		{
			sigPCR1.SetHold(1);
		}

		if(strPCR2Next=="E")
		{
			sigPCR2.SetHold(0);
		}
		else
		{
			sigPCR2.SetHold(1);
		}
	}
}

The first character of the queue is examined to determine whether the next train coming is express or stopping, and the Hold flag is set/unset as appropriate.

Note that this bit of the script occurs every time a train passes either SpeedDetection as well as the pcr clearing points. This is because if a train clears a pcr, the script needs to be reactivated in case other trains have their selections queued in the queue and are waiting for their selections to take effect.



import