Most control systems need a mechanism for keeping track of which trains are where. One possible system could use local identification systems to decide which train is arriving and then decide what to do with it. That is of course very restrictive and a better solution is generally to keep track of where each train is so that fully informed decisions may be made regarding its routing.
I think there are only two basic ways of tracking trains - either having the train 'know' where it is, and pass that information to control (the signalman, control centre, or whatever) or alternatively having the track detect the trains. As the first option is impractical for most scales I shall ignore it and consider only trackside detection.
There are two basic ways of representing a trains location. One is to have some location identity associated with each train. The other is to have a train identity associated with each track section. I suggest that the second option is safer and more efficient. It is easier to get confused with the strategy of storing locations against trains - bugs in your code (as if they ever happen) might mean having two trains in the same location. Also the most common information you need is 'which train is here', in order to decide what you are going to do with that train.
So therefore the key information for following trains is having a train identity against each section of track. If we ignore for now how these identities are made and allocated when a train is first placed on the track, and just concentrate on keeping track of just a train number.
Naturally the train identity itself does not of itself tell us much, but all the other train related information we might want (such as route, type, length, power settings etc.) could be stored in arrays, indexed by train number. This means that the higher layers of control software can retrieve the information about a train sitting on a given track by using the train number stored against that track. For example the progressive route selection logic might look at the train numbers of the reserved sections to deduce when to reserve the next set of track, and when to release the track the train has passed.
If we take an example of track sections that have current detectors (ie. you have track circuiting), but nothing else, then the following code springs to mind:
{ we see a train (current on) but don't know which train it is here.t=0 }
{ so copy the train number from the previous section (here.t=prev.t) }
WHEN here.t=0, Cur=TRUE, prev.t<>0 DO here.t=prev.t
{ the train departs for the next section (here.t<>0 and current off) and the }
{ next section has already copied our train number, so clear out train number }
WHEN here.t<>0, Cur=FALSE, here.t=next.t DO here.t=0The seemingly extra checks (prev.t<>0 and here.t=next.t) are to ensure that the numbers are passed reliably. Without them a train number would get lost if the current detector reported absense of current while a train was stationary for example. Such checks improve reliability considerably and should always be incorporated in any design, whether software based or hardware based as the detection hardware should be considered to be fallible (sensors occasionally misreport because of external events such as the hand of God holding up the train to add an extra wagon.
As long as we know which track the train arrived from and which track the train travels to, we can move train numbers around quite reliably. This of course assumes that sufficient axles in the train are conductive so that the end of the train can be detected safely.
If you are using optical detectors then exactly the same code can be used (with 'Cur' replaced by 'Opt', or the name given to your local optical detector of course). The various .t variables then reflect which train is passing (or has recently passed) each detector.