123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596 |
- import logging
- import numpy
- from units.AbstractSimulationUnit import AbstractSimulationUnit, STEP_ACCEPT
- l = logging.getLogger()
- class InacurateControllerArmatureAdaptation(AbstractSimulationUnit):
- """
- This is the adaptation of the armature signal coming from the power system and into the controller statechart.
- It therefore gets a continuous input and outputs events.
- The input will be the armature continuous signal.
- The output will be the event "obj" whenever the absolute value of
- the armature signal exceeds a certain threshold.
-
- Note that we could have coded a generic signal crossing adaptation unit
- and there is a whole range of pathological cases that we are not dealing with now.
- For these, see the implementation of the AbstractZeroCrossingBlock
- of the DiracCBD Simulator
-
- The detailed behaviour of this block is as follows:
- ______________________________
- f = InacurateControllerArmatureAdaptation(...)
- f.enterInitMode()
- f.setValues(...,armature)
- The FMU records this value in its internal state.
- "" = f.getValues(...)
- The empty event is returned because at time t=0, there can be no crossing.
- f.exitInitMode()
-
- f.setValues(..., None)
- The FMU records the value as the current input in its internal state.
- f.doStep(..., H)
- The FMU checks whether the current input has crossed the given threshold,
- taking into account the previous value of the input,
- already stored in the internal state.
- The output value is then calculated and the current input moved into the internal state.
- "someReaction" = f.getValues(...)
- Gets the output event. Can either be absent, or the obj event.
- ______________________________
-
- """
-
- def __init__(self, name, num_rtol, num_atol, threshold, upward):
-
- self._num_rtol = num_rtol
- self._num_atol = num_atol
-
- assert upward, "Not implemented yet."
-
- self.__crossUpward = upward
-
- self.__threshold = threshold
-
- self.armature_current = "armature_current"
- self.out_event = "out_event"
- input_vars = [self.armature_current]
- state_vars = [self.out_event]
-
- algebraic_functions = {}
- AbstractSimulationUnit.__init__(self, name, algebraic_functions, state_vars, input_vars)
-
- def _isClose(self, a, b):
- return numpy.isclose(a,b, self._num_rtol, self._num_atol)
-
- def _biggerThan(self, a, b):
- return not numpy.isclose(a,b, self._num_rtol, self._num_atol) and a > b
-
- def _doInternalSteps(self, time, step, iteration, cosim_step_size):
- l.debug(">%s._doInternalSteps(%f, %d, %d, %f)", self._name, time, step, iteration, cosim_step_size)
-
- assert self._biggerThan(cosim_step_size, 0), "cosim_step_size too small: {0}".format(cosim_step_size)
- assert iteration == 0, "Fixed point iterations not supported yet."
-
- current_input = self.getValues(step, iteration, self._getInputVars())[self.armature_current]
- previous_input = self.getValues(step-1, iteration, self._getInputVars())[self.armature_current]
-
- output_event = ""
-
- l.debug("%s.previous_input=%f", self._name, previous_input)
- l.debug("%s.current_input=%f", self._name, current_input)
-
- if (not self._biggerThan(previous_input, self.__threshold)) \
- and self._biggerThan(current_input, self.__threshold) \
- and self.__crossUpward:
- output_event = "obj"
-
- l.debug("%s.output_event=%s", self._name, output_event)
- self.setValues(step, iteration, {self.out_event: output_event})
-
- l.debug("<%s._doInternalSteps() = (%s, %d)", self._name, STEP_ACCEPT, cosim_step_size)
- return (STEP_ACCEPT, cosim_step_size)
-
-
|