Esempio n. 1
0
    def simulate(self, inputs, dt=None):
        """Simulate IMC.

        Arguments:
        ----------
        U : `numpy.ndarray`
            2-dimensional array with two rows. First row U[0] contain a setting value,
            second row U[1] contain a return value from plant/process.
        time : `int`
            Simulation number of iterations
            Default ``time``=1
        Returns:
        --------
        y : `numpy.ndarray`
            Last controller's value
        """

        u, yplant = inputs
        u = Models.convert_2dim_array(u)
        yplant = Models.convert_2dim_array(yplant)

        yloop = Models.StateSpace.algebraic_loop_solver(
            u - yplant, self.controller, self.model)

        ymodel = self.model.simulate(inputs=yloop, dt=dt)

        super().simulate(u + ymodel - yplant, dt=dt)

        ycontrol = self.controller.simulate(inputs=super().now, dt=dt)

        return ycontrol
Esempio n. 2
0
    def simulate(self, inputs, dt=1):
        """Simulate IMC.

        Arguments:
        ----------
        U : `numpy.ndarray`
            2-dimensional array with two rows. First row U[0] contain a setting value,
            second row U[1] contain a return value from plant/process.
        time : `int`
            Simulation number of iterations
            Default ``time``=1
        Returns:
        --------
        y : `numpy.ndarray`
            Last controller's value
        """

        u, yplant = inputs
        u = Models.convert_2dim_array(u)
        yplant = Models.convert_2dim_array(yplant)

        ymodel = self.delay.now if self.delay else self.model.now
        super().simulate(u + ymodel - yplant, dt=dt)

        ycontrol = self.controller.simulate(inputs=super().now, dt=dt)
        self.model.simulate(inputs=self.controller.now, dt=dt)

        if self.delay:
            self.delay.simulate(inputs=self.model.now, dt=dt)

        return ycontrol
Esempio n. 3
0
    def __init__(self, Kp=0, Ti=0, Td=0, dt=1, N=float('inf'), **opt):
        """
       Arguments:
       ----------
       Kp : `float`
           Proportional gain.
           Default ``Kp``=1.
       Ti :  `float`
           Integral time constant.
           Default ``Ti``=0.
       Td : `float`
           Derivative time constant.
           Default ``Td``=0.
       dt : `float`
           Sampling period.
           Default ``dt``=1
       N : `float`
           Derivative filter coefficient
           Default ``N``=float('inf')
       """
        self.P_block = Models.Gain(Kp=Kp, dt=dt, **opt) if Kp else None
        self.I_block = Models.Integral(Ki=1 / Ti, dt=dt, **opt) if Ti else None
        self.D_block = None
        if Td:
            self.D_block = Models.Derivative(Kd=Td, dt=dt, **opt) if N == float('inf') \
                else Models.StateSpace(ABCD=[[[-N / Td]], [[1]], [[- N ** 2 / Td]], [[N]]], dt=dt, **opt)

        super().__init__(in_len=1, name='PID_Serial', **opt)
Esempio n. 4
0
def trapezoid_func_F(th_e):
    """Calculate value of trapezoidal waveform for a given motor electrical angle.
    
    Arguments
    ---------
    th_e : `float`
        Motor electrical angle in range [0, 2pi]
        
    Returns
    -------
    F : `float`
        Returns value of trapezoidal waveform for given angle
    """
    tau = np.pi / 6
    f = 2 / 3 * np.pi
    T = np.pi
    A = 1

    if th_e <= tau:
        F = th_e / tau
    elif th_e <= f + tau:
        F = A
    elif th_e <= T:
        F = A - A / tau * (th_e - (T - tau))
    elif th_e <= T + tau:
        F = -A / tau * (th_e - T)
    elif th_e <= 2 * T - tau:
        F = -1
    elif th_e <= 2 * T:
        F = -A + A / tau * (th_e - (2 * T - tau))
    else:
        raise Exception(
            "Could not get trapezoid value for argument th={}".format(th_e))
    return Models.convert_2dim_array(F)
Esempio n. 5
0
    def simulate(self, inputs, dt=None):
        """Simulation of a block.

        Arguments:
        ----------
        e : `float`, `numpy.ndarray`
            Input to the controller as error e=u-y, where u is a setting value, y a return value from a process.
        time : `int`
            Number of simulation iterations.
            Default ``time``=1

        Return:
        -------
        y : `float`
            Returns last value of simulation
        """
        e = Models.convert_2dim_array(inputs).reshape(-1, 1)

        yd = self.D_block.simulate(inputs=e, dt=dt) + e if self.D_block else e
        yp = self.P_block.simulate(inputs=yd, dt=dt) if self.P_block else yd
        yi = self.I_block.simulate(inputs=yp,
                                   dt=dt) + yp if self.I_block else yp

        super().simulate(yi)

        return yi
Esempio n. 6
0
    def simulate(self, inputs, dt=None):
        inputs = Models.convert_2dim_array(inputs).reshape(-1, 1)

        ea, eb, ec = self.back_Emf.now[3:6]
        uab, ubc, Tl = inputs

        U = [[uab], [ubc], [ea - eb], [eb - ec], [self.torque.now], [Tl]]
        super().simulate(inputs=U, dt=dt)
        self.back_Emf.simulate(inputs=self.now[3:5], dt=dt)  # [w, th_m]
        self.torque.simulate(inputs=[self.back_Emf.now[0:3], self.now[0:3]],
                             dt=dt)  # [Fa, Fb, Fc, ia, ib, ic]
Esempio n. 7
0
    def simulate(self, inputs, dt=None):
        """Simulate SP block.

        Arguments:
        ----------
        U : `numpy.ndarray`
            2-dimensional array with two rows. First row [0] contain a setting value,
            second [1] contain a return value from plant/process.
        dt : `float`
            Step time of simulation.
            Default ``dt``=1
        Returns:
        --------
        y : `numpy.ndarray`
            Last controller's value
        """

        u, yplant = inputs
        u = Models.convert_2dim_array(u)
        yplant = Models.convert_2dim_array(yplant)

        yfilter = yplant - self.model_delay.now
        if self.filter:
            yfilter = self.filter.simulate(yfilter, dt)

        ureg = u - yfilter

        yloop = Models.StateSpace.algebraic_loop_solver(ureg,
                                                        self.controller,
                                                        self.model,
                                                        sign=-1)
        ymodel = self.model.simulate(yloop, dt)
        ycontrol = self.controller.simulate(ureg - ymodel, dt)

        self.model_delay.simulate(ymodel, dt)

        return ycontrol
Esempio n. 8
0
 def __init__(self, reg, model, delay, **opt):
     """
     Arguments:
     reg : `Models.Block`
         Controller block.
     model : `Models.Block`
         Model of a process/plant.
     opt : `dict`
         ``Models.Block`` options.
     """
     self.controller = reg
     self.model = model
     self.delay = Models.Delay(d=delay, **
                               opt) if delay is not None else None
     super().__init__(in_len=1, output_no_mem=True, **opt)
Esempio n. 9
0
    def __init__(self,
                 Kp=1,
                 Ti=0,
                 Td=0,
                 dt=1,
                 N=float('inf'),
                 alpha=None,
                 beta=None,
                 **opt):
        """
        Arguments:
        ----------
        Kp : `float`
            Proportional gain.
            Default ``Kp``=1.
        Ti :  `float`
            Integral time constant.
            Default ``Ti``=0.
        Td : `float`
            Derivative time constant.
            Default ``Td``=0.
        dt : `float`
            Sampling period.
            Default ``dt``=1
        N : `float`
            Derivative filter coefficient
            Default ``N``=float('inf')
        alpha : `float`
            Alpha coefficient for two-degree of freedom controller.
            Default ``alpha``=None
        beta : `float`
            Alpha coefficient for two-degree of freedom controller.
            Default ``alpha``=None
        """
        self.P_block = Models.Gain(Kp=Kp, dt=dt, **opt) if Kp else None
        self.I_block = Models.Integral(Ki=Kp /
                                       Ti, dt=dt, **opt) if Ti else None
        self.D_block = None
        self.P2_block = None
        self.D2_block = None
        if Td:
            self.D_block = Models.Derivative(Kd=Td * Kp, dt=dt, **opt) if N == float('inf') \
                else Models.StateSpace(ABCD=[[[-N / Td]], [[1]], [[- N ** 2 / Td]], [[N]]], dt=dt, K=Kp, **opt)

            if alpha: self.P2_block = Models.Gain(Kp=Kp * alpha, **opt)
            if beta:
                self.D2_block = Models.Derivative(Kd=Kp * Td * beta, dt=dt, **opt) if N == float('inf') \
                    else Models.StateSpace(ABCD=[[[-N / Td]], [[1]], [[- N ** 2 / Td]], [[N]]], dt=dt, K=Kp * beta, **opt)

        super().__init__(in_len=1, name='PID_Parallel', **opt)
Esempio n. 10
0
 def __init__(self, reg, model, delay, filter=None, **opt):
     """
     Arguments:
     ---------
     reg : `Models.Block`
         Regulator represantation.
     model : `Models.Block`
         Model of a process.
     delay : `int`
         Dead time. Number of samples to be delayed.
     filter : `Models.Block`, optional
         Filtering block.
     opt : `dict`, optional
         `Model.Block` options.
     """
     self.controller = reg
     self.model = model
     self.model_delay = Models.Delay(d=delay, **opt)
     self.filter = filter
     super().__init__(model='Smith-Predictor',
                      shape=(2, 1, 0),
                      model_func=None,
                      **opt)
Esempio n. 11
0
    def simulate(self, inputs, dt=None):
        """Simulation of a block.

         Arguments:
         ----------
         inputs : `float`, `numpy.ndarray`
             Input to the controller as array ['e'] for 1-degree controller or ['e', 'u'] for 2-degree controller,
             where 'u' is a setting value, 'e' is an error 'e = yplant - u' with plant output 'yplant'.
         dt : `float`

         Return:
         -------
         y : `float`
             Returns last value from regulator.
         """
        inputs = Models.convert_2dim_array(inputs).reshape(-1, 1)

        if inputs.shape[0] == 1:
            e = inputs
            u = np.zeros((1, 1))
        elif inputs.shape[0] == 2:
            e, u = inputs
        else:
            raise Exception("PID: Expected max. 2 inputs. Got {}".format(
                inputs.shape))

        yp, yi, yd, yalfa, ybeta = np.zeros((5, 1, 1))

        if self.P_block: yp = self.P_block.simulate(inputs=e, dt=dt)
        if self.I_block: yi = self.I_block.simulate(inputs=e, dt=dt)
        if self.D_block: yd = self.D_block.simulate(inputs=e, dt=dt)
        if self.P2_block: yalfa = self.P2_block.simulate(inputs=u, dt=dt)
        if self.D2_block: ybeta = self.D2_block.simulate(inputs=u, dt=dt)
        y = yp + yi + yd + yalfa + ybeta
        super().simulate(y, dt=dt)

        return y
Esempio n. 12
0
import matplotlib.pyplot as plt
from smacontrol import PID, Models
"""Simulation parameters"""
N = 100  # Simulation time's end
dt = 0.01  # Sampling time
max_len = int(N / dt)  # Simulation's vectors' length
time = np.arange(0, N, dt)  # Time vector
u = np.ones((1, max_len))  # Input vector u=1
input_on_time = 10  # Start time of input
u[0, :int(input_on_time / dt)] = 0  # Input u = 0 if t < input_on_time
"""State-Space model of inertia P(s) = 2/(50s+1)"""
A = [[-1 / 50]]
B = [[1]]
C = [[2 / 50]]
D = [[0]]
Plant_parallel = Models.StateSpace(ABCD=[A, B, C, D], dt=dt, len=max_len)
Plant_serial = Models.StateSpace(ABCD=[A, B, C, D], dt=dt, len=max_len)
Plant_open = Models.StateSpace(ABCD=[A, B, C, D], dt=dt, len=max_len)
"""Parallel and serial PID objects"""
Kp = 10
Ti = 2
Td = 0.2
Reg_PID_parallel = PID.PID(Kp=Kp, Ti=Ti, Td=Td, dt=dt, len=max_len)

Kps = Kp / 2 * np.sqrt(1 + 4 * Td / Ti)
Tis = Ti / 2 * np.sqrt(1 + 4 * Td / Ti)
Tds = Ti / 2 * np.sqrt(1 - 4 * Td / Ti)
Reg_PID_serial = PID.SerialPID(Kp=Kps, Ti=Tis, Td=Tds, dt=dt, len=max_len)
"""Simulation"""
for it in range(0, max_len):
    t = time[it]
Esempio n. 13
0
import matplotlib.pyplot as plt
"""Simulation parameters"""
N = 100  # Simulation time's end
dt = 0.01  # Sampling time
max_len = int(N / dt)  # Simulation's vectors' length
time = np.arange(0, N, dt)  # Time vector
u = np.ones((1, max_len))  # Input vector u=1
input_on_time = 20  # Start time of input
u[0, 0:int(input_on_time / dt)] = 0  # Input u = 0 if t < input_on_time
"""
Open loop - step response
"""
# Process P(s) = 12/(12s+1)e^-2 to state-space
A, B, C, D = [[-1 / 12]], [[1]], [[1]], [[0]]
d = int(2 / dt)
Plant_openloop0 = Models.StateSpace(ABCD=[A, B, C, D], dt=dt, len=max_len)
Delay_openloop0 = Models.Delay(d=d, dt=dt, len=max_len)
"""
******
*** IMC 1 - model with delay
******
"""
# Process P(s) = 12/(12s+1)e^-2s to state-space
Plant1 = Models.StateSpace(ABCD=[A, B, C, D], dt=dt, len=max_len)

Delay1 = Models.Delay(d=d, dt=dt, len=max_len)
# Model Pm(s) = 12/(12s+1)e^-2s
Plant_model1 = Models.StateSpace(ABCD=[A, B, C, D], dt=dt, len=max_len)
# Regulator Q(s) = 12s+1/6s+12
Ar1, Br1, Cr1, Dr1 = [[-2]], [[1]], [[-23 / 6]], [[2]]
Reg1 = Models.StateSpace(ABCD=[Ar1, Br1, Cr1, Dr1], dt=dt, len=max_len)
Esempio n. 14
0
"""Simulation parameters"""
N = 50  # Simulation time's end
dt = 0.1  # Sampling time
max_len = int(N / dt)  # Simulation's vectors' length
time = np.arange(0, N, dt)  # Time vector
u = np.ones((1, max_len))  # Input vector u=1
v = -1*np.ones((1, max_len))  # Disturbance vector v=-1, for t>=20
v_start = int(20 / dt)
v[0, :v_start] = 0

"""Open loop - step response"""
# Process model P(s) =  1/(1s+1)e^-5 to state-space
A, B, C, D = [[-1]], [[1]], [[1]], [[0]]
d = int(5 / dt)
Plant_openloop = Models.StateSpace(ABCD=[A, B, C, D], dt=dt, len=max_len)
Delay_openloop = Models.Delay(d=d, dt=dt, len=max_len)

"""Smith Predictor"""
# Process model P(s) = 1/(1s+1)e^-5 to state-space
Plant = Models.StateSpace(ABCD=[A, B, C, D], dt=dt, len=max_len)
Delay = Models.Delay(d=d, dt=dt, len=max_len)
# Model Pmo(s) = 1/(1s+1)
Model = Models.StateSpace(ABCD=[A, B, C, D], dt=dt, len=max_len)
# Regulator C(s) = (1s + 1)/(0.5s)
Ar, Br, Cr, Dr = [[0]], [[1]], [[2]], [[2]]
Reg = Models.StateSpace(ABCD=[Ar, Br, Cr, Dr], dt=dt, len=max_len)
# Output memory
Mem = Models.Memory(in_len=1, dt=dt, len=max_len)
# SmithPredictor structure
SmithPred = SP.SmithPredictor(reg=Reg, model=Model, delay=d, len=max_len)