Assignment 1 — Trains
In this assignment, you will practise mutual exclusion using semaphores and communicating with other concurrently executing programs through a prewritten interface.
In the following, "should" is used to denote a weak requirement; something characteristic of a good solution. "must" and "may not" denote strong requirements; failure to achieve these may cause your assignment to be failed.
Background
A small railway company is looking for a way to automate their train control in order to downsize their staff and improve safety. You have been tasked with implementing the train control software. However, the company executives do not want to take any chances with their trains. For this reason, they want you to write control software for two trains on a simulated track as a proof of concept (and your skills). The functioning of the simulation will strongly affect your chances of getting a multi-million Euro contract.
Task description
Your task is to write a Java program that controls two trains
travelling between the two stations of a specific track in the
tsim train simulator. All the
required files can be found in
Niksula and
HUT-CC (Unix only) in
~jlonnber/tsim
or in the tsim installation package. To
start tsim in Niksula, run ~jlonnber/tsim/tsim.sh
<track>, where
<track> is the track you want to
load into tsim (~jlonnber/tsim/track
contains the track
used in this assignment). In order to complete this task, you must:
- Add sensors to the track.
- Write code that receives sensor events and sets the speed of a train and the state of switches based on these events.
Train behaviour requirements
The trains must travel from one station to another without requiring any user input until the simulator or train control program is terminated. They must stop at each station and unload and load passengers and goods. Obviously, the trains may not collide with each other, derail or run into the stops at the ends of the track. The trains should move between stations with few delays and good speed; a train must always move from one station to the other in less than 2 minutes (simulation time) after unloading/loading and after program start, but fine-tuning the trains to cut every possible millisecond off their travel time is not the goal of this assignment. You need not take into account user interaction with the simulator through its GUI.
Both trains must use the same code. The trains should use the upper track at the stations and the shorter track halfway between the stations if the other train is not in the way.
Your trains must behave correctly when the default acceleration is used and with any simulation time speed-up factor up to 15.
Track requirements
You may add sensors as required to the track. However, you may not modify the track in any other way. You may not change the initial position of the trains, add or remove trains or change their length. All tests of your code will be run with the track you submit. The purpose of this exercise is not to write a solution that works on any track; that is a much harder problem.
Concurrency and synchronisation requirements
Each train must be controlled by a separate process (virtual
machine) that uses the tsim Java API to control the speed of the
train, start unloading/loading, flip switches and receive sensor
events for the train. Semaphores are the standard synchronisation
technique for rail traffic, so the train processes must communicate
with each other using nothing but TSim.Semaphore
s. The
trains must both use the same code and base their actions on no
other external input than sensor events and semaphore states.
Inefficient solutions, such as polling and busy-waiting, will be rejected.
Style requirements
The program must be written in Java, and should have a clear and simple structure. Cryptic method and variable names may not be used.
Explanatory comments are required for code that is not self-explanatory to a programmer fluent in Java. However, you should not clutter your program by stating the obvious. As an example, Javadoc comments describing the syntax of trivial methods (such as accessors) will be tolerated but are discouraged.
Execution
Your program must contain a class trains.Train
, a
subclass of java.lang.Runnable
, whose
run()
method runs one of the two trains and drives them
from station to station as described above, when called by the
tsim
package. In other words, your solution should
start running (assuming Java is in the path and your solution and
the tsim package are in the current directory) on Unix with the
command:
tsim/run.sh -strict
On Niksula and HUT-CC machines, your solution (in the current directory) must run using the command:
~jlonnber/tsim/run.sh -strict
Language
Comments, variable and method names and reports may be written in English, Swedish or Finnish. We recommend that you use only English; if you use Finnish or Swedish, you must specify this when submitting.
Report
Your submission must contain a report describing briefly:
- The reasoning behind your solution, in particular the reasoning behind your placement of sensors and how your code reacts to sensor events.
- What measures you have taken to ensure your solution is correct (e.g. model checking, proofs, testing).
- Any unexpected behaviour you may have encountered during testing and how you have investigated and resolved it.
The report should not exceed 2 A4 pages of 10-12 point text. Please focus on explaining your reasoning rather than what your solution does in detail.
Hints
- You have no way of telling how fast your train is going except dead reckoning (it accelerates at 5.0 pixels/second² until it reaches the set speed; this means, for example, that the train needs 40 pixels (2 squares) to stop from 20 pixel/s; you should add an extra square to account for rounding, interprocess communication delays and such) and previous speed change commands. When stopping and turning, take into account that your train may be travelling at anything between 0 and maximum speed unless you have given it enough time to accelerate/decelerate to the right speed.
- tsim and each of your trains is running in a separate process. This means that the trains will continue to move at the speed your code has given them irrespective of what your code is doing. Don't expect the simulated trains to wait while your code figures out what to do.
- High speedup factors (10-15) are good for finding problems with your code quickly, but don't rely on testing to expose all problems.
- Interprocess communication may introduce delays, so don't cut the braking distances too fine. This is especially noticeable at high speedup factors.
- The trains travel forwards and backwards equally well, and you can't turn them around on this track.
- Slowing down one of your trains or manually stopping it helps you find problems quicker. Overriding your trains' speeds through the tsim GUI may, of course, mess up your synchronisation code, so don't panic if something goes wrong when you do that.
-
The
try_acquire
method inTSim.Semaphore
will help you keep things running smoothly (or at least smoother). -
You can use
System.err
andSystem.out
for debug output. You will be sent the debug output from the tests run on your solution (up to 10 MB). - The supplied example train implementation drives one of the trains from one station to another and back on the supplied track with sensors. You can use this example code as a basis for your solution.
Submission
Before the deadline (2007-10-22 23:59, resubmission 2007-12-10 23:59), you must submit a gzipped tar archive containing your solution using the form below. The archive must contain the following files (all other files will be ignored):
trains/
|
The Java (version 1.4 or earlier) source code of your train
control program (the directory corresponds to the
trains package).
|
track-sensors
|
The supplied track with your sensors added. |
report.pdf
|
The report describing your solution (as PDF). |
Your program will be compiled and run with the simulator Java interface and standard library included in the classpath.
You may work in pairs. The grading does not depend on whether you are working alone or in a pair.
Results will be sent to both students at <student
number>@students.hut.fi
.
Page last updated by Jan Lönnberg 2007-11-26.