Kaynağa Gözat

corrected and calibrated case study

Cláudio Gomes 8 yıl önce
ebeveyn
işleme
82157a70c3

+ 3 - 0
.gitignore

@@ -1,2 +1,5 @@
 /SemanticAdaptationForFMI/FMIAbstraction/src/sampleunits/*.pyc
 /SemanticAdaptationForFMI/FMIAbstraction/src/units/*.pyc
+/SemanticAdaptationForFMI/FMIAbstraction/src/abstract_units/*.pyc
+/SemanticAdaptationForFMI/FMIAbstraction/src/case_study/*.pyc
+/SemanticAdaptationForFMI/FMIAbstraction/src/case_study/units/*.pyc

+ 6 - 5
ModelicaModels/Obstacle.mo

@@ -1,11 +1,12 @@
 model Obstacle
-  parameter Real c = 1e5;
+  parameter Real c = 1e10;
   parameter Real fixed_x = 0.45;
   input Real x;
   output Real F;
+  Real compression;
 equation
-  F = if x > fixed_x then c*(x - fixed_x) else 0;
-annotation(
-  experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-6, Interval = 0.002)
-);
+  compression = x - fixed_x;
+  F = if x > fixed_x then c * compression else 0;
+  annotation(
+    experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-06, Interval = 0.002));
 end Obstacle;

+ 4 - 4
ModelicaModels/PowerSystem.mo

@@ -1,7 +1,7 @@
 model PowerSystem
   parameter Real J = 0.085;
   parameter Real b = 5;
-  parameter Real K = 1.8;
+  parameter Real K = 7.45;
   parameter Real R = 0.15;
   parameter Real L = 0.036;
   parameter Real V_abs = 12;
@@ -14,10 +14,10 @@ model PowerSystem
   input Real d;
 equation
   V = if u > 0.5 then V_abs 
-      else if d > 0.5 then - V_abs
+      else if d > 0.5 then -V_abs
       else 0.0;
-  der(omega) = (K * i + tau - b * omega) / J;
-  L * der(i) = V - R * i - K * omega;
+  J * der(omega) + b * omega = K * i - tau;
+  L * der(i) + R * i = V - K * omega;
   der(theta) = omega;
 annotation(
   experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-6, Interval = 0.002)

+ 3 - 2
ModelicaModels/PowerSystem_Test.mo

@@ -1,7 +1,8 @@
 model PowerSystem_Test
   PowerSystem power();
 equation
-  power.tau = 0.0;
+  power.tau = if time < 4 then 0.0 else 100.0;
   power.u = if time < 0.5 then 0.0 else 1.0;
   power.d = 0.0;
-end PowerSystem_Test;
+annotation(
+    experiment(StartTime = 0, StopTime = 6, Tolerance = 1e-06, Interval = 0.0024));end PowerSystem_Test;

+ 4 - 2
ModelicaModels/UncontrolledScenario.mo

@@ -7,8 +7,10 @@ equation
   power.d = 0.0;
   window.omega_input = power.omega;
   window.theta_input = power.theta;
-  power.tau = -(window.tau + obstacle.F*window.r);
+  window.obj_F = obstacle.F;
+  power.tau = window.tau;
   obstacle.x = window.x;
   annotation(
-    experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-06, Interval = 0.004));
+    experiment(StartTime = 0, StopTime = 6, Tolerance = 1e-06, Interval = 0.0024),
+    __OpenModelica_simulationFlags(jacobian = "coloredNumerical", s = "dassl", lv = "LOG_STATS"));
 end UncontrolledScenario;

+ 16 - 16
ModelicaModels/Window.mo

@@ -1,25 +1,25 @@
 model Window
-  parameter Real J = 0.08;
-  parameter Real r = 0.017;
-  parameter Real b = 150;
-  parameter Real c = 1e3;
+  //parameter Real J = 0.01;
+  parameter Real r = 0.11;
+  parameter Real b = 10;
+  //parameter Real c = 1e5;
   input Real omega_input;
   input Real theta_input;
+  input Real obj_F;
   output Real tau;
   output Real x;
   output Real v;
-  output Real omega;
-  output Real theta;
+  //output Real omega;
+  //output Real theta;
   output Real friction;
 equation
-  der(theta) = omega;
-  tau = c * (theta_input - theta) - friction;
-  //tau = c * (theta - theta_input);
-  der(omega) = tau/J;
-  x = r * theta;
-  v = r * omega;
-  friction = b*v;
-annotation(
-  experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-6, Interval = 0.002)
-);
+//der(theta) = omega;
+//tau = c * (theta_input - theta) ; //- obj_F*r
+  tau = obj_F * r + friction;
+//der(omega) = (tau - friction)/J;
+  x = r * theta_input;
+  v = r * omega_input;
+  friction = b * v;
+  annotation(
+    experiment(StartTime = 0, StopTime = 1, Tolerance = 1e-06, Interval = 0.002));
 end Window;

+ 8 - 5
SemanticAdaptationForFMI/FMIAbstraction/src/abstract_units/AbstractSimulationUnit.py

@@ -108,8 +108,11 @@ class AbstractSimulationUnit(object):
     def _doInternalSteps(self, time, step, iteration, cosim_step_size):
         raise "Must be implemented in subclasses"
 
-    def __computeOutputs(self, step, iteration):
-        l.debug(">__computeOutputs(%d, %d)", step, iteration)
+    def __computeOutputs(self, step, iteration, whichOnes=None):
+        l.debug(">__computeOutputs(%d, %d, %s)", step, iteration, whichOnes)
+        
+        var_names = self.__algebraic_vars if whichOnes==None else whichOnes
+        
         # This does not support algebraic loops.
         
         # Get the state and input vars to be used for the computation of the values
@@ -123,12 +126,12 @@ class AbstractSimulationUnit(object):
         
         l.debug("outputs to update = %s", self.__algebraic_vars)
         
-        for var in self.__algebraic_vars:
+        for var in var_names:
             new_value = self.__algebraic_functions[var](current_state_snaptshot, current_input_snaptshot)
             Utils.copyValueToStateTrace(self.__state, var, step, iteration, new_value)
         
         l.debug("Updated portion of the state:\n%s", 
-                    self._printState(step, iteration, self.__algebraic_functions.keys()))
+                    self._printState(step, iteration, var_names))
         
         l.debug("<__computeOutputs()")
     
@@ -179,7 +182,7 @@ class AbstractSimulationUnit(object):
     def getValues(self, step, iteration, var_names):
         l.debug(">%s.getValues(%d, %d, %s)", self._name, step, iteration, var_names)
         if self.__areAlgVarsDirty(step, iteration, var_names):
-            self.__computeOutputs(step, iteration)
+            self.__computeOutputs(step, iteration, whichOnes=var_names)
             self.__markAlgVars(step, iteration, dirty=False, whichOnes=var_names);
         
         values = {}

+ 57 - 57
SemanticAdaptationForFMI/FMIAbstraction/src/case_study/scenarios/ControlledScenario_CTStatecharts.py

@@ -15,7 +15,6 @@ from case_study.units.ct_based.WindowFMU import WindowFMU
 from case_study.units.de_based.DriverControllerStatechartFMU_CTInOut import DriverControllerStatechartFMU_CTInOut
 from case_study.units.de_based.EnvironmentStatechartFMU_CTInOut import EnvironmentStatechartFMU_CTInOut
 
-
 NUM_RTOL = 1e-08
 NUM_ATOL = 1e-08
 
@@ -23,8 +22,8 @@ l = logging.getLogger()
 l.setLevel(logging.DEBUG)
 
 cosim_step_size = 0.001
-num_internal_steps = 10
-stop_time = 10;
+num_internal_steps = 1
+stop_time = 6;
 
 environment = EnvironmentStatechartFMU_CTInOut("env", NUM_RTOL, NUM_ATOL)
 
@@ -33,21 +32,17 @@ controller = DriverControllerStatechartFMU_CTInOut("controller", NUM_RTOL, NUM_A
 power = PowerFMU("power", NUM_RTOL, NUM_ATOL, cosim_step_size/num_internal_steps, 
                      J=0.085, 
                      b=5, 
-                     K=1.8, 
+                     K=7.45, 
                      R=0.15, 
                      L=0.036,
                      V_a=12)
 
-armature_threshold = 20.0
+armature_threshold = 5
 adapt_armature = InacurateControllerArmatureAdaptation_CT("arm_adapt", NUM_RTOL, NUM_ATOL, armature_threshold, True)
 
-window_radius = 0.017
-
-window = WindowFMU("window", NUM_RTOL, NUM_ATOL, cosim_step_size/num_internal_steps, 
-                     J=0.085, 
-                     r=window_radius, 
-                     b = 150, 
-                     c = 1e3) # c = 1e5 makes this an unstable system.
+window = WindowFMU("window", NUM_RTOL, NUM_ATOL, cosim_step_size/num_internal_steps,
+                     r=0.11, 
+                     b = 10)
 
 obstacle = ObstacleFMU("obstacle", NUM_RTOL, NUM_ATOL, cosim_step_size/num_internal_steps, 
                      c=1e5, 
@@ -66,6 +61,10 @@ The initialisation may impose a completely different order for the execution of
 In this case we know that there is no direct feed-through between the power input and its outputs,
     so we can safely set its initial state, get its output, and then compute all the other FMUs,
     before setting the new inputs to the power.
+There is also a tight coupling between the window and the obstacle FMU but we 
+    know what the initial force is, so we can use that to set the inputs and outputs in the right order,
+    without having to do a fixed point iteration.
+    But in the general case, we would need a fixed point iteration.
 """
 
 power.setValues(0, 0, {
@@ -77,14 +76,15 @@ pOut = power.getValues(0, 0, [power.omega, power.theta, power.i])
 
 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, window.x])
+wOut = window.getValues(0, 0, [window.x])
 
 obstacle.setValues(0, 0, {obstacle.x: wOut[window.x]})
 oOut = obstacle.getValues(0, 0, [obstacle.F])
 
+window.setValues(0, 0, {window.F_obj: oOut[obstacle.F]})
+wOut = window.getValues(0, 0, [window.tau])
+
 adapt_armature.setValues(0, 0, {adapt_armature.armature_current: pOut[power.i],
                                 adapt_armature.out_obj: 0.0 })
 
@@ -98,11 +98,8 @@ controller.setValues(0, 0, {controller.in_dup : envOut[environment.out_up],
 
 cOut = controller.getValues(0, 0, [controller.out_up, controller.out_down])
 
-# Coupling equation for power
-power_tau = - ( wOut[window.tau] + window_radius * oOut[obstacle.F])
-
 # Finally set the other power inputs
-power.setValues(0, 0, {power.tau: power_tau, 
+power.setValues(0, 0, {power.tau: wOut[window.tau], 
                        power.up: cOut[controller.out_up],
                        power.down: cOut[controller.out_down]})
 
@@ -131,62 +128,65 @@ for step in range(1, int(stop_time / cosim_step_size) + 1):
     # value given for the inputs. However, that creates an algebraic loop, 
     # so for now, we just get old values for the inputs.
     
-    # Apart from that, the code below is the same as the one in the initialization
+    # Compute environment
+    environment.doStep(time, step, iteration, cosim_step_size) 
+    envOut = environment.getValues(step, iteration, [environment.out_up, environment.out_down])
     
-    oOut = obstacle.getValues(step-1, iteration, [obstacle.F])
-    wOut = window.getValues(step-1, iteration, [window.tau, window.x])
-    cOut = controller.getValues(step-1, iteration, [controller.out_up, controller.out_down])
+    # Get delayed output from power, to break the algebraic loop.
+    pOut = power.getValues(step-1, iteration, [power.omega, power.theta, power.i])
     
-    # Coupling equation for power
-    power_tau = - ( wOut[window.tau] + window_radius * oOut[obstacle.F])
+    # Compute armature
+    adapt_armature.setValues(step, iteration, {adapt_armature.armature_current: pOut[power.i]})
+    adapt_armature.doStep(time, step, iteration, cosim_step_size) 
+    adaptArmOut = adapt_armature.getValues(step, iteration, [adapt_armature.out_obj])
     
-    # Set the delayed inputs to the power
-    power.setValues(step, iteration, {power.tau: power_tau, 
-                           power.up: cOut[controller.out_up],
-                           power.down: cOut[controller.out_down]})
+    # Compute controller
+    controller.setValues(step, iteration, {controller.in_dup : envOut[environment.out_up],
+                            controller.in_ddown : envOut[environment.out_down],
+                            controller.in_obj : adaptArmOut[adapt_armature.out_obj]})
+    controller.doStep(time, step, iteration, cosim_step_size) 
+    cOut = controller.getValues(step, iteration, [controller.out_up, controller.out_down])
     
-    power.doStep(time, step, iteration, cosim_step_size)
+    # Get delayed outputs from window, to break the algebraic loop it was with the obstacle.
+    wOut = window.getValues(step-1, iteration, [window.tau, window.x])
     
-    pOut = power.getValues(step, iteration, [power.omega, power.theta, power.i])
+    # Compute obstacle
+    obstacle.setValues(step, iteration, {obstacle.x: wOut[window.x]})
+    obstacle.doStep(time, step, iteration, cosim_step_size) 
+    oOut = obstacle.getValues(step, iteration, [obstacle.F])
     
+    # Compute the window, with the delayed inputs from the power
     window.setValues(step, iteration, {window.omega_input: pOut[power.omega],
-                            window.theta_input: pOut[power.theta]
+                                       window.theta_input: pOut[power.theta],
+                                       window.F_obj: oOut[obstacle.F]
                             })
     window.doStep(time, step, iteration, cosim_step_size) 
     wOut = window.getValues(step, iteration, [window.tau, window.x])
     
-    obstacle.setValues(step, iteration, {obstacle.x: wOut[window.x]})
-    obstacle.doStep(time, step, iteration, cosim_step_size) 
-    oOut = obstacle.getValues(step, iteration, [obstacle.F])
+    # Compute the power
+    power.setValues(step, iteration, {power.tau: wOut[window.tau], 
+                           power.up: cOut[controller.out_up],
+                           power.down: cOut[controller.out_down]})
     
-    adapt_armature.setValues(step, iteration, {adapt_armature.armature_current: pOut[power.i]})
-    adapt_armature.doStep(time, step, iteration, cosim_step_size) 
-    adaptArmOut = adapt_armature.getValues(step, iteration, [adapt_armature.out_obj])
+    power.doStep(time, step, iteration, cosim_step_size)
+    pOut = power.getValues(step, iteration, [power.omega, power.theta, power.i])
     
-    environment.doStep(time, step, iteration, cosim_step_size) 
-    envOut = environment.getValues(step, iteration, [environment.out_up, environment.out_down])
+    """
+    Here is where we would compute the inputs that were previously delays and
+    repeat the step if these were too different.
+    """
     
-    # coupling equation for the input event of the controller
-    controller.setValues(step, iteration, {controller.in_dup : envOut[environment.out_up],
-                            controller.in_ddown : envOut[environment.out_down],
-                            controller.in_obj : adaptArmOut[adapt_armature.out_obj]})
-    controller.doStep(time, step, iteration, cosim_step_size) 
-    cOut = controller.getValues(step, iteration, [controller.out_up, controller.out_down])
-
-    # Coupling equation for power
-    power_tau = - ( wOut[window.tau] + window_radius * oOut[obstacle.F])
+    # Update the delayed inputs
     
-    # Finally set the other power inputs
     """
-    The instruction below is not really needed, as power has already performed the step.
-    However, we leave it here because in case an algebraic loop were being solved,
-    this is where we would set the improved values for the power inputs, 
-    and check for convergence.
+    adapt_armature.setValues(step, iteration, {adapt_armature.armature_current: pOut[power.i]})
     
+    window.setValues(step, iteration, {window.omega_input: pOut[power.omega],
+                                       window.theta_input: pOut[power.theta]})
+    
+    obstacle.setValues(step, iteration, {obstacle.x: wOut[window.x]})
     """
-    power.setValues(step, iteration, {power.tau: power_tau, 
-                           power.up: cOut[controller.out_up],
-                           power.down: cOut[controller.out_down]})
+    
     
     trace_omega.append(pOut[power.omega])
     trace_i.append(pOut[power.i])

+ 20 - 26
SemanticAdaptationForFMI/FMIAbstraction/src/case_study/scenarios/ControlledScenario_EventController.py

@@ -44,11 +44,10 @@ adapt_armature = InacurateControllerArmatureAdaptation_Event("arm_adapt", NUM_RT
 
 adapt_power_input = PowerInputAdaptation_Event("power_adapt")
 
-window_radius = 0.017
 
 window = WindowFMU("window", NUM_RTOL, NUM_ATOL, cosim_step_size/num_internal_steps, 
                      J=0.085, 
-                     r=window_radius, 
+                     r=0.017, 
                      b = 150, 
                      c = 1e3) # c = 1e5 makes this an unstable system.
 
@@ -70,6 +69,10 @@ The initialisation may impose a completely different order for the execution of
 In this case we know that there is no direct feed-through between the power input and its outputs,
     so we can safely set its initial state, get its output, and then compute all the other FMUs,
     before setting the new inputs to the power.
+There is also a tight coupling between the window and the obstacle FMU but we 
+    know what the initial force is, so we can use that to set the inputs and outputs in the right order,
+    without having to do a fixed point iteration.
+    But in the general case, we would need a fixed point iteration.
 """
 
 pOut = power.setValues(0, 0, {
@@ -84,11 +87,14 @@ window.setValues(0, 0, {window.omega_input: pOut[power.omega],
                             window.theta: 0.0,
                             window.omega: 0.0
                             })
-wOut = window.getValues(0, 0, [window.tau, window.x])
+wOut = window.getValues(0, 0, [window.x])
 
-obstacle.setValues(0, 0, {obstacle.x: wOut[window.x]})
+obstacle.setValues(0,0, {obstacle.x: wOut[window.x]})
 oOut = obstacle.getValues(0, 0, [obstacle.F])
 
+window.setValues(0, 0, {window.F_obj: oOut[obstacle.F]})
+wOut = window.getValues(0, 0, [window.tau])
+
 adapt_armature.setValues(0, 0, {adapt_armature.armature_current: pOut[power.i],
                                 adapt_armature.out_event: "" })
 
@@ -114,17 +120,12 @@ adapt_power_input.setValues(0, 0, {adapt_power_input.in_event : cOut[controller.
 
 adaptPowerOut = adapt_power_input.getValues(0, 0, [adapt_power_input.out_up, adapt_power_input.out_down])
 
-
-# Coupling equation for power
-power_tau = - ( wOut[window.tau] + window_radius * oOut[obstacle.F])
-
 # Finally set the other power inputs
-power.setValues(0, 0, {power.tau: power_tau, 
+power.setValues(0, 0, {power.tau: wOut[window.tau], 
                        power.up: adaptPowerOut[adapt_power_input.out_up],
                        power.down: adaptPowerOut[adapt_power_input.out_down]})
 
 
-
 environment.exitInitMode()
 controller.exitInitMode()
 power.exitInitMode()
@@ -149,32 +150,28 @@ for step in range(1, int(stop_time / cosim_step_size) + 1):
     # value given for the inputs. However, that creates an algebraic loop, 
     # so for now, we just get old values for the inputs.
     
-    oOut = obstacle.getValues(step-1, 0, [obstacle.F])
     wOut = window.getValues(step-1, 0, [window.tau, window.x])
-    adaptPowerOut = adapt_power_input.getValues(step-1, 0, [adapt_power_input.out_up, adapt_power_input.out_down])
     
-    # Coupling equation for power
-    power_tau = - ( wOut[window.tau] + window_radius * oOut[obstacle.F])
+    adaptPowerOut = adapt_power_input.getValues(step-1, 0, [adapt_power_input.out_up, adapt_power_input.out_down])
     
-    power.setValues(step, 0, {power.tau: power_tau, 
+    power.setValues(step, 0, {power.tau: wOut[window.tau], 
                            power.up: adaptPowerOut[adapt_power_input.out_up],
                            power.down: adaptPowerOut[adapt_power_input.out_down]})
     
     power.doStep(time, step, 0, cosim_step_size)
-    
     pOut = power.getValues(step, 0, [power.omega, power.theta, power.i])
     
+    obstacle.setValues(step, 0, {obstacle.x: wOut[window.x]})
+    obstacle.doStep(time, step, 0, cosim_step_size) 
+    oOut = obstacle.getValues(step, 0, [obstacle.F])
+        
     window.setValues(step, 0, {window.omega_input: pOut[power.omega],
-                            window.theta_input: pOut[power.theta],
-                            window.theta: 0.0,
-                            window.omega: 0.0
+                               window.theta_input: pOut[power.theta],
+                               window.F_obj: oOut[obstacle.F]
                             })
     window.doStep(time, step, 0, cosim_step_size) 
     wOut = window.getValues(step, 0, [window.tau, window.x])
     
-    obstacle.setValues(step, 0, {obstacle.x: wOut[window.x]})
-    obstacle.doStep(time, step, 0, cosim_step_size) 
-    oOut = obstacle.getValues(step, 0, [obstacle.F])
     
     adapt_armature.setValues(step, 0, {adapt_armature.armature_current: pOut[power.i]})
     adapt_armature.doStep(time, step, 0, cosim_step_size) 
@@ -195,9 +192,6 @@ for step in range(1, int(stop_time / cosim_step_size) + 1):
     adapt_power_input.doStep(time, step, 0, cosim_step_size) 
     adaptPowerOut = adapt_power_input.getValues(step, 0, [adapt_power_input.out_up, adapt_power_input.out_down])
     
-    # Coupling equation for power
-    power_tau = - ( wOut[window.tau] + window_radius * oOut[obstacle.F])
-    
     # Finally set the other power inputs
     """
     The instruction below is not really needed, as power has already performed the step.
@@ -206,7 +200,7 @@ for step in range(1, int(stop_time / cosim_step_size) + 1):
     and check for convergence.
     
     """
-    power.setValues(step, 0, {power.tau: power_tau, 
+    power.setValues(step, 0, {power.tau: wOut[window.tau], 
                            power.up: adaptPowerOut[adapt_power_input.out_up],
                            power.down: adaptPowerOut[adapt_power_input.out_down]})
     

+ 5 - 9
SemanticAdaptationForFMI/FMIAbstraction/src/case_study/scenarios/NoObstacleTest.py

@@ -22,16 +22,14 @@ stop_time = 1.0;
 power = PowerFMU("power", 1e-08, 1e-08, cosim_step_size/num_internal_steps, 
                      J=0.085, 
                      b=5, 
-                     K=1.8, 
+                     K=7.45, 
                      R=0.15, 
                      L=0.036,
                      V_a=12)
 
 window = WindowFMU("window", 1e-08, 1e-08, cosim_step_size/num_internal_steps, 
-                     J=0.085, 
-                     r=0.017, 
-                     b = 150, 
-                     c = 1e3) # c = 1e5 makes this an unstable system.
+                     r=0.11, 
+                     b = 10)
 
 power.enterInitMode()
 window.enterInitMode()
@@ -49,9 +47,7 @@ power.setValues(0, 0, {power.i: 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
+                            window.theta_input: pOut[power.theta]
                             })
 
 wOut = window.getValues(0, 0, [window.tau])
@@ -80,7 +76,7 @@ for step in range(1, int(stop_time / cosim_step_size) + 1):
     wOut = window.getValues(step, 0, [window.tau, window.x])
     
     # Coupling equation
-    power_tau = - wOut[window.tau]
+    power_tau = wOut[window.tau]
     
     power.setValues(step, 0, {power.tau: power_tau,
                                   power.up: env_up(time),

+ 1 - 1
SemanticAdaptationForFMI/FMIAbstraction/src/case_study/units/adaptations/InacurateControllerArmatureAdaptation_CT.py

@@ -55,7 +55,7 @@ class InacurateControllerArmatureAdaptation_CT(AbstractSimulationUnit):
         self.__threshold = threshold
         
         self.armature_current = "armature_current"
-        self.out_obj = "out_event"
+        self.out_obj = "out_obj"
         input_vars = [self.armature_current]
         state_vars = [self.out_obj]
         

+ 1 - 1
SemanticAdaptationForFMI/FMIAbstraction/src/case_study/units/ct_based/PowerFMU.py

@@ -22,7 +22,7 @@ class PowerFMU(CTSimulationUnit_Euler):
         def der_theta(x, u):
             return x[self.omega]
         def der_omega(x, u):
-            return (K * x[self.i] + u[self.tau] - b * x[self.omega]) / J
+            return (K * x[self.i] - u[self.tau] - b * x[self.omega]) / J
         def der_i(x, u):
             volt = get_v(u[self.up], u[self.down])
             return (volt - K * x[self.omega] - R * x[self.i]) / L

+ 15 - 9
SemanticAdaptationForFMI/FMIAbstraction/src/case_study/units/ct_based/WindowFMU.py

@@ -3,32 +3,38 @@ from abstract_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):
+    def __init__(self, name, num_rtol, num_atol, internal_step_size, r, b):
         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"
+        #self.omega = "omega"
+        #self.theta = "theta"
+        self.F_obj = "F_obj"
         
-        input_vars = [self.omega_input, self.theta_input]
+        input_vars = [self.omega_input, self.theta_input, self.F_obj]
         
+        def calc_obj_torque(x,u):
+            return r * u[self.F_obj]
         def calc_v(x, u):
-            return r * x[self.omega]
+            return r * u[self.omega_input]
         def calc_x(x, u):
-            return r * x[self.theta]
+            return r * u[self.theta_input]
         def calc_tau(x,u):
-            return c * ( u[self.theta_input] - x[self.theta] ) - b * calc_v(x,u)
+            return b * calc_v(x,u) + calc_obj_torque(x,u)
+            #return c * ( u[self.theta_input] - x[self.theta] ) - b * calc_v(x,u) - calc_obj_torque(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
+                             #self.theta: der_theta,
+                             #self.omega: der_omega
                              }
         
         algebraic_functions = {