Using Virtual Channels to Calculate Train Speeds

Using Virtual Channels to Calculate Train Speeds

You can calculate train speeds by using virtual channels. This approach requires identifying two adjacent track circuits and then performing some calculations using a virtual channel.

Virtual Channels

As a virtual channel is a mechanism to allow the combination of one or more physical channels with a logical or mathematical expression to transform data, it can be used to convert data types and apply a formula to transform variables.

By using a simple operator to measure the duration of the occupation, as well as a simple time x distance calculation, you can derive the average speed of the train through that section of track.

Using the TimeBetween Operator

The time_between operator can be used in a virtual channel expression to measure train speeds. Effectively you use it to measure how long a track circuit is occupied for, by producing analogue values that represent the time between a start trigger and a end trigger in milliseconds. When the start trigger fires, a timer is started, and this timer finishes either when the end trigger fires, or when a timeout occurs; the timeout can be used to define the minimum speed that you are interested in measuring.

The timeout value consists of an integer and a unit, which must be: hour, hours, min, mins, sec, secs or ms.

Note that the output of a time_between channel is always in milliseconds, regardless of the unit used in the timeout.

Here's an example of a virtual channel used for this purpose to calculate speed in miles per hour using two track circuits HNF and THND (note this example covers an approach to points, so it is also checking that the 3109 points are in the normal position):

virtual-channel-example.png

Dividing by 1000 converts from milliseconds to seconds. The 'magic' numbers 113 and 2.23 are the length of track circuit THND (in meters) and the metric to imperial conversion to get to miles respectively.

Here's what an export of the resulting events on this channel would look like:

Date,Time,Channel,Value,Units 06-Nov-25,02:42.9,1645961 Speed over HNF with 3109 and 3107 Normal,62.7153,mph 06-Nov-25,10:57.6,1645961 Speed over HNF with 3109 and 3107 Normal,78.4283,mph 06-Nov-25,16:31.3,1645961 Speed over HNF with 3109 and 3107 Normal,12.5995,mph 06-Nov-25,23:43.9,1645961 Speed over HNF with 3109 and 3107 Normal,105.789,mph

Worked Example

Using the Pride Park model railway, we can demonstrate how to set this up.

Assume that there are two adjacent track circuits BE and BF:

lx-approach.png

Here tn represents the time each track is first occupied, assuming the train is going right to left.
The formula for calculating the train speed across track BE would then be:

VBE = (t2 - t1) / xBE

where x is the length of the track section.

A normal, non-anomalous track occupation sequence will have the following properties:

  • Tracks BF, BE will have been occupied, and then cleared in this order.

  • If any of the above track sections have points, these must have remained stationary.

If we assume that the track length of BE is x = 100m, t1 = 0s and t2 = 3s, then the average train speed over this section of track would be:

V = 100 / (3 - 0) = 0.03 m/s

To convert to kph multiply by 3600:

0.03 x 3600 = 108 kph

Putting it Together (kph)

This section gives a worked example how to make the speed calculation in kilometres per hour.

First, to get the elapsed time between exiting track circuit BF and exiting track circuit BE (in other words the length of time spent occupying BE), use this expression:

time_between([dip:BF]DN, [dip:BE]UP, 2 mins)/1000

If we assume that the length of BE is 100m then this give the m/s:

100 / (time_between([dip:BF]DN, [dip:BE]UP, 2 mins)/1000)

To get to kilometers per hour, multiply by 3.6:

100 / (time_between([dip:BF]DN, [dip:BE]UP, 2 mins)/1000) * 3.6

Here's what the resulting virtual channel should look like:

worked-example.png