timer

More Factoring FSM States
ENGR 110
2016
#10
Peter Andreae
Computer Science
Victoria University of Wellington
Copyright: Peter Andreae, Victoria University of Wellington
Menu
ENGR 110 20: 2
• Factoring states in a FSM Controller
Admin:
• Assignment 3 (FSM) starting today.
• Test on Wed 10 Aug, 6-7pm, MC LT101, MC LT103
© Peter Andreae
ENGR 110 20: 3
Understanding the Lights Controller
“EW Stopping,
EW car present
waiting for short timer”
EW
Stopping
carEW
“NS Go, EW Stop,
waiting for EW car,
waiting for long timer”
timer
→ EW:red
→ NS:grn
→ setTimer(15)
carEW
carNS
EW
timer
NS Go
→ EW:amb Stopping → EW:red
→ setTimer(3)
→ NS:grn
→ setTimer(15)
EW Go
EW Go
ready
→ EW:amb
→ setTimer(3)
timer
EW Go
must
change
carNS
timer
“NS Go, EW Stop,
EW car present,
waiting for long timer”
NS Go
must
change
carEW
timer
→ NS:amb
→ setTimer(3)
timer
EW Go
NS
timer
→ NS:red Stopping
→ EW:grn
→ setTimer(15) carNS
NS Go
carEW
ready
→ NS:amb
→ setTimer(3)
“NS Go, EW Stop,
long timer done,
waiting for carEW”
NS
timer
Stopping
→ NS:red
carNS
→ EW:grn
→ setTimer(15)
© Peter Andreae
ENGR 110 20: 4
Understanding the Lights Controller
NS Go
EW
Stopping
carEW
timer
→ EW:red
→ NS:grn
→ setTimer(15)
carEW
&&
timer
ONE SENSOR
ONLY, EVER!
→ NS:amb
→ setTimer(3)
carEW
carNS
EW
timer
NS Go
→ EW:amb Stopping → EW:red
→ setTimer(3)
→ NS:grn
→ setTimer(15)
EW Go
EW Go
ready
→ EW:amb
→ setTimer(3)
timer
EW Go
must
change
carNS
NS Go
must
change
carEW
timer
timer
→ NS:amb
→ setTimer(3)
timer
EW Go
NS
timer
→ NS:red Stopping
→ EW:grn
→ setTimer(15) carNS
NS Go
carEW
ready
→ NS:amb
→ setTimer(3)
One “base” state
plus things to
remember
NS
timer
Stopping
→ NS:red
carNS
→ EW:grn
→ setTimer(15)
© Peter Andreae
ENGR 110 20: 5
Design with Factored States
state variables
(things the FSM
needs to remember)
carEWflag
carNSflag
timerFlag
carEW
→ carEWflag=true
EW
Stopping
timer && carNSflag OR
carNS && timerFlag
→ carNSflag=false
→ timerFlag=false
→ NS:amb
.
→ setTimer(5)
.
timer
→ EW:red
→ NS:grn
→ setTimer(30)
Always need ONE sensor
on each transition.
May have any number of
variable tests
EW Go
carNS & timerFlag
→ carNSflag=true
carEW & timerFlag
→ carEWflag=true
timer & carNSFlag
→ timerFlag=true
timer & carEWFlag
→ timerFlag=true
NS Go
timer && carEWflag OR
carEW && timerFlag
→ carEWflag=false
→ timerFlag=false
→ NS:amb
.
→ setTimer(5)
.
NS
timer
Stopping
→ NS:red
→ EW:grn
→ setTimer(30)
must reset
flags once
not needed!
carEW
→ carEWflag=true
© Peter Andreae
Factoring State: Extra variables
ENGR 110 20: 6
• Identify groups of states which are only there to remember sensors
• not doing different actions
• Combine into single group
• Make Boolean variables for the sensors to be remembered
• Add conditions to the transitions based on the variables
• Turn the variables off once they have been “used”
• Add self-transitions to all states, for setting the variables, wherever they may need
to be remembered.
© Peter Andreae
Implementing with factored states
ENGR 110 20: 7
private String state = "NSgo";
private boolean carEWflag;
private boolean carNSflag;
private boolean timerFlag;
public void signal(String sensor){
if (state.equals("NSgo") {
if (!timerFlag && sensor.equals("carEW") )
{ carEWflag=true; }
if (!carEWflag && sensor.equals(“timerExpired")) { timerFlag=true; }
if ((carEWflag && sensor.equals(“timerExpired”) ) ||
(timerFlag && sensor.equals(“carEW”))) {
intersection.NSamber();
.
resetTimer(5000);
state = “NSStopping”;
carEWflag=false;
timerFlag=false;
}
© Peter Andreae
ENGR 110 20: 8
Adding Right Turns
• How do right turns work?
Hide some details
carEW
→ carEWflag=true
EW
Stopping
timer && carNSflag OR
carNS && timerFlag
timer
→ EW:red
→ NS:grn
→ setTimer(30)
→ carNSflag=false
→ timerFlag=false
→ NS:amb
.
→ setTimer(5)
.
timer & carEWFlag
→ timerFlag=true
NS Go
timer && carEWflag OR
carEW && timerFlag
N
→ carEWflag=false
→ timerFlag=false
→ NS:amb
.
→ setTimer(5)
.
EW Go
carNS & timerFlag
→ carNSflag=true
carEW & timerFlag
→ carEWflag=true
timer & carNSFlag
→ timerFlag=true
NS
timer
Stopping
→ NS:red
→ EW:grn
→ setTimer(30)
W
E
carEW
→ carEWflag=true
S
© Peter Andreae
ENGR 110 20: 9
Adding Right Turns
timer
carEW.
EW
Stopping
timer “and” carNS
→ NS:amb
.
→ setTimer(5)
.
timer
→ EW:red
→ NS:grn
→ setTimer(30)
carEW.
NS Go
timer “and” carEW
→ NS:amb
.
→ setTimer(5)
.
EW Go
timer
carNS.
NS
timer
Stopping
→ NS:red
→ EW:grn
→ setTimer(30)
carNS.
N
W
E
S
© Peter Andreae
ENGR 110 20: 10
Adding Right Turns
NS Right
NS Right
Stopping
carEW.
timer
carEW.
EW
Stopping
timer “and” carNS
→ NS:amb
.
→ setTimer(5)
.
timer
→ EW:red
→ NS:grn
→ setTimer(30)
NS Go
timer “and” carEW
→ NS:amb
.
→ setTimer(5)
.
NS
timer
Stopping
→ NS:red
→ EW:grn
→ setTimer(30)
EW Go
timer
carNS.
N
W
E
carNS.
EW Right
Stopping
EW Right
S
© Peter Andreae
ENGR 110 20: 11
Adding Right Turns
timer && carNSrtFlag
→ EW:red
timer
NS Right
NS Right
→ NSrt:grn
→ NSrt:amb
.
Stopping
→ setTimer(15)
→ setTimer(5)
→ carNSrtflag=false
.
carEW.
timer
→ NSrt:red
→ NS:grn
→ setTimer(30)
timer
carEW.
EW
Stopping
timer “and” carNS
→ NS:amb
.
→ setTimer(5)
.
timer && carNSrtFlag
→ EW:red
→ NS:grn
→ setTimer(30)
EW Go
timer
carNS.
timer
EW Right
→ EWrt:red
Stopping
→ EW:grn
→ setTimer(30)
timer && carEWrtFlag
→ NS:red
→ EW:grn
→ setTimer(30)
NS Go
timer “and” carEW
→ NS:amb
.
→ setTimer(5)
.
N
NS
Stopping
W
E
carNS.
timer
EW Right
→ EWrt:amb
.
→ setTimer(5)
→ carEWrtflag=false
.
timer && carEWrtFlag
→ NS:red
→ EWrt:grn
→ setTimer(15)
S
© Peter Andreae
Alternative designs for signal(…)
ENGR 110 20: 12
• Simple design:
Could use switch statement
• Large nested if-else
• one case for each state
• one nested case for each transition from that state.
– Can get very large and unwieldy
• Alternate:
• Large nested if-else
• one case for each sensor
• one nested case for each state that has a transition for that sensor
• One method per state:
• if-else on state
• each case calls a method for that state
• each method has if-else for transitions from that state
• Table driven:
• Have a big table of transitions.
© Peter Andreae
Decomposing signal(…)
ENGR 110 20: 13
public void signal(String sensor){
if (state.equals("NSgo"))
{ signalNSgo(sensor); }
else if (state.equals("EWgo")) { signalEWgo(sensor); }
else if (state.equals("NSwait")){ signalNSwait(sensor); }
...
private void signalNSgo(String sensor){
if (sensor.equals("timer") && !carEWflg){
system.turnNSred();
state = "NSgoReady";
}
else if (sensor.equals("carEW")){
careEWflg = true;
}
}
private void signalEWgo(String sensor){
...
© Peter Andreae
ENGR 110 20: 14
Table Driven Design
• Look-up table of transitions
• Code
State
Sensor
Action
New State
NSgo
timer
turnNSred
turnEWgreen
EWgo
NSgo
carEW
EWgo
&& carNSflg
timer
carEWflg=true
turnEWred
turnNSgreen
NSgo
…
• Looks up current state and sensor in the table.
• Performs the actions
• Changes the state
• Much neater design: signal() method much smaller
• Easier to change
• A bit tricky to implement without more advanced Java features.
© Peter Andreae
ENGR 110 20: 15
Alternate Designs:
• Event Driven Controller
Signals/sensors
Controller
sensor
action
sensor
action
sensor
action
actions
System:
autonomous vehicle
lift
traffic lights
etc.
• Integrated Controller
System
Controller
infinite loop:
action
action
access system state
and internal variables
eg, Arduino processor
controlling device
sensors always reporting
action
© Peter Andreae