Skip to content

Commit fb5ebf6

Browse files
committed
Merge branch 'master' into improve-docs
Conflicts: control/ctrlutil.py
2 parents fa2fd07 + 90133e8 commit fb5ebf6

61 files changed

Lines changed: 3854 additions & 2935 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.gitignore

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
*.pyc
2+
build/
3+
dist/
4+
.ropeproject/
5+
MANIFEST
6+
control/version.py
7+
build.log
8+
*.egg-info/
9+
.coverage

.travis.yml

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
language: python
2+
python:
3+
- "2.7"
4+
- "3.2"
5+
- "3.3"
6+
# install required system libraries
7+
before_install:
8+
- export DISPLAY=:99.0
9+
- sh -e /etc/init.d/xvfb start
10+
- sudo apt-get update --fix-missing -qq
11+
- sudo apt-get build-dep python-scipy -qq
12+
# command to install dependencies from source
13+
# note, separating requirements so that travis
14+
# will get output in less than 5 min and won't
15+
# terminate, using q to keep build info to a
16+
# minumum for dependencies
17+
install:
18+
- while [[ 1 ]]; do echo "building deps"; sleep 300; done &
19+
- msg_pid=$!
20+
- pip install -q coverage
21+
- pip install -q coveralls
22+
- pip install -q nose
23+
- pip install -q numpy
24+
- pip install -q scipy
25+
- pip install -q slycot
26+
- pip install -q matplotlib
27+
- kill $msg_pid
28+
29+
# command to run tests
30+
script:
31+
- coverage run --source=control setup.py test
32+
after_success:
33+
- coveralls

ChangeLog

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
2014-08-09 Richard Murray <murray@sidamo.local>
2+
3+
* Cloned python-control/code from SourceForge, mapping SF user names
4+
to git format (name, e-mail)
5+
* Pushed to python-control/python-control on GitHub
6+
* Converted subversion branches/tags to git branches/tags
7+
8+
==== Repository moved from SourceForge to GitHub ====
9+
10+
---- control-0.6d released -----
11+
112
2014-03-22 Richard Murray <murray@sidamo.local>
213

314
* src/matlab.py (ss): allow five arguments to create a discrete time

MANIFEST.in

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
include examples/*.py
22
include tests/*.py
3+
include README.rst
4+
include ChangeLog
5+
include Pending
Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,52 @@
11
Python Control System Library
2+
=============================
3+
4+
.. image:: https://travis-ci.org/python-control/python-control.svg?branch=master
5+
:target: https://travis-ci.org/python-control/python-control
6+
.. image:: https://coveralls.io/repos/python-control/python-control/badge.png
7+
:target: https://coveralls.io/r/python-control/python-control
8+
29
RMM, 23 May 09
310

411
This directory contains the source code for the Python Control Systems
512
Library (python-control). This package provides a library of standard
613
control system algorithms in the python programming environment.
714

8-
Installation instructions
9-
-------------------------
10-
Standard python package installation:
15+
Installation
16+
------------
17+
18+
Using pip
19+
~~~~~~~~~~~
20+
21+
Pip is a python packaging system. It can be installed on debian based
22+
linux distros with the command::
23+
24+
sudo apt-get install pip
25+
26+
Pip can then be used to install python-control::
27+
28+
sudo pip install control
29+
1130

12-
python setup.py install
31+
From Source
32+
~~~~~~~~~~~
33+
34+
Standard python package installation::
35+
36+
python setup.py install
1337

1438
To see if things are working, you can run the script
1539
examples/secord-matlab.py (using ipython -pylab). It should generate a step
1640
response, Bode plot and Nyquist plot for a simple second order linear
1741
system.
1842

19-
You can also run a set of unit tests to make sure that everything is working
20-
correctly. After installation, run
21-
22-
python tests/test_all.py
43+
Testing
44+
-------
2345

24-
from the source distribution directory (note: doesn't yet work in python
25-
3.x). Alternatively, if you have nosetests installed, you can simply run
26-
27-
nosetests
46+
You can also run a set of unit tests to make sure that everything is working
47+
correctly. After installation, run::
2848

29-
which gives a somewhat cleaner output (and works in python 3.x)
49+
python runtests.py
3050

3151
Slycot
3252
------
@@ -38,7 +58,8 @@ without slycot, but some functionality is limited or absent, and
3858
installation of Slycot is definitely recommended. The Slycot wrapper
3959
can be found at:
4060

41-
https://github.com/repagh/Slycot
61+
https://github.com/jgoppert/Slycot
62+
63+
and can be installed with::
4264

43-
(was forked from https://github.com/avventi/Slycot, but
44-
development/merging appear to have stopped there for now)
65+
sudo pip install slycot

control/__init__.py

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
# __init__.py - initialization for control systems toolbox
2+
#
3+
# Author: Richard M. Murray
4+
# Date: 24 May 09
5+
#
6+
# This file contains the initialization information from the control package.
7+
#
8+
# Copyright (c) 2009 by California Institute of Technology
9+
# All rights reserved.
10+
#
11+
# Redistribution and use in source and binary forms, with or without
12+
# modification, are permitted provided that the following conditions
13+
# are met:
14+
#
15+
# 1. Redistributions of source code must retain the above copyright
16+
# notice, this list of conditions and the following disclaimer.
17+
#
18+
# 2. Redistributions in binary form must reproduce the above copyright
19+
# notice, this list of conditions and the following disclaimer in the
20+
# documentation and/or other materials provided with the distribution.
21+
#
22+
# 3. Neither the name of the California Institute of Technology nor
23+
# the names of its contributors may be used to endorse or promote
24+
# products derived from this software without specific prior
25+
# written permission.
26+
#
27+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
28+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
29+
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
30+
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CALTECH
31+
# OR THE CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
32+
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
33+
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
34+
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
35+
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
36+
# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
37+
# OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38+
# SUCH DAMAGE.
39+
#
40+
# $Id$
41+
42+
"""Control System Library
43+
44+
The Python Control System Library (control) provides common functions
45+
for analyzing and designing feedback control systems.
46+
47+
Common functions
48+
----------------
49+
tf create a transfer function from num, den coefficients
50+
ss create a state space system from A, B, C, D matrices
51+
pzk create a transfer function from pole, zero, gain
52+
frd create a system description as frequency response
53+
bode generate a Bode plot for a linear I/O system
54+
nyquist generate a Nyquist plot for a linear I/O system
55+
lqr linear quadratic regulator
56+
lqe linear quadratic estimator
57+
"""
58+
59+
try:
60+
__CONTROL_SETUP__
61+
except NameError:
62+
__CONTROL_SETUP__ = False
63+
64+
if __CONTROL_SETUP__:
65+
import sys as _sys
66+
_sys.stderr.write('Running from control source directory.\n')
67+
del _sys
68+
else:
69+
70+
# Import functions from within the control system library
71+
# Should probably only import the exact functions we use...
72+
from .bdalg import series, parallel, negate, feedback
73+
from .delay import pade
74+
from .dtime import sample_system
75+
from .freqplot import bode_plot, nyquist_plot, gangof4_plot
76+
from .freqplot import bode, nyquist, gangof4
77+
from .lti import issiso, timebase, timebaseEqual, isdtime, isctime
78+
from .margins import stability_margins, phase_crossover_frequencies
79+
from .mateqn import lyap, dlyap, care, dare
80+
from .modelsimp import hsvd, modred, balred, era, markov
81+
from .nichols import nichols_plot, nichols
82+
from .phaseplot import phase_plot, box_grid
83+
from .rlocus import root_locus
84+
from .statefbk import place, lqr, ctrb, obsv, gram, acker
85+
from .statesp import StateSpace
86+
from .timeresp import forced_response, initial_response, step_response, \
87+
impulse_response
88+
from .xferfcn import TransferFunction
89+
from .ctrlutil import unwrap, issys
90+
from .frdata import FRD
91+
from .canonical import canonical_form, reachable_form
92+
93+
# Exceptions
94+
from .exception import *
95+
96+
# Import some of the more common (and benign) MATLAB shortcuts
97+
# By default, don't import conflicting commands here
98+
#! TODO (RMM, 4 Nov 2012): remove MATLAB dependencies from __init__.py
99+
#!
100+
#! Eventually, all functionality should be in modules *other* than matlab.
101+
#! This will allow inclusion of the matlab module to set up a different set
102+
#! of defaults from the main package. At that point, the matlab module will
103+
#! allow provide compatibility with MATLAB but no package functionality.
104+
#!
105+
from .matlab import ss, tf, ss2tf, tf2ss, drss
106+
from .matlab import pole, zero, evalfr, freqresp, dcgain
107+
from .matlab import nichols, rlocus, margin
108+
# bode and nyquist come directly from freqplot.py
109+
from .matlab import step, impulse, initial, lsim
110+
from .matlab import ssdata, tfdata
111+
112+
# The following is to use Numpy's testing framework
113+
# Tests go under directory tests/, benchmarks under directory benchmarks/
114+
from numpy.testing import Tester
115+
test = Tester().test
116+
bench = Tester().bench

src/bdalg.py renamed to control/bdalg.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@
5454
"""
5555

5656
import scipy as sp
57-
import control.xferfcn as tf
58-
import control.statesp as ss
59-
import control.frdata as frd
57+
from . import xferfcn as tf
58+
from . import statesp as ss
59+
from . import frdata as frd
6060

6161
def series(sys1, sys2):
6262
"""Return the series connection sys2 * sys1 for --> sys1 --> sys2 -->.
@@ -97,7 +97,7 @@ def series(sys1, sys2):
9797
>>> sys3 = series(sys1, sys2) # Same as sys3 = sys2 * sys1.
9898
9999
"""
100-
100+
101101
return sys2 * sys1
102102

103103
def parallel(sys1, sys2):
@@ -117,12 +117,12 @@ def parallel(sys1, sys2):
117117
------
118118
ValueError
119119
if `sys1` and `sys2` do not have the same numbers of inputs and outputs
120-
120+
121121
See Also
122122
--------
123123
series
124124
feedback
125-
125+
126126
Notes
127127
-----
128128
This function is a wrapper for the __add__ function in the
@@ -140,7 +140,7 @@ def parallel(sys1, sys2):
140140
>>> sys3 = parallel(sys1, sys2) # Same as sys3 = sys1 + sys2.
141141
142142
"""
143-
143+
144144
return sys1 + sys2
145145

146146
def negate(sys):
@@ -170,7 +170,7 @@ def negate(sys):
170170
>>> sys2 = negate(sys1) # Same as sys2 = -sys1.
171171
172172
"""
173-
173+
174174
return -sys;
175175

176176
#! TODO: expand to allow sys2 default to work in MIMO case?
@@ -184,7 +184,7 @@ def feedback(sys1, sys2=1, sign=-1):
184184
The primary plant.
185185
sys2: scalar, StateSpace, TransferFunction, FRD
186186
The feedback plant (often a feedback controller).
187-
sign: scalar
187+
sign: scalar
188188
The sign of feedback. `sign` = -1 indicates negative feedback, and
189189
`sign` = 1 indicates positive feedback. `sign` is an optional
190190
argument; it assumes a value of -1 if not specified.
@@ -215,7 +215,7 @@ def feedback(sys1, sys2=1, sign=-1):
215215
object. If `sys1` is a scalar, then it is converted to `sys2`'s type, and
216216
the corresponding feedback function is used. If `sys1` and `sys2` are both
217217
scalars, then TransferFunction.feedback is used.
218-
218+
219219
"""
220220

221221
# Check for correct input types.
@@ -225,7 +225,7 @@ def feedback(sys1, sys2=1, sign=-1):
225225
"or FRD object, or a scalar.")
226226
if not isinstance(sys2, (int, float, complex, tf.TransferFunction,
227227
ss.StateSpace, frd.FRD)):
228-
raise TypeError("sys2 must be a TransferFunction, StateSpace " +
228+
raise TypeError("sys2 must be a TransferFunction, StateSpace " +
229229
"or FRD object, or a scalar.")
230230

231231
# If sys1 is a scalar, convert it to the appropriate LTI type so that we can
@@ -257,19 +257,19 @@ def append(*sys):
257257
sys1, sys2, ... sysn: StateSpace or Transferfunction
258258
LTI systems to combine
259259
260-
260+
261261
Returns
262262
-------
263263
sys: LTI system
264-
Combined LTI system, with input/output vectors consisting of all
264+
Combined LTI system, with input/output vectors consisting of all
265265
input/output vectors appended
266-
266+
267267
Examples
268268
--------
269269
>>> sys1 = ss("1. -2; 3. -4", "5.; 7", "6. 8", "9.")
270270
>>> sys2 = ss("-1.", "1.", "1.", "0.")
271271
>>> sys = append(sys1, sys2)
272-
272+
273273
.. todo::
274274
also implement for transfer function, zpk, etc.
275275
'''
@@ -327,12 +327,12 @@ def connect(sys, Q, inputv, outputv):
327327
elif outp < 0 and -outp >= -sys.outputs:
328328
K[inp,-outp-1] = -1.
329329
sys = sys.feedback(sp.matrix(K), sign=1)
330-
330+
331331
# now trim
332332
Ytrim = sp.zeros( (len(outputv), sys.outputs) )
333333
Utrim = sp.zeros( (sys.inputs, len(inputv)) )
334334
for i,u in enumerate(inputv):
335335
Utrim[u-1,i] = 1.
336336
for i,y in enumerate(outputv):
337337
Ytrim[i,y-1] = 1.
338-
return sp.matrix(Ytrim)*sys*sp.matrix(Utrim)
338+
return sp.matrix(Ytrim)*sys*sp.matrix(Utrim)

control/bench/time_freqresp.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
from control import tf
2+
from control.matlab import rss
3+
from numpy import logspace
4+
from timeit import timeit
5+
6+
nstates = 10
7+
sys = rss(nstates)
8+
sys_tf = tf(sys)
9+
w = logspace(-1,1,50)
10+
ntimes = 1000
11+
time_ss = timeit("sys.freqresp(w)", setup="from __main__ import sys, w", number=ntimes)
12+
time_tf = timeit("sys_tf.freqresp(w)", setup="from __main__ import sys_tf, w", number=ntimes)
13+
print("State-space model on %d states: %f" % (nstates, time_ss))
14+
print("Transfer-function model on %d states: %f" % (nstates, time_tf))

0 commit comments

Comments
 (0)