【问题标题】:How to generate outputs from PyTransitions FSM?如何从 PyTransitions FSM 生成输出?
【发布时间】:2021-10-01 17:33:58
【问题描述】:

我正在使用 PyTransitions 生成一个简单的 FSM,并使用 yml 文件对其进行配置。 一个例子可能是这样的:

initial: A
states:
  - A
  - B
  - C
transitions:
  - {trigger: "AtoC", source: "A", dest: "C"}
  - {trigger: "CtoB", source: "C", dest: "B"}

我的问题是,使用 yml 文件,我如何写入状态输出?例如,在状态 A 打开 LED 1,状态 B 打开 LED2,状态 C 打开 LED1 和 2。我在 PyTransitions 页面中找不到任何文档。

【问题讨论】:

    标签: pytransitions


    【解决方案1】:

    我的问题是,使用 yml 文件,我如何写入状态输出?

    状态没有专用的输出槽,但您可以使用transitions 在进入或离开状态时触发某些操作。 动作可以在回调中完成。这些动作需要在模型中实现。如果你想通过配置做大部分事情,你可以自定义Machine 和使用的State 类。例如,您可以创建一个自定义 LEDState 并为其分配一个名为 led_states 的值数组,其中每个值代表一个 LED 状态。该数组应用于模型的 after_state_change 回调中的 LED,称为 update_leds

    from transitions import Machine, State
    
    
    class LEDState(State):
    
        ALL_OFF = [False] * 2  # number of LEDs
    
        def __init__(self, name, on_enter=None, on_exit=None,
                     ignore_invalid_triggers=None, led_states=None):
            # call the base class constructor without 'led_states'...
            super().__init__(name, on_enter, on_exit, ignore_invalid_triggers)
            # ... and assign its value to a custom property
            # when 'led_states' is not passed, we assign the default 
            # setting 'ALL_OFF'
            self.led_states = led_states if led_states is not None else self.ALL_OFF
    
    # create a custom machine that uses 'LEDState'
    # 'LEDMachine' will pass all parameters in the configuration
    # dictionary to the constructor of 'LEDState'.
    class LEDMachine(Machine):
       
        state_cls = LEDState
    
    
    class LEDModel:
    
        def __init__(self, config):
            self.machine = LEDMachine(model=self, **config, after_state_change='update_leds')
    
        def update_leds(self):
            print(f"---New State {self.state}---")
            for idx, led in enumerate(self.machine.get_state(self.state).led_states):
                print(f"Set LED {idx} {'ON' if led else 'OFF'}.")
    
    # using a dictionary here instead of YAML
    # but the process is the same
    config = {
        'name': 'LEDModel',
        'initial': 'Off',
        'states': [
            {'name': 'Off'},
            {'name': 'A', 'led_states': [True, False]},
            {'name': 'B', 'led_states': [False, True]},
            {'name': 'C', 'led_states': [True, True]}
        ]
    }
    
    model = LEDModel(config)
    model.to_A()
    # ---New State A---
    # Set LED 0 ON.
    # Set LED 1 OFF.
    model.to_C()
    # ---New State C---
    # Set LED 0 ON.
    # Set LED 1 ON.
    

    这只是实现这一点的一种方式。您也可以只传递一个带有索引的数组,该索引代表所有应为ON 的 LED。退出 before_state_change 状态时,我们会关闭所有 LED

    
    
    ALL_OFF = []
    
    #  ...
    
    self.machine = LEDMachine(model=self, **config, before_state_change='reset_leds', after_state_change='set_lets')
    
    # ...
    
     def reset_leds(self):
        for led_idx in range(num_leds):
            print(f"Set {led_idx} 'OFF'.")
    
     def set_lets(self):
        for led_idx in self.machine.get_state(self.state).led_states:
            print(f"Set LED {led_idx} 'ON'.")
    # ...
    
        {'name': 'A', 'led_states': [0]},
        {'name': 'B', 'led_states': [1]},
        {'name': 'C', 'led_states': [0, 1]}
    
    

    【讨论】:

      猜你喜欢
      • 2010-10-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-02
      • 2016-05-02
      • 1970-01-01
      • 2014-06-25
      • 2018-05-02
      相关资源
      最近更新 更多