Example: Model Train Controller
Purposes of example: Follow a design through several levels of abstraction. Gain experience with UML.
Model train setup
rcvr motor
power supply console
header
address
command
ECC
Requirements
Console can control 8 trains on 1 track. Throttle has at least 63 levels. Inertia control adjusts responsiveness with at least 8 levels. Emergency stop button. Error detection scheme on messages.
Requirements form
name purpose inputs model train controller control speed of <= 8 model trains throttle, inertia, emergency stop, train # outputs train control signals functions set engine speed w. inertia; emergency stop performance can update train speed at least 10 times/sec manufacturing cost $50 power wall powered physical console comfortable for 2 hands; < 2 size/weight lbs.
Conceptual specification
Before we create a detailed specification, we will make an
initial, simplified specification.
Gives us practice in specification and UML. Good idea in general to identify potential problems before
investing too much effort in detail.
Basic system commands
command name parameters set-speed set-inertia estop speed (positive/negative) inertia-value (non-negative) none
Typical control sequence
:console set-inertia set-speed set-speed estop set-speed :train_rcvr
Time
Message classes
command
set-speed value: integer
set-inertia value: unsignedinteger
estop
Roles of message classes
Implemented message classes derived from message
class. Attributes and operations will be filled in for detailed specification. Implemented message classes specify message type by their class. May have to add type as parameter to data structure in implementation.
Subsystem collaboration diagram
Shows relationship between console and receiver (ignores role of track):
sequence :console message type 1..n: command :receiver
System structure modeling
Some classes define non-computer components. Denote by *name. Choose important systems at this point to show basic
relationships.
Major subsystem roles
Console: read state of front panel; format messages; transmit messages. Train: receive message; interpret message; control the train.
Console class roles
panel: describes analog knobs and interface hardware. formatter: turns knob settings into bit streams. transmitter: sends data on track.
Console system classes
1 1 panel 1 receiver* 1 console 1 1 formatter 1 1 transmitter 1 1 sender*
Train class roles
receiver: digitizes signal from track. controller: interprets received commands and makes
control decisions. motor interface: generates signals required by motor.
Train system classes
train set 1 1..t train 1 1 controller 1 1 motor interface 1 1 pulser*
1 receiver 1 detector* 1 1
Detailed specification
We can now fill in the details of the conceptual
specification: more classes; behaviors. Sketching out the spec first helps us understand the basic relationships in the system.
Train speed control
Motor controlled by pulse width modulation:
duty cycle
+ V -
Train system analog physical object classes
knobs* train-knob: integer speed-knob: integer inertia-knob: unsignedinteger emergency-stop: boolean set_knobs() pulser* pulse-width: unsignedinteger direction: boolean sender* send-bit() detector* read-bit() : integer
Class descriptions
panel class defines the controls. new-settings() behavior reads the controls. motor-interface class defines the motor speed held as
state.
Panel and motor interface classes
panel train-number() : integer speed() : integer inertia() : integer estop() : boolean new-settings() motor-interface speed: integer
Class descriptions
transmitter class has one behavior for each type of
message sent. receiver function provides methods to: detect a new message; determine its type; read its parameters (estop has no parameters).
Transmitter and receiver classes
transmitter send-speed(adrs: integer, speed: integer) send-inertia(adrs: integer, val: integer) send-estop(adrs: integer) receiver current: command new: boolean read-cmd() new-cmd() : boolean rcv-type(msg-type: command) rcv-speed(val: integer) rcv-inertia(val:integer)
Formatter class description
Formatter class holds state for each train, setting for
current train. The operate() operation performs the basic formatting task.
Control input cases
Use a soft panel to show current panel settings for each
train. Changing train number: must change soft panel settings to reflect current trains speed, etc. Controlling throttle/inertia/estop: read panel, check for changes, perform command.
Formatter class
formatter current-train: integer current-speed[ntrains]: integer current-inertia[ntrains]: unsigned-integer current-estop[ntrains]: boolean send-command() panel-active() : boolean operate()
Control input sequence diagram
change in change in speed/ train number inertia/estop :knobs :panel :formatter :transmitter change in read panel panel-active control panel settings settings send-command read panel send-speed, send-inertia. panel settings send-estop read panel change in panel settings train number new-settings set-knobs
Formatter operate behavior
(in the formatter class)
update-panel() panel-active() idle other send-command() new train number
Panel-active behavior
(in the formatter class)
T panel*:read-train()
current-train != train-knob
F T
current-train = train-knob update-screen changed = true
panel*:read-speed()
current-speed != throttle
current-speed = throttle changed = true ...
...
Train controller class
controller current-train: integer current-speed[ntrains]: integer current-direction[ntrains]: boolean current-inertia[ntrains]: unsigned-integer operate() issue-command()
Setting the speed
Dont want to change speed instantaneously. Controller should change speed gradually by sending
several commands.
Controller operate behavior
wait for a command from receiver
receive-command() issue-command()
Sequence diagram for set-speed command
:receiver :controller new-cmd cmd-type rcv-speed :motor-interface :pulser*
set-speed
set-pulse set-pulse set-pulse set-pulse set-pulse
Refined command classes
command type: 3-bits address: 3-bits parity: 1-bit
set-speed type=010 value: 7-bits
set-inertia type=001 value: 3-bits
estop type=000
Summary
Separate specification and programming. Small mistakes are easier to fix in the spec. Big mistakes in programming cost a lot of time. You cant completely separate specification and
architecture. Make a few tasteful assumptions.