CS452 - Real-Time Programming - Spring 2017

Lecture 20 - Short moves; Anthropomorphic Programming.

Public Service Annoucements

  1. On Monday the 19th we decided that
  2. First Train Control Milestone: Thursday, 29 June.
  3. Stalling trains.

Calibration IV

1. Calibrating Stopping Distance

2. Calibrating Constant Velocity

Moving the train at a Pre-chosen Velocity

v = b*v1 + (1-b)*v2

Were the six trains running on the figure eight given velocities like this?

How Long does it Take to Stop?

3. Short Moves.

Trains often must travel short distance, starting with the train stopped, and finishing with it stopped. When doing so the train spends its whole time either accelerating or decelerating. Your constant speed calibration is useless because the train doesn't travel at constant speed. Simmilarly your measured stopping distances are not useful.

Creating a perfect calibration of the train's position while it is accelerating is hard. But there is an easy and precise calibration that covers most of the moves the train makes where you need a good calibration It's the subject of this section.

Most of the your train project can get away with ignoring acceleration and decelleration. The one place you can't is when you are doing a short move, giving a speed command followed by a stop command before it gets up to speed. How far will the train go? How long will it be before the train is fully stopped?

Short moves are common when the train is changing direction, which you need to increase the number of possible paths from one point to another.

The general idea is to give the train a carefully timed series of commands knowing how far and for how long the train moves during the series of commands.

4. Calibrating Acceleration and Deceleration: Doing Better

At this point you can do most of the things you will want to do for your project. But some things cannot be done from a standing stop. When one train is following another, for example, it's more elegant to keep the train moving, speeding up and slowing down as required. To do so it's necessary fully to calibrate velocity during the act of accelerating and decelerating. Keeping a train at a pre-determined velocity, for example, requires changing from one speed to another frequently.

To explain velocity changes we must introduce models. On the track the train has a real location, so many cm past sensor S. In your program the train has a position, so many cm past sensor S'. The model is linked to the real train by the calibration. Neither the number of cm nor even the sensor is necessarily the same in the model and in reality because no calibration is perfect. The performance of a project, such as whether trains collide or not, depends on the difference between the model and reality. The remainder of this section is based on minimizing different measures of discrepancies beteen a model and reality.

Back to real trains. When a train driver gives the train a command to change speed, we know roughly how the velocity changes.

  1. slowly at first
  2. increasing
  3. reaching a maximum rate of change, possibly for a non-zero time
  4. decreasing
  5. more and more slowly as the new velocity is approached
Is this description true of our trains?

How should we model speed changes?

The simplest possible model is a step change from the initial velocity to the final velocity. When should the change occur?

How much does the train in the model fall behind the real train? It depends on what the real train is doing.

What can we do with a video camera?

Things you might try

  1. Use the video camera that's already there on the ceiling. Measure pixels and frames.
  2. Use the fiducial marks that have been put along the walls, tracks and ceiling.
  3. Use something better than video. e.g. Arduino

Anthropomorphic Programming

We all, even most programmers (!), have effective intuitions about human relations

Tasks are independent entities

Servers and Attendant Tasks

Why do servers need attendant tasks?

1. Proprietor with a Notifier

Proprietor `owns' a service, which usually means a resource.


  1. Notifier is usually of higher priority than server
  2. The server buffers both clients and data from the notifier. In this implementation client and data buffering are duals of each other. Our server code should

2. Using a Courier

We can handle two interrupts coming very close together using a courier. Simplest is best, so we shouldn't go beyond a courier unless we expect more than two.

Transmit Notifier Code

Transmit Courier Code

Transmit Proprietor Code


This gets you through a bottleneck where at most than two events come too fast.

Remember that all the calls provide error returns. You can/should use them for error recovery

Another possible arrangement for task creation

Another possible arrangement for initialization

Distributed gating

I am showing you collections of tasks implemented together because sets of related tasks is a level of organization above the individual task.

E.g., the decision to add a courier requires revision of code within the group, but not outside it.

3. The Warehouse

Add a warehouse between the courier and the notifier.


The initialization given for the courier, above, generalizes to include the warehouse, essentially without change.


The notifier is now talking directly to a server and has the shape given above for the proprietor. The warehouse cannot talk directly to the proprietor because both are servers.


This structure clears up most problems when a burst of requests to the server would leave the notifier waiting in a long sendQ.


  1. Handles bottlenecks of all sizes. Give a precise and quantitative definition of `bottleneck'.

What this amounts to is that a server should be lean and hungry

Return to: