code_generator.jpg

Fine state machines (FSM) are an easy way to define behaviour of software programs. Writing FSM is tedious. Therefore, code generators for FSM are desirable. This wiki pages compares state machine code generators.

Requirements

The ideal state machine code generator must have the following features:
  1. It is able to execute actions when entering and leaving states.
  2. It supports default transitions.
  3. It is able to execute transition actions.
  4. It supports transition guards.
  5. It has mean to get the current state.
  6. It has a mean to get the previous state.
  7. It is feasible to subvert the FSM and set the current state directly.
Python.org contains as description of available state machine generators.

The FSM generator must generate the following FSM:

laser_fsm.png

SMC The State Machine Compiler / The State Map Compiler

  1. Home page: http://smc.sourceforge.net/
    1. Pro
      1. Supports C++ and Python as target language.
      2. User specifies FSM by writing a plain text file.
      3. FSM specification syntax is simple and is based on yacc.
      4. Generated code is easy to grasp.
      5. It produces one (1) Python class.
      6. The command for generating the Python FSM is simple, e.g. java -jar Smc.jar -python loop.fsm
  2. Contra:
    1. This FSM code generator requires Java in version 7 or above.
    2. The generated Python class requires a special Python module.
  3. Example:
    %{ %} %class Loop %package argos.arbitator.loop %fsmclass LoopFSM %start LoopFSM::OPEN %map LoopFSM %% OPEN { Close CLOSED { closeLoop(); } } CLOSED { Open OPEN { openLoop(); } } %% 

Fysom

  1. Home page: https://github.com/oxplot/fysom
  2. Pro:
    1. Fysom consists of single Python module.
    2. Fysom source code is short.
    3. No 3rd party dependencies
    4. Easy configuration.
  3. Contra:
    1. Project is one-man show.
    2. Project has many forks at github.
    3. Documentation is part of source code.
    4. A table specifies the state transitions.
  4. Example:
    import fysom class Laser(object): _squirrelSleeping= True def __init__(self): self._fsm= fysom.Fysom({ 'initial': 'POWERED_OFF', 'events': [ {'name': 'EVENT_POWER_ON', 'src': 'POWERED_OFF', 'dst': 'POWERED_ON'}, {'name': 'EVENT_POWER_OFF', 'src': 'POWERED_ON', 'dst': 'POWERED_OFF'} ] }) self._fsm.onbeforeEVENT_POWER_ON= self.isSquirrelSleeping self._fsm.onenterPOWERED_ON= self.laserFlameOn self._fsm.onleavePOWERED_ON= self.laserCoolDown self._fsm.onenterPOWERED_OFF= self.nop self._fsm.onchangestate= self.onChangeState def nop(self, o): print "nop" def powerOn(self): if self._squirrelSleeping: self._fsm.EVENT_POWER_ON() else: raise Exception("squirrel awake") def powerOff(self): self._fsm.EVENT_POWER_OFF() def state(self): return self._fsm.current def laserCoolDown(self, o): print "cooling down laser" raise Exception("laser cool down error") def laserFlameOn(self, o): print "flame on laser" def isSquirrelSleeping(self, o): print "checking if squirrel is sleeping", type(o), dir(o) return self._squirrelSleeping def onChangeState(self, o): print "change state" laser= Laser() assert "POWERED_OFF" == laser.state() laser.powerOn() assert "POWERED_ON" == laser.state(), "laser in state: %s" % laser.state() laser.powerOff() assert "POWERED_ON" == laser.state(), "laser in state: %s" % laser.state() 

pexpect/FSM.py

  1. Home page: http://www.noah.org/python/FSM/
  2. Pro:
    1. FSM is used in pexpect module.
    2. It is easily available on CentOS because it comes with pexpect.
  3. Contra:
    1. No domain specific language available for constructing FSM
    2. User must write many configuration lines
  4. Example:
    import FSM class ActionSeq(object): def __init__(self, actions): self._actions= actions def __call__(self, e): for each in self._actions: each(e) class Laser(object): _squirrelIsSleeping= True def _onEnteringPOWERED_ON(self, o): if self._squirrelIsSleeping: print "powering on entry: laser flame on" else: raise Exception("squirrel is awake") def _onEnteringPOWERED_OFF(self, o): print "NOP" def _coolDownLaser(self, e): print "powering off: laser cool down" raise Exception("laser cool down failure") def __init__(self): self._fsm= FSM.FSM("POWERED_OFF") self._fsm.add_transition("POWER_ON", "POWERED_OFF", self._onEnteringPOWERED_ON, "POWERED_ON") self._fsm.add_transition("POWER_OFF", "POWERED_ON", ActionSeq([ self._coolDownLaser, self._onEnteringPOWERED_OFF]), "POWERED_OFF") def powerOn(self): self._fsm.process("POWER_ON") def powerOff(self): self._fsm.process("POWER_OFF") def state(self): return self._fsm.current_state laser= Laser() laser.powerOn() laser.powerOff() assert "POWERED_ON" == laser.state(), "laer in state: " % laser.state() print "OK"
Topic revision: r4 - 15 Aug 2018, AndrewColson
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback