commit
This commit is contained in:
commit
8a24549cdb
21 changed files with 3478 additions and 0 deletions
74
StartingPoint/lib/yakindu_helpers.py
Normal file
74
StartingPoint/lib/yakindu_helpers.py
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
# In this module, stuff that is specific to Yakindu's generated code
|
||||
# Author: Joeri Exelmans
|
||||
|
||||
from lib.controller import Controller, pretty_time
|
||||
|
||||
# for some stupid reason, we have to import the 'Observable' class like this, or `type(obj) == Observable` will fail:
|
||||
import sys, os
|
||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '../lib')))
|
||||
from yakindu.rx import Observable, Observer
|
||||
|
||||
# Adapter to allow Yakindu generated code to (un)set timeouts
|
||||
# Uses event queue of the underlying Controller, making all timed transitions scheduled in simulated time (instead of wall-clock time as in Yakindu's own TimerService).
|
||||
class YakinduTimerServiceAdapter:
|
||||
def __init__(self, controller: Controller):
|
||||
self.controller = controller;
|
||||
self.timers = {}
|
||||
|
||||
# Duration: milliseconds
|
||||
def set_timer(self, sc, event_id, duration, periodic):
|
||||
self.unset_timer(None, event_id)
|
||||
|
||||
controller_duration = duration * 1000000 # ms to ns
|
||||
|
||||
e = self.controller.add_input_lowlevel(
|
||||
self.controller.simulated_time + controller_duration, # timestamp relative to simulated time
|
||||
raise_method=sc.time_elapsed,
|
||||
value=event_id,
|
||||
event_name="__timer"+str(event_id))
|
||||
|
||||
self.timers[event_id] = e
|
||||
|
||||
def unset_timer(self, _, event_id):
|
||||
try:
|
||||
e = self.timers[event_id]
|
||||
e.canceled = True
|
||||
except KeyError:
|
||||
pass
|
||||
|
||||
|
||||
# Could not find a better way to get list of output events of a YAKINDU statechart
|
||||
def iter_output_observables(sc):
|
||||
for attr in dir(sc):
|
||||
obj = getattr(sc, attr)
|
||||
if type(obj) == Observable:
|
||||
yield (attr[0:-11], obj)
|
||||
|
||||
|
||||
# Useful for debugging
|
||||
class OutputEventTracer(Observer):
|
||||
def __init__(self, controller, event_name, callback):
|
||||
self.controller = controller
|
||||
self.event_name = event_name
|
||||
self.callback = callback
|
||||
def next(self, value=None):
|
||||
self.callback(self.controller.simulated_time, self.event_name, value)
|
||||
|
||||
def trace_output_events(controller, sc, callback, iface=None):
|
||||
if iface == None:
|
||||
for event_name, observable in iter_output_observables(sc):
|
||||
observable.subscribe(OutputEventTracer(controller, event_name, callback))
|
||||
else:
|
||||
for event_name, observable in iter_output_observables(getattr(sc, iface)):
|
||||
full_event_name = iface + '.' + event_name
|
||||
observable.subscribe(OutputEventTracer(controller, full_event_name, callback))
|
||||
|
||||
# Allows use of a simple callback to respond to an output event
|
||||
class CallbackObserver(Observer):
|
||||
def __init__(self, callback):
|
||||
self.callback = callback
|
||||
def next(self, value=None):
|
||||
if value == None:
|
||||
self.callback()
|
||||
else:
|
||||
self.callback(value)
|
||||
Loading…
Add table
Add a link
Reference in a new issue