From dbf0a9d77e068fcc42bd3e311f7d521fac43ccc1 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Mon, 26 Dec 2016 20:13:57 -0800 Subject: [PATCH 01/10] DOC: updated Slycot URL to github.com/python-control --- README.rst | 2 +- doc/intro.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.rst b/README.rst index f5d4bd97b..48b398bc8 100644 --- a/README.rst +++ b/README.rst @@ -41,7 +41,7 @@ functionality is limited or absent, and installation of slycot is recommended (see below). Note that in order to install slycot, you will need a FORTRAN compiler on your machine. The Slycot wrapper can be found at: -https://github.com/jgoppert/Slycot +https://github.com/python-control/Slycot Installation ============ diff --git a/doc/intro.rst b/doc/intro.rst index bd3add56b..c02c0af04 100644 --- a/doc/intro.rst +++ b/doc/intro.rst @@ -58,7 +58,7 @@ The package requires `numpy` and `scipy`, and the plotting routines require a Python wrapper around some FORTRAN routines. Many parts of `python-control` will work without `slycot`, but some functionality is limited or absent, and installation of `slycot` is recommended. For more information, see the GitHub -repository for `slycot `_. +repository for `slycot `_. Getting Started --------------- From 4cbd4cbe0d2a3105e946b01d0bbd0171a08171e3 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Mon, 26 Dec 2016 20:32:59 -0800 Subject: [PATCH 02/10] DOC: default method for sample_system was incorrect --- control/dtime.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/control/dtime.py b/control/dtime.py index 25ebfb8b6..36053da33 100644 --- a/control/dtime.py +++ b/control/dtime.py @@ -65,7 +65,7 @@ def sample_system(sysc, Ts, method='zoh', alpha=None): Ts : real Sampling period method : string - Method to use for conversion: 'matched' (default), 'tustin', 'zoh' + Method to use for conversion: 'matched', 'tustin', 'zoh' (default) Returns ------- From 06b5fe4e7bf397e6479bdd70dd3ea724df40c082 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Mon, 26 Dec 2016 20:43:36 -0800 Subject: [PATCH 03/10] DOC: created conventions section in manual + moved doc for time series conventions to a single place --- control/timeresp.py | 76 +++------------------------------------------ doc/control.rst | 68 ---------------------------------------- doc/conventions.rst | 76 +++++++++++++++++++++++++++++++++++++++++++++ doc/index.rst | 1 + 4 files changed, 82 insertions(+), 139 deletions(-) create mode 100644 doc/conventions.rst diff --git a/control/timeresp.py b/control/timeresp.py index 3e9e168ca..6040a3f5b 100644 --- a/control/timeresp.py +++ b/control/timeresp.py @@ -1,78 +1,12 @@ # timeresp.py - time-domain simulation routes -""" -Time domain simulation. - -This file contains a collection of functions that calculate -time responses for linear systems. - -.. _time-series-convention: - -Convention for Time Series --------------------------- - -This is a convention for function arguments and return values that -represent time series: sequences of values that change over time. It -is used throughout the library, for example in the functions -:func:`forced_response`, :func:`step_response`, :func:`impulse_response`, -and :func:`initial_response`. - -.. note:: - This convention is different from the convention used in the library - :mod:`scipy.signal`. In Scipy's convention the meaning of rows and columns - is interchanged. Thus, all 2D values must be transposed when they are - used with functions from :mod:`scipy.signal`. - -Types: - - * **Arguments** can be **arrays**, **matrices**, or **nested lists**. - * **Return values** are **arrays** (not matrices). - -The time vector is either 1D, or 2D with shape (1, n):: - - T = [[t1, t2, t3, ..., tn ]] - -Input, state, and output all follow the same convention. Columns are different -points in time, rows are different components. When there is only one row, a -1D object is accepted or returned, which adds convenience for SISO systems:: - - U = [[u1(t1), u1(t2), u1(t3), ..., u1(tn)] - [u2(t1), u2(t2), u2(t3), ..., u2(tn)] - ... - ... - [ui(t1), ui(t2), ui(t3), ..., ui(tn)]] - - Same for X, Y - -So, U[:,2] is the system's input at the third point in time; and U[1] or U[1,:] -is the sequence of values for the system's second input. - -The initial conditions are either 1D, or 2D with shape (j, 1):: - - X0 = [[x1] - [x2] - ... - ... - [xj]] - -As all simulation functions return *arrays*, plotting is convenient:: - - t, y = step(sys) - plot(t, y) - -The output of a MIMO system can be plotted like this:: - - t, y, x = lsim(sys, u, t) - plot(t, y[0], label='y_0') - plot(t, y[1], label='y_1') +"""Time domain simulation. -The convention also works well with the state space form of linear systems. If -``D`` is the feedthrough *matrix* of a linear system, and ``U`` is its input -(*matrix* or *array*), then the feedthrough part of the system's response, -can be computed like this:: +This file contains a collection of functions that calculate time +responses for linear systems. - ft = D * U +See doc/conventions.rst#time-series-conventions_ for more information +on how time series data are represented. ----------------------------------------------------------------- """ """Copyright (c) 2011 by California Institute of Technology diff --git a/doc/control.rst b/doc/control.rst index 3fdf48475..0b607148b 100644 --- a/doc/control.rst +++ b/doc/control.rst @@ -47,74 +47,6 @@ Time domain simulation step_response phase_plot -.. _time-series-convention: - -Convention for Time Series --------------------------- - -This is a convention for function arguments and return values that -represent time series: sequences of values that change over time. It -is used throughout the library, for example in the functions -:func:`forced_response`, :func:`step_response`, :func:`impulse_response`, -and :func:`initial_response`. - -.. note:: - This convention is different from the convention used in the library - :mod:`scipy.signal`. In Scipy's convention the meaning of rows and columns - is interchanged. Thus, all 2D values must be transposed when they are - used with functions from :mod:`scipy.signal`. - -Types: - - * **Arguments** can be **arrays**, **matrices**, or **nested lists**. - * **Return values** are **arrays** (not matrices). - -The time vector is either 1D, or 2D with shape (1, n):: - - T = [[t1, t2, t3, ..., tn ]] - -Input, state, and output all follow the same convention. Columns are different -points in time, rows are different components. When there is only one row, a -1D object is accepted or returned, which adds convenience for SISO systems:: - - U = [[u1(t1), u1(t2), u1(t3), ..., u1(tn)] - [u2(t1), u2(t2), u2(t3), ..., u2(tn)] - ... - ... - [ui(t1), ui(t2), ui(t3), ..., ui(tn)]] - - Same for X, Y - -So, U[:,2] is the system's input at the third point in time; and U[1] or U[1,:] -is the sequence of values for the system's second input. - -The initial conditions are either 1D, or 2D with shape (j, 1):: - - X0 = [[x1] - [x2] - ... - ... - [xj]] - -As all simulation functions return *arrays*, plotting is convenient:: - - t, y = step(sys) - plot(t, y) - -The output of a MIMO system can be plotted like this:: - - t, y, x = lsim(sys, u, t) - plot(t, y[0], label='y_0') - plot(t, y[1], label='y_1') - -The convention also works well with the state space form of linear systems. If -``D`` is the feedthrough *matrix* of a linear system, and ``U`` is its input -(*matrix* or *array*), then the feedthrough part of the system's response, -can be computed like this:: - - ft = D * U - - Block diagram algebra ===================== .. autosummary:: diff --git a/doc/conventions.rst b/doc/conventions.rst new file mode 100644 index 000000000..a01109861 --- /dev/null +++ b/doc/conventions.rst @@ -0,0 +1,76 @@ +.. _conventions-ref: + +################### +Library conventions +################### + +The python-control library uses a set of standard conventions for the way +that different types of standard information used by the library. + +.. _time-series-convention: + +Time series data +================ + +This is a convention for function arguments and return values that +represent time series: sequences of values that change over time. It +is used throughout the library, for example in the functions +:func:`forced_response`, :func:`step_response`, :func:`impulse_response`, +and :func:`initial_response`. + +.. note:: + This convention is different from the convention used in the library + :mod:`scipy.signal`. In Scipy's convention the meaning of rows and columns + is interchanged. Thus, all 2D values must be transposed when they are + used with functions from :mod:`scipy.signal`. + +Types: + + * **Arguments** can be **arrays**, **matrices**, or **nested lists**. + * **Return values** are **arrays** (not matrices). + +The time vector is either 1D, or 2D with shape (1, n):: + + T = [[t1, t2, t3, ..., tn ]] + +Input, state, and output all follow the same convention. Columns are different +points in time, rows are different components. When there is only one row, a +1D object is accepted or returned, which adds convenience for SISO systems:: + + U = [[u1(t1), u1(t2), u1(t3), ..., u1(tn)] + [u2(t1), u2(t2), u2(t3), ..., u2(tn)] + ... + ... + [ui(t1), ui(t2), ui(t3), ..., ui(tn)]] + + Same for X, Y + +So, U[:,2] is the system's input at the third point in time; and U[1] or U[1,:] +is the sequence of values for the system's second input. + +The initial conditions are either 1D, or 2D with shape (j, 1):: + + X0 = [[x1] + [x2] + ... + ... + [xj]] + +As all simulation functions return *arrays*, plotting is convenient:: + + t, y = step(sys) + plot(t, y) + +The output of a MIMO system can be plotted like this:: + + t, y, x = lsim(sys, u, t) + plot(t, y[0], label='y_0') + plot(t, y[1], label='y_1') + +The convention also works well with the state space form of linear systems. If +``D`` is the feedthrough *matrix* of a linear system, and ``U`` is its input +(*matrix* or *array*), then the feedthrough part of the system's response, +can be computed like this:: + + ft = D * U + diff --git a/doc/index.rst b/doc/index.rst index fcce6d38c..928da28a2 100644 --- a/doc/index.rst +++ b/doc/index.rst @@ -26,6 +26,7 @@ implements basic operations for analysis and design of feedback control systems. :maxdepth: 2 intro + conventions control classes matlab From c253d336f43fdbed678ff20efa293e7b08b045a2 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Mon, 26 Dec 2016 20:49:10 -0800 Subject: [PATCH 04/10] DOC: added documentation for return_x --- control/timeresp.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/control/timeresp.py b/control/timeresp.py index 6040a3f5b..ed95e319a 100644 --- a/control/timeresp.py +++ b/control/timeresp.py @@ -387,6 +387,9 @@ def step_response(sys, T=None, X0=0., input=None, output=None, If True, transpose all input and output arrays (for backward compatibility with MATLAB and scipy.signal.lsim) + return_x: bool + If True, return the state vector (default = False). + Returns ------- T: array @@ -463,6 +466,9 @@ def initial_response(sys, T=None, X0=0., input=0, output=None, If True, transpose all input and output arrays (for backward compatibility with MATLAB and scipy.signal.lsim) + return_x: bool + If True, return the state vector (default = False). + Returns ------- T: array @@ -533,6 +539,9 @@ def impulse_response(sys, T=None, X0=0., input=0, output=None, If True, transpose all input and output arrays (for backward compatibility with MATLAB and scipy.signal.lsim) + return_x: bool + If True, return the state vector (default = False). + Returns ------- T: array From 211111700cd7258072053b2891baf66be62049cb Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Mon, 26 Dec 2016 20:54:55 -0800 Subject: [PATCH 05/10] DOC: removed redundant entries for frequency domain plots --- doc/control.rst | 4 ---- 1 file changed, 4 deletions(-) diff --git a/doc/control.rst b/doc/control.rst index 0b607148b..4fcb0199e 100644 --- a/doc/control.rst +++ b/doc/control.rst @@ -26,13 +26,9 @@ Frequency domain plotting .. autosummary:: :toctree: generated/ - bode bode_plot - nyquist nyquist_plot - gangof4 gangof4_plot - nichols nichols_plot Time domain simulation From 1f156781f3eb239ddd458c91ec49d7defa2747e0 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Mon, 26 Dec 2016 21:59:51 -0800 Subject: [PATCH 06/10] add robust module to list of included files --- control/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/control/__init__.py b/control/__init__.py index a7ea1e61d..6f3295dfe 100644 --- a/control/__init__.py +++ b/control/__init__.py @@ -65,6 +65,7 @@ from .ctrlutil import * from .frdata import * from .canonical import * +from .robust import * # Exceptions from .exception import * From 92570bcdb6b85ec46d039669dbddf13ef2f7d58d Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Mon, 26 Dec 2016 22:00:37 -0800 Subject: [PATCH 07/10] TRV: use double quotes for multi-line comment --- control/frdata.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/control/frdata.py b/control/frdata.py index a7130e35f..ff1663b15 100644 --- a/control/frdata.py +++ b/control/frdata.py @@ -469,7 +469,7 @@ def _convertToFRD(sys, omega, inputs=1, outputs=1): sys.__class__) def frd(*args): - ''' + """ Construct a Frequency Response Data model, or convert a system frd models store the (measured) frequency response of a system. @@ -501,5 +501,5 @@ def frd(*args): See Also -------- ss, tf - ''' + """ return FRD(*args) From 303480fa8cf7853c1300db08e30f98238c5b7f58 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Mon, 26 Dec 2016 22:01:15 -0800 Subject: [PATCH 08/10] DOC: add missing functions to documentation list --- doc/control.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/doc/control.rst b/doc/control.rst index 4fcb0199e..f3d124ee5 100644 --- a/doc/control.rst +++ b/doc/control.rst @@ -17,9 +17,22 @@ System creation ss tf + frd rss drss +System interconnections +======================= +.. autosummary:: + :toctree: generated/ + + append + connect + feedback + negate + parallel + series + Frequency domain plotting ========================= @@ -88,6 +101,8 @@ Control system synthesis :toctree: generated/ acker + h2syn + hinfsyn lqr place @@ -111,12 +126,15 @@ Utility functions and conversions unwrap db2mag mag2db + damp isctime isdtime + issiso issys pade sample_system canonical_form + observable_form reachable_form ss2tf ssdata From 93b50b13ecb9e04039958098e40beed5d4590a19 Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Tue, 27 Dec 2016 09:09:14 -0800 Subject: [PATCH 09/10] Add documentation for custom configurations --- control/__init__.py | 1 + control/config.py | 9 +++++++++ doc/conventions.rst | 27 +++++++++++++++++++++++++++ 3 files changed, 37 insertions(+) diff --git a/control/__init__.py b/control/__init__.py index 6f3295dfe..99cf9a73d 100644 --- a/control/__init__.py +++ b/control/__init__.py @@ -66,6 +66,7 @@ from .frdata import * from .canonical import * from .robust import * +from .config import * # Exceptions from .exception import * diff --git a/control/config.py b/control/config.py index 9e5b027ec..188a4efd7 100644 --- a/control/config.py +++ b/control/config.py @@ -16,6 +16,10 @@ # Set defaults to match MATLAB def use_matlab_defaults(): + """ + Use MATLAB compatible configuration settings + * Bode plots plot gain in dB, phase in degrees, frequency in Hertz + """ # Bode plot defaults global bode_dB; bode_dB = True global bode_deg; bode_deg = True @@ -23,6 +27,11 @@ def use_matlab_defaults(): # Set defaults to match FBS (Astrom and Murray) def use_fbs_defaults(): + """ + Use `Astrom and Murray `_ compatible settings + * Bode plots plot gain in powers of ten, phase in degrees, + frequency in Hertz + """ # Bode plot defaults global bode_dB; bode_dB = False global bode_deg; bode_deg = True diff --git a/doc/conventions.rst b/doc/conventions.rst index a01109861..881a0a6bb 100644 --- a/doc/conventions.rst +++ b/doc/conventions.rst @@ -1,5 +1,7 @@ .. _conventions-ref: +.. currentmodule:: control + ################### Library conventions ################### @@ -74,3 +76,28 @@ can be computed like this:: ft = D * U +Package configuration +===================== + +The python-control library can be customized to allow for different plotting +conventions. The currently configurable options allow the units for Bode +plots to be set as dB for gain, degrees for phase and Hertz for frequency +(MATLAB conventions) or the gain can be given in magnitude units (powers of +10), corresponding to the conventions used in `Feedback Systems +`_. + +Variables that can be configured, along with their default values: + * bode_dB (False): Bode plot magnitude plotted in dB (otherwise powers of 10) + * bode_deg (True): Bode plot phase plotted in degrees (otherwise radians) + * bode_Hz (False): Bode plot frequency plotted in Hertz (otherwise rad/sec) + * bode_number_of_samples (None): Number of frequency points in Bode plots + * bode_feature_periphery_decade (1.0): How many decades to include in the + frequency range on both sides of features (poles, zeros). + +Functions that can be used to set standard configurations: + +.. autosummary:: + :toctree: generated/ + + use_fbs_defaults + use_matlab_defaults From 349025b4dfcec8f99dc46bd5db422a0d9a1a007f Mon Sep 17 00:00:00 2001 From: Richard Murray Date: Wed, 28 Dec 2016 22:37:28 -0800 Subject: [PATCH 10/10] DOC: updated installation instructions (including conda as an option) --- doc/intro.rst | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/doc/intro.rst b/doc/intro.rst index c02c0af04..a55913291 100644 --- a/doc/intro.rst +++ b/doc/intro.rst @@ -35,14 +35,38 @@ some thing to keep in mind: Installation ------------ -The `python-control` package may be installed using pip or the standard -distutils/setuptools mechanisms. +The `python-control` package may be installed using pip, conda or the +standard distutils/setuptools mechanisms. To install using pip:: pip install slycot # optional pip install control +Many parts of `python-control` will work without `slycot`, but some +functionality is limited or absent, and installation of `slycot` is +recommended. + +*Note*: the `slycot` library only works on some platforms, mostly +linux-based. Users should check to insure that slycot is installed +correctly by running the command:: + + python -c "import slycot" + +and verifying that no error message appears. It may be necessary to install +`slycot` from source, which requires a working FORTRAN compiler and the +`lapack` library. More information on the slycot package can be obtained +from the `slycot project page `_. + +For users with a working the Anaconda distribution of Python, the following +command can be used:: + + conda install -c python-control -c cyclus slycot python-control + +This installs `slycot` and `python-control` from the `python-control` +channel and uses the `cyclus` channel to obtain the required `lapack` +package. + Alternatively, to use setuptools, first `download the source `_ and unpack it. To install in your home directory, use:: @@ -54,11 +78,8 @@ or to install for all users (on Linux or Mac OS):: sudo python setup.py install The package requires `numpy` and `scipy`, and the plotting routines require -`matplotlib`. In addition, some routines use a module called `slycot`, which is -a Python wrapper around some FORTRAN routines. Many parts of `python-control` -will work without `slycot`, but some functionality is limited or absent, and -installation of `slycot` is recommended. For more information, see the GitHub -repository for `slycot `_. +`matplotlib`. In addition, some routines require the `slycot` module, +described above. Getting Started ---------------