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
© Copyright 2024 Paperzz