Statechart Assignment 

Train driving interface using Statecharts

General information

  • The due date is December 6th, before 23:55.
  • Submissions must be done via BlackBoard. Beware that BlackBoard's clock may differ slightly from yours. All results must be uploaded to BlackBoard and accessible from links in the main (index.html) file.
  • The assignment must be made in groups of maximum 2 people. It is understood that all partners will understand the complete assignment (and will be able to answer questions about it). Clearly identify who did what.
  • Grading will be done based on correctness and completeness of the solution. Do not forget to document your requirements, assumptions, design, implementation and modelling and simulation results in detail!
  • To get feedback about the assignment workload, provide the number of hours you spent on this assignment.
  • Contact: Yentl Van Tendeloo.


This assignment will make you familiar with modelling in Statecharts, simulation, and code synthesis.

Problem statement

In this assignment, you will design a Statechart model spcifying the reactive behaviour of the interface for driving a train.

You are provided with a simple GUI, which will send events to your statechart, and which will respond to the commands issued by the statechart. The GUI itself is therefore stateless and non-intelligent, as all state and knowledge is encoded in your statechart.

The GUI presents a simple interface with a slider to set the acceleration, thus automatically controling the engine and brakes. The slider ranges from -1 (emergency brake) to 1 (full throttle). There are additional buttons to open and close the doors. Buttons are also present to pause and resume the simulation. Finally, there is a button which the system uses to poll whether or not the train driver is still able to drive, the so called "dead man's button".

In this assignment, you will create the statechart which listens to the events generated by this interface, and modifies the behaviour of the train. Instead of directly linking these buttons to their respective actions, some safety measures should be encoded to guarantee that unsafe things (e.g., opening the doors at full speed) will never happen.


Your statechart should comply with the following requirements:

  • A train is either standing still (either in a station, or outside of it), driving, or cruising at full speed.
  • The train can only open its doors when it is standing still in a station. Pressing the 'open' button at any other time will just be ignored.
  • After opening the doors, they must remain open for at least 10 seconds to allow people to unboard and board. Pressing the 'close' button before that will just be ignored.
  • Standing still does not necessarily imply that you are at a station, so the doors should remain closed if the train is outside of a station.
  • When reaching the maximally allowed speed (120 kilometers per hour), further (positive) acceleration will be ignored and the speed will be set to the maximum (thus correcting rounding errors).
  • Likewise, when standing still, further (negative) acceleration should be ignored. Again, rounding errors can be countered by setting the speed and acceleration to exactly 0. Make sure that in all cases, it is impossible to go backwards!
  • The train can go in emergency brake mode when dangerous situations occur. In this mode, the interface no longer listens to the driver, and the train will decelerate as hard as possible, before turning itself off when speed has reached 0.
  • When driving in a train station at a speed above 30 kilometers per hour, the train automatically goes into emergency brake mode.
  • When passing a red light, the train automatically goes into emergency brake mode.
  • When passing a yellow light at a speed above 50 kilometers per hour, the train automatically goes into emergency brake mode.
  • Leaving a train station without stopping will make the train go in emergency brake mode.
  • The driver needs to press the "dead man's button" every 10 seconds. If the button is not pressed within 5 seconds of the prompt, the train goes into emergency brake mode. Pressing the button before the prompt occurs will have no effect.
  • When a train has stopped at a train station, it ignores all acceleration requests until its doors have been opened and subsequently closed. This to prevent the train from leaving without opening the doors.
  • Pressing the pause button will stop the simulation completely. Pressing continue afterwards will make it resume.
  • You will have to manually call the update operation to update the current speed and GUI. Do this every 0.02 seconds.

Events send to the statechart

The following events will be raised in the statechart to indicate a button press, slider change, or event happening:

  • accel: the 'acceleration' slider was modified. It has a parameter containing the new acceleration.
  • continue: the "continue" button was pressed.
  • pause: the "pause" button was pressed.
  • open: the "open" button was pressed.
  • close: the "close" button was pressed.
  • awake: the "poll" button was pressed.
  • enter: entering a station.
  • leave: leaving a station.
  • green_light: passed a green traffic light.
  • yellow_light: passed a yellowtraffic light.
  • red_light: passed a red traffic light.

Interface of the GUI to the statechart

The following method calls can be made in the actions.

  • self.openDoors(): open the doors.
  • self.closeDoors(): close the doors.
  • self.updateState(): update the current speed (speed attribute of the statechart) depending on the acceleration attribute. This also updates the GUI visualization and makes the train progress.
  • self.notify(msg, colour): show a notification to the user in the specified colour. Colour can be any string that is accepted by Tk as a colour (e.g., "red"). This will also erase the previous notification.

Additionally, the following attributes can be read and/or modified.

  • self.speed: the current speed of the train, as shown in the GUI. You can write to it yourself, for example to fix rounding errors, but the formulas to update it according to the current acceleration are done by the updateState() call automatically.
  • self.acceleration: the current acceleration of the train. This should be set to the value passed by the slider if acceleration is allowed.

Starting point

As you should only focus on the reactive behaviour of the interface, we have provided a starting point for you. The starting point already includes the binding with the GUI, which is also provided.

Practical information

Modelling of the Statechart model can be done using AToMPM. For this, you will need to install Node.js v0.10.31 (NOT a newer version!). After starting AToMPM with the instruction node httpwsd.js, use Google Chrome or Chromium (Firefox or others are NOT yet supported) and go to http://localhost:8124/atompm. In the toolbar, load the model /Models/SCCD/train.model. Designed models can be exported by loading the toolbar /Toolbars/SCCD/compile.buttons.model and pressing the 'export' icon, either without state highlighting (leftmost button) or with state highlighting (rightmost button).

As the synthesized model will be in Python, you should write your methods in Python code. When you are happy with your model, you can export it to SCCDXML and compile it by invoking python python_sccd_compiler/ -p eventloop train.xml in the exported_to_sccdxml folder. Afterwards, you can execute your model by running python Make sure you are using Python 2.7.x!

Please hand in any file that you modified. Include links to these files in your index.html. DO NOT include files that weren't modified. Also, please include your model as an image. You can use the SVG export functionality of AToMPM by loading the toolbar /Toolbars/Utilities/Utils.model and pressing its first button. Alternatively, just take a screenshot.

Some peculiarities of AToMPM, which you should take into account:

  • Press shift+return instead of return while filling in attributes that require a newline.
  • Your guards and conditions should use single quotes (') instead of double quotes (") for string literals.
  • To use the parameter of an event, you should put its name (you can choose one yourself) as the first string in the lowest attribute (a list of strings), called "parameters".
  • Orthogonal components require that a composite state is inside, as otherwise the link will not be made correctly.
  • If you cannot select something, but are instead selecting other elements (e.g., the enclosing composite state), you should lower the layer of the other elements. This can be done by hovering your mouse over the enclosing elements and scroll down while holding shift.
  • The "option" attribute does not work when set to OTF (outer first), for this, you need to replace "OTF" with " OTF" (a space before) in plugins/exporttosccdxml.js and plugins/exporttosccdxml_debug.js.

You are encouraged to use all functionality that Statecharts offer, such as history states, after events, and orthogonal components.

Maintained by Hans Vangheluwe. Last Modified: 2016/08/24 10:20:04.