text: CS452 - s17 - Lecture 24
  Train Control II demo on Thursday, 13 July.
  Project proposal: Next Wednesday
  Only single failures need be handled.
  The train is expected to pass sensor n, which is a distance X from where it is now, at time T, with a margin for error of 2\DeltaT.
  T comes from the velocity calibration: T = X/v
  2\DeltaT also comes from the noise in my velocity calibration, and may not be symmetrical around T.
  The requirement that sensor attribution be robust against single errors increases the number of alternatives your software must expect.
  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.
  The usual cause is output to the train queued in a buffer waiting its turn to be sent to the train UART.
  For example, if your programme is requesting sensor reports faster than the train controller can provide them then the time between asking for a report and getting the corresponding report lengthens monotonically. Growing buffers and queues in servers is an early warning of performance problems.
  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.
  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.
  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.
  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.
  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.
  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.
  When a train stops it should retain a reservation only on track it currently occupies.
  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.