ddcontrol/control.py
def pidopt(tf, end=10.0, wd=0.5, k0=(1.0,1.0,1.0,1.0), freq=10.0, lim=(-float('Inf'),float('Inf'))):
    """PID optimization function for given transfer function

    Args:
        tf (TransferFunction): TransferFunction object for optimization.
        end (float, optional): Optimization end time
        wd (float, optional): Disturbance loss weight [0,1].
        k0 (tuple, optional): Initial PID controller gains.
        freq (float, optional): PID controller frequency.
        lim (tuple, optional): Output limit values of PID controller

    Returns:
        tuple: Optimized PIDController and OptimizeResult.

    Example:
        >>> from ddcontrol.model import TransferFunction
        >>> from ddcontrol.control import pidopt

        >>> #Creates transfer function
        >>> tf = TransferFunction([1.0], [1.0,10.0,20.0], udelay=0.1)

        >>> #Optimizes pid controller
        >>> pid, _ = pidopt(tf)
        >>> print('Optimized PID gains..:', pid.kp, pid.ki, pid.kd, pid.kn)

    Todo:
        Optimization is very slow. Improve performance
    """
    #Creates timestamps and time ranges
    dt = 1.0 / freq
    t = arange(0, end, dt)
    #Creates input, output and disturbance arrays
    y, u = zeros(t.size, 'float32'), zeros(t.size, 'float32')
    #Objective function for pid gains
    pid = PIDController(kp=k0[0], ki=k0[1], kd=k0[2], kn=k0[3], freq=freq, lmin=lim[0], lmax=lim[1])
    def objective(k):
        #Initializes controller
        pid.kp, pid.ki, pid.kd, pid.kn = k
        tf.set_initial_value()
        pid.set_initial_value()
        #Control loop
        for index in range(1, t.size):
            y[index] = tf.step(t[index], u[index-1]+wd)
            u[index] = pid.step(dt, 1.0-y[index])
        #If the signals contains nan, loss is infinite
        if isnan(y).any() or isnan(u).any():
            return inf
        #Calculates loss
        loss = (t * absolute(1.0-y)).mean()
        return loss
    #Optimize pid gains
    res = minimize(objective, x0=(pid.kp, pid.ki, pid.kd, pid.kn),
                   method='SLSQP', options={'ftol':1e-4, 'eps':1e-2})
    tf.set_initial_value()
    pid.kp, pid.ki, pid.kd, pid.kn = res.x
    pid.set_initial_value()
    return pid, res
PID optimization function for given transfer function

    Args:
        tf (TransferFunction): TransferFunction object for optimization.
        end (float, optional): Optimization end time
        wd (float, optional): Disturbance loss weight [0,1].
        k0 (tuple, optional): Initial PID controller gains.
        freq (float, optional): PID controller frequency.
        lim (tuple, optional): Output limit values of PID controller

    Returns:
        tuple: Optimized PIDController and OptimizeResult.

    Example:
        >>> from ddcontrol.model import TransferFunction
        >>> from ddcontrol.control import pidopt

        >>> #Creates transfer function
        >>> tf = TransferFunction([1.0], [1.0,10.0,20.0], udelay=0.1)

        >>> #Optimizes pid controller
        >>> pid, _ = pidopt(tf)
        >>> print('Optimized PID gains..:', pid.kp, pid.ki, pid.kd, pid.kn)

    Todo:
        Optimization is very slow. Improve performance
    
PID optimization function for given transfer function
PID optimization function for given transfer function
def pidopt(tf, end=10.0, wd=0.5, k0=(1.0,1.0,1.0,1.0), freq=10.0, lim=(-float('Inf'),float('Inf'))):
    dt = 1.0 / freq
    t = arange(0, end, dt)
    y, u = zeros(t.size, 'float32'), zeros(t.size, 'float32')
    pid = PIDController(kp=k0[0], ki=k0[1], kd=k0[2], kn=k0[3], freq=freq, lmin=lim[0], lmax=lim[1])
    def objective(k):
        pid.kp, pid.ki, pid.kd, pid.kn = k
        tf.set_initial_value()
        pid.set_initial_value()
        for index in range(1, t.size):
            y[index] = tf.step(t[index], u[index-1]+wd)
            u[index] = pid.step(dt, 1.0-y[index])
        if isnan(y).any() or isnan(u).any():
            return inf
        loss = (t * absolute(1.0-y)).mean()
        return loss
    res = minimize(objective, x0=(pid.kp, pid.ki, pid.kd, pid.kn),
                   method='SLSQP', options={'ftol':1e-4, 'eps':1e-2})
    tf.set_initial_value()
    pid.kp, pid.ki, pid.kd, pid.kn = res.x
    pid.set_initial_value()
    return pid, res
def pidopt ( tf , end = 10.0 , wd = 0.5 , k0 = ( 1.0 , 1.0 , 1.0 , 1.0 ) , freq = 10.0 , lim = ( - float ( 'Inf' ) , float ( 'Inf' ) ) ) : dt = 1.0 / freq t = arange ( 0 , end , dt ) y , u = zeros ( t . size , 'float32' ) , zeros ( t . size , 'float32' ) pid = PIDController ( kp = k0 [ 0 ] , ki = k0 [ 1 ] , kd = k0 [ 2 ] , kn = k0 [ 3 ] , freq = freq , lmin = lim [ 0 ] , lmax = lim [ 1 ] ) def objective ( k ) : pid . kp , pid . ki , pid . kd , pid . kn = k tf . set_initial_value ( ) pid . set_initial_value ( ) for index in range ( 1 , t . size ) : y [ index ] = tf . step ( t [ index ] , u [ index - 1 ] + wd ) u [ index ] = pid . step ( dt , 1.0 - y [ index ] ) if isnan ( y ) . any ( ) or isnan ( u ) . any ( ) : return inf loss = ( t * absolute ( 1.0 - y ) ) . mean ( ) return loss res = minimize ( objective , x0 = ( pid . kp , pid . ki , pid . kd , pid . kn ) , method = 'SLSQP' , options = { 'ftol' : 1e-4 , 'eps' : 1e-2 } ) tf . set_initial_value ( ) pid . kp , pid . ki , pid . kd , pid . kn = res . x pid . set_initial_value ( ) return pid , res
PID optimization function for given transfer function
PID optimization function for given transfer function
"""PID optimization function for given transfer function

    Args:
        tf (TransferFunction): TransferFunction object for optimization.
        end (float, optional): Optimization end time
        wd (float, optional): Disturbance loss weight [0,1].
        k0 (tuple, optional): Initial PID controller gains.
        freq (float, optional): PID controller frequency.
        lim (tuple, optional): Output limit values of PID controller

    Returns:
        tuple: Optimized PIDController and OptimizeResult.

    Example:
        >>> from ddcontrol.model import TransferFunction
        >>> from ddcontrol.control import pidopt

        >>> #Creates transfer function
        >>> tf = TransferFunction([1.0], [1.0,10.0,20.0], udelay=0.1)

        >>> #Optimizes pid controller
        >>> pid, _ = pidopt(tf)
        >>> print('Optimized PID gains..:', pid.kp, pid.ki, pid.kd, pid.kn)

    Todo:
        Optimization is very slow. Improve performance
    """ #Creates timestamps and time ranges #Creates input, output and disturbance arrays #Objective function for pid gains #Initializes controller #Control loop #If the signals contains nan, loss is infinite #Calculates loss #Optimize pid gains
Optimized PIDController and OptimizeResult.
Optimized PIDController and OptimizeResult .
tuple
tf
TransferFunction object for optimization.
TransferFunction object for optimization .
end
Optimization end time
Optimization end time
wd
Disturbance loss weight [0,1].
Disturbance loss weight [ 0 1 ] .
k0
Initial PID controller gains.
Initial PID controller gains .
freq
PID controller frequency.
PID controller frequency .
lim
Output limit values of PID controller
Output limit values of PID controller
examples
>>> from ddcontrol.model import TransferFunction
>>> from ddcontrol.control import pidopt




>>> from ddcontrol . model import TransferFunction >>> from ddcontrol . control import pidopt