|
|
@@ -0,0 +1,382 @@
|
|
|
+Diagram(name = 'Weaved_CBD_FSA_Simulator_Manual',
|
|
|
+ author = 'Sadaf Mustafiz and Bruno Barroca and Claudio Gomes',
|
|
|
+ description = 'Automatically woven CBD and FSA simulators with the FSA being the dominant.'):
|
|
|
+ Top {
|
|
|
+ import copy
|
|
|
+ from CBD_Controller import CBDController
|
|
|
+ import Options
|
|
|
+ from fsa_cbd_weaved_classes import CBDState
|
|
|
+ from weaved_cbd_fsa_lib import FSACBDLib
|
|
|
+ }
|
|
|
+
|
|
|
+ Class(name = 'Weaved_CBD_FSA_Simulator', default = True):
|
|
|
+ Attribute(name = 'fsa_timestep')
|
|
|
+ Attribute(name = 'fsa_elapsed')
|
|
|
+ Attribute(name = 'fsa_currentState')
|
|
|
+ Attribute(name = 'fsa_logicalTime')
|
|
|
+ Attribute(name = 'fsa_currentEvent')
|
|
|
+ Attribute(name = 'fsa_selectedTransition')
|
|
|
+ Attribute(name = 'fsa_eventList')
|
|
|
+
|
|
|
+ Attribute(name='cbd_iteration')
|
|
|
+ Attribute(name='cbd_strongComponentList')
|
|
|
+ Attribute(name='cbd_currentCompIdx')
|
|
|
+ Attribute(name='cbd_clock')
|
|
|
+ Attribute(name='cbd_options')
|
|
|
+ Attribute(name='cbd_delta')
|
|
|
+ Attribute(name='cbd_controller')
|
|
|
+ Attribute(name='cbd_depGraph')
|
|
|
+
|
|
|
+ Attribute(name='weaved_delta')
|
|
|
+ Attribute(name='woven_child_initialized')
|
|
|
+ Attribute(name='weaved_model')
|
|
|
+ Attribute(name='weaved_global_state')
|
|
|
+ Attribute(name='weaved_previous_global_state')
|
|
|
+ Attribute(name='weaved_triggered_when_transition')
|
|
|
+ Attribute(name='weaved_lib')
|
|
|
+
|
|
|
+ Method fsa_processEvent(event) {
|
|
|
+ if (event != None):
|
|
|
+ self.fsa_eventList->popEvent(event)
|
|
|
+ event.processed = True
|
|
|
+ end
|
|
|
+ }
|
|
|
+
|
|
|
+ Method fsa_getInputEventAt(time) {
|
|
|
+ return self.fsa_eventList->getInputAt(time)
|
|
|
+ }
|
|
|
+
|
|
|
+ Method cbd_computeBlock(){
|
|
|
+ if self->cbd_currentComponentIsCycle():
|
|
|
+ self.cbd_controller->computeNextAlgebraicLoop(self.cbd_strongComponentList[self.cbd_currentCompIdx], self.cbd_iteration)
|
|
|
+ else:
|
|
|
+ self.cbd_controller->computeNextBlock(self.cbd_strongComponentList[self.cbd_currentCompIdx], self.cbd_iteration)
|
|
|
+ end
|
|
|
+ }
|
|
|
+
|
|
|
+ Method cbd_maxIterationsReached() {
|
|
|
+ return self.cbd_iteration >= self.cbd_options->getMaxIterations()
|
|
|
+ }
|
|
|
+
|
|
|
+ Method cbd_hasNextStrongComponent() {
|
|
|
+ return (self.cbd_currentCompIdx) < len(self.cbd_strongComponentList)
|
|
|
+ }
|
|
|
+
|
|
|
+ Method cbd_currentComponentIsCycle() {
|
|
|
+ return self.cbd_controller->componentIsCycle(self.cbd_strongComponentList[self.cbd_currentCompIdx], self.cbd_depGraph)
|
|
|
+ }
|
|
|
+
|
|
|
+ Method updateGlobalState() {
|
|
|
+ self.weaved_previous_global_state = copy->deepcopy(self.weaved_global_state)
|
|
|
+ self.weaved_lib->updateGlobalState(self.weaved_global_state, self.fsa_currentState.cbd, self.cbd_clock)
|
|
|
+ }
|
|
|
+
|
|
|
+ Method updateCBDState() {
|
|
|
+ self.weaved_lib->updateCBDState(self.weaved_global_state, self.fsa_currentState.cbd)
|
|
|
+ }
|
|
|
+
|
|
|
+ Method getTriggeredWhenTransition() {
|
|
|
+ return self.weaved_lib->getTriggeredWhenTransition(self.weaved_model, self.fsa_currentState, self.weaved_global_state, self.weaved_previous_global_state)
|
|
|
+ }
|
|
|
+
|
|
|
+ Constructor(cbd_options, amodel, fsa_events) {
|
|
|
+ self.weaved_lib = FSACBDLib()
|
|
|
+
|
|
|
+ self.cbd_options = cbd_options
|
|
|
+ self.cbd_delta = self.cbd_options->getDeltaT()
|
|
|
+
|
|
|
+ self.weaved_model = amodel
|
|
|
+ self.fsa_eventList = fsa_events
|
|
|
+ self.fsa_timestep = 1.0
|
|
|
+ }
|
|
|
+
|
|
|
+ StateMachine:
|
|
|
+ initial = 'FSA'
|
|
|
+ final = 'HybridTerminated'
|
|
|
+ State('ParentStarted'):
|
|
|
+ Transition(target='../FSA/Initialized'):
|
|
|
+ Actions {
|
|
|
+ print('From ParentStarted to FSA/Initialized... ')
|
|
|
+ self.weaved_global_state = dict()
|
|
|
+ self.weaved_previous_global_state = dict()
|
|
|
+ self.woven_child_initialized = False
|
|
|
+ }
|
|
|
+ State('FSA'):
|
|
|
+ initial = 'Started'
|
|
|
+ State('Started'):
|
|
|
+ Transition(target='../../ParentStarted'):
|
|
|
+ Actions {
|
|
|
+ print('From FSA/Started to ParentStarted... ')
|
|
|
+ self.weaved_delta = min(self.fsa_timestep, self.cbd_delta)
|
|
|
+ self.fsa_logicalTime = 0.0
|
|
|
+ self.fsa_elapsed = 0
|
|
|
+ self.fsa_timestep = self.weaved_delta
|
|
|
+ self.fsa_currentState = self.weaved_model.initialState
|
|
|
+ }
|
|
|
+ State('Initialized'):
|
|
|
+ Transition(target='../CheckTermination'):
|
|
|
+ Actions {
|
|
|
+ print('From FSA/Initialized to FSA/CheckTermination... ')
|
|
|
+ }
|
|
|
+ State('CheckTermination'):
|
|
|
+ initial = 'MacroStepProcessed'
|
|
|
+ State('MacroStepProcessed'):
|
|
|
+ Transition(target='../../MacroStepPrepared'):
|
|
|
+ guard = { not self.fsa_currentState.final }
|
|
|
+ Actions {
|
|
|
+ print('From FSA/CheckTermination/MacroStepProcessed to FSA/MacroStepPrepared and reading events... ')
|
|
|
+ self.fsa_currentEvent = self->fsa_getInputEventAt(self.fsa_logicalTime)
|
|
|
+ self.fsa_selectedTransition = self.weaved_model->getTransitionFrom(self.fsa_currentState, self.fsa_currentEvent, self.fsa_elapsed)
|
|
|
+ print(self.fsa_currentEvent)
|
|
|
+ print(self.fsa_selectedTransition)
|
|
|
+ }
|
|
|
+ Transition(target='../../Terminated'):
|
|
|
+ guard = { self.fsa_currentState.final }
|
|
|
+ Actions {
|
|
|
+ print('From FSA/CheckTermination/MacroStepProcessed to Terminated... ')
|
|
|
+ }
|
|
|
+ State('MacroStepPrepared'):
|
|
|
+ Transition(target='../MicroStepProcessed'):
|
|
|
+ guard = { False }
|
|
|
+ Actions {
|
|
|
+ print('From FSA/MacroStepPrepared to MicroStepProcessed... ')
|
|
|
+ }
|
|
|
+ Transition(target='../../ParentPaused'):
|
|
|
+ Actions {
|
|
|
+ print('From FSA/MacroStepPrepared to ParentPaused... ')
|
|
|
+ }
|
|
|
+ State('MicroStepProcessed'):
|
|
|
+ Transition(target='../CheckTermination'):
|
|
|
+ guard = { self.fsa_selectedTransition == None}
|
|
|
+ Actions {
|
|
|
+ print('From FSA/MicroStepProcessed to FSA/CheckTermination and advancing time... ')
|
|
|
+ self.fsa_logicalTime = self.fsa_logicalTime + self.fsa_timestep
|
|
|
+ self.fsa_elapsed = self.fsa_elapsed + self.fsa_timestep
|
|
|
+ print(self.fsa_logicalTime)
|
|
|
+ print(self.fsa_elapsed)
|
|
|
+ }
|
|
|
+ Transition(target='../MicroStepPrepared'):
|
|
|
+ guard = { self.fsa_selectedTransition != None }
|
|
|
+ Actions {
|
|
|
+ print('From FSA/MicroStepProcessed to MicroStepPrepared... ')
|
|
|
+ }
|
|
|
+ State('MicroStepPrepared'):
|
|
|
+ Transition(target='../MicroStepProcessed'):
|
|
|
+ guard = { False }
|
|
|
+ Actions {
|
|
|
+ print('From FSA/MicroStepPrepared to MicroStepProcessed and attempting to take transition... ')
|
|
|
+ print('Transition to be taken: ' + str(self.fsa_selectedTransition))
|
|
|
+ self.fsa_currentState = self.fsa_selectedTransition.target
|
|
|
+ self.fsa_elapsed = 0
|
|
|
+ self->fsa_processEvent(self.fsa_currentEvent)
|
|
|
+ self.weaved_lib->dumpDiscreteEvent(self.weaved_model, self.fsa_logicalTime, self.fsa_currentState , self.fsa_selectedTransition)
|
|
|
+ self.weaved_lib->dumpGlobalState(self.weaved_model, self.weaved_global_state , self.fsa_logicalTime, self.fsa_currentState)
|
|
|
+ print('New state: ' + str(self.fsa_currentState))
|
|
|
+
|
|
|
+ print('Reading events:')
|
|
|
+ self.fsa_currentEvent = self->fsa_getInputEventAt(self.fsa_logicalTime)
|
|
|
+ self.fsa_selectedTransition = self.weaved_model->getTransitionFrom(self.fsa_currentState, self.fsa_currentEvent, self.fsa_elapsed)
|
|
|
+ print(self.fsa_currentEvent)
|
|
|
+ print(self.fsa_selectedTransition)
|
|
|
+ }
|
|
|
+ Transition(target='../../ParentMicroStepProcessed'):
|
|
|
+ Actions {
|
|
|
+ print('From FSA/MicroStepPrepared to ParentMicroStepProcessed and attempting to take transition... ')
|
|
|
+ print('Transition to be taken: ' + str(self.fsa_selectedTransition))
|
|
|
+ self.fsa_currentState = self.fsa_selectedTransition.target
|
|
|
+ self.fsa_elapsed = 0
|
|
|
+ self->fsa_processEvent(self.fsa_currentEvent)
|
|
|
+ self.weaved_lib->dumpDiscreteEvent(self.weaved_model, self.fsa_logicalTime, self.fsa_currentState , self.fsa_selectedTransition)
|
|
|
+ self.weaved_lib->dumpGlobalState(self.weaved_model, self.weaved_global_state , self.fsa_logicalTime, self.fsa_currentState)
|
|
|
+ print('New state: ' + str(self.fsa_currentState))
|
|
|
+
|
|
|
+ print('Reading events:')
|
|
|
+ self.fsa_currentEvent = self->fsa_getInputEventAt(self.fsa_logicalTime)
|
|
|
+ self.fsa_selectedTransition = self.weaved_model->getTransitionFrom(self.fsa_currentState, self.fsa_currentEvent, self.fsa_elapsed)
|
|
|
+ print(self.fsa_currentEvent)
|
|
|
+ print(self.fsa_selectedTransition)
|
|
|
+ }
|
|
|
+ State('Terminated'):
|
|
|
+ Transition(target='../../HybridTerminated'):
|
|
|
+ Actions {
|
|
|
+ print('From FSA/Terminated to HybridTerminated... ')
|
|
|
+ }
|
|
|
+ State('ParentMicroStepProcessed'):
|
|
|
+ Transition(target='../ParentPaused'):
|
|
|
+ Actions {
|
|
|
+ print('From ParentMicroStepProcessed to ParentPaused and resetting the child... ')
|
|
|
+ self.woven_child_initialized = False
|
|
|
+ }
|
|
|
+ State('HybridTerminated')
|
|
|
+ State('ChildNotInitialized'):
|
|
|
+ Transition(target='../CBD/Started'):
|
|
|
+ Actions {
|
|
|
+ print('From ChildNotInitialized to CBD/Started... ')
|
|
|
+ self.cbd_delta = self.weaved_delta
|
|
|
+ self->updateCBDState()
|
|
|
+ self.woven_child_initialized = True
|
|
|
+ }
|
|
|
+ State('ChildInitialized'):
|
|
|
+ Transition(target='../CBD/MacroStepProcessed'):
|
|
|
+ Actions {
|
|
|
+ print('From ChildInitialized to CBD/MacroStepProcessed... ')
|
|
|
+ self.cbd_clock = self.cbd_clock + self.cbd_delta
|
|
|
+ self.cbd_iteration = self.cbd_iteration + 1
|
|
|
+ self.cbd_controller->advanceTimeStep()
|
|
|
+ print("CBD clock: " + str(self.cbd_clock))
|
|
|
+ print("CBD iteration: " + str(self.cbd_iteration))
|
|
|
+ }
|
|
|
+ State('ChildPaused'):
|
|
|
+ Transition(target='../StateEventDetected'):
|
|
|
+ guard = { self.weaved_triggered_when_transition != None }
|
|
|
+ Actions {
|
|
|
+ print('From ChildPaused to StateEventDetected... ')
|
|
|
+ }
|
|
|
+ Transition(target='../NoStateEventDetected'):
|
|
|
+ guard = { self.weaved_triggered_when_transition == None }
|
|
|
+ Actions {
|
|
|
+ print('From ChildPaused to NoStateEventDetected... ')
|
|
|
+ }
|
|
|
+ State('NoStateEventDetected'):
|
|
|
+ Transition(target='../ChildProcessed'):
|
|
|
+ Actions {
|
|
|
+ print('From NoStateEventDetected to ChildProcessed... ')
|
|
|
+ }
|
|
|
+ State('StateEventDetected'):
|
|
|
+ Transition(target='../ChildProcessed'):
|
|
|
+ Actions {
|
|
|
+ print('From StateEventDetected to ChildProcessed... ')
|
|
|
+ if self.fsa_selectedTransition == None:
|
|
|
+ self.fsa_selectedTransition = self.weaved_triggered_when_transition
|
|
|
+ end
|
|
|
+ }
|
|
|
+ State('ChildProcessed'):
|
|
|
+ Transition(target='../FSA/MicroStepProcessed'):
|
|
|
+ Actions {
|
|
|
+ print('From ChildProcessed to FSA/MicroStepProcessed... ')
|
|
|
+ }
|
|
|
+ State('ParentPaused'):
|
|
|
+ Transition(target='../ChildProcessed'):
|
|
|
+ guard = { not isinstance(self.fsa_currentState, CBDState) }
|
|
|
+ Actions {
|
|
|
+ print('From ParentPaused to ChildProcessed without any child to process... ')
|
|
|
+ }
|
|
|
+ Transition(target='../ChildDetected'):
|
|
|
+ guard = { isinstance(self.fsa_currentState, CBDState) }
|
|
|
+ Actions {
|
|
|
+ print('From ParentPaused to ChildDetected... ')
|
|
|
+ self.cbd_model = self.fsa_currentState.cbd
|
|
|
+ }
|
|
|
+ State('ChildDetected'):
|
|
|
+ Transition(target='../ChildNotInitialized'):
|
|
|
+ guard = { not self.woven_child_initialized }
|
|
|
+ Actions {
|
|
|
+ print('From ChildDetected to ChildNotInitialized... ')
|
|
|
+ }
|
|
|
+ Transition(target='../ChildInitialized'):
|
|
|
+ guard = { self.woven_child_initialized }
|
|
|
+ Actions {
|
|
|
+ print('From ChildDetected to ChildInitialized... ')
|
|
|
+ }
|
|
|
+ State('CBD'):
|
|
|
+ initial = 'Started'
|
|
|
+ State('Started'):
|
|
|
+ Transition(target='../Initialized'):
|
|
|
+ Actions {
|
|
|
+ print('From CBD/Started to Initialized... ')
|
|
|
+ print('Performing initialization...')
|
|
|
+ self.cbd_iteration = 0
|
|
|
+ self.cbd_clock = 0
|
|
|
+ self.cbd_controller = CBDController(self.cbd_model,self.cbd_delta)
|
|
|
+ self.cbd_controller->initSimulation()
|
|
|
+ print('Performing initialization... DONE')
|
|
|
+ }
|
|
|
+ State('Initialized'):
|
|
|
+ Transition(target='../MacroStepProcessed'):
|
|
|
+ Actions {
|
|
|
+ print('From CBD/Initialized to MacroStepProcessed... ')
|
|
|
+ }
|
|
|
+ State('MacroStepProcessed'):
|
|
|
+ Transition(target='../MacroStepPrepared'):
|
|
|
+ guard = { not self->cbd_maxIterationsReached() }
|
|
|
+ Actions {
|
|
|
+ print('From CBD/MacroStepProcessed to MacroStepPrepared... ')
|
|
|
+ self.cbd_currentCompIdx = 0
|
|
|
+ self.cbd_depGraph = self.cbd_controller->createDepGraph(self.cbd_iteration)
|
|
|
+ self.cbd_strongComponentList = self.cbd_controller->createStrongComponents(self.cbd_depGraph, self.cbd_iteration)
|
|
|
+ }
|
|
|
+ Transition(target='../Terminated'):
|
|
|
+ guard = { self->cbd_maxIterationsReached() }
|
|
|
+ Actions {
|
|
|
+ print('From CBD/MacroStepProcessed to Terminated... ')
|
|
|
+ }
|
|
|
+ State('MacroStepPrepared'):
|
|
|
+ Transition(target='../MicroStepProcessed'):
|
|
|
+ Actions {
|
|
|
+ print('From CBD/MacroStepPrepared to MicroStepProcessed... ')
|
|
|
+ }
|
|
|
+ State('MicroStepProcessed'):
|
|
|
+ Transition(target='../MacroStepProcessed'):
|
|
|
+ guard = { not self->cbd_hasNextStrongComponent() and False }
|
|
|
+ Actions {
|
|
|
+ print('From CBD/MicroStepProcessed to MacroStepProcessed and advancing time... ')
|
|
|
+ self.cbd_clock = self.cbd_clock + self.cbd_delta
|
|
|
+ self.cbd_iteration = self.cbd_iteration + 1
|
|
|
+ self.cbd_controller->advanceTimeStep()
|
|
|
+ print("CBD clock: " + str(self.cbd_clock))
|
|
|
+ print("CBD iteration: " + str(self.cbd_iteration))
|
|
|
+ }
|
|
|
+ Transition(target='../../ChildPaused'):
|
|
|
+ guard = { not self->cbd_hasNextStrongComponent() }
|
|
|
+ Actions {
|
|
|
+ print('From CBD/MicroStepProcessed to ChildPaused and detecting triggered transitions... ')
|
|
|
+ self->updateGlobalState()
|
|
|
+ self.weaved_lib->dumpGlobalState(self.weaved_model, self.weaved_global_state , self.fsa_logicalTime, self.fsa_currentState)
|
|
|
+ self.weaved_triggered_when_transition = self->getTriggeredWhenTransition()
|
|
|
+ }
|
|
|
+ Transition(target='../MicroStepPrepared'):
|
|
|
+ guard = { self->cbd_hasNextStrongComponent() }
|
|
|
+ Actions {
|
|
|
+ print('From CBD/MicroStepProcessed to MicroStepPrepared')
|
|
|
+ }
|
|
|
+ State('MicroStepPrepared'):
|
|
|
+ Transition(target='../MicroStepProcessed'):
|
|
|
+ Actions {
|
|
|
+ print('From CBD/MicroStepPrepared to MicroStepProcessed...')
|
|
|
+ self->cbd_computeBlock()
|
|
|
+ self.cbd_currentCompIdx = self.cbd_currentCompIdx + 1
|
|
|
+ }
|
|
|
+ State('Terminated'):
|
|
|
+ Transition(target='../../HybridTerminated'):
|
|
|
+ Actions {
|
|
|
+ print('From CBD/Terminated to HybridTerminated... ')
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|