State Modelling Homework
We now have a Yakindu License server. Many of you probably use the free trial. This will expire before the exam, so please try to get the license before doing this homework!
Acknowledgements: This project is adapted from this assignment by Hans Vangheluwe.
In this assignment, you will specify a statechart capturing the behavior of a digital watch, inspired by the 1981 Texas Instruments LCD Alarm Chronograph. The statechart must be designed and tested using Yakindu SCT. You are not required to write Java code, for this assignment is provided to you in a zip file containing an initial Yakindu project. In this project, the GUI code is ready to be plugged to the statechart. You are allowed to add only internal events and variables but not to modify the interfaces “Buttons”, “Display” or “LogicUnit”.
Requirements
- The time value should be updated every second, even when it is not displayed (as for example, when the chrono is running). However, time is not updated when it is being edited.
- Pressing the top right button turns on the background light. The light stays on for as long as the button remains pressed. From the moment the button is released, the light stays on for 2 more seconds, after which it is turned off.
- Pressing the top left button alternates between the chrono and the time display modes. The system starts in the time display mode. In this mode, the time (HH:MM:SS) and date (MM/DD/YY) are displayed.
- When in chrono display mode, the elapsed time is displayed MM:SS:FF (with FF hundredths of a second). Initially, the chrono starts at 00:00:00. The bottom right button is used to start the chrono. The running chrono updates in 1/100 second increments.
- Subsequently pressing the bottom right button will pause/resume the chrono.
- Pressing the bottom left button when the chrono is paused will reset the chrono to 00:00:00.
- Pressing the bottom left button when the chrono is running, will freeze the display to allow you to write down intermediate lap times, but this will not stop the timer (as a background process). Pressing the same button again will resume the chrono, showing the total elapsed time, as if there had been no freeze.
- The chrono will keep running (when in running mode) or keep its value (when in paused mode), even when the watch is in a different display mode (for example, when the time is displayed).
- For simplicity, we will not store these intermediate lap values, so if the user switches mode while an intermediate time is showing, it is unspecified (meaning the watch can crash for all I care), but the example implementation just resumes the chrono, so one has to press the upper left button twice.
- Note: interactive simulation of a model containing time increments of 1/100 second is possible, but it is difficult to manually insert other events. Hence, while you are simulating your model, it is advisable to use larger increments (such as 1/4 second) for simulation purposes.
- When in time display mode, the watch will go into time editing mode when the bottom right button is held pressed for at least 1 seconds. In this mode, one of the fields of the time or the date is marked as “selected”. The currently selected field blinks while in edit mode (e.g. if the “hour” field is selected, it blinks).
- Initially, when the editing mode is entered, the “hour” field is selected.
- Briefly pressing the bottom-left button increases the value of the currently selected field (e.g. if the currently selected field is the “hour”, and the current value of the hour is 10, the value changes to 11). It is only possible to increase the value of the currently selected field; there is no way to decrease it – but when the value reaches its maximum value (e.g. hour = 23), then it moves back to the smallest value (i.e. hour = 0).
- If the bottom-left button is held down, the value of the currently selected field is incremented automatically every 0.1 seconds.
- The editing mode is exited if neither the bottom-left nor the bottom-right buttons are pressed during an interval of 5 seconds.
- Holding the bottom-right button down for 2 seconds will also exit the editing mode.
- Pressing the bottom-right button for less than 2 seconds will change the “selected field” to the next one in the following order: from the “hour”, to the “minute” to the “second”, to the “month”, to the day, to the year and back to the “hour”.
To help clarify the requirements, you can find a working solution here: digitalwatch.jar (to run the demo use java –jar digitalwatch.jar
).
What to submit?
A zip file containing the Yakindu statechart digitalwatch.sct
as well as a document solution.pdf
explaining your solution.
- It must be possible to take your file and place it into my project and Yakindu should build it. NOTE: You may not change the code of the GUI. In particular, you will get zero points if the Java code is the one from last year.
- The document must be a PDF file (Word is also accepted), describing your solution. The document should indicate the set of satisfied requirements, open issues, known bugs, etc. and the list of names of the team members. Ideally, this is a very short document because your design is clean and self-explanatory.
Grading
The solution will be graded as follows:
- One point for each of the following requirements: 1 and 2.
- Three points for chrono mode (requirement 4).
- Three points for time editing (requirement 5).
- Two points for simplicity and understandability of the overall solution. My solution has less than 20 states and uses only one internal variable (as in the stub). If you use significantly more states or variables, your solution is probably overly complicated.
If the statechart you produce can be simulated, but for some reason the application does not work, you can get up to 80% of the points. To get 100% of the points, the application has to run as well (and of course it should be possible to simulate your statechart).
Starting point
The dwatch.zip file provided to you contains a Yakindu project that implements the GUI. As the entry point for starting to launch the application, you must use the class dwatch.Main
. The latter class sets up all the elements in the application (State machine, Timer Service, GUI controllers and views, etc.) and launches the simulation.
The stub statechart file contains some silly logic, but it also contains some useful idioms that may come in handy for the real solution. We'll be abusing the Yakindu timer service, so this part of the docs may be useful.
The code provided to you is decomposed into three components exposing the following interfaces.
Interface Buttons:
This interface give a hook for the simulation to generate the events associated with the buttons in the watch. We distinguish the following events:
topRightPressed
andtopRightReleased
for the light switch.topLeftPressed
andtopLeftReleased
for the mode button.botRightPressed
andbotRightReleased
for start/paus chron) and time editing next.botLeftPressed
andbotRightReleased
for lap/reset chrono and time editing increment.
Interface Display:
This interface exposes the functions associated with the watch display. Not that this interface defines only operations and no event. The list of operations supported is the following:
refreshTimeDisplay()
redraws the time with the current internal time and date values. The display does not need to be cleaned before calling this function. For instance, if the chrono is currently displayed, it will be deleted before drawing the time.refreshChronoDisplay()
. See refreshTimeDisplay()setIndiglo()
turns on the display background light.unsetIndiglo()
turns off the display background light.hidePos(pos: integer)
. This method allows you to hide a position (the positions range from 0 to 5, indicating hours, minutes, seconds, months, days, years). You will implement the blinking animation for the time editing mode by alternating between calls to this operation and refreshTimeDisplay.
Interface LogicUnit:
This interface exposes the behavior internal to the digital watch (e.g., time counting, date counting, etc.). The set of operations and their descriptions follows:
increaseTimeByOne()
increases the time by one second. Note how minutes, hours, days, month and year will be modified appropriately, if needed (for example, when increaseTimeByOne() is called at time 11:59:59, the new time will be 12:00:00).increaseChronoByOne()
increases the chrono time by 10 milliseconds. All the other parts, i.e., seconds, minutes, and hours will be updated accordingly.resetChrono()
resets the time count for the chrono.increasePos(pos: integer)
increases the given digit group's value by one (positions are the same as in hidePos above). This is what you will use to set the date and time!