CS452 - Real-Time Programming - Spring 2017

Lecture 24 - Multiple Trains

Public Service Annoucements

  1. Train Control II demo on Thursday, 13 July.
  2. The exam will start at 19.30, July 28, 2017 and finish at 22.00, 29 July 2017.
  3. Project proposal: Next Wednesday


Multi-Train Control

By the second milestone you will be able to control two trains at the same time.

Sensor Attribution

To accomplish the first milestone you sorted sensor responses from the train controller into two categories:

  1. ones caused by a train, and
  2. ones you ignored.
For the second milestone you split the first case into two: ones caused by train 1, and ones caused by train 2. In other words, Which train triggered which sensor?

One way of doing this is to plan ahead.

Communication bandwidth to train controller

This is the scarcest resource.

The symptom that you are trying to use it too much is getting time-outs for events that have already occurred. Switches switching too late is another symptom.


Route Finding and Following

You need to be able to route in the presence of obstacles. Some obstacles are stationary; others are moving: you should handle both properly. It's normally a good idea to start with stationary obstacles. Blocking one or more sections of track by a keyboard command, then asking for a route is probably the easiest way to debug route-finding in the presence of obstacles.

You need routes that reverse because they improve the performance of your project.

Please remember that it's not enough to find a route; you must also be able to drive a train along it. Driving over a route to a destination is not too hard, but it must be very robust because it's a basic capability required for driving two trains at once. Train-driving failures usually stop execution dead.

You can try a gradually harder approach.

  1. Make sure that you really have the train finding the shortest route using only one train.
  2. Make sure that you can route around one or more obstacles by manually removing an edge from the graph. You should be able to do this interactively at the keyboard, and you probably want to display on the terminal which edge(s) have been removed from the graph.
  3. Drive a second train to some point; make sure that you route around it automatically.
  4. Let the second train move in a simple way; make sure that you can route around.
  5. Make two trains route simultaneously.
When you are testing, calculate mentally, or by hand, the shortest route before you start the train moving. Why? The human brain has a pronouced recency bias: you will think the train is correct unless you are sure that you know the answer.

When calculating the length of a path you might want to add some extra distance every time the train has to turn around. That is, you are probably most interested in the time a train takes getting to its destination, and reversing adds significant time.

Driving a Train

Driving a train along a route seems easy. But maybe I am wrong to think so, because many students seem to have trouble making it robust. It's highly desirable to have route following robust enough that it's not giving you trouble. Here's my suggestion, based on starting with something that's easy, then making it harder.

  1. The easiest way to follow a route is to put all the switches into the correct state, then drive the train along the route at a modest speed, maybe 8, at which the train moves reliably and your software has no trouble keeping up with it.
  2. Then speed up making certain that you don't fall behind in knowing where the train is.
  3. In your project several trains will be using the track at once, and you can't assume that other trains won't want to use some of your route before you get to it. To minimize interference you must switch as you go. (We will see later that coordinating switching and reserving track is very natural.) Thus, you need to follow the route, switching switches as you come to them. Make the switches wrong before you test to ensure that you are not just being lucky.


Collision Avoidance

This would be hard if the trains stopped instantaneously, but they don't, which makes it harder.

Your train program must plan ahead, far enough ahead that two trains on a collision course will be stopped before they collide. That means you must modify the routes and/or speeds of trains when they are as much as two stopping distances apart: this can be more than a metre.

It is usually your method of collision avoidance that limits the number of trains that can run simultaneously.

I like distributed solutions, where each train operates -- plans, drives, make decisions, etc -- as though there are no other trains on the track. Why do I like this?

Treating the track as a shared resource

Analogy to pixels in a window environment.

A track server gives out and takes back pieces of track.

What policy should it have?

  1. Trains can only occupy track they have obtained from the server.
  2. The server never gives out pices of track that are already out.
  3. A train can only operate on track it owns. In practice, "operate on" means switching turn-outs and returning reserved track to the track server.
  4. Track should be returned to the track server as soon as a train leaves it.
  5. When a train stops it should retain a reservation only on track it currently occupies.
  6. To avoid leapfrog deadlock, all the track owned by a train must be contiguous.

The first three are necessary for correctness. Are they sufficient? The fourth and fifth avoid bugs and improve performance. The sixth eliminates a surprisingly common bug.


Return to: