Exemplo n.º 1
0
def bodeclosedloop(G,
                   K,
                   w_start=-2,
                   w_end=2,
                   axlim=None,
                   points=1000,
                   margin=False):
    """ 
    Shows the bode plot for a controller model
    
    Parameters
    ----------
    G : tf
        Plant transfer function.     
    K : tf
        Controller transfer function.    
    margin : boolean
        Show the cross over frequencies on the plot (optional).
    """

    if axlim is None:
        axlim = [None, None, None, None]
    plt.gcf().set_facecolor('white')

    w = numpy.logspace(w_start, w_end, points)
    L = G(1j * w) * K(1j * w)
    S = utils.feedback(1, L)
    T = utils.feedback(L, 1)

    plt.subplot(2, 1, 1)
    plt.loglog(w, abs(L))
    plt.loglog(w, abs(S))
    plt.loglog(w, abs(T))
    plt.axis(axlim)
    plt.grid()
    plt.ylabel("Magnitude")
    plt.legend(["L", "S", "T"])

    if margin:
        plt.plot(w, 1 / numpy.sqrt(2) * numpy.ones(len(w)), linestyle='dotted')

    plt.subplot(2, 1, 2)
    plt.semilogx(w, utils.phase(L, deg=True))
    plt.semilogx(w, utils.phase(S, deg=True))
    plt.semilogx(w, utils.phase(T, deg=True))
    plt.axis(axlim)
    plt.grid()
    plt.ylabel("Phase")
    plt.xlabel("Frequency [rad/s]")
Exemplo n.º 2
0
def bodeclosedloop(G, K, w_start=-2, w_end=2, axlim=None, points=1000, margin=False):
    """
    Shows the bode plot for a controller model

    Parameters
    ----------
    G : tf
        Plant transfer function.
    K : tf
        Controller transfer function.
    margin : boolean
        Show the cross over frequencies on the plot (optional).
    """

    if axlim is None:
        axlim = [None, None, None, None]
    plt.gcf().set_facecolor('white')

    w = numpy.logspace(w_start, w_end, points)
    L = G(1j*w) * K(1j*w)
    S = utils.feedback(1, L)
    T = utils.feedback(L, 1)

    plt.subplot(2, 1, 1)
    plt.loglog(w, abs(L))
    plt.loglog(w, abs(S))
    plt.loglog(w, abs(T))
    plt.axis(axlim)
    plt.grid()
    plt.ylabel("Magnitude")
    plt.legend(["L", "S", "T"])

    if margin:
        plt.plot(w, 1/numpy.sqrt(2) * numpy.ones(len(w)), linestyle='dotted')

    plt.subplot(2, 1, 2)
    plt.semilogx(w, utils.phase(L, deg=True))
    plt.semilogx(w, utils.phase(S, deg=True))
    plt.semilogx(w, utils.phase(T, deg=True))
    plt.axis(axlim)
    plt.grid()
    plt.ylabel("Phase")
    plt.xlabel("Frequency [rad/s]")
Exemplo n.º 3
0
import matplotlib.pyplot as plt
import numpy as np
from utils import feedback, tf

# Process model of G with various Controller Gains
s = tf([1, 0], 1)
G = 3 * (-2 * s + 1) / ((10 * s + 1) * (5 * s + 1))

tspan = np.linspace(0, 50, 100)

#  calculate the time domain response
Ks = [0.5, 1.5, 2, 2.5]
for K in Ks:
    T = feedback(G * K, 1)
    [t, y] = T.step(0, tspan)
    plt.plot(t, y)

plt.legend(["Kc = %1.1f" % K for K in Ks])
plt.xlabel('Time [s]')
plt.show()
Exemplo n.º 4
0
[t, y] = f.step()

plt.title('Figure 2.8')
plt.xlabel('Time [s]')
plt.plot(t, y)
plt.figure()


# Bode magnitude and phase plot - Figure 2.14
w = np.logspace(-2, 1, 1000)
s = w*1j
K = Kc*(1+1/(Tauc*s))
G = 3*(-2*(s)+1)/((10*s+1)*(5*s+1))
L = G*K
S = feedback(1, L)
T = feedback(L, 1)

plt.subplot(2, 1, 1)
plt.loglog(w, abs(L))
plt.loglog(w, abs(S))
plt.loglog(w, abs(T))
plt.ylabel("Magnitude")
plt.legend(["L", "S", "T"],
           bbox_to_anchor=(0, 1.01, 1, 0), loc=3, ncol=3)
plt.subplot(2, 1, 2)
plt.semilogx(w, phase(L, deg=True))
plt.semilogx(w, phase(S, deg=True))
plt.semilogx(w, phase(T, deg=True))
plt.ylabel("Phase")
plt.xlabel("Frequency [rad/s]")
Exemplo n.º 5
0
The example used here is the same as in the reference
"""

# First example in reference to demonstrate working of tf object

# Define s as tf to enable its use as a variable
s = tf([1, 0])

# Define the transfer functions
F = tf(1, [1, 1])
G = tf(100, [1, 5, 100])
C = 20*(s**2 + s + 60) / s / (s**2 + 40*s + 400)
S = tf(10, [1, 10])

T = F * feedback(G*C, S)

# This is the same figure as in the reference

tf_step(T, 6)



# Assign names to lines as in second example
F.u = 'r';  F.y = 'uF'
C.u = 'e';  C.y = 'uC'
G.u = 'u';  G.y = 'ym'
S.u = 'ym'; S.y = 'y'


# There must be a better way to call the name of an object if the object has
Exemplo n.º 6
0
# closed-loop transfer function
L = G * K

# magnitude and phase of L
plt.figure('Figure 2.19')
bode(L, -2, 1)

# From the figure we can calculate w180
#         w180 = 0.44
GM, PM, wc, wb, wbt, valid = marginsclosedloop(L)
print('GM:', np.round(GM, 2))
print('PM:', np.round(PM * np.pi / 180, 2), "rad or", np.round(PM, 2), "deg")
print('wb:', np.round(wb, 2))
print('wc:', np.round(wc, 2))
print('wbt:', np.round(wbt, 4))

# Response to step in reference for loop shaping design
# y = Tr, r(t) = 1 for t > 0
# u = KSr, r(t) = 1 for t > 0

plt.figure('Figure 2.20')
T = feedback(L, 1)
S = feedback(1, L)
u = K * S
step_response_plot(T, u, 50, 0)

# magnitude and phase of K
plt.figure('Figure 2.21')
bode(K, -2, 1)
plt.show()
Exemplo n.º 7
0
from utilsplot import step_response_plot
from utils import feedback, tf

s = tf([1, 0], 1)

Kd = 0.5

G = 5 / ((10 * s + 1) * (s - 1))
Gd = Kd / ((s + 1) * (0.2 * s + 1))
K = 0.04 / s * ((10 * s + 1)**2) / ((0.1 * s + 1)**2)

L = G * K

# Transfer function between disturbance and output y
S = feedback(1, L) * Gd

# Transfer function between disturbance and controller input u
Gu = -S * K

plt.figure('Figure 5.16 (a)')

plt.subplot(1, 2, 1)
w = np.logspace(-2, 1, 1000)
wi = w * 1j
plt.loglog(w, np.abs(G(wi)))
plt.loglog(w, np.abs(Gd(wi)))
plt.axhline(1, color='black', linestyle=':')
plt.title('(a) $|G|$ & $|G_d|$ with $k_d$=0.5')
plt.xlabel('Frequency [rad/s]')
plt.ylabel('Magnitude')
Exemplo n.º 8
0
def freq_step_response_plot(G,
                            K,
                            Kc,
                            t_end=50,
                            freqtype='S',
                            w_start=-2,
                            w_end=2,
                            axlim=None,
                            points=1000):
    """
    A subplot function for both the frequency response and step response for a
    controlled plant

    Parameters
    ----------
    G : tf
        Plant transfer function.
    K : tf
        Controller transfer function.
    Kc : integer
        Controller constant.
    t_end : integer
        Time period which the step response should occur.
    freqtype : string (optional)
        Type of function to plot:

        ========    ==================================
        freqtype    Type of function to plot
        ========    ==================================
        S           Sensitivity function
        T           Complementary sensitivity function
        L           Loop function
        ========    ==================================

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

    """

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

    plt.subplot(1, 2, 1)

    # Controllers transfer function with various controller gains
    Ks = [(kc * K) for kc in Kc]
    Ts = [utils.feedback(G * Kss, 1) for Kss in Ks]

    if freqtype == 'S':
        Fs = [(1 - Tss) for Tss in Ts]
        plt.title('(a) Sensitivity function')
        plt.ylabel('Magnitude $|S|$')
    elif freqtype == 'T':
        Fs = Ts
        plt.title('(a) Complementary sensitivity function')
        plt.ylabel('Magnitude $|T|$')
    else:  # freqtype=='L'
        Fs = [(G * Kss) for Kss in Ks]
        plt.title('(a) Loop function')
        plt.ylabel('Magnitude $|L|$')

    wi = w * 1j
    i = 0
    for F in Fs:
        plt.loglog(w, abs(F(wi)), label='Kc={d%s}=' % Kc[i])
        i += 1
    plt.axis(axlim)
    plt.grid(b=None, which='both', axis='both')
    plt.xlabel('Frequency [rad/unit time]')
    plt.legend(["Kc = %1.2f" % k for k in Kc], loc=4)

    plt.subplot(1, 2, 2)
    plt.title('(b) Response to step in reference')
    tspan = numpy.linspace(0, t_end, points)
    for T in Ts:
        [t, y] = T.step(0, tspan)
        plt.plot(t, y)
    plt.plot(tspan, 0 * numpy.ones(points), ls='--')
    plt.plot(tspan, 1 * numpy.ones(points), ls='--')
    plt.axis(axlim)
    plt.xlabel('Time')
    plt.ylabel('$y(t)$')
Exemplo n.º 9
0
The example used here is the same as in the reference
"""

# First example in reference to demonstrate working of tf object

# Define s as tf to enable its use as a variable
s = tf([1, 0])

# Define the transfer functions
F = tf(1, [1, 1])
G = tf(100, [1, 5, 100])
C = 20 * (s**2 + s + 60) / s / (s**2 + 40 * s + 400)
S = tf(10, [1, 10])

T = F * feedback(G * C, S)
# This is NOT the same figure as in the reference
t, y = tf_step(T, 6)
plt.plot(t, y)
plt.xlabel('Time')
plt.ylabel('y(t)')
plt.show()
#utilsplot.step(T, t_end = 6)

# Assign names to lines as in second example
F.u = 'r'
F.y = 'uF'
C.u = 'e'
C.y = 'uC'
G.u = 'u'
G.y = 'ym'
Exemplo n.º 10
0
import matplotlib.pyplot as plt
import numpy as np
from utils import tf, feedback

# Process model transfer function
s = tf([1, 0])
G = (-s + 1) / (s + 1)

# Controllers transfer function with various controller gains
Ks = [Kc * ((s + 1) / s) * (1 / (0.05 * s + 1)) for Kc in [0.2, 0.5, 0.8]]

# Complementary sensitivity transfer functions
Ts = [feedback(G * K, 1) for K in Ks]

plt.figure("Figure 5.7")
w = np.logspace(-2, 2, 1000)
wi = w * 1j
plt.subplot(1, 2, 1)
plt.title("(a) Sensitivity function")
for T in Ts:
    S = 1 - T
    plt.loglog(w, abs(S(wi)))
plt.xlabel("Frequency [rad/s]")
plt.ylabel("Magnitude |S|")
plt.legend(["Kc=0.2", "Kc=0.5", "Kc=0.8"], bbox_to_anchor=(0, 1.03, 1, 0), loc=3, ncol=3)

plt.subplot(1, 2, 2)
plt.title("(b) Response to step in reference")
tspan = np.linspace(0, 5, 100)
for T in Ts:
    [t, y] = T.step(0, tspan)
Exemplo n.º 11
0
import matplotlib.pyplot as plt
import numpy as np

from utils import feedback, tf

# Process model of G with various Controller Gains
s = tf([1, 0], 1)
G = 3 * (-2 * s + 1) / ((10 * s + 1) * (5 * s + 1))

tspan = np.linspace(0, 50, 100)
plt.figure('Figure 2.6')
plt.title('Effect of proportional gain Kc on closed loop response')

#  calculate the time domain response
Ks = [0.5, 1.5, 2, 2.5, 3.0]
for K in Ks:
    T = feedback(G * K, 1)
    [t, y] = T.step(0, tspan)
    if K >= 3.0:
        plt.plot(t, y, '-.')
    else:
        plt.plot(t, y)

plt.legend(["Kc = %1.1f" % K for K in Ks])
plt.xlabel('Time [s]')
plt.ylim(-0.5, 2.5)
plt.show()
from utils import tf, feedback, tf_step
import utilsplot
import matplotlib.pyplot as plt
import numpy as np

s = tf([1,0], 1)
G = 200/((10*s + 1)*(0.05*s + 1)**2)
Gd = 100/(10*s + 1)

wc = 10
K = wc*(10*s + 1)*(0.1*s + 1)/(200*s*(0.01*s + 1))
L = G*K

t = np.linspace(0, 3)
Sd = (1/(1 + G*K))*Gd
T = feedback(L, 1)

[t,y] = tf_step(T, 3)
plt.figure('Figure 2.22')
plt.subplot(1, 2, 1)
plt.plot(t, y)
plt.title('Tracking Response')
plt.ylabel('y(t)')
plt.xlabel('Time (s)')
plt.ylim([0, 1.5])

[t,yd] = Sd.step(0, t)
plt.subplot(1, 2, 2)
plt.plot(t, yd)
plt.ylabel('y(t)')
plt.xlabel('Time (s)')
Exemplo n.º 13
0
import matplotlib.pyplot as plt
import numpy as np
from utils import tf, feedback

# Process model transfer function
s = tf([1, 0])
G = (-s + 1)/(s + 1)

# Controllers transfer function with various controller gains
Ks = [Kc * ((s + 1)/s) * (1 / (0.05 * s + 1)) for Kc in [0.2, 0.5, 0.8]]

# Complementary sensitivity transfer functions
Ts = [feedback(G * K, 1) for K in Ks]

plt.figure('Figure 5.7')
w = np.logspace(-2, 2, 1000)
wi = w * 1j
plt.subplot(1, 2, 1)
plt.title('(a) Sensitivity function')
for T in Ts:
    S = 1 - T
    plt.loglog(w, abs(S(wi)))
plt.xlabel('Frequency [rad/s]')
plt.ylabel('Magnitude |S|')
plt.legend(["Kc=0.2", "Kc=0.5", "Kc=0.8"],
           bbox_to_anchor=(0, 1.03, 1, 0), loc=3, ncol=3)
           
plt.subplot(1, 2, 2)
plt.title('(b) Response to step in reference')
tspan = np.linspace(0, 5, 100)
Exemplo n.º 14
0
#magnitude and phase
plt.subplot(2, 1, 1)
plt.loglog(w, abs(L(wi)))
plt.loglog(w, np.ones_like(w))
plt.ylabel('Magnitude')

plt.subplot(2, 1, 2)
plt.semilogx(w, phase(L(wi), deg=True))
plt.semilogx(w, -180*np.ones_like(w))
plt.ylabel('Phase')
plt.xlabel('frequency (rad/s)')
plt.figure()

# From the figure we can calculate GM and PM,
# cross-over frequency wc and w180
# results:GM = 1/0.354 = 2.82
#         PM = -125.3 + 180 = 54 degC
#         w180 = 0.44
#         wc = 0.15

#Response to step in reference for loop shaping design
#y = Tr, r(t) = 1 for t > 0

T = feedback(L, 1)
tspan = np.linspace(0, 50, 100)
[t, y] = T.step(0, tspan)
plt.plot(t, y)
plt.xlabel('Time (s)')
plt.grid()
plt.show()
Exemplo n.º 15
0
def freq_step_response_plot(G, K, Kc, t_end=50, freqtype='S', w_start=-2, w_end=2, axlim=None, points=1000):
    """
    A subplot function for both the frequency response and step response for a
    controlled plant

    Parameters
    ----------
    G : tf
        Plant transfer function.
    K : tf
        Controller transfer function.
    Kc : integer
        Controller constant.
    t_end : integer
        Time period which the step response should occur.
    freqtype : string (optional)
        Type of function to plot:

        ========    ==================================
        freqtype    Type of function to plot
        ========    ==================================
        S           Sensitivity function
        T           Complementary sensitivity function
        L           Loop function
        ========    ==================================

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

    """

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

    plt.subplot(1, 2, 1)

    # Controllers transfer function with various controller gains
    Ks = [(kc * K) for kc in Kc]
    Ts = [utils.feedback(G * Kss, 1) for Kss in Ks]

    if freqtype == 'S':
        Fs = [(1 - Tss) for Tss in Ts]
        plt.title('(a) Sensitivity function')
        plt.ylabel('Magnitude $|S|$')
    elif freqtype == 'T':
        Fs = Ts
        plt.title('(a) Complementary sensitivity function')
        plt.ylabel('Magnitude $|T|$')
    else:  # freqtype=='L'
        Fs = [(G*Kss) for Kss in Ks]
        plt.title('(a) Loop function')
        plt.ylabel('Magnitude $|L|$')

    wi = w * 1j
    i = 0
    for F in Fs:
        plt.loglog(w, abs(F(wi)), label='Kc={d%s}=' % Kc[i])
        i += 1
    plt.axis(axlim)
    plt.grid(b=None, which='both', axis='both')
    plt.xlabel('Frequency [rad/unit time]')
    plt.legend(["Kc = %1.2f" % k for k in Kc],loc=4)

    plt.subplot(1, 2, 2)
    plt.title('(b) Response to step in reference')
    tspan = numpy.linspace(0, t_end, points)
    for T in Ts:
        [t, y] = T.step(0, tspan)
        plt.plot(t, y)
    plt.plot(tspan, 0 * numpy.ones(points), ls='--')
    plt.plot(tspan, 1 * numpy.ones(points), ls='--')
    plt.axis(axlim)
    plt.xlabel('Time')
    plt.ylabel('$y(t)$')
from utilsplot import step_response_plot
from utils import feedback, tf


s = tf([1, 0], 1)

Kd = 0.5

G = 5/((10*s + 1)*(s - 1))
Gd = Kd/((s + 1)*(0.2*s + 1))
K = 0.04/s * ((10*s + 1)**2)/((0.1*s + 1)**2)

L = G * K

# Transfer function between disturbance and output y
S = feedback(1, L)*Gd

# Transfer function between disturbance and controller input u
Gu = -S*K
    
plt.figure('Figure 5.16 (a)')

plt.subplot(1, 2, 1)
w = np.logspace(-2, 1, 1000)
wi = w*1j 
plt.loglog(w, np.abs(G(wi)))
plt.loglog(w, np.abs(Gd(wi)))
plt.axhline(1, color='black', linestyle=':')
plt.title('(a) $|G|$ & $|G_d|$ with $k_d$=0.5')
plt.xlabel('Frequency [rad/s]')
plt.ylabel('Magnitude')
Exemplo n.º 17
0
s = tf([1, 0])

#Figure 5.8
G = (-s + 1)/(s + 1)
Kcs = [0.1, 0.5, 0.9]
K = -1*s/((1 + 0.02*s)*(1 + 0.05*s))

plt.figure('Figure 5.8')
utilsplot.freq_step_response_plot(G, K, Kcs, 0.2, 'S')

# Plot negative step response
t = np.linspace(0, 0.2, 1000)
u1 = np.ones(500)
u2 = np.zeros(500)
u = np.hstack((u1, u2))

plt.figure('Figure 5.8(b)')
plt.title('(b) Response to step in reference')
for Kc in Kcs:
    K2 = Kc * K
    T = feedback(G * K2, 1)
    tout, y, _ = T.lsim(u, t)    
    plt.plot(tout, y)

plt.plot(tout, u, color='black', linestyle='--', linewidth=0.25)
plt.legend(["Kc = %1.1f" % Kc for Kc in Kcs])
plt.ylabel('y(t)')
plt.xlabel('Time [s]')
plt.show()