GithubHelp home page GithubHelp logo

python-control / python-control Goto Github PK

View Code? Open in Web Editor NEW
1.6K 1.6K 411.0 17.96 MB

The Python Control Systems Library is a Python module that implements basic operations for analysis and design of feedback control systems.

Home Page: http://python-control.org

License: BSD 3-Clause "New" or "Revised" License

Python 99.99% Batchfile 0.01%

python-control's Introduction

Python Control Systems Library

The Python Control Systems Library is a Python module that implements basic operations for analysis and design of feedback control systems.

Have a go now!

Try out the examples in the examples folder using the binder service.

The package can also be installed on Google Colab using the commands:

!pip install control
import control as ct

Features

  • Linear input/output systems in state-space and frequency domain
  • Block diagram algebra: serial, parallel, feedback, and other interconnections
  • Time response: initial, step, impulse
  • Frequency response: Bode, Nyquist, and Nichols plots
  • Control analysis: stability, reachability, observability, stability margins, root locus
  • Control design: eigenvalue placement, linear quadratic regulator, sisotool, hinfsyn, rootlocus_pid_designer
  • Estimator design: linear quadratic estimator (Kalman filter)
  • Nonlinear systems: optimization-based control, describing functions, differential flatness

Links

Dependencies

The package requires numpy, scipy, and matplotlib. In addition, some routines use a module called slycot, that 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 (see below). The Slycot wrapper can be found at:

https://github.com/python-control/Slycot

Installation

Conda and conda-forge

The easiest way to get started with the Control Systems library is using Conda.

The Control Systems library has packages available using the conda-forge Conda channel, and as of Slycot version 0.3.4, binaries for that package are available for 64-bit Windows, OSX, and Linux.

To install both the Control Systems library and Slycot in an existing conda environment, run:

conda install -c conda-forge control slycot

Mixing packages from conda-forge and the default conda channel can sometimes cause problems with dependencies, so it is usually best to instally NumPy, SciPy, and Matplotlib from conda-forge as well.

Pip

To install using pip:

pip install slycot   # optional; see below
pip install control

If you install Slycot using pip you'll need a development environment (e.g., Python development files, C and Fortran compilers). Pip installation can be particularly complicated for Windows.

Installing from source

To install from source, get the source code of the desired branch or release from the github repository or archive, unpack, and run from within the toplevel python-control directory:

pip install .

Article and Citation Information

An article about the library is available on IEEE Explore. If the Python Control Systems Library helped you in your research, please cite:

@inproceedings{python-control2021,
  title={The Python Control Systems Library (python-control)},
  author={Fuller, Sawyer and Greiner, Ben and Moore, Jason and
          Murray, Richard and van Paassen, Ren{\'e} and Yorke, Rory},
  booktitle={60th IEEE Conference on Decision and Control (CDC)},
  pages={4875--4881},
  year={2021},
  organization={IEEE}
}

or the GitHub site: https://github.com/python-control/python-control

Development

Code

You can check out the latest version of the source code with the command:

git clone https://github.com/python-control/python-control.git

Testing

You can run the unit tests with pytest to make sure that everything is working correctly. Inside the source directory, run:

pytest -v

or to test the installed package:

pytest --pyargs control -v

License

This is free software released under the terms of the BSD 3-Clause License. There is no warranty; not even for merchantability or fitness for a particular purpose. Consult LICENSE for copying conditions.

When code is modified or re-distributed, the LICENSE file should accompany the code or any subset of it, however small. As an alternative, the LICENSE text can be copied within files, if so desired.

Contributing

Your contributions are welcome! Simply fork the GitHub repository and send a pull request.

Please see the Developer's Wiki for detailed instructions.

python-control's People

Contributors

adm78 avatar billtubbs avatar bnavigator avatar cwrowley avatar don4get avatar forgi86 avatar gonmolina avatar gristroph avatar henklaak avatar hungpham2511 avatar icam0 avatar jgoppert avatar joaoantoniocardoso avatar jpickard1 avatar jrforbes avatar juanodecc avatar kayarre avatar kybernetikjo avatar laurensvalk avatar mark-yeatman avatar marthoch avatar martinup avatar mp4096 avatar murrayrm avatar rabraker avatar repagh avatar roryyorke avatar sawyerbfuller avatar scliao47 avatar slivingston avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

python-control's Issues

Interactive plots in IPython notebooks

I find IPython notebooks a great way to work interactively, and it would be nice if inline plots could be interactive (e.g., letting you zoom, or having tool tips show more information). With matplotlib, though, inline plots are just images, so they cannot be interactive.

There's a new plotting library called Bokeh, an open-source project led by Continuum Analytics (the wonderful folks that make Anaconda), that looks really nice for making interactive plots like this. I'd like to try making an alternate backend one could specify with, say, control.set_backend("bokeh") that would make commands like bode() and nyquist() generate plots using Bokeh. The default could still be matplotlib, of course.

Any thoughts or suggestions for other libraries that might be useful for making interactive plots?

Implementation of lsim, step, initial, impulse, dcgain [sf#1]

Reported by eike on 2011-05-12 21:32 UTC
This patch contains an implementation of the four simulation functions lsim, step, initial, and impulse of the module matlab. It also adds a function dcgain, which computes the gain of a linear system for steady state and constant input.

The patch also contains a bug fix for class StateSpace, which enables it to work properly together with Scipy's signal module.

The simulation functions' return values are changed (back?) to arrays, because matrices confuse Matplotlib.

Implementation Notes

The implementation is centered around lsim, which checks the parameters thoroughly, and generates useful error messages. It then calls scipy.signal.lsim2 to solve the differential equations. The other simulation functions (step, initial, impulse) are small and call lsim.

Parameter Convention

The new convention for parameters and return values harmonizes with the way how the system equations are written. It can be generalized to MIMO systems, and it also works well with Matplotlib:

All parameters can be arrays, matrices, or nested lists.

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

The initial conditions are either 1D, or 2D with shape (j, 1)::

 X0 = [[u1]
       [u2]
       ...
       ...
       [uj]]

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.

As all simulation functions return array plotting is convenient::

t, y = step(sys)
plot(t, y)

The output of a MIMO system would 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')

Use dB as default for Bode plot?

Roberto Bucher suggests:

"bode" and "bode_plot": in my opinion the flag dB=True should be the
default choice (but this is only my opinion...)

dare function gives wrong results (compared to MATLAB dlqr, scilab) [sf#7]

Reported by murrayrm on 2014-03-22 19:22 UTC
Roberto Bucher reported the following bug to the discussion list:

The dare functions gives some wrong results, and I'll check the lqr function asap. Using the delivered "dare" function (mateqn.py) I have wrong values of the feedback gains (compared with the values given by matlab dlqr and scilab)

Extend dare to handle S != 0, E != I case correctly (using scipy?)

From commit 7cf9630:

Note: the scipy implementation handles only the case S = 0, E = I, the default values. If S and E are specified, the old routine (using slycot) is called. This passes the existing tests, but the tests include only one simple case, so it would be good to test this more extensively.

@robertobucher suggests the following fix:

# Check dimensions for consistency
    nstates = B.shape[0];
    ninputs = B.shape[1];
    if (A.shape[0] != nstates or A.shape[1] != nstates):
        raise ControlDimension("inconsistent system dimensions")

    elif (Q.shape[0] != nstates or Q.shape[1] != nstates or
          R.shape[0] != ninputs or R.shape[1] != ninputs) :
        raise ControlDimension("incorrect weighting matrix dimensions")

    X,rcond,w,S,T = \
        sb02od(nstates, ninputs, A, B, Q, R, 'D');

    return X

This doesn't seem to directly deal with the S and E arguments, so need to figure that part out.

Upload docs to pythonhosted / pypi

Pypi now has a place to host docs for python packages. It would be good to upload our docs there.

You can now host documentation at http://pythonhosted.org/control. To upload documentation, prepare a .zip file that is unpacked into this URL. Only static pages are supported. The zip file must have a top-level "index.html".

Inconsistent output from time response routines

The time response routines in matlab.py return values in a different order from their counterparts in timeresp.py. For instance, one does

t, y = timeresp.step_response(sys)

but

y, t = matlab.step(sys)

Worse, for matlab.impulse, matlab.initial, and matlab.lsim, the actual behavior (y,t) is inconsistent with what is in the docstring (t,y). This is confusing, and I think the order should be consistent. I guess it would make the most sense to make all of these consistent with MATLAB, which is (y,t).

This is a nasty change, though, that is likely to break existing code people may have. Any thoughts?

Root locus with parameter other than gain

This feature is probably classified as "nice to have" by control engineers. But as an integrated circuit designer, I think I would find this very useful. For one, we do not have much control over the gain K (limited by power dissipation specs, for example). I also do not find it common to compensate for stability through cascaded systems; we gravitate towards feedback compensation. This means that we usually adjust poles and zeros, rather than gain K.

Can I plot the root locus with the sweep parameter other than gain? Is it possible in the current version? Or can we put this on the roadmap?

Separation of plotting from computation

If a system is passed in, both the root locus and bode functions do both computations and produce a plot. In my opinion, it would be better to separate the computation from the plotting. The plotting commands should then return matplotlib axes and maybe figure instances and the computation methods would return the results of the computations, e.g. roots, mag/phase, etc.

Right now there aren't clean ways to get hold of the figure and axes (I don't consider .gca() and .gcf() that "clean"). And if you are using a plotting library other than matplotlib you may not want to call functions that create matplotlib plots.

There maybe other plotting functions in the library that I haven't play with yet too that this is applicable too.

Add Project to the Python Package Index [sf#3]

Reported by eike on 2011-06-12 13:43 UTC
The Python Control project should be added to the Python Package Index.
http://pypi.python.org/pypi

This would ease some administrative work:

  • Uploading packages can be easily automated.
  • Each package has a documentation website. Uploading the the generated website can be automated too.
  • Users can install the library with easy_install. A user would only need to type easy_install python-control to download and install the package.
  • It would also give the project additional visibility.

An introduction how to automate build and upload tasks, in conjunction with the Python Package Index, is here:
http://packages.python.org/an_example_pypi_project/

undefined dt in dtime [sf#5]

*Reported by anonymous on 2014-02-04 15:39 UTC
In dtime.py of 0.6.c in sample_systems 'dt' is used to build a TransferFunction for methods 'tustin' and 'zoh' but it's not defined: it should be 'Ts' instead.

Thank you for the nice module!
thomas.handzsuj-at-draeger.com

Feature request pretty printing zpk form

It would be nice to be able to print TransferFunction instances in zero-pole-gain form. I haven't found this functionality if it exists. Maybe a simple zpk_print() method would suffice.

Add webhook to automatically build documentation

Now that we are hosting the documentation on readthedocs.org, it would be convenient to have the documentation automatically rebuild whenever somebody pushes to the repository on github. This can apparently be set up very easily as explained here:

  • on the project's github page, go to Settings
  • click "Webhooks and Services"
  • in the "Services" section, click "Add service"
  • select "ReadTheDocs"
  • check "Active", and click "Add service"

@murrayrm, could you or another administrator set that up?

Function ``lsim``: swap order of arguments ``U`` and ``T`` [sf#1]

Reported by eike on 2011-06-09 20:16 UTC
The function control.matlab.lsim is defined as::

def lsim(sys, U=0., T=None, X0=0., **keywords):
    ...

To execute the function the arguments sys and T must be supplied, they can not have default values. While the arguments U and X0 have useful default values (arrays of zeros). The fact that T has a default value which is an erroneous input for the function, is confusing for new users. (And it is inelegant.)

Therefor I suggest that the order of the arguments U and T should be swapped. The function should better be defined like this::

def lsim(sys, T, U=0., X0=0., **keywords):
    ...

This way Python's syntax would be used to naturally document which values are required to run the function. As there seem to be only very few user of the Python Control library, changing the API should not create much disruption.

The issue is also mentioned in the source code of scipy.signal.lsim2.

Alterneative Solution

Compute a suitable time vector from the system matrix's (A) eigenvalues, like it is done in step, initial and imulse``.

Move to Git? [sf#9]

Reported by jgoppert on 2014-03-24 23:03 UTC
I think this is a great project. I would like to see more people get involved. +1 for moving to git. I think it would help with community contributions.

Numpy array style access to statespace subsystems [sf#6]

Reported by jgoppert on 2014-03-25 11:07 UTC
This gives state-space array style access to subsystems like matlab.

For example you can type ss[0,:] to the response of output 0 to all inputs (miso)
or ss[:,1] for mimo for input 1, or ss[3,4] for the siso with output 3 and input 4. Note that this follows the matlab convention of ss[output,input] which makes the most sense when doing multiplication of state-space systems. It also know how to work with slices just like numpy so you can do ss[0:1,0:1] etc.

https://github.com/jgoppert/python-control/commit/de30106d26e93f80050a0b72bb925abc36a998ba.patch

c2d should maintain states [sf#7]

Reported by murrayrm on 2014-03-22 19:17 UTC
Roberto Bucher sent the following request to the discussion list:

The c2d function should maintain the form of the state-space function. It seems that the system is first transformed into a transfer function and then discretized. In my opinion it is important that the state-space form of the discrete system is exactly the same (same states) that I have in the continuous representation.

lsim is slow

The lsim command can be much, much slower than scipy.signal.lsim. For instance, consider the following example (run in IPython for %timeit):

import scipy.signal as sig
import control
import numpy as np
t = np.arange(0,1000,0.5)
u = np.sin(2.*t)
sys1 = sig.lti(1.,[1,0,1])
sys2 = control.tf(1.,[1,0,1])
%timeit sig.lsim(sys1,u,t)
%timeit control.lsim(sys2,u,t)

For me, scipy.signal.lsim gives 17.4 ms per loop, and control.lsim gives 7.64 s per loop.

The current implementation of control.lsim calls a general-purpose ODE solver at each step. I think it is better to assume a linear system with constant-spaced timesteps in t (as done in scipy.signal.lsim and in Matlab's lsim), and then one can evaluate the matrix exponential once and apply it at each step. If non-uniform timesteps are desired (which is very rare, at least in my experience), then we could have an alternative routine control.lsim2 that calls the general-purpose ODE solver--that is what is done in scipy.signal.

Improve interface of ``bdalg.feedback`` [sf#4]

Reported by eike on 2011-06-13 15:07 UTC
Change the interface of bdalg.feedback to that of Matlab's feedback function. The current interface is too cumbersome for MIMO models.

The function should react differently whether it has 2, 3, 4, or 5 arguments:

Implies: both systems may be MIMO or SISO; sys1.inputs == sys2.outputs; sys2.inputs == sys1.outputs
feedback(sys1, sys2)
feedback(sys1, sys2, sign)

Implies: sys1: MIMO; sys2: SISO
feedback(sys1, sys2, sys1_in, sys1_out)
feedback(sys1, sys2, sys1_in, sys1_out, sign)

See:
http://www.mathworks.com/help/toolbox/control/ref/feedback.html

The implementation should be no big intellectual endeavor, because a general implementation of feedback for MIMO systems already exists.
It just requires work, and a little design (maybe introduce a function siso2mimo).
The current implementation covers the case of 2, and 3 arguments.

Time response functions give unnecessary warnings

Both step_response and impulse_response issue warnings in some cases when (at least in my opinion) they are not needed. For instance:

>>> from control import *
>>> g = ss("0 0;0 0","1 0;0 1","1 0;0 1","0 0;0 0")
>>> t,y = step(g, input=0, output=0)
/Users/clancy/Work/Projects/pycontrol/control/statesp.py:829: UserWarning: Converting MIMO system to SISO system. Only input 0 and output 0 are used.
  .format(i=input, o=output))
>>> t,y = step(g)
/Users/clancy/Work/Projects/pycontrol/control/statesp.py:879: UserWarning: Converting MIMO system to SIMO system. Only input 0 is used.
  .format(i=input))

In the first use of step, I feel a warning is inappropriate, since the user has explicitly specified the input and output. In the second use, I think it's appropriate to issue a warning.

Runtests fails

At least on my Mac, python runtests.py fails, with the messages below:

Building, see build.log...
running install
Checking .pth file support in /Users/clancy/Work/Projects/pycontrol/build/testenv/lib/python2.7/site-packages/
/usr/local/opt/python/bin/python2.7 -E -c pass
TEST FAILED: /Users/clancy/Work/Projects/pycontrol/build/testenv/lib/python2.7/site-packages/ does NOT support .pth files
error: bad install directory or PYTHONPATH

You are attempting to install a package to a directory that is not
on PYTHONPATH and which Python does not read ".pth" files from.  The
installation directory you specified (via --install-dir, --prefix, or
the distutils default setting) was:

    /Users/clancy/Work/Projects/pycontrol/build/testenv/lib/python2.7/site-packages/

and your PYTHONPATH environment variable currently contains:

    '/Users/clancy/Work/Projects/pycontrol'

This happens for me with python 2.7.8 and 3.4.1. If I run python runtests.py -n to skip the build, then the tests run fine. So it seems like there might be a problem either with runtests.py or setup.py. But if I understand correctly from @jgoppert, these files were taken directly from numpy, and if I clone the numpy source and do python runtests.py in that, it works fine. So this is mysterious to me.

MIMO capabilities + better docs [sf#2]

Reported by eike on 2011-06-12 16:56 UTC
This pathch is against subversion revision 156.

  • This patch adds MIMO capabilities for lsim, step, impulse, initial. The code for lsim was taken from scipy.signal.lsim2.
  • It also adds a function dcgain.
  • The big table in the module documentation was formatted into a real reStructuredText table. It looks now quite nice in the generated Sphinx documentation. A section that explains the convention for time series (as arguments and return values) was added.
  • The documentation of functions lsim, step, impulse, initial was expanded too. Some parts were copied from scipy.signal.
  • The Sphinx configuration was expanded so that links to Scipy are done automatically.

I'm doing the development in a separate Mercurial repository:
https://bitbucket.org/eike_welk/python-control/

Arguments of ``lsim``, ``step``, ``impulse``, ``initial`` [sf#2]

Reported by eike on 2011-06-09 20:32 UTC
Decide on a convention for the arguments of (control.matlab.) lsim, step, and impulse, initial. Document the convention in the module documentation of control.matlab. This convention should be used everywhere in Python-Control for arguments that are chronological sequences of values.

My proposal for this convention, which is contrary to the convention in scipy.signal:

Parameter Convention

This convention for parameters and return values harmonizes with the way
how the system equations are written. It can be generalized to MIMO systems,
and it also works well with Matplotlib:

All parameters can be arrays, matrices, or nested lists.

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

The initial conditions are either 1D, or 2D with shape (j, 1)::

 X0 = [[u1]
       [u2]
       ...
       ...
       [uj]]

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.

As all simulation functions return array plotting is convenient::

t, y = step(sys)
plot(t, y)

The output of a MIMO system would 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')

LQR should work with 3 arguments [sf#8]

Reported by murrayrm on 2014-03-22 19:27 UTC
Roberto Bucher sent the following feature request to the discussion list:

the lqr function doesn't accept a call like

lqr(sys,Q,R) -> only 3 parameters!

Test rlocus_test.TestRootLocus fails due to array order [sf#3]

Reported by waldherr on 2012-08-23 08:58 UTC
I get the following output:

FAIL: testRootLocus (rlocus_test.TestRootLocus)

Basic root locus plot

Traceback (most recent call last):
File "/.../control-0.5b/tests/rlocus_test.py", line 31, in testRootLocus
rlist[k], feedback(self.sys1, klist[k]).pole())
File "/Library/Frameworks/EPD64.framework/Versions/7.2/lib/python2.7/site-packages/numpy/testing/utils.py", line 800, in assert_array_almost_equal
header=('Arrays are not almost equal to %d decimals' % decimal))
File "/Library/Frameworks/EPD64.framework/Versions/7.2/lib/python2.7/site-packages/numpy/testing/utils.py", line 636, in assert_array_compare
raise AssertionError(msg)
AssertionError:
Arrays are not almost equal to 6 decimals

(mismatch 100.0%)
x: array([-1.5-1.6583124j, -1.5+1.6583124j])
y: array([-1.5+1.6583124j, -1.5-1.6583124j])

I guess that test shouldn't fail just because of a different element order in the array?

Set up new homepage for python-control at python-control.org

I have python-control.org reserved and we can redirect this to an appropriate homepage for the project that links to the documentation, source code, downloads, etc.

Q: where should the "homepage" for the python-control project be? An easy possibility is to set this up to be python-control.sourceforge.net and then put a state page there that contains the relevant links. Or we could point it at the SourceForge wiki page, though I find that a bit clunky looking.

Thoughts?

This also relates to a comment in issue #33.

rlocus should allow kvect=None as an argument

From Roberto Bucher:

"rlocus" creates automatically a vector with the k values, if not provided. "root_locus" should have the possibility to pass kvect=None, but it is not accepted (-> error). It can be simply solved by adding the same lines as in rlocus, before finding a better algorithm to get the k values

#! TODO: update with a smart calculation of the gains using sys poles/zeros
if klist == None:
klist = logspace(-3, 3)

Mistakes in examples in documentation

I noticed a minor mistake in the documentation for _convertToTransferFunction. In particular, in the example

sys = _convertToTransferFunction([[1. 0.], [2. 3.]])

the numbers should be separated by commas. That made me wonder if there were mistakes in other examples, so I ran all of the examples as doctests with nosetests --with-doctest. That reveals 38 failed tests, and 1 error. Many of these problems are because some quantities are not defined in the examples. For instance:

T, yout = initial_response(sys, T, X0)

gives NameError: name 'sys' is not defined. I think it would be good to make these examples all self-contained and "runnable", so that 1) they are complete (e.g., users know exactly how to define an object like sys in the example above); and 2) they can be automatically tested as doctests. Any comments or objections?

Move away from SLICOT?

Reported by Clancy Rowley on 2014-07-26
I'm considering rewriting some of the routines in python-control so that it will no longer depend on SLICOT. The main reasons for this are that 1) because SLICOT is written in Fortran, installation can be a pain (see several other comments in this forum); 2) SLICOT has apparently now gone closed-source; 3) most of the key functionality SLICOT provides (e.g., solving Lyapunov equations and Riccati equations) is now included in scipy.linalg, so I'm thinking this might not be too much of a pain.

Does anybody have thoughts or opinions on this?

evalfr does not behave as expected [sf#6]

*Reported by anonymous on 2013-05-24 14:32 UTC
The current implementation of evalfr is different from the matlab function evalfr. Could you please "fix" it.

Example: Evaluate the transfer function G=tf(1,[2,3,4]) at s=1+2j

In Matlab one would type evalfr(G,s) and get the expectet result (0.0051-0.0711j).
Using this module typing evalfr(G,s) will actually compute evalfr(G,s*j) which is (0.09756098+0.12195122j), that is, it evaluated G at the point -2+j instead.

I agree that this is what one would expect (after reading the documentation of evalfr) but I would rather have a behavior that conforms with matlab (after all the module control.matlab was designed to emulate matlab's routines)

Thanks,

Juan C. Cockburn
[email protected]

Convert Documentation to Sphinx Format [sf#3]

Reported by eike on 2011-06-21 01:29 UTC
This patch converts many function doc-strings to proper Sphinx format. All functions of matlab do now appear in the documentation: They are included with .. autofunction:: in the matlab documentation, until their modules are documented.

The big table at the start of module matlab was split into multiple small tables. The names of all implemented functions are now links to the their documentation.

TODOs were enabled and included in the documentation.

Stability Margin may give incorrect results with FRD system

When calling stability_margins() with an FRD system, or with a (mag, phase, omega) system that is converted to FRD, the phase crossover frequency in particular (and consequently the gain margin) can be radically inaccurate. Sometimes I even get the phase crossover as a negative frequency! I am working with a fairly simply system with a zero, a couple poles, no resonances, etc., so I looked to see if I could figure out what was going on.

I found that changing lines 207 and 208 in margins.py from:

wc = np.array([sp.optimize.fsolve(mod, sys.omega[0])])[0]
w_180 = np.array([sp.optimize.fsolve(arg, sys.omega[0])])[0]

to:

wc = np.array([sp.optimize.fsolve(mod, np.median(sys.omega))])[0]
w_180 = np.array([sp.optimize.fsolve(arg, np.median(sys.omega))])[0]

Always produces the expected result. It makes sense to seed the fsolve function with the median frequency in the defined FRD system because one would expect the crossovers to generally be in "the middle" of the bode plot instead of at the lowest frequency.

Just an improvement I'm using myself, but it may be worth incorporating.

Bode, Nyquist, and root locus plots are crude

Bode, Nyquist, and root locus plots are all much nicer in Matlab, both because they make smarter choices for things like frequencies to plot, and because their plots are interactive, so you can click on points to get additional information, etc.
I have some ideas for how to improve this (e.g., more sophisticated ways of generating frequencies for Bode/Nyquist plots, with finer resolution near lightly damped poles or zeros; better gains for root locus plots, with finer resolution near break-out and break-in points, etc), and I'm planning to try implementing those.

Series connection of frd models fails [sf#6]

Reported by roadrunner660 on 2014-03-12 07:11 UTC
Connecting two frd-models with identical frequency data fails.
It seems to me that this functionality is simply missing.
And code that handles the series connection in the frdata class
looks identical to the code in xferfcn.py.

Example:

:::python
import control
 # create a simple tranfer function
Gf = control.tf([1], [1, 1])
# convert it into a frequency response data model
omega = control.freqplot.default_frequency_range(Gf)
Gfrd = control.FRD(Gf, omega)
# series connection between frequency response data models
G = control.series(Gfrd, Gfrd)

Results in:

Traceback (most recent call last):
File "", line 1, in
File "C:\Python27\lib\site-packages\control-0.6c-py2.7.egg\control\bdalg.py", line 98, in series
return sys2 * sys1
File "C:\Python27\lib\site-packages\control-0.6c-py2.7.egg\control\frdata.py", line 273, in mul
num_summand[k] = polymul(self.num[i][k], other.num[k][j])
AttributeError: FRD instance has no attribute 'num'

bode [sf#2]

Reported by thomas_ha on 2011-04-19 19:13 UTC
In Ver 0.4b, the "bode" command crashes. It worked in Ver 0.3c.

return type of "step" function [sf#1]

Reported by thomas_ha on 2011-04-19 18:37 UTC
The function "step" is supposed to return an array for the time:

T, yout = step(sys, T, X0)
T: array
Instead, a matrix is returned. To convert it to a time array, currently the following step is required (which should not be required):
t2 = array(T)[0,:]

Fix for bug in margin.py

Calling margin() or stability_margins() with (mag, phase, omega) form yields incorrect result. I found that the issue is in line 125 of margin.py, where it calls frdata.FRD to create the system:

sys = frdata.FRD(mag*np.exp((1j/360.)*phase), omega, smooth=True)

The phase angle conversion is incorrect. Changing this line to:

sys = frdata.FRD(mag*np.exp(1j*phase*np.pi/180), omega, smooth=True)

yields the correct result. Also, it may be good to clearly indicate that the magnitude data in this form must be absolute magnitude, not dB, and that the phase must be in degrees. The frequency can be either Hz or rad/s... the output frequency is in the same units as whatever you put in (Matlab's documentation has a similar note).

Tests generate a lot of text output

Some of the unit tests (e.g., matlab_test.py) generate text output or warning messages that make it difficult to tell at a glance whether the tests are passing. Ideally unit tests should generate no such output.

For the warnings, I believe you can use the warnings.catch_warnings context manager to check that a warning was given. I will plan to clean this up soon.

Can't install control in Travis-CI

I have a package that depends on control but I have trouble testing it in Travis-CI due to the following error when running pip install control:

ImportError: Unable to import git_revision. Try removing control/version.py and the build directory before building.

The full log is here: https://travis-ci.org/kdavies4/ModelicaRes/jobs/35359894.

Do you know how to fix this? It seems that control.version can't be imported until the control package is installed, which requires control.version. A catch-22?

Add user manual to python-control distribution tarball

Suggestions received via e-mail:

On 2 Nov 2014, at 4:57 , Ralph Koettlitz wrote:

Hello,
would you be so kind to put the manual into the archive of Python Control?

Regards
R. Koettlitz

It seems like it would be useful for people downloading the tarball from SourceForge to have some sort of user manual that is part of the distribution (without needing to compile). Need to look into how other distributions handle this and then decide how to proceed.

webserver usage: import control let's webserver "hang" [sf#4]

*Reported by anonymous on 2013-07-11 09:34 UTC
When using apache with mod_wsgi the (debian wheezy) webserver does not respond anymore when "import control" is used. Using python (2.6/2.7) on command line and using "import control" gives no error.
Tested versions were 0.5b (tried to see if it was a backwards compatibility problem) and 0.6c.

The following simple application.wsgi was used:

import web

import control

urls = (
'/(.*)', 'hello'
)

class hello:
def GET(self, name):
if not name:
name = 'World'
return 'Hello ' + name

if name == "main":
app.run()

app = web.application(urls, globals(), autoreload=False)
application = app.wsgifunc()

sample_system for methods tustin and zoh not working on dtime.py [sf#4]

Reported by awesomebytes on 2013-11-17 21:05 UTC
Trying to use c2d I've encountered:
syst_fake_dis = c2d(syst_fake, 0.01, method='zoh')
File "/usr/local/lib/python2.7/dist-packages/control-0.6c-py2.7.egg/control/matlab.py", line 1395, in c2d
return sample_system(sysc, Ts, method)
File "/usr/local/lib/python2.7/dist-packages/control-0.6c-py2.7.egg/control/dtime.py", line 87, in sample_system
sysd = TransferFunction(scipySysD[0][0],scipySysD[1], dt)
NameError: global name 'dt' is not defined

Which I think can be fixed just changing "dt" to "Ts". I tried for my example and it works.

By the way, I may be trying to implement the MATLAB "stmcb" (http://www.mathworks.es/es/help/signal/ref/stmcb.html ) function to your toolbox.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.