Browse Source

added scenario which is unstable

Cláudio Gomes 4 years ago
parent
commit
551269f0f4

+ 1 - 0
SemanticAdaptationForFMI/FMIAbstraction/.gitignore

@@ -0,0 +1 @@
+/log.txt

+ 41 - 0
SemanticAdaptationForFMI/FMIAbstraction/src/sampleunits/WindowFMU.py

@@ -0,0 +1,41 @@
+from units.CTSimulationUnit_Euler import CTSimulationUnit_Euler
+
+class WindowFMU(CTSimulationUnit_Euler):
+    
+    def __init__(self, name, num_rtol, num_atol, internal_step_size, J, r, b, c):
+        self.omega_input = "omega_input"
+        self.theta_input = "theta_input"
+        self.tau = "tau"
+        self.x = "x"
+        self.v = "v"
+        self.omega = "omega"
+        self.theta = "theta"
+        
+        input_vars = [self.omega_input, self.theta_input]
+        
+        def calc_v(x, u):
+            return r * x[self.omega]
+        def calc_x(x, u):
+            return r * x[self.theta]
+        def calc_tau(x,u):
+            return c * ( u[self.theta_input] - x[self.theta] ) - b * calc_v(x,u)
+        
+        def der_theta(x, u):
+            return x[self.omega]
+        def der_omega(x, u):
+            return calc_tau(x,u) / J
+        
+        state_derivatives = {
+                             self.theta: der_theta,
+                             self.omega: der_omega
+                             }
+        
+        output_functions = {
+                            self.v : calc_v,
+                            self.x : calc_x,
+                            self.tau: calc_tau
+                            }
+        
+        CTSimulationUnit_Euler.__init__(self, name, num_rtol, num_atol, internal_step_size, state_derivatives, output_functions, input_vars)
+    
+    

+ 1 - 0
SemanticAdaptationForFMI/FMIAbstraction/src/scenarios/.gitignore

@@ -1 +1,2 @@
 /results.html
+/results_x.html

+ 114 - 0
SemanticAdaptationForFMI/FMIAbstraction/src/scenarios/NoObstacleTest.py

@@ -0,0 +1,114 @@
+from bokeh.plotting import figure, output_file, show
+from sampleunits.PowerFMU import PowerFMU
+import logging
+from sampleunits.WindowFMU import WindowFMU
+l = logging.getLogger()
+l.setLevel(logging.DEBUG)
+
+def env_up(time):
+    return 1.0 if time < 6 else 0.0
+
+def env_down(time):
+    return 0.0 if time < 6 else 1.0
+
+cosim_step_size = 0.00001;
+stop_time = 1.0;
+
+power = PowerFMU("power", 1e-08, 1e-08, cosim_step_size, 
+                     J=0.085, 
+                     b=5, 
+                     K=1.8, 
+                     R=0.15, 
+                     L=0.036,
+                     V=12)
+
+window = WindowFMU("window", 1e-08, 1e-08, cosim_step_size, 
+                     J=0.085, 
+                     r=0.017, 
+                     b = 150, 
+                     c = 1e5)
+
+power.enterInitMode()
+window.enterInitMode()
+
+# Solve initialisation.
+# Notice the order in which the FMUs can be given inputs and obtained outputs.
+
+power.setValues(0, 0, {power.i: 0.0,
+                            power.omega: 0.0,
+                            power.theta: 0.0,
+                            power.up: env_up(0.0),
+                            power.down: env_down(0.0)
+                            })
+
+pOut = power.getValues(0, 0, [power.omega, power.theta])
+
+window.setValues(0, 0, {window.omega_input: pOut[power.omega],
+                            window.theta_input: pOut[power.theta],
+                            window.theta: 0.0,
+                            window.omega: 0.0
+                            })
+
+wOut = window.getValues(0, 0, [window.tau])
+
+power.setValues(0, 0, {power.tau: wOut[window.tau]})
+
+power.exitInitMode()
+window.exitInitMode()
+
+trace_i = [0.0]
+trace_omega = [0.0]
+trace_x = [0.0]
+times = [0.0]
+
+time = 0.0
+
+for step in range(1, int(stop_time / cosim_step_size) + 1):
+    
+    # set old values for window (this is not ideal)
+    pOut = power.getValues(step-1, 0, [power.omega, power.theta, power.i])
+    window.setValues(step, 0, {window.omega_input: pOut[power.omega],
+                            window.theta_input: pOut[power.theta]})
+    
+    window.doStep(time, step, 0, cosim_step_size)
+    
+    wOut = window.getValues(step, 0, [window.tau, window.x])
+    
+    # Coupling equation
+    power_tau = - wOut[window.tau]
+    
+    power.setValues(step, 0, {power.tau: power_tau,
+                                  power.up: env_up(time),
+                                  power.down: env_down(time)})
+    
+    power.doStep(time, step, 0, cosim_step_size)
+    
+    pOut = power.getValues(step, 0, [power.omega, power.theta, power.i])
+    
+    times.append(time)
+    trace_omega.append(pOut[power.omega])
+    trace_i.append(pOut[power.i])
+    trace_x.append(wOut[window.x])
+    time += cosim_step_size
+
+color_pallete = [
+                "#e41a1c",
+                "#377eb8",
+                "#4daf4a",
+                "#984ea3",
+                "#ff7f00",
+                "#ffff33",
+                "#a65628",
+                "#f781bf"
+                 ]
+
+output_file("./results.html", title="Results")
+p = figure(title="Plot", x_axis_label='time', y_axis_label='')
+p.line(x=range(len(trace_omega)), y=trace_omega, legend="trace_omega", color=color_pallete[0])
+p.line(x=range(len(trace_i)), y=trace_i, legend="trace_i", color=color_pallete[1])
+show(p)
+
+output_file("./results_x.html", title="Results")
+p = figure(title="Plot", x_axis_label='time', y_axis_label='')
+p.line(x=range(len(trace_x)), y=trace_x, legend="trace_x", color=color_pallete[2])
+show(p)

+ 27 - 7
SemanticAdaptationForFMI/FMIAbstraction/src/units/AbstractSimulationUnit.py

@@ -37,9 +37,9 @@ class AbstractSimulationUnit(object):
         
         self._name = name
         self.__state = {}
+        self.__outputs_dirty = {}
         self.__computed_time = []
         self.__mode = INSTANTIATED_MODE
-        self.__outputs_dirty = False
         
         self.__out_functions = output_functions
         self.__state_vars = state_vars
@@ -54,6 +54,7 @@ class AbstractSimulationUnit(object):
             self.__state[var] = []
         for var in self.__output_vars:
             self.__state[var] = []
+            self.__outputs_dirty[var] = False
         for var in input_vars:
             self.__state[var] = []
         
@@ -88,9 +89,12 @@ class AbstractSimulationUnit(object):
         assert self.__mode == STEP_MODE
         assert step_size > 0
         
+        """ This is not done here because it may not be possible to do it for 
+                the current step as it has not been computed.
         if self.__outputs_dirty:
             self.__computeOutputs(step, current_iteration)
             self.__outputs_dirty = False
+        """
         
         # Record time, even if the step is not accepted.
         self.__recordTime(time, step, current_iteration, step_size)
@@ -134,20 +138,36 @@ class AbstractSimulationUnit(object):
         for var in varsToPrint:
             strState += var + "=" + str(self.__state[var][step][iteration]) + "\n"
         return strState
+    
+    def __markOutputsDirty(self, step, iteration, whichOnes=None):
+        output_vars = self.__output_vars if whichOnes==None else whichOnes
+        for out_var in output_vars:
+            if self.__outputs_dirty.has_key(out_var):
+                self.__outputs_dirty[out_var] = True
+            
+    def __areOutputsDirty(self, step, iteration, whichOnes=None):
+        var_names = self.__output_vars if whichOnes==None else whichOnes
+        for out_var in var_names:
+            if self.__outputs_dirty.has_key(out_var):
+                if self.__outputs_dirty[out_var]:
+                    return True
+        return False
         
     def setValues(self, step, iteration, values):
         l.debug(">%s.setValues(%d, %d, %s)", self._name, step, iteration, values)
         Utils.copyMapToStateTrace(self.__state, step, iteration, values)
-        self.__outputs_dirty = True
+        
+        self.__markOutputsDirty(step, iteration);
+        
         l.debug("New state: \n%s", self._printState(step,iteration, values.keys()))
         l.debug("<%s.setValues()", self._name)
         
     
     def getValues(self, step, iteration, var_names):
         l.debug(">%s.getValues(%d, %d, %s)", self._name, step, iteration, var_names)
-        if self.__outputs_dirty:
+        if self.__areOutputsDirty(step, iteration, var_names):
             self.__computeOutputs(step, iteration)
-            self.__outputs_dirty = True
+            self.__markOutputsDirty(step, iteration, var_names);
         
         values = {}
         for var in var_names:
@@ -169,9 +189,9 @@ class AbstractSimulationUnit(object):
         
     def exitInitMode(self):
         l.debug(">%s.exitInitMode()", self._name)
-        if self.__outputs_dirty:
-            self.__computeOutputs(0, 0)
-            self.__outputs_dirty = False
+        if self.__areOutputsDirty(0,0):
+            self.__computeOutputs(0,0)
+            self.__markOutputsDirty(0,0)
         self.__mode = STEP_MODE
         l.debug("<%s.exitInitMode()", self._name)
         

+ 5 - 5
SemanticAdaptationForFMI/FMIAbstraction/src/units/Utils.py

@@ -9,7 +9,7 @@ class Utils(object):
     @staticmethod
     def copyMapToStateTrace(target, step, iteration, source):
         for var in source:
-            Utils.copyValueToStateTrace(target, var, step, iteration, source)
+            Utils.copyValueToStateTrace(target, var, step, iteration, source[var])
     
     @staticmethod
     def getValuesUpToDate(source, vars_to_select, step, iteration):
@@ -23,14 +23,14 @@ class Utils(object):
         return result
     
     @staticmethod
-    def copyValueToStateTrace(target, var, step, iteration, source):
+    def copyValueToStateTrace(target, var, step, iteration, value):
         assert target.has_key(var)
         if step == len(target[var]):
-            target[var].append([source[var]])
+            target[var].append([value])
         elif iteration == len(target[var][step]):
-            target[var][step].append(source[var])
+            target[var][step].append(value)
         else:
-            target[var][step][iteration] = source[var]
+            target[var][step][iteration] = value
     
     @staticmethod
     def trimList(listToTrim, target_size):