コード例 #1
0
def ref_perfect_const_plot(G, R, wr, w_start=-2, w_end=2, axlim=None,
                           points=1000, plot_type='all'):
    """
    Use these plots to determine the constraints for perfect control in terms
    of combined reference changes. Equation 6.52 (p241) calculates the
    minimal requirement for input saturation to check in terms of set point
    tracking. A more tighter bounds is calculated with equation 6.53 (p241).

    Parameters
    ----------
    G : tf
        Plant transfer function.
    R : numpy matrix (n x n)
        Reference changes (usually diagonal with all elements larger than 1)
    wr : float
        Frequency up to witch reference tracking is required
    type_eq : string
        Type of plot:

        =========      ==================================
        plot_type      Type of plot
        =========      ==================================
        minimal        Minimal requirement, equation 6.52
        tighter        Tighter requirement, equation 6.53
        allo           All requirements
        =========      ==================================

    Returns
    -------
    Plot : matplotlib figure

    Note
    ----
    All the plots in this function needs to be larger than 1 for perfect
    control, otherwise input saturation will occur.
    """

    s, w, axlim = df.frequency_plot_setup(axlim, w_start, w_end, points)

    lab1 = '$\sigma_{min} (G(jw))$'
    bound1 = [utils.sigmas(G(si), 'min') for si in s]
    lab2 = '$\sigma_{min} (R^{-1}G(jw))$'
    bound2 = [utils.sigmas(numpy.linalg.pinv(R) * G(si), 'min') for si in s]

    if plot_type == 'all':
        plt.loglog(w, bound1, label=lab1)
        plt.loglog(w, bound2, label=lab2)
    elif plot_type == 'minimal':
        plt.loglog(w, bound1, label=lab1)
    elif plot_type == 'tighter':
        plt.loglog(w, bound2, label=lab2)

    else:
        raise ValueError('Invalid plot_type parameter.')

    mm = bound1 + bound2 + [1]  # ensures that whole graph is visible
    plt.loglog([wr, wr], [0.5 * numpy.min(mm), 5 * numpy.max(mm)],
               'r', ls=':', label='Ref tracked')
    plt.loglog([w[0], w[-1]], [1, 1], 'r', label='Bound')
    plt.legend()
コード例 #2
0
ファイル: Project.py プロジェクト: pdawsonsa/CBT700Project
def uncertAnalisys():
    #Aditive uncertainty Function ==============================        
    def WA(s):
        K = 9
        ta1 = 1./0.35
        Wa = K/((ta1*s + 1))
        return(np.abs(Wa))
    #Multiplicative uncertainty Function =======================        
    def WM(s):
        tm1 = 1./0.09
        tm2 = 1./0.25
        Wm = (tm1*s + 0.2)/((tm2*s + 1))
        return(np.abs(Wm))
    def M(s):
        Ma = -WA(s) * Kc(s) * S(s)
        Mm = -WM(s) * T(s)
        return(Ma, Mm)
    w = np.logspace(-3,0,1000)
    Mat = np.zeros((len(w)))
    Mmt = np.zeros((len(w)))
    Su = np.zeros((len(w)))
    Tu = np.zeros((len(w)))
    WI = np.zeros((len(w)))
    for i in range(len(w)):
        Ma, Mm = M(w[i]*1j)
        Mat[i] = utils.sigmas(Ma)[0]
        Mmt[i] = utils.sigmas(Mm)[0]
        WI[i] = np.abs(WM(w[i]*1j))
        Su[i] = utils.sigmas(S(w[i]*1j))[0]
        Tu[i] = utils.sigmas(T(w[i]*1j))[0]
    plt.figure(8)
    plt.clf()
    plt.subplot(211)
    plt.semilogx(w, Mmt, 'r-', label = 'Multiplicative W$_O$')
    plt.semilogx(w, Mat, 'b-', label = 'Additive W$_A$')
    plt.axvline(wB_, color='blue', ls=':', lw='2')
    plt.text(wB_*1.1, np.max(Mmt)*0.9, 'req wB', color='blue')
    plt.axhline(1.0, color='blue', ls = ':', lw='2')
    plt.ylabel('Magnitude')
    plt.xlabel('Frequency [rad/s)]')
    plt.axis([None, None, None, None])
    plt.grid(True)
    plt.legend(loc='upper left', fontsize = 12, ncol=5)
    plt.subplot(212)
    plt.loglog(w, Tu, 'r-')
    plt.loglog(w, 1/WI, 'k:', lw='2')
    plt.ylabel('Magnitude')
    plt.xlabel('Frequency [rad/s)]')
    plt.axis([None, None, None, None])
    plt.text(0.2, np.max(Tu), '|T|$_{(not RS)}$', color='red')
#    plt.text(0.11, np.max(Tu)*0.4, '|T|$_{(RS)}$', color='green')
    plt.text(0.01, 5, '1/|W$_I$|')
    plt.grid(True)
    fig = plt.gcf()
    BG = fig.patch
    BG.set_facecolor('white')
    fig.subplots_adjust(bottom=0.2) 
    fig.subplots_adjust(top=0.9) 
    fig.subplots_adjust(left=0.2) 
    fig.subplots_adjust(right=0.9)   
コード例 #3
0
def ref_perfect_const_plot(G, R, wr, w_start=-2, w_end=2, axlim=None,
                           points=1000, plot_type='all'):
    """
    Use these plots to determine the constraints for perfect control in terms
    of combined reference changes. Equation 6.52 (p241) calculates the
    minimal requirement for input saturation to check in terms of set point
    tracking. A more tighter bounds is calculated with equation 6.53 (p241).

    Parameters
    ----------
    G : tf
        Plant transfer function.
    R : numpy matrix (n x n)
        Reference changes (usually diagonal with all elements larger than 1)
    wr : float
        Frequency up to witch reference tracking is required
    type_eq : string
        Type of plot:

        =========      ==================================
        plot_type      Type of plot
        =========      ==================================
        minimal        Minimal requirement, equation 6.52
        tighter        Tighter requirement, equation 6.53
        allo           All requirements
        =========      ==================================

    Returns
    -------
    Plot : matplotlib figure

    Note
    ----
    All the plots in this function needs to be larger than 1 for perfect
    control, otherwise input saturation will occur.
    """

    s, w, axlim = df.frequency_plot_setup(axlim, w_start, w_end, points)

    lab1 = '$\sigma_{min} (G(jw))$'
    bound1 = [utils.sigmas(G(si), 'min') for si in s]
    lab2 = '$\sigma_{min} (R^{-1}G(jw))$'
    bound2 = [utils.sigmas(numpy.linalg.pinv(R) * G(si), 'min') for si in s]

    if plot_type == 'all':
        plt.loglog(w, bound1, label=lab1)
        plt.loglog(w, bound2, label=lab2)
    elif plot_type == 'minimal':
        plt.loglog(w, bound1, label=lab1)
    elif plot_type == 'tighter':
        plt.loglog(w, bound2, label=lab2)

    else:
        raise ValueError('Invalid plot_type parameter.')

    mm = bound1 + bound2 + [1]  # ensures that whole graph is visible
    plt.loglog([wr, wr], [0.5 * numpy.min(mm), 5 * numpy.max(mm)],
               'r', ls=':', label='Ref tracked')
    plt.loglog([w[0], w[-1]], [1, 1], 'r', label='Bound')
    plt.legend()
コード例 #4
0
ファイル: utilsplot.py プロジェクト: Mvuyiso/Skogestad-Python
    def subbode(A, text, crossover, labB, labP):
        Sv = numpy.zeros((len(w), dim), dtype=complex)
        f = False
        wA = 0
        for i in range(len(w)):
            Sv[i, :] = utils.sigmas(G(s[i]))
            if not f:
                if (labB == 'wC' and Sv[i, -1] < 1) or (labB == 'wB' and Sv[i, 0] > 0.707):
                    wA = w[i]
                    f = True
        ymin = numpy.min(Sv[:, -1])

        if not sv_all:
            plt.loglog(w, Sv[:, 0], 'b', label=('$\sigma_{max}(%s)$') % labP)
            plt.loglog(w, Sv[:, -1], 'g', label=('$\sigma_{min}(%s)$') % labP)
        else:
            for j in range(dim):
                plt.loglog(w, Sv[:, j], label=('$\sigma_{%s}(%s)$' % (j, labP)))
        plt.axhline(crossover, ls=':', lw=2, color='r')
        if text:
            plt.axvline(wA, ls=':', lw=2, color='r')
            plt.text(wA*1.1, ymin*1.1, labB, color='r')
        plt.axis(axlim)
        plt.grid()
        plt.xlabel('Frequency [rad/unit time]')
        plt.ylabel('$\sigma$')
        plt.legend()
        return wA
コード例 #5
0
def input_acceptable_const_plot(G, Gd, w_start=-2, w_end=2, axlim=None,
                                points=1000, modified=False):
    """
    Subbplots for input constraints for accepatable control. Applies equation
    6.55 (p241).

    Parameters
    ----------
    G : numpy matrix
        Plant model.
    Gd : numpy matrix
        Plant disturbance model.
    modified : boolean
        If true, the arguments in the equation are change to :math:`\sigma_1
        (G) + 1 \geq |u_i^H g_d|`. This is to avoid a negative log scale.

    Returns
    -------
    Plot : matplotlib figure

    Note
    ----
    This condition only holds for :math:`|u_i^H g_d|>1`.
    """

    s, w, axlim = df.frequency_plot_setup(axlim, w_start, w_end, points)

    freqresp = [G(si) for si in s]
    sig = numpy.array([utils.sigmas(Gfr) for Gfr in freqresp])
    one = numpy.ones(points)

    plot_No = 1

    dimGd = numpy.shape(Gd(0))[1]
    dimG = numpy.shape(G(0))[0]
    acceptable_control = numpy.zeros((dimGd, dimG, points))
    for j in range(dimGd):
        for i in range(dimG):
            for k in range(points):
                U, _, _ = utils.SVD(G(s[k]))
                acceptable_control[j, i, k] = numpy.abs(U[:, i].H *
                                                        Gd(s[k])[:, j])
            plt.subplot(dimG, dimGd, plot_No)
            if not modified:
                plt.loglog(w, sig[:, i],
                           label=('$\sigma_%s$' % (i + 1)))
                plt.plot(w, acceptable_control[j, i] - one,
                         label=('$|u_%s^H.g_{d%s}|-1$' % (i + 1, j + 1)))
            else:
                plt.loglog(w, sig[:, i] + one,
                           label=('$\sigma_%s+1$' % (i + 1)))
                plt.plot(w, acceptable_control[j, i],
                         label=('$|u_%s^H.g_{d%s}|$' % (i + 1, j + 1)))
                plt.loglog([w[0], w[-1]], [1, 1], 'r',
                           ls=':', label='Applicable')
            plt.xlabel('Frequency [rad/unit time]')
            plt.grid(True)
            plt.axis(axlim)
            plt.legend()
            plot_No += 1
コード例 #6
0
    def subbode(A, text, crossover, labB, labP):
        Sv = numpy.zeros((len(w), dim), dtype=complex)
        f = False
        wA = 0
        for i in range(len(w)):
            Sv[i, :] = utils.sigmas(G(s[i]))
            if not f:
                if ((labB == 'wC' and Sv[i, -1] < 1) or
                        (labB == 'wB' and Sv[i, 0] > 0.707)):
                    wA = w[i]
                    f = True
        ymin = numpy.min(Sv[:, -1])

        if not sv_all:
            plt.loglog(w, Sv[:, 0], 'b', label=('$\sigma_{max}(%s)$') % labP)
            plt.loglog(w, Sv[:, -1], 'g', label=('$\sigma_{min}(%s)$') % labP)
        else:
            for j in range(dim):
                plt.loglog(w, Sv[:, j],
                           label=('$\sigma_{%s}(%s)$' % (j, labP)))
        plt.axhline(crossover, ls=':', lw=2, color='r')
        if text:
            plt.axvline(wA, ls=':', lw=2, color='r')
            plt.text(wA*1.1, ymin*1.1, labB, color='r')
        # This function does not seem to do anything, since axlim is a list of
        # none values. See doc_func.py.frequency_spot_setup
        # plt.axis(axlim)
        plt.grid()
        plt.xlabel('Frequency [rad/unit time]')
        plt.ylabel('$\sigma$')
        plt.legend(loc=legend_loc)
        return wA
コード例 #7
0
    def subbode(A, text, crossover, labB, labP):
        Sv = numpy.zeros((len(w), dim), dtype=complex)
        f = False
        wA = 0
        for i in range(len(w)):
            Sv[i, :] = utils.sigmas(G(s[i]))
            if not f:
                if ((labB == 'wC' and Sv[i, -1] < 1)
                        or (labB == 'wB' and Sv[i, 0] > 0.707)):
                    wA = w[i]
                    f = True
        ymin = numpy.min(Sv[:, -1])

        if not sv_all:
            plt.loglog(w, Sv[:, 0], 'b', label=('$\sigma_{max}(%s)$') % labP)
            plt.loglog(w, Sv[:, -1], 'g', label=('$\sigma_{min}(%s)$') % labP)
        else:
            for j in range(dim):
                plt.loglog(w,
                           Sv[:, j],
                           label=('$\sigma_{%s}(%s)$' % (j, labP)))
        plt.axhline(crossover, ls=':', lw=2, color='r')
        if text:
            plt.axvline(wA, ls=':', lw=2, color='r')
            plt.text(wA * 1.1, ymin * 1.1, labB, color='r')
        plt.axis(axlim)
        plt.grid()
        plt.xlabel('Frequency [rad/unit time]')
        plt.ylabel('$\sigma$')
        plt.legend()
        return wA
コード例 #8
0
def input_acceptable_const_plot(G, Gd, w_start=-2, w_end=2, axlim=None,
                                points=1000, modified=False):
    """
    Subplots for input constraints for acceptable control. Applies equation
    6.55 (p241).

    Parameters
    ----------
    G : numpy matrix
        Plant model.
    Gd : numpy matrix
        Plant disturbance model.
    modified : boolean
        If true, the arguments in the equation are changed to :math:`\sigma_1
        (G) + 1 \geq |u_i^H g_d|`. This is to avoid a negative log scale.

    Returns
    -------
    Plot : matplotlib figure

    Note
    ----
    This condition only holds for :math:`|u_i^H g_d|>1`.
    """

    s, w, axlim = df.frequency_plot_setup(axlim, w_start, w_end, points)

    freqresp = [G(si) for si in s]
    sig = numpy.array([utils.sigmas(Gfr) for Gfr in freqresp])
    one = numpy.ones(points)

    plot_No = 1

    dimGd = numpy.shape(Gd(0))[1]
    dimG = numpy.shape(G(0))[0]
    acceptable_control = numpy.zeros((dimGd, dimG, points))
    for j in range(dimGd):
        for i in range(dimG):
            for k in range(points):
                U, _, _ = utils.SVD(G(s[k]))
                acceptable_control[j, i, k] = numpy.abs(U[:, i].H *
                                                        Gd(s[k])[:, j])
            plt.subplot(dimG, dimGd, plot_No)
            if not modified:
                plt.loglog(w, sig[:, i],
                           label=('$\sigma_%s$' % (i + 1)))
                plt.plot(w, acceptable_control[j, i] - one,
                         label=('$|u_%s^H.g_{d%s}|-1$' % (i + 1, j + 1)))
            else:
                plt.loglog(w, sig[:, i] + one,
                           label=('$\sigma_%s+1$' % (i + 1)))
                plt.plot(w, acceptable_control[j, i],
                         label=('$|u_%s^H.g_{d%s}|$' % (i + 1, j + 1)))
                plt.loglog([w[0], w[-1]], [1, 1], 'r',
                           ls=':', label='Applicable')
            plt.xlabel('Frequency [rad/unit time]')
            plt.grid(True)
            plt.axis(axlim)
            plt.legend()
            plot_No += 1
コード例 #9
0
ファイル: Project.py プロジェクト: pdawsonsa/CBT700Project
def distRej():
    w = np.logspace(-3,0,1000)
    S1 = np.zeros((len(w)))
    S2 = np.zeros((len(w)))
    Gd1 = np.zeros((len(w)))
    distCondNum = np.zeros((len(w)))
    condNum = np.zeros((len(w)))
    for i in range(len(w)):
        U, Sv, V = utils.SVD(S(w[i]*1j))
        S1[i] = Sv[0]                      #S = 1/|L + 1| 
        S2[i] = Sv[2]
        Gd1[i], distCondNum[i] = utils.distRej(G(w[i]*1j), Gd(w[i]*1j))
        condNum[i] = utils.sigmas(G(w[i]*1j),)[0]*utils.sigmas(la.inv(G(w[i]*1j)))[0]
    plt.figure(5)
    plt.clf()
    plt.subplot(211)
    plt.loglog(w, S1, 'r-', label = 'max $\sigma$S')
    plt.loglog(w, S2, 'r-', alpha = 0.4, label = 'min $\sigma$S')
    plt.loglog(w, Gd1, 'k-', label = '1/||Gd||$_2$')
    plt.axvline(wB, color='green')
    plt.ylabel('Magnitude')
    plt.xlabel('Frequency [rad/s)]')
    plt.text(wB*1.1, 0.015, 'wB = %s rad/s'%(np.round(wB,3)), color='green')
    plt.axis([None, None, None, 10])
    plt.grid(True)
    plt.legend(loc='upper left', fontsize = 12, ncol=5)
    fig = plt.gcf()
    BG = fig.patch
    BG.set_facecolor('white')
    plt.subplot(212)
    plt.semilogx(w, distCondNum, 'r-', label = 'Dist CondNum')
    plt.semilogx(w, condNum, 'k-', label = 'CondNum')
    plt.axvline(wB, color='green')
    plt.ylabel('Disturbance condtion number')
    plt.xlabel('Frequency [rad/s)]')
    plt.text(wB*1.1, 0.2, 'wB = %s rad/s'%(np.round(wB,3)), color='green')
    plt.axis([None, None, 0, None])
    plt.legend(loc='upper left', fontsize = 12, ncol=5)
    plt.grid(True)
    fig = plt.gcf()
    BG = fig.patch
    BG.set_facecolor('white')
    fig.subplots_adjust(bottom=0.2) 
    fig.subplots_adjust(top=0.9) 
    fig.subplots_adjust(left=0.2) 
    fig.subplots_adjust(right=0.9)
コード例 #10
0
ファイル: utilsplot.py プロジェクト: wakum/Skogestad-Python
def sv_plot(G, axlim=None, w_start=-2, w_end=2, points=100):
    '''
    Plot of Maximum and minimum singular values of a matirix
    
    Parameters
    ----------
    G : numpy array
        plant model or sensitivity function
              
    Returns
    -------
    fig(Max Min SV) : figure
        A figure of the maximum and minimum singular values of the matrix G
    
    Note
    ----
    Can be used with the plant matrix G and the sensitivity function S
    for controlability analysis
    '''

    if axlim is None:
        axlim = [None, None, None, None]

    w = numpy.logspace(w_start, w_end, points)
    s = w * 1j

    freqresp = map(G, s)

    plt.figure('Min Max SV')
    plt.clf()
    plt.gcf().set_facecolor('white')

    plt.semilogx(w, [utils.sigmas(Gfr)[0] for Gfr in freqresp],
                 label=('$\sigma$$_{MAX}$'),
                 color='blue')
    plt.semilogx(w, [utils.sigmas(Gfr)[-1] for Gfr in freqresp],
                 label=('$\sigma$$_{MIN}$'),
                 color='blue',
                 alpha=0.5)
    plt.xlabel('Frequency (rad/unit time)')

    plt.axhline(1., color='red', ls=':')
    plt.legend()
    plt.show()
    return
コード例 #11
0
def sv_plot(G, axlim=[None, None, None, None], w_start=-2, w_end=2, points=100):
    '''
    Plot of Maximum and minimum singular values of a matirix
    
    Parameters
    ----------
    G : numpy array
        plant model or sensitivity function
              
    Returns
    -------
    fig(Max Min SV) : figure
        A figure of the maximum and minimum singular values of the matrix G
    
    Note
    ----
    Can be used with the plant matrix G and the sensitivity function S
    for controlability analysis
    '''
    w = numpy.logspace(w_start, w_end, points)
    s = w*1j    
    
    freqresp = map(G, s)
    
    plt.figure('Min Max SV')
    plt.clf()
    plt.gcf().set_facecolor('white')
    
    plt.semilogx(w, [utils.sigmas(Gfr)[0] for Gfr in freqresp], label=('$\sigma$$_{MAX}$'), color='blue')
    plt.semilogx(w, [utils.sigmas(Gfr)[-1] for Gfr in freqresp], label=('$\sigma$$_{MIN}$'), color='blue', alpha=0.5)
    plt.xlabel('Frequency (rad/unit time)')
    
    plt.axhline(1., color='red', ls=':')
    plt.legend()  
    plt.show()
    return
コード例 #12
0
I = np.asmatrix(np.identity(2))


def G(s):
        """process transfer matrix"""
        return 1 / ((s ** 2) + a ** 2) * np.matrix([[s - a ** 2, a * (s + 1)],
                                                    [-a * (s + 1), s - a ** 2]])


def K(s):
    """controller"""
    return I


def T(s):
    """this is a special case where T_I(s)= T(s) """
    return G(s) * K(s) * (I + G(s) * K(s)).I

frequency = np.logspace(-3, 2, 1000)
s = 1j * frequency

max_singular_value_of_T = [max(utils.sigmas(T(si))) for si in s]
mu_T = [max(np.abs(np.linalg.eigvals(T(si)))) for si in s]

plt.loglog(frequency, max_singular_value_of_T, 'b')
plt.loglog(frequency, mu_T, 'r')
plt.legend(('max_singular_value(T)', 'mu(T)'), 'best', shadow=False)
plt.xlabel('frequency')
plt.ylabel('Magnitude')
plt.show()
コード例 #13
0
ファイル: utilsplot.py プロジェクト: wakum/Skogestad-Python
def dis_rejctn_plot(G, Gd, S, axlim=None, w_start=-2, w_end=2, points=100):
    '''
    A subplot of disturbance conditition number to check for input saturation
    and a subplot of  to see if the disturbances fall withing the bounds on
    the singular values of S.
    Parameters
    ----------
    G : numpy array
        plant model
    
    Gd : numpy array
        plant disturbance model

    S : numpy array
        Sensitivity function
              
              
    Returns
    -------
    fig(Condition number and performance objective) : figure
        A figure of the disturbance condition number and the bounds imposed
        by the singular values.
    
    Note
    ----
    The disturbance condition number provides a measure of how a disturbance gd
    is aligned with the plant G. Alignment can vary between 1 and the condition
    number.
    
    For acceptable performance the singular values of S must fall below the
    inverse 2-norm of gd.
    '''

    if axlim is None:
        axlim = [None, None, None, None]

    w = numpy.logspace(w_start, w_end, points)
    s = w * 1j

    dim = numpy.shape(G(0))
    inv_norm_gd = numpy.zeros((dim[1], points))
    condtn_nm_gd = numpy.zeros((dim[1], points))
    for i in range(dim[1]):
        for k in range(points):
            inv_norm_gd[i, k], condtn_nm_gd[i, k] = utils.distRej(
                G(s[k]),
                Gd(s[k])[:, i])

    s_min = [utils.sigmas(S(s[i]))[-1] for i in range(points)]
    s_max = [utils.sigmas(S(s[i]))[0] for i in range(points)]

    plt.figure('Condition number and performance objective')
    plt.clf()
    plt.gcf().set_facecolor('white')

    plt.subplot(2, 1, 1)
    for i in range(dim[1]):
        plt.loglog(w,
                   condtn_nm_gd[i],
                   label=('$\gamma$$_{d%s}$(G)' % (i + 1)),
                   color='blue',
                   alpha=((i + 1.) / dim[1]))
    plt.axhline(1., color='red', ls=':')
    plt.axis(axlim)
    plt.ylabel('$\gamma$$_d$(G)')
    plt.axhline(1., color='red', ls=':')
    plt.legend()

    plt.subplot(2, 1, 2)
    for i in range(dim[1]):
        plt.loglog(w,
                   inv_norm_gd[i],
                   label=('1/||g$_{d%s}$||$_2$' % (i + 1)),
                   color='blue',
                   alpha=((i + 1.) / dim[1]))
    plt.loglog(w, s_min, label=('$\sigma$$_{MIN}$'), color='green')
    plt.loglog(w, s_max, label=('$\sigma$$_{MAX}$'), color='green', alpha=0.5)
    plt.xlabel('Frequency (rad/unit time)')
    plt.ylabel('1/||g$_d$||$_2$')
    plt.axhline(1., color='red', ls=':')
    plt.legend()

    plt.show()
    return
コード例 #14
0
ファイル: Project.py プロジェクト: pdawsonsa/CBT700Project
def perfectControl():
    #For perfect cotnrol
    w = np.logspace(-3,0,1000)
    Gd1 = np.zeros((len(w)))
    Gd2 = np.zeros((len(w)))
    Gd3 = np.zeros((len(w)))
    for i in range(len(w)):
        Gt = G(w[i]*1j)                 #Gt just a temp assignmnet for G
        Gdt = Gd(w[i]*1j)               #Gdt just a temp assignmnet for Gd
#        Gd1[i] = la.norm(la.inv(Gt)*Gdt, ord=np.inf)
        Gd1[i] = utils.sigmas(la.inv(Gt)*Gdt)[0]
        Gd2[i] = utils.sigmas(la.inv(Gt)*Gdt)[1]
        Gd3[i] = utils.sigmas(la.inv(Gt)*Gdt)[2]
    plt.figure(6)
    plt.clf()
    plt.subplot(211)
    plt.semilogx(w, Gd1, 'r-', label = '|G$^{-1}$$_1$g$_d$|')
    plt.semilogx(w, Gd2, 'b-', label = '|G$^{-1}$$_2$g$_d$|')
    plt.semilogx(w, Gd3, 'k-', label = '|G$^{-1}$$_3$g$_d$|')
    plt.axvline(wB, color='green')
    plt.text(wB*1.1, np.max(Gd1), 'wB = %s rad/s'%(np.round(wB,3)), color='green')
    plt.ylabel('Magnitude')
    plt.xlabel('Frequency [rad/s)]')
    plt.axis([None, None, None, None])
    plt.grid(True)
    plt.legend(loc='upper left', fontsize = 12, ncol=1)
    fig = plt.gcf()
    BG = fig.patch
    BG.set_facecolor('white')
    fig.subplots_adjust(bottom=0.2) 
    fig.subplots_adjust(top=0.9) 
    fig.subplots_adjust(left=0.2) 
    fig.subplots_adjust(right=0.9)
    #For acceptable control
    S1 = np.zeros((len(w)))
    S2 = np.zeros((len(w)))
    S3 = np.zeros((len(w)))
    Gd1 = np.zeros((len(w)))
    Gd2 = np.zeros((len(w)))
    Gd3 = np.zeros((len(w)))
    for i in range(len(w)):
        U, Sv ,V = utils.SVD(G(w[i]*1j))
        Gdt = Gd(w[i]*1j)               #Gdt just a temp assignmnet for Gd
        S1[i] = Sv[0]
        S2[i] = Sv[1]
        S3[i] = Sv[2]
        Gd1[i] = np.max(np.abs(np.transpose(np.conj(U[0]))*Gdt) - 1)
        Gd2[i] = np.max(np.abs(np.transpose(np.conj(U[1]))*Gdt) - 1)
        Gd3[i] = np.max(np.abs(np.transpose(np.conj(U[2]))*Gdt) - 1)
    plt.subplot(212)
    plt.semilogx(w, S1, 'r-', label = '$\sigma$$_1$(G)')
    plt.semilogx(w, Gd1, 'r-', label = '|u$_1$$^H$g$_d$|', alpha = 0.4)
    plt.semilogx(w, S2, 'k-', label = '$\sigma$$_2$(G)')
    plt.semilogx(w, Gd2, 'k-', label = '|u$_2$$^H$g$_d$|', alpha = 0.4)
    plt.semilogx(w, S3, 'b-', label = '$\sigma$$_3$(G)')
    plt.semilogx(w, Gd3, 'b-', label = '|u$_3$$^H$g$_d$|', alpha = 0.4)
    plt.ylabel('Magnitude')
    plt.xlabel('Frequency [rad/s)]')
    plt.axis([None, None, None, None])
    plt.grid(True)
    plt.legend(loc='upper right', fontsize = 12)
    fig = plt.gcf()
    BG = fig.patch
    BG.set_facecolor('white')
    fig.subplots_adjust(bottom=0.2) 
    fig.subplots_adjust(top=0.9) 
    fig.subplots_adjust(left=0.2) 
    fig.subplots_adjust(right=0.9)   
コード例 #15
0
def dis_rejctn_plot(G,
                    Gd,
                    S=None,
                    w_start=-2,
                    w_end=2,
                    axlim=None,
                    points=1000):
    """
    A subplot of disturbance condition number to check for input saturation
    (equation 6.43, p238). Two more subplots indicate if the disturbances fall
    withing the bounds of S, applying equations 6.45 and 6.46 (p239).

    Parameters
    ----------
    G : numpy matrix
        Plant model.
    Gd : numpy matrix
        Plant disturbance model.
    S : numpy matrix
        Sensitivity function (optional, if available).
    # TODO test S condition
    Returns
    -------
    Plot : matplotlib figure

    Note
    ----
    The disturbance condition number provides a measure of how a disturbance gd
    is aligned with the plant G. Alignment can vary between 1 and the condition
    number.

    For acceptable performance the singular values of S must fall below the
    inverse 2-norm of gd.
    """

    s, w, axlim = df.frequency_plot_setup(axlim, w_start, w_end, points)

    dim = numpy.shape(Gd(0))[1]  # column count
    inv_norm_gd = numpy.zeros((dim, points))
    # row count
    yd = numpy.zeros((dim, points, numpy.shape(Gd(0))[0]), dtype=complex)
    condtn_nm_gd = numpy.zeros((dim, points))
    for i in range(dim):
        for k in range(points):
            inv_norm_gd[i, k], yd[i, k, :], condtn_nm_gd[i, k] = utils.distRej(
                G(s[k]),
                Gd(s[k])[:, i])

    if S is None:
        sub = 2
    else:
        sub = 3

    # Equation 6.43
    plt.subplot(sub, 1, 1)
    for i in range(dim):
        plt.loglog(w, condtn_nm_gd[i], label=('$\gamma_{d%s} (G)$' % (i + 1)))
    plt.axhline(1., color='red', ls=':')
    plt.axis(axlim)
    plt.xlabel('Frequency [rad/unit time]')
    plt.ylabel('$\gamma$$_d (G)$')
    plt.axhline(1., color='red', ls=':')
    plt.legend()

    # Equation 6.44
    plt.subplot(sub, 1, 2)
    for i in range(dim):
        plt.loglog(w, inv_norm_gd[i], label=('$1/||g_{d%s}||_2$' % (i + 1)))
        if S is not None:
            S_yd = numpy.array([
                numpy.linalg.norm(S(p) * yd[i, p, :].T, 2)
                for p in range(points)
            ])
            plt.loglog(w, S_yd, label='$||Sy_d||_2$')
    plt.axis(axlim)
    plt.xlabel('Frequency [rad/unit time]')
    plt.legend()

    if S is not None:  # subplot should not be repeated with S is not available
        # Equation 6.45
        plt.subplot(3, 1, 3)
        for i in range(dim):
            plt.loglog(w,
                       inv_norm_gd[i],
                       label=('$1/||g_{d%s}||_2$' % (i + 1)))
            s_min = numpy.array(
                [utils.sigmas(S(s[p]), 'min') for p in range(points)])
            s_max = numpy.array(
                [utils.sigmas(S(s[p]), 'max') for p in range(points)])
            plt.loglog(w, s_min, label='$\sigma_{min}$')
            plt.loglog(w, s_max, label='$\sigma_{max}$')
        plt.axis(axlim)
        plt.xlabel('Frequency [rad/unit time]')
        plt.legend()
コード例 #16
0
ファイル: utilsplot.py プロジェクト: wakum/Skogestad-Python
 def cndtn_nm(G):
     return (utils.sigmas(G)[0] / utils.sigmas(G)[-1])
コード例 #17
0
ファイル: utilsplot.py プロジェクト: Mvuyiso/Skogestad-Python
def dis_rejctn_plot(G, Gd, S=None, w_start=-2, w_end=2, axlim=None, points=1000):
    """
    A subplot of disturbance condition number to check for input saturation
    (equation 6.43, p238). Two more subplots indicate if the disturbances fall
    withing the bounds of S, applying equations 6.45 and 6.46 (p239).

    Parameters
    ----------
    G : numpy matrix
        Plant model.
    Gd : numpy matrix
        Plant disturbance model.
    S : numpy matrix
        Sensitivity function (optional, if available).
    # TODO test S condition
    Returns
    -------
    Plot : matplotlib figure

    Note
    ----
    The disturbance condition number provides a measure of how a disturbance gd
    is aligned with the plant G. Alignment can vary between 1 and the condition
    number.

    For acceptable performance the singular values of S must fall below the
    inverse 2-norm of gd.
    """

    s, w, axlim = df.frequency_plot_setup(axlim, w_start, w_end, points)

    dim = numpy.shape(Gd(0))[1]  # column count
    inv_norm_gd = numpy.zeros((dim, points))
    yd = numpy.zeros((dim, points, numpy.shape(Gd(0))[0]), dtype=complex)  # row count
    condtn_nm_gd = numpy.zeros((dim, points))
    for i in range(dim):
        for k in range(points):
            inv_norm_gd[i, k], yd[i, k, :], condtn_nm_gd[i, k] = utils.distRej(G(s[k]), Gd(s[k])[:, i])

    if S is None:
        sub = 2
    else:
        sub = 3

    # Equation 6.43
    plt.subplot(sub, 1, 1)
    for i in range(dim):
        plt.loglog(w, condtn_nm_gd[i], label=('$\gamma_{d%s} (G)$' % (i+1)))
    plt.axhline(1., color='red', ls=':')
    plt.axis(axlim)
    plt.xlabel('Frequency [rad/unit time]')
    plt.ylabel('$\gamma$$_d (G)$')
    plt.axhline(1., color='red', ls=':')
    plt.legend()

    # Equation 6.44
    plt.subplot(sub, 1, 2)
    for i in range(dim):
        plt.loglog(w, inv_norm_gd[i], label=('$1/||g_{d%s}||_2$' % (i+1)))
        if not S is None:
            S_yd = numpy.array([numpy.linalg.norm(S(p) * yd[i, p, :].T, 2) for p in range(points)])
            plt.loglog(w, S_yd, label='$||Sy_d||_2$')
    plt.axis(axlim)
    plt.xlabel('Frequency [rad/unit time]')
    plt.legend()

    if S is not None:  # this subplot should not be repeated with S is not available
        # Equation 6.45
        plt.subplot(3, 1, 3)
        for i in range(dim):
            plt.loglog(w, inv_norm_gd[i], label=('$1/||g_{d%s}||_2$' % (i+1)))
            s_min = numpy.array([utils.sigmas(S(s[p]), 'min') for p in range(points)])
            s_max = numpy.array([utils.sigmas(S(s[p]), 'max') for p in range(points)])
            plt.loglog(w, s_min, label='$\sigma_{min}$')
            plt.loglog(w, s_max, label='$\sigma_{max}$')
        plt.axis(axlim)
        plt.xlabel('Frequency [rad/unit time]')
        plt.legend()
コード例 #18
0
def condition_number(G):
    """Function to determine condition number"""
    sig = utils.sigmas(G)
    return max(sig) / min(sig)
コード例 #19
0
ファイル: utilsplot.py プロジェクト: Mvuyiso/Skogestad-Python
 def cndtn_nm(G):
     return utils.sigmas(G)[0]/utils.sigmas(G)[-1]
コード例 #20
0
def condition_number(G):
    """Function to determine condition number"""
    sig = utils.sigmas(G)
    return max(sig) / min(sig)
コード例 #21
0
def maxsigma(G):
    return max(utils.sigmas(G))
コード例 #22
0
def maxsigma(G):
    return max(utils.sigmas(G))
コード例 #23
0
def dis_rejctn_plot(G, Gd, S, axlim=[None, None, None, None], w_start=-2, w_end=2, points=100):
    '''
    A subplot of disturbance conditition number to check for input saturation
    and a subplot of  to see if the disturbances fall withing the bounds on
    the singular values of S.
    Parameters
    ----------
    G : numpy array
        plant model
    
    Gd : numpy array
        plant disturbance model

    S : numpy array
        Sensitivity function
              
              
    Returns
    -------
    fig(Condition number and performance objective) : figure
        A figure of the disturbance condition number and the bounds imposed
        by the singular values.
    
    Note
    ----
    The disturbance condition number provides a measure of how a disturbance gd
    is aligned with the plant G. Alignment can vary between 1 and the condition
    number.
    
    For acceptable performance the singular values of S must fall below the
    inverse 2-norm of gd.
    '''
    w = numpy.logspace(w_start, w_end, points)
    s = w*1j
    
    dim = numpy.shape(G(0))    
    inv_norm_gd = numpy.zeros((dim[1],points))
    condtn_nm_gd = numpy.zeros((dim[1],points))
    for i in range(dim[1]):
        for k in range(points):
            inv_norm_gd[i,k], condtn_nm_gd[i,k] = utils.distRej(G(s[k]), Gd(s[k])[:,i])
                      
    s_min = [utils.sigmas(S(s[i]))[-1] for i in range(points)]
    s_max = [utils.sigmas(S(s[i]))[0] for i in range(points)]
    
    plt.figure('Condition number and performance objective')
    plt.clf()
    plt.gcf().set_facecolor('white')
    
    plt.subplot(2,1,1)
    for i in range(dim[1]):
        plt.loglog(w, condtn_nm_gd[i], label=('$\gamma$$_{d%s}$(G)' % (i+1)), color='blue', alpha=((i+1.)/dim[1]))
    plt.axhline(1., color='red', ls=':')  
    plt.axis(axlim)
    plt.ylabel('$\gamma$$_d$(G)')
    plt.axhline(1., color='red', ls=':')
    plt.legend()
    
    plt.subplot(2,1,2)
    for i in range(dim[1]):
        plt.loglog(w, inv_norm_gd[i], label=('1/||g$_{d%s}$||$_2$' % (i+1)), color='blue', alpha=((i+1.)/dim[1]))   
    plt.loglog(w, s_min, label=('$\sigma$$_{MIN}$'), color='green')
    plt.loglog(w, s_max, label=('$\sigma$$_{MAX}$'), color='green', alpha = 0.5)  
    plt.xlabel('Frequency (rad/unit time)')
    plt.ylabel('1/||g$_d$||$_2$')
    plt.axhline(1., color='red', ls=':')
    plt.legend()    
    
    plt.show()
    return