Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

States node #62

Open
jonathanjfshaw opened this issue Apr 24, 2020 · 2 comments
Open

States node #62

jonathanjfshaw opened this issue Apr 24, 2020 · 2 comments

Comments

@jonathanjfshaw
Copy link
Contributor

A state machine is a fundmental programming pattern, and keeping track of states is a natural part of many biofeedback and BCI apps. Therefore I suggest having a state machine node in core.

Proof that this should be core comes from the fact that the state machine implementation I have developed would make it possible to deprecate the Periodic and Gate nodes.

This was referenced Apr 24, 2020
@jonathanjfshaw
Copy link
Contributor Author

jonathanjfshaw commented Apr 25, 2020

Here's how you would get a gate by combining a States node and an ExpressionFilter from #65:

nodes: 
    - id: my_data_source 
      ...
    - id: my_event_source
      ... 
    - id: my_gate
      module: timeflux.nodes.states
      class: States
      params:
        states: ['close', 'open']
    - id: my_filter
      module: timeflux.nodes.expression
      class: ExpressionFilter
      params:
        expression: i_gate == 'open'
        eval_on: ports

    edges:
    - source: my_data_source
      target: my_gate
    - source: my_event_source
      target: my_gate:events
    - source: my_data_source
      target: my_filter
    - source: my_gate
      target: my_filter:gate

@jonathanjfshaw
Copy link
Contributor Author

jonathanjfshaw commented Apr 25, 2020

Here's how you would get a periodic event by combining 2 states.

This example will send 5 events called "on" (spaced 200ms apart) whenever it is triggered, except not in the first 30 seconds of its life. There's no requirement for a manual trigger, I could just as well have made it be triggered automatically every 10 seconds.

nodes: 
   - id: trigger
    ...
    - id: phase
      module: timeflux.nodes.states
      class: States
      params:
        states: ['wait','quiet', 'active']
        properties: 
          wait: # This is the initial state, preventing anything from happenig in first 30 seconds.
            min_seconds: 30
            auto_transition: quiet
            auto_transition_seconds: 30
          active: # Bursts of activity last for exactly 1 second when the event "active" is received
            min_seconds: 1
            auto_transition: quiet
            auto_transition_seconds: 1
    - id: flicker # Flickers happen constantly every 200ms
      module: timeflux.nodes.states
      class: States
      params:
        states: ['on']
        properties: 
          on:
            auto_transition: on
            auto_transition_seconds: 0.2
    - id: flashes # We want the flickers to pass through only in the "active" phase
      module: timeflux.nodes.expression
      class: ExpressionFilter
      params:
        expression: i_flicker == 'on' and i_phase == 'active'
        eval_on: ports
    - id: flashes_only # If we don't want NaNs in the quiet phase, we can remove them
      module: timeflux.nodes.missing
      class: Missing
      params:
        dropna: True

    edges:
    - source: trigger
      target: phase:events
    - source: phase:transitions
      target: flashes:phase
    - source: flicker:transitions
      target: flashes:flicker
    - source: flicker:transitions
      target: flashes
    - source: flashes
      target: flashes_only

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant