Introduction To The Python Control Package: Finn Aakre Haugen
Introduction To The Python Control Package: Finn Aakre Haugen
2
Contents
1 Introduction 7
2 Transfer functions 9
3 Frequency response 25
3
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
5 Discrete-time models 39
5.1.1 Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
4
Preface
Welcome to this tutorial for the Python Control Package for analysis and design of dynamic
systems in general and feedback control systems in particular. The package resembles the
Control System Toolbox in MATLAB.
This tutorial is based on version 0.8.2 which was released on 17th April 2019.
This tutorial covers only some of the functions in the Python Control Package. However,
these function are basic, and if you master these functions, you should be well prepared for
using other functions in the package.
Most of the tutorial is about continuous-time models, i.e. transfer functions based on the
Laplace transform and state space models based on differential equations. Discrete-time
models are briefly covered in one chapter at the end of the tutorial. That coverage is brief
because the basic functions for continuous-time models can be used also for discrete-time
models, i.e. with the same syntax, however with the sampling time (period) as an extra
input argument in the functions.
The programming environment used in this book is Spyder, which comes with the
Anaconda distribution of Python.
http://techteach.no/python control
On the home page, you can also find files used in the tutorial.
A simple introduction to Python and Spyder is provided by the free pdf book Python
Simply available on http://techteach.no.
5
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
6
Chapter 1
Introduction
https://pypi.org/project/control/
https://python-control.readthedocs.io/en/0.8.2/control.html
The following command (in Python) imports the Python Control package into Python:
import control
1
In Windows: Start menu / Anaconda prompt.
7
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
In Python, tuples, lists and arrays can be used to store numerical data. However, only
arrays are practical for mathematical operations on the data, like addition and
multiplication. Therefore, I use arrays as the numerical data type consistently in this book,
even in cases where lists may be used.
To use arrays, you must import the numpy package. It has become a tradition to rename
the numpy package as np. Thus, in the beginning of your programs, you should include the
command
import numpy as np
Creation, manipulation and mathematical operation on arrays are described in detail e.g. in
the book Python Simply (cf. the Preface).
8
Chapter 2
Transfer functions
This chapter is about Laplace transform based transfer functions, or simply s-transfer
functions. Discrete time transfer functions, or z-transfer functions, are covered by Chapter
5.1.2.
The control.tf() function is used to create transfer functions with the following syntax:
H = control.tf(num, den)
where H is the resulting transfer function (object). num (representing the numerator) and
den (representing the denominator) are arrays where the elements are the coefficients of the
s-polynomials in descending order from left to right.
Of course, you can use any other names than H, num, and den in your own programs.
and
where, of course, the values of b1, b0, a1 and a0 have been defined earlier.
9
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
2
H(s) = (2.2)
5s + 1
The Python program 2.1 creates this transfer function. The code print(’H(s) = ’, H) is used
to present the transfer function in the console (of Spyder).
H(s) =
2
--------
5s+1
If you execute “H” (+ enter) in the Spyder console, the transfer function is more nicely
displayed, see Figure 2.1.
Figure 2.1: The transfer function nicely displayed with H (+ enter) executed in the console.
10
CHAPTER 2. TRANSFER FUNCTIONS
u y
H1 H2
Figure 2.2: A series combination of two transfer functions, H1 (s) and H2 (s)
Whether SISO or MIMO, you create a series combination with the series() function of the
Python Control package:
H = control.series(H1, H2)
Program 2.2 shows how the calculations can be done with the control.series() function.
1
SISO = Single Input Single Output
2
MIMO = Multiple Input Multiple Output
11
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
import numpy as np
import control
K1 = 2
K2 = 3
T = 4
num1 = np . array ([ K1 ])
den1 = np . array ([1 , 0])
num2 = np . array ([ K2 ])
den2 = np . array ([ T , 1])
H = control . series ( H1 , H2 )
print ( ’ H = ’ , H )
H=
6
------------
4 sˆ2 + s
y(s)
= H(s) = H2 (s) + H1 (s) (2.6)
u(s)
12
CHAPTER 2. TRANSFER FUNCTIONS
H1
u + y
+
H2
Figure 2.3: A parallel combination of two transfer functions, H1 (s) and H2 (s)
H = control.parallel(H1, H2)
2 3 2(4s + 1) + 3s 11s + 2
H(s) = + = = 2
s 4s + 1 s(4s + 1) 4s + s
Program 2.3 shows how the calculations can be done with the control.parallel() function.
import numpy as np
import control
K1 = 2
K2 = 3
T = 4
num1 = np . array ([ K1 ])
den1 = np . array ([1 , 0])
num2 = np . array ([ K2 ])
den2 = np . array ([ T , 1])
3
For simplicity, I insert here the numbers directly instead of the symbolic parameters, but in general I
recommend using symbolic parameters.
13
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
H = control . parallel ( H1 , H2 )
print ( ’ H = ’ , H )
H=
11 s + 2
------------
4 sˆ2 + s
r y
H1
_
H2
Figure 2.4: A feedback combination of two transfer functions, H1 (s) and H2 (s)
The resulting transfer function, from r (reference) to y, which can be denoted the closed
loop transfer function, can be calculated from the following expression defining y (for
simplicity, I drop the argument s here):
y = H1 · (r − H2 y) = H1 r − H1 H2 y
which gives
H1
y= r
1 + H1 H2
Thus, the resulting transfer function is
y(s) H1 (s)
= H(s) = (2.7)
r(s) 1 + H1 (s)H2 (s)
14
CHAPTER 2. TRANSFER FUNCTIONS
You may drop the argument sign = −1 if there is negative feedback since negative feedback
is the default setting.
You must use sign = 1 if there is a positive feedback instead of a negative feedback in
Figure 2.4.
In most cases – at least in feedback control systems – a negative feedback with H2 (s) = 1 in
the feedback path is assumed. Then, H1 () is the open loop transfer function, L(s), and
(2.7) becomes
y(s) L(s)
= H(s) = (2.8)
r(s) 1 + L(s)
In such cases, you can write
H = control.feedback(L, 1)
L(s) may be the series combination (i.e. the product) of the controller, the process, the
sensor, and the measurement filter:
Given a negative feedback loop with the following open loop transfer function:
2
L(s) = (2.10)
s
Manual calculation of the closed loop transfer function with (2.8) gives
2
L(s) 2
H(s) = = s 2 = (2.11)
1 + L(s) 1+ s
s+2
Program 2.4 shows how the calculations can be done with the control.feedback() function.
15
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
"""
import numpy as np
import control
H = control . feedback (L , 1)
print ( ’ H = ’ , H )
The result:
H=
2
---------
s+2
You can get (read) the numerator coefficients and denominator coefficients of a transfer
function, say H, with the control.tfdata() function:
where num list and den list are lists (not arrays) containing the coefficients.
To convert the lists to arrays, you can use the np.array() function:
and
16
CHAPTER 2. TRANSFER FUNCTIONS
# %% Getting the num and den coeffs as lists and then as arrays :
( num_list , den_list ) = control . tfdata ( H )
num_array = np . array ( num_list )
den_array = np . array ( den_list )
The result:
To “get rid of” the two inner pairs of square brackets, i.e. to reduce the dimensions of the
arrays:
producing:
[2]
[5 1]
The function control.forced response() is a function for simulation with transfer function
and state space models. Here, we focus on simulation with transfer functions.
control.forced response() can simulated with any user-defined input signal. Some
alternative simulation functions assuming special input signals are:
• control.step response()
• control.impulse response()
17
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
• control.initial response()
control.forced response() may be used in any of these cases. Therefore, I limit the
presentation in this document to the control.forced response() function.
where:
• Input arguments:
To plot the simulated output (y above), and maybe the input (u above), you can use the
plotting function in the matplotlib.pyplot module which requires import of this module.
The common way to import the module is:
y(s) 2
=
u(s) 5s + 1
18
CHAPTER 2. TRANSFER FUNCTIONS
• Initial state is 0.
# %% Creating model :
num = np . array ([2])
den = np . array ([5 , 1])
H = control . tf ( num , den )
# %% Defining signals :
t0 = 0
t1 = 20
dt = 0.01
nt = int ( t1 / dt ) + 1 # Number of points of sim time
t = np . linspace ( t0 , t1 , nt )
u = 2* np . ones ( nt )
# %% Simulation :
(t , y , x ) = control . forced_response (H , t , u , X0 =0)
# %% Plotting :
plt . close ( ’ all ’)
fig_width_cm = 24
fig_height_cm = 18
plt . figure (1 , figsize =( fig_width_cm /2.54 , fig_height_cm /2.54))
plt . subplot (2 , 1 , 1)
plt . plot (t , y , ’ blue ’)
# plt . xlabel ( ’ t [ s ] ’)
plt . grid ()
plt . legend ( labels =( ’y ’ ,))
plt . subplot (2 , 1 , 2)
plt . plot (t , u , ’ green ’)
plt . xlabel ( ’ t [ s ] ’)
plt . grid ()
plt . legend ( labels =( ’u ’ ,))
19
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
4 y
0
0.0 2.5 5.0 7.5 10.0 12.5 15.0 17.5 20.0
2.10 u
2.05
2.00
1.95
1.90
0.0 2.5 5.0 7.5 10.0 12.5 15.0 17.5 20.0
t [s]
Poles and zeros of a transfer function, H, can be calculated and plotted in a cartesian
diagram with
(p, z) = control.pzmap(H)
s+2
H(s) =
s2 + 4
Manual calculations gives:
20
CHAPTER 2. TRANSFER FUNCTIONS
• Poles:
p1,2 = ±2j
• Zero:
z = −2
Program 2.7 calculates the poles and the zero and plots them with the control.pzmap()
function. The plt.savefig() function is used to generate a pdf file of the diagram.
(p , z ) = control . pzmap ( H )
print ( ’ poles = ’ , p )
print ( ’ zeros = ’ , z )
The result:
e−Td s (2.12)
where Td is the time delay. In the Python Control Package, there is no function to you can
not define this s-transfer function (while this is straightforward for z-transfer functions, cf.
Ch. 5.1.2). However, you can use the control.pade() function to generate an
Padé-approximation of the time delay (2.12).
21
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
0.0
0.5
1.0
1.5
2.0
4 3 2 1 0 1 2
Real
Once you have a Padé-approximation of the time delay, you may use the control.series()
function to combine it with the transfer function having no time delay:
Given the following transfer function with time constant of 10 s and no time delay:
1
Hwithout delay (s) = (2.14)
10s + 1
Assume that this transfer function is combined in series with a transfer function, Hpade (s),
of a 10th order Padé-apprioximation representing a time delay of 10 s. The resulting
transfer function is:
1
Hwith delay (s) = Hwithout delay (s) · Hpade (s) = · Hpade (s) (2.15)
10s + 1
Program 2.8 generates these transfer functions and simulated a step response of
Hwith delay (s).
22
CHAPTER 2. TRANSFER FUNCTIONS
1.0
0.8
0.6
0.4
0.2
0.0
0 5 10 15 20 25 30 35 40
t [s]
Figure 2.7: Step response of Hwith delay (s) where the time delay is approximated with a
Padé-approximation.
23
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
24
Chapter 3
Frequency response
The function control.bode plot() generates frequency response data in terms of magnitude
and phase. The function may also plot the data in a Bode diagram. However, in the
following example, I have instead used the plt.plot() function to plot the data as this gives
more freedom to configure the plot.
Program 3.1 generates and plots frequency response of H(s) in terms of magnitude and
phase.
wb = 1 # Bandwidth [ rad / s ]
H = control . tf ([1] , [1/ wb , 1])
w0 = 0.1
25
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
w1 = 10
dw = 0.001
nw = int (( w1 - w0 )/ dw ) + 1 # Number of points of freq
w = np . linspace ( w0 , w1 , nw )
# %% Plotting :
plt . subplot (2 , 1 , 1)
plt . plot ( np . log10 ( w ) , mag , ’ blue ’)
# plt . xlabel ( ’ w [ rad / s ] ’)
plt . grid ()
plt . legend ( labels =( ’ mag ’ ,))
plt . subplot (2 , 1 , 2)
plt . plot ( np . log10 ( w ) , phase_rad *180/ np . pi , ’ green ’)
plt . xlabel ( ’ w [ rad / s ] ’)
plt . grid ()
plt . legend ( labels =( ’ phase [ deg ] ’ ,))
Figure 3.1 shows the Bode plot. In the plot we can that bandwidth is indeed 1 rad/s (which
is at 0 = log10(1) rad/s in the figure).
Figure 3.2 shows a feedback loop with its loop transfer function, L(s).
control.bode plot()
We can use the function control.bode plot() to calculate the magnitude and phase of L, and
to plot the Bode plot of L.
26
CHAPTER 3. FREQUENCY RESPONSE
1.0 mag
0.8
0.6
0.4
0.2
phase [deg]
20
40
60
80
1.00 0.75 0.50 0.25 0.00 0.25 0.50 0.75 1.00
w [rad/s]
r y
L(s)
_
Figure 3.2: A feedback loop with its loop transfer function, L(s)
In addition to calculating the three return arguments above, control.bode plot() can show
the following analysis values in the plot:
• The amplitude cross-over frequency, ωb [rad/s], which is also often regarded as the
bandwidth of the feedback system.
• The gain margin, GM, which is found at ω180 ≡ ωg [rad/s] (g for gain margin).
• The phase margin, PM, which is found at ωb ≡ ωp [rad/s] (p for phase margin).
control.margin()
27
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
The control.bode plot() does not return the above four analysis values to the workspace
(although it shows them in the Bode plot). Fortunately, we can use the control.margin()
function to calculate these analysis values. control.margin() can be used as follows:
where L is the loop transfer function, and the four return arguments are as in the list above.
Note that GM has unit one; not dB, and that PM is in degrees.
Given a control loop where the process to be controlled has the following transfer function
(an integrator and two time constants in series):
1
P (s) =
(s + 1)2 s
Program 3.2 generates and plots frequency response of H(s), and shows the stability
margins and the cross-over frequencies.
Kp = 1
C = control . tf ([ Kp ] ,[1])
P = control . tf ([1] , [1 , 2 , 1 , 0])
L = control . series (C , P )
# %% Frequencies :
w0 = 0.1
28
CHAPTER 3. FREQUENCY RESPONSE
w1 = 10
dw = 0.001
nw = int (( w1 - w0 )/ dw ) + 1 # Number of points of freq
w = np . linspace ( w0 , w1 , nw )
# %% Plotting :
( GM , PM , wg , wp ) = control . margin ( L )
# %% Printing :
Below are the results of control.margin() as shown in the console. The values are the same
as shown in the Bode plot in Figure 3.3 (2 dB ≈ 6).
29
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
20
0
Magnitude (dB)
20
40
60
10 1 100 101
90
135
Phase (deg)
180
225
270
10 1 100 101
Frequency (rad/sec)
Figure 3.3: Bode plot including the stability margins and the crossover frequencies
30
Chapter 4
The function control.ss() creates a linear state space model with the following form:
ẋ = Ax + Bu (4.1)
y = Cx + Bu (4.2)
where A, B, C, D are the model matrices.
S = control.ss(A, B, C, D)
where S is the resulting state space model, and the matrices A, B, C, D are in the form of
2D arrays in Python. (Actually, they may be of the list data type, but I recommend using
arrays, cf. Section 1.4.)
• Position:
x1 = z
31
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
k [N/m]
F [N]
m [kg]
d [N/(m/s)]
0 z [m]
• Speed:
x2 = ż = ẋ1
y = x1
Eq. (4.3) can now be expressed with the following equivalent state space model:
0 1 0
ẋ1 x1 +
= F (4.4)
ẋ2 k d x2 1
−m − m
{z m } x
| {z } | {z }
ẋ | | {z }
A B
x1
y= 1 0 + 0 F (4.5)
| {z } x2 | {z }
C | {z } D
x
Program 4.1 creates the above state space model with the control.ss() function.
m = 10 # [ kg ]
k = 4 # [N/m]
d = 2 # [ N /( m / s )]
32
CHAPTER 4. STATE SPACE MODELS
# %% Displaying S :
print ( ’ S = ’ , S )
A = [[ 0. 1.]
[-0.4 -0.2]]
B = [[0. ]
[0.1]]
C = [[1. 0.]]
D = [[0.]]
You can get (read) the model matrices of a given state space model, say S, with the
control.ssdata() function:
To convert the lists to arrays, you can use the np.array() function, e.g.
Example 4.2 Getting the model matrices of a given state space model
Program 4.2 creates a state space model and gets its matrices with the control.ssdata()
function.
33
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
S = control . ss (A , B , C , D )
Simulation with state space models can be done with the control.forced response() function,
cf. Section 2.4, with the following syntax:
The program shown below runs a simulation with the state space model presented in
Example 4.1 with the following conditions:
34
CHAPTER 4. STATE SPACE MODELS
import numpy as np
import control
import matplotlib . pyplot as plt
# %% Model parameters :
m = 10 # [ kg ]
k = 4 # [N/m]
d = 2 # [ N /( m / s )]
S = control . ss (A , B , C , D )
# %% Defining signals :
t0 = 0 # [ s ]
t1 = 50 # [ s ]
dt = 0.01 # [ s ]
nt = int ( t1 / dt ) + 1 # Number of points of sim time
t = np . linspace ( t0 , t1 , nt )
F = 10* np . ones ( nt ) # [ N ]
# %% Initial state :
x1_0 = 1 # [ m ]
x2_0 = 0 # [ m / s ]
x0 = np . array ([ x1_0 , x2_0 ])
35
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
# %% Simulation :
(t , y , x ) = control . forced_response (S , t , F , x0 )
x1 = x [0 ,:]
x2 = x [1 ,:]
# %% Plotting :
plt . subplot (3 , 1 , 1)
plt . plot (t , x1 , ’ blue ’)
plt . grid ()
plt . legend ( labels =( ’ x1 [ m ] ’ ,))
plt . subplot (3 , 1 , 2)
plt . plot (t , x2 , ’ green ’)
plt . grid ()
plt . legend ( labels =( ’ x2 [ m / s ] ’ ,))
plt . subplot (3 , 1 , 3)
plt . plot (t , F , ’red ’)
plt . grid ()
plt . legend ( labels =( ’ F [ N ] ’ ,))
plt . xlabel ( ’ t [ s ] ’)
The function control.ss2tf() derives a transfer function from a given state space model. The
syntax is:
H = control.ss2tf(S)
36
CHAPTER 4. STATE SPACE MODELS
x1 [m]
3
1
0 10 20 30 40 50
x2 [m/s]
0.5
0.0
0.5
0 10 20 30 40 50
10.50 F [N]
10.25
10.00
9.75
9.50
0 10 20 30 40 50
t [s]
In Example 4.1 a state space model of a mass-spring-damper system is created with the
control.ss() function. The program shown below derives the following two transfer functions
from this model:
Program 4.4 derives the two transfer functions from a state space model.
# %% Model params :
37
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
m = 10 # [ kg ]
k = 4 # [N/m]
d = 2 # [ N /( m / s )]
H1 = control . ss2tf ( S1 )
# %% Displaying H1 :
print ( ’ H1 = ’ , H1 )
H2 = control . ss2tf ( S2 )
# %% Displaying H1 :
print ( ’ H2 = ’ , H2 )
The result of the code above, as shown in the console of Spyder, is shown below. The very
small numbers – virtually zeros – in the numerators of H1 and H2 are due to numerical
inaccuracies in the control.ss2tf() function.
H1 =
0.1
---------------------
sˆ2 + 0.2 s + 0.4
H2 =
0.1 s + 1.665e-16
---------------------
sˆ2 + 0.2 s + 0.4
38
Chapter 5
Discrete-time models
5.1.1 Introduction
Many functions in the Python Control Package are used in the same way for discrete-time
transfer functions, or z-transfer functions, as for continuous-time transfer function, or
s-transfer function, except that for z-transfer functions, you must include the sampling time
Ts as an additional parameter. For example, to create a z-transfer function, the control.tf()
is used in this way:
Thus, the descriptions in Ch. 2 gives you a basis for using these functions for z-transfer
functions as well. Therefore, the descriptions are not repeated here. Still there are some
specialities related to z-transfer function, and they are presented in the subsequent sections.
The control.tf() function is used to create z-transfer functions with the following syntax:
where H is the resulting transfer function (object). num (representing the numerator) and
den (representing the denominator) are arrays where the elements are the coefficients of the
z-polynomials of the numerator and denominator, respectively, in descending order from left
to right, with positive exponentials of z. Ts is the sampling time (time step).
39
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
Note that control.tf() assumes positive exponents of z. Here is one example of such a
transfer function:
0.1z
H(z) = (5.1)
z−1
(which is used in Example 5.1). However, in e.g. signal processing, we may see negative
exponents in transfer functions. H(z) given by (5.1) and written in terms of negative
exponents of z, are:
0.1
H(z) = (5.2)
1 − z −1
(5.1) and () are equivalent. But, in the Python Control Package, we must use only positive
exponents of z in transfer functions.
Program 5.1 creates H(z). The code print(’H(z) = ’, H) is used to present the transfer
function in the console (of Spyder).
H(z) =
0.1 z
--------
z-1
dt = 0.1
40
CHAPTER 5. DISCRETE-TIME MODELS
where:
• sys cont is the continuous-time model – a transfer function, or a state space model.
• The discretization method is ’zoh’ (zero order hold) by default, but you can
alternatively use ’matched’ or ’tustin’. (No other methods are supported.)
• sys disc is the resulting discrete-time model – a transfer function, or a state space
model.
3
Hc (s) = (5.4)
2s + 1
Program 5.2 discretizes this transfer function using the zoh method with sampling time 0.1
s.
# %% Discretizing :
Ts = 0.1
H_disc = control . sample_system ( H_cont , Ts , method = ’ zoh ’)
41
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
H disc(z) =
0.1463
-----------
z - 0.9512
dt = 0.1
In Section 2.6 we saw how to use the control.pade() function to generate a transfer function
which is an Padé-approximation of the true transfer function of the time delay, e−Td s . As
alternative to the Padé-approximation, you can generate an exact representation of the time
delay in terms of a z-transfer function.
with
Td 5
nd = = = 50
Ts 0.1
Python program 5.3 creates Hdelay (z), which represents this time delay exactly. The
program also simulates the step response of Hdelay (z).2
42
CHAPTER 5. DISCRETE-TIME MODELS
Ts = 0.1
Td = 5
nd = int ( Td / Ts )
denom_tf = np . append ([1] , np . zeros ( nd ))
H_delay = control . tf ([1] , denom_tf , Ts )
t = np . arange (0 , 10+ Ts , Ts )
(t , y ) = control . step_response ( H_delay , t )
y = y [0 ,:] # Turning 2 D array into 1 D array for plotting
plt . plot (t , y )
plt . xlabel ( ’ t [ s ] ’)
plt . grid ()
H delay(z) =
1
--------
zˆ50
dt = 0.1
Frequency response analysis of z-transfer functions is accomplished with the same functions
as for s-transfer function. Therefore, I assume it is sufficient that I refer you to Ch. 3.
However, note the following comment in the manual of the Python Control Package: “If a
discrete time model is given, the frequency response is plotted along the upper branch of
43
Finn Aakre Haugen: INTRODUCTION TO PYTHON CONTROL PACKAGE
1.0
0.8
0.6
0.4
0.2
0.0
0 2 4 6 8 10
t [s]
the unit circle, using the mapping z = exp(j omega dt) where omega ranges from 0 to pi/dt
and dt is the discrete timebase. If not timebase is specified (dt = True), dt is set to 1.”
In the Python Control Package, discrete-time linear state space models have the following
form:
xk+1 = Ad xk + Bd uk (5.7)
yk = Cd xk + Budk (5.8)
where Ad , Bd , Cd , Dd are the model matrices.
Many functions in the package are used in the same way for both discrete-time linear state
space models and for continuous-time state space models, except that for discrete-time state
space models, you must include the sampling time Ts as an additional parameter. For
example, to create a discrete-time state space model, the control.ss() is used in this way:
S d = control.ss(A d, B d, C d, D d, Ts)
where Ts is the sampling time. S d is the resulting discrete time state space model.
Thus, the descriptions in Ch. 4 gives you a basis for using these functions for
continuous-time state space models as well. Therefore, the descriptions are not repeated
here.
44