Skip to content
Richard Murray edited this page Mar 31, 2024 · 50 revisions

This page contains information for developers on the past and future releases for the package. For each release, the major changes are listed. Each release should (eventually) have its own page describing the detailed changes that are included for that release.

Release naming conventions: starting with release 0.7.0, we use the major.minor.revision numbering convention for releases:

  • The revision number is incremented when minor bugs are fixed. All previous code should function without change.
  • The minor number is incremented when minor features or significant fixes have been added.
  • The major number is incremented when there are significant jumps in functionality such as changing the framework which could cause incompatibility with interfacing systems

Upcoming releases (planned)

python-control 0.10.1

Pending items (remove when done):

Current release

python-control 0.10.0 (31 Mar 2024)

This release changes the interface for plotting to use a "response/plot" design pattern (#920, #924, #953), adds multivariable interconnect functionality (#881), restructures I/O system classes (#916), and adds the norm() function to compute input/output system norms (#971). A number of other smaller enhancements, bug fixes, and updates to documentation and examples are also included.

Note: This release may break code that was using v0.9.4 or earlier. In addition, the matrix class in NumPy is no longer supported, and Python 3.10 or higher is required.

Full list of changes: https://github.com/python-control/python-control/releases/tag/0.10.0

Detailed changelog: https://github.com/python-control/python-control/compare/0.9.4...0.10.0

python-control 0.9.4 (9 Jun 2023)

This release adds functions for optimization-based estimation and moving horizon estimation (#877), better handling of system and signal names (#857, #892, #884) as well a number of bug fixes, small enhancements, and updated documentation.

Full list of changes: https://github.com/python-control/python-control/releases/tag/0.9.4

Detailed changelog: https://github.com/python-control/python-control/compare/0.9.3.post2...0.9.4

Past releases

python-control 0.9.3 (31 Dec 2022)

This release adds support for collocation in finding optimal trajectories (#799), adds the ability to compute optimal trajectories for flat systems (#763) adds support for passivity indices and passivity tests for discrete time systems (#750), and includes support for gain scheduling (in create_statefbk_iosystem, #827). Setup is now done using setuptools (pip install . instead of python setup.py install).

Full list of changes: https://github.com/python-control/python-control/releases/tag/0.9.3

Detailed changelog: https://github.com/python-control/python-control/compare/0.9.2...0.9.3

python-control 0.9.2 (28 May 2022)

This is a minor release that includes I/O system enhancements (#710), optimal control enhancements (#712), new functionality for stochastic systems (#714), updated system class functionality (#721), bug fixes and improvements to Nyquist plots (#722) and Nichols charts (#723), and L-infinity norm for linear systems (#729).

New features:

  • I/O system enhancements by @murrayrm in https://github.com/python-control/python-control/pull/710
    • Modify the ss(), rss(), and drss() functions to return LinearIOSystem objects (instead of StateSpace objects). This makes it easier to create LTI state space systems that can be combined with other I/O systems without having to add a conversation step. Since LinearIOSystem objects are also StateSpace objects, no functionality is lost. (This change is implemented through the introduction of a internal NamedIOSystem class, to avoid import cycles.)
    • Added a new function create_statefbk_iosystem() that creates an I/O system for implementing a linear state feedback controller of the form u = ud - Kp(x - xd). The function returns an I/O system that takes xd, ud, and x as inputs and generates u as an output. The integral_action keyword can be used to define a set of outputs y = C x for which integral feedback is also included: u = ud - Kp(x - xd) - Ki(C x - C xd).
    • The lqr and dlqr commands now accept an integral_action keyword that allows outputs to be specified for implementing integral action. The resulting gain matrix has the form K = [Kp, Ki]. (This is useful for combining with the integral_action functionality in create_statefbk_iosystem()).
  • Optimal control enhancements by @murrayrm in https://github.com/python-control/python-control/pull/712
    • Allow t_eval keyword in input_output_response to allow a different set of time points to be used for the input vector and the computed output
    • The final cost is now saved in optimal control result (#694)
  • Stochastic systems additions by @murrayrm in https://github.com/python-control/python-control/pull/714
    • Added two new functions supporting random signals: white_noise, which creates a white noise vector in continuous or discrete time, and correlation, which calculates the correlation function (or [cross-] correlation matrix), R(tau).
    • Added a new function create_estimator_iosystem that matches the style of create_statefbk_iosystem (#710) and creates an I/O system implementing an estimator (including covariance update).
    • Added the ability to specify initial conditions for input_output_response as a list of values, so that for estimators that keep track of covariance you can set the initial conditions as [X0, P0]. In addition, if you specify a fewer number of initial conditions than the number of states, the remaining states will be initialized to zero (with a warning if the last initial condition is not zero). This allows the initial conditions to be given as [X0, 0].
    • Added the ability to specify inputs for input_output_response as a list of variables. Each element in the list will be treated as a portion of the input and broadcast (if necessary) to match the time vector. This allows input for a system with noise as [U, V] and inputs for a system with zero noise as [U, np.zero(n)] (where U is an input signal and np.zero(n) gets broadcast to match the time vector).
    • Added new Jupyter notebooks demonstrate the use of these functions: stochresp.ipynb, pvtol-outputfbk.ipynb, kincar-fusion.ipynb.
  • Updated system class functionality by @murrayrm in https://github.com/python-control/python-control/pull/721
    • Changed the LTI class to use poles() and zeros() for retrieving poles and zeros, with pole() and zero() generating a PendingDeprecationWarning (which is ignored by default in Python). (The MATLAB compatibility module still uses pole() and zero().)
    • The TimeResponseData and FrequencyResponseData objects now implement a to_pandas() method that creates a simple pandas dataframe.
    • The FrequencyResponseData class is now used as the output for frequency response produced by freqresp() and a new function frequency_response has been defined, to be consistent with the input_output_response function. A FrequencyResponseData object can be assigned to a tuple to provide magnitude, phase, and frequency arrays, mirroring TimeResponseData functionality from PR #649.
    • The drss, rss, ss2tf, tf2ss, tf2io, and ss2io functions now all accept system and signal name arguments (via _process_namedio_keywords().
    • The ss function can now accept function names as arguments, in which case it creates a NonlinearIOSystem (I'm not sure how useful this is, but ss is a sort of wrapper function that calls the appropriate class constructor, so it was easy enough to implement.)
  • Added linform to compute linear system L-infinity norm by @roryyorke in https://github.com/python-control/python-control/pull/729

Improvements, bug fixes:

Additional changes:

Full changelog: https://github.com/python-control/python-control/compare/0.9.1...0.9.2

python-control 0.9.1 (31 Dec 2021)

This is a minor release that includes new functionality for discrete time systems (dlqr, dlqe, drss), flat systems (optimization and constraints), a new time response data class, and many individual improvements and bug fixes.

New features:

  • Add optimization to flat systems trajectory generation (#569 by murrayrm)
  • Return a discrete time system with drss() (#589 by bnavigator)
  • A first implementation of the singular value plot (#593 by forgi86)
  • Include InfValue into settling min/max calculation for step_info (#600 by bnavigator)
  • New time response data class (#649 by murrayrm)
  • Check for unused subsystem signals in InterconnectedSystem (#652 by roryyorke)
  • New PID design function built on sisotool (#662 by sawyerbfuller)
  • Modify discrete-time contour for Nyquist plots to indent around poles (#668 by sawyerbfuller)
  • Additional I/O system type conversions (#672 by murrayrm)
  • Remove Python 2.7 support and leverage @ operator (#679 by bnavigator)
  • Discrete time LQR and LQE (#670 by sawyerbfuller, murrayrm)

Improvements, bug fixes:

  • Change step_info undershoot percentage calculation (#590 by juanodecc)
  • IPython LaTeX output only generated for small systems (#607 by roryyorke)
  • Fix warnings generated by sisotool (#608 by roryyorke)
  • Discrete time LaTeX repr of StateSpace systems (#609 by bnavigator)
  • Updated rlocus.py to remove warning by sisotool() with rlocus_grid=True (#616 by nirjhar-das)
  • Refine automatic contour determination in Nyquist plot (#620 by bnavigator)
  • Fix damp method for discrete time systems with a negative real-valued pole (#647 by vincentchoqueuse)
  • Plot Nyquist frequency correctly in Bode plot in Hz (#651 by murrayrm)
  • Return frequency response for 0 and 1-state systems directly (#663 by bnavigator)
  • Fixed prewarp not working in c2d and sample_system, margin docstring improvements (#669 by sawyerbfuller)
  • Improved lqe calling functionality (#673 by murrayrm)
  • Vectorize FRD feedback function (#680 by bnavigator)
  • BUG: extrapolation in ufun throwing errors (#682 by miroslavfikar)
  • Allow use of SciPy for LQR, LQE (#683 by murrayrm)
  • Improve forced_response and its documentation (#588 by bnavigator)
  • Add documentation about use of axis('equal') in pzmap, rlocus (#685 by murrayrm)

Additional changes:

  • Replace Travis badge with GHA workflows, add PyPI and conda badges (#584 by bnavigator)
  • Don't install toplevel benchmarks package (#585 by bnavigator)
  • LTI squeeze: ndarray.ndim == 0 is also a scalar (#595 by bnavigator)
  • xfail testmarkovResults until #588 is merged (#601 by bnavigator)
  • Remove from readme.rst that you need a fortran compiler (#602 by sawyerbfuller)
  • Remove statement that slycot only on linux (#603 by sawyerbfuller)
  • Allow float precision in result assertions (#615 by bnavigator)
  • Improved unit test coverage for root_locus: dtime and sisotool (#617 by bnavigator)
  • Add DefaultDict for deprecation handling (#619 by bnavigator)
  • Documentation updates (#633 by murrayrm)
  • Various docstring edits + fixed plot legends on cruise control example (#643 by billtubbs)
  • Ease test tolerance on timeseries (#659 by bnavigator)
  • Use conda-forge for numpy (CI fix) (#667 by bnavigator)
  • Fix doc escape (#674 by bnavigator)
  • Remove duplicate Slycot error handling, require Slycot >=0.4 (#678 by bnavigator)
  • Full list of merged pull requests associated with this release.
  • Full list of commits associated with this release.

python-control 0.9.0 (20 Mar 2021)

Version 0.9.0 of the Python Control Toolbox (python-control) contains a number of enhanced features and changes to functions. Some of these changes may require modifications to existing user code and, in addition, some default settings have changed that may affect the appearance of plots or operation of certain functions.

Significant new additions including improvements in the I/O systems modules that allow automatic interconnection of signals having the same name (via the interconnect function), generation and plotting of describing functions for closed loop systems with static nonlinearities, and a new optimal control module that allows basic computation of optimal controls (including model predictive controllers). Some of the changes that may break use code include the deprecation of the NumPy matrix type (2D NumPy arrays are used instead), changes in the return value for Nyquist plots (now returns number of encirclements rather than the frequency response), switching the default timebase of systems to be 0 rather than None (no timebase), and changes in the processing of return values for time and frequency responses (to make them more consistent). In many cases, the earlier behavior can be restored by calling use_legacy_defaults('0.8.4'). A full list of additions and changes is described below.

New features

  • Optimal control module, including rudimentary MPC control (#549 by murrayrm)
  • Describing functions plots (#521 by murrayrm)
  • MIMO impulse and step response (#514 by murrayrm)
  • I/O system improvements:
    • linearize() retains signal names plus new interconnect() function (#497 by murrayrm)
    • Add summing junction + implicit signal interconnection (#517 by murrayrm)
  • Implementation of initial_phase, wrap_phase keywords for bode_plot (#494 by murrayrm)
  • Added IPython LaTeX representation method for StateSpace objects (#450 by roryyorke)
  • New dynamics() and output() methods in StateSpace (#566 by sawyerbfuller)
  • FRD systems can now be created from a discrete time LTI system (#568 by bnavigator)
  • Cost and constraints are now allowed for flatsys.point_to_point() (#569 by murrayrm)

Interface changes

  • Switch default state space matrix type to 'array' (instead of 'matrix') (#480 by murrayrm, #486 by bnavigator, #433 by sawyerbfuller)
  • Use __call__ instead of evalfr in lti system classes (#449 by sawyerbfuller)
  • Default dt is now 0 instead of None (#431 by sawyerbfuller, #490 by bnavigator)
  • Change default value of statesp.remove_useless_states to False (#509 by murrayrm)
  • Standardize time response return values, return_x/squeeze keyword processing (#511 by murrayrm)
  • Standardize squeeze processing in frequency response functions (#507 by murrayrm)
  • Nyquist plot now returns number of encirclements (#534 by murrayrm)
  • Switch LTI class and subclasses to use ninputs, noutputs, nstates (#515 by murrayrm)
  • Use standard time series convention for markov() input data (#508 by murrayrm)
  • TransferFunction array priority plus system type conversion checking (#498 by murrayrm)
  • Generate error for tf2ss of non-proper transfer function (#492 by murrayrm)
  • Updated return values for frequency response evaluated at poles (#542 by murrayrm)

Improvements, bug fixes

  • Nyquist plot improvements: better arrows, handle poles on imaginary axis (#534 by murrayrm)
  • Sisotool small visual cleanup, new feature to show step response of different input-output than loop (#531 by sawyerbfuller)
  • Add bdschur() and fox modal form with repeated eigenvalues (#495 by roryyorke)
  • Fix rlocus timeout due to inefficient _default_wn calculation (#527 by murrayrm)
  • Fix #523: finding z for |H(z)|=1 computed the wrong polynomials (#525 by bnavigator)
  • Freqplot improvements (#522 by sawyerbfuller)
  • Fix rlocus plotting problem in Jupyter notebooks (#503 by murrayrm)
  • Handle empty pole vector for timevector calculation (#485 by bnavigator)
  • Fix lqe() docstring and input array type (#483 by bnavigator)
  • Updated markov() to add tranpose keyword + default warning (#478 by murrayrm)
  • Fix impulse size for discrete-time impulse response (#447 by sawyerbfuller)
  • Extend returnScipySignalLTI() to handle discrete-time systems (#445 by bnavigator)
  • Bug fixes and extensions for step_info() (#555 by sawyerbfuller, #567 by juanodecc, #577 by bnavigator)

Additional changes

  • Address NumPy deprecations np.int, np.float (#539 by dapperfu, #548 by murrayrm)
  • Shift CI tests from Travis CI to GitHub Actions (#504 by murrayrm)
  • Link to developer wiki in docs. (#502 by sawyerbfuller)
  • Reduce Python 3 testing to speed up Travis CI testing (#487 by murrayrm)
  • Refactor the test suite using pytest for array and matrix types (#438 by bnavigator)
  • Full list of merged pull requests associated with this release.
  • Full list of commits associated with this release.

python-control 0.8.4 (28 Dec 2020)

  • Improved default time vector for time response functions (bnavigator, sawyerbfuller)
  • New use_legacy_defaults function to allow compatibility with previous versions (sawyerbfuller)
  • Allow creation of non-proper transfer functions (bnavigator, rlegnain)
  • Added ability to set arrow head length and width option in nyquist_plot (geekonloose)
  • Added ability to 'prewarp' the conversion of continuous to discrete-time systems (sawyerbfuller)
  • Added rlocus capability for discrete-time systems (sawyerbfuller)
  • Updated pzmap grid to be compatible with matplotlib updates (bnavigator)
  • Implement loadable string representation (repr) for tf, ss, and frd (repagh)
  • Fixed margin computation for discrete time systems (bnavigator)
  • Fixed indexing bug in bdalg.connect (sawyerbfuller)
  • Fixed InterconnectedSystem naming bugs, improved conventions (samlaf)
  • Fixed LinearIOSystem output bug in output function (francescoseccamonte)
  • Fixed bug in forced_response that overrode squeeze parameter (bnavigator)
  • Use rad/sec for Bode plot in MATLAB bode (was erroneously defaulting to Hertz) (paulvicioso)
  • Removed deprecated scipy calls and updated to latest numpy (bnavigator)
  • Multiple documentation updates (bnavigator, laurensvalk)
  • New and improved examples for sisotool, pvtol (repagh, samlaf)
  • The rlocus function no longer automatically creates a new figure
  • Updated unit tests + switch to pytest (bnavigator, sawyerbfuller)
  • Return type for eigenvalues in lqe changed to 1D array (matches lqr)
  • Small fixes + documentation updates to markov
  • Full list of merged pull requests associated with this release.
  • Full list of commits associated with this release

python-control 0.8.3 (4 Jan 2020)

  • New input/output systems module for creating nonlinear systems from individual I/O subsystems, with find_eqpt, input_output_response, and linearize functionality
  • Initial implementation of differential flatness module for computing feasible trajectories for differentially flat (nonlinear) systems
  • Preliminary version of lqe function (sawyerbfuller)
  • New dict-based implementation of user-configurable package/module configuration parameters
  • Added similarity transformation function
  • Add 's' and 'z' variable support to tf()
  • Fixed discrete time simulation time step issue
  • Reordered Gang of Four plots to match FBS
  • Check for symmetric matrices with machine precision (bnavigator)
  • Changed root precision tolerance and imaginary detection in xferfcn._common_den (bnavigator)
  • Fixed bug in timeresp.forced_response (adm78)
  • Improved latex representation for exp format and multi-digit exponents of s or z (bnavigator)
  • Renamed FRD class name FrequencyResponseData to fix MacOS sphinx build problems (FRD still defined for backward compatibility`
  • Allow np.array or np.matrix for state space matrices, operations via use_numpy_matrix
  • Improved detection of when to add additional points in root_locus
  • Adaptive gain click criterion and zoom bug fix for root_locus (icam0)
  • Improved code for ctrb and obsv (billtubbs)
  • Documentation updates (bnavigator, murrayrm, roryyorke)
  • Updated examples to be PEP compliant
  • Improved unit tests (bnavigator, murrayrm), increased coverage to ~80%
  • Full list of merged pull requests associated with this release.
  • Full list of commits associated with this release

python-control 0.8.2 (16 Apr 2019)

  • Fixed a number of small bugs , including discrete time simulations (bnavigator), integer values in state space matrics (don4get), missing zeros on pole/zero plots (Sup3rGeo)
  • First cut at a new step_info() function, similar to MATLAB (joaoantoniocardoso)
  • Added a new function for dynamically setting gain in sisotool (icam0)
  • Anti-stabilizing solutions for Riccati equations are now available (dbacc)
  • Printout out state space systems in Jupyter notebooks now formats using LaTeX (alchemyst)
  • Additional performance and visualiation improvements: _remove_useless_states (adm78), margins on Bode plots ( icam0), improved damping lines in discrete pzmap (Sup3rGeo)
  • List of merged pull requests associated with this release.
  • List of commits associated with this release

python-control 0.8.1 (22 Dec 2018)

  • A new canonical function modal_form can be used to convert a state space system to modal form (ipa-lth)
  • Improved pole placement algorithm place_varga (rabraker)
  • Bug fix in computing poles of MIMO transfer functions
  • Indexing of MIMO transfer functions (hungpham2511)
  • Additional small bug fixes (adm78, stertingen)
  • Documentation updates and fixes (joaoantoniocardoso)
  • List of merged pull requests associated with this release.
  • List of commits associated with this release

python-control 0.8.0 (7 Jul 2018)

  • Updated and corrected docstrings (PR #198, PR #216)
  • Better support for MIMO systems in pole() and zero() functions (PR #205, PR #206)
  • Support for SciPy-1.0.0 updates to the scipy.signal module that is used for some python-control functions and support for numpy data types (int32, int64, etc) in all python-control functions (PR #170)
  • Support for static gains (0D state space systems and constant transfer functions) (PR #104, PR #110, PR #126, PR #129, PR #145)
    • Note: Open issues related to this: #165
  • New functions obsv (observable canonical form, PR #103), augw and mixsyn (mixed sensitivity synthesis, PR #151)
  • List of merged pull requests associated with this release.
  • List of commits associated with this release

python-control 0.7.0 (23 Oct 2015)

  • Fixes to docstrings and examples (multiple)
  • Bug fix to gain margin calculation for phase crossing through zero
  • c2d functionality added for MIMO state-space systems
  • Faster versions of freqresp for transfer functions and state space models
  • Fixed bug in dare so that it returns stabilizing solution
  • Faster version of force_response (lsim)
  • Installation via pip and conda
  • Gain vector now optional in root_locus
  • List of commits associated with this release

python-control 0.6d (23 Mar 2014)

  • Fixed a bug in dime.py that caused errors when using method tustin or zoh.
  • Improved stability margin calculations, including support for FRD systems.
  • Minimal realization support for transfer functions and state space systems.
  • New MATLAB-like functions: append, connect, minreal
  • Increased python3 compatibility.

python-control 0.6c (3 Nov 2012)

  • Support for discrete time systems using the 'timebase' variable dt. For continuous systems dt = 0 and for discrete time systems dt = sampling time. If dt = None, timebase is not specified and can be either discrete or continuous time. System compositions (series, parallel, feedback) requires matching timebases (with automatic conversion if one timebase is None and the other is specified).

  • There is now a frequency response data (FRD) subclass contributed by Rene van Paassen. For now, the frequency vectors of different FRD objects need to match; no interpolation / clipping yet.

  • There is now a mineral function for computing minimal transfer functions (by removing pole zero cancellations), contributed by Rene van Paassen.

  • Improved support for python 3.x: the current version should run in python 2.6+ (tested in 2.7) and python 3.x (tested in 3.2). I haven't yet tested slycot in python 3.x, but the functions that don't require slycot (most SISO calculations) are working.

python-control 0.5c (6 Oct 2011)

  • Bode and Nyquist plot enhancements that allows matplotlib keywords to be passed through functions for more flexible setting of line styles (thanks to Kevin Davies for the initial code). Nyquist plots now allow labeling of frequency points via the labelFreq keyword (code contributed by Kevin Davies).
  • Fixed problems in tf2ss conversions when there are poles with multiplicity > 1. This was generating lots of errors in the unit tests (properly, as it turns out, since there was a bug!).
  • Added acker function from Roberto Bucher
  • Improved unit testing with fewer warnings and error messages. Substantial modifications to convert_test.py that included fixing bugs in the unit test code and the conversion code (as noted above).

python-control 0.5a (7 Aug 2011)

  • Updated time responses functions: step_response, initial_response, impulse_response and forced_response, along with MATLAB compatible versions (step, initial, impulse, lsim). Handles MIMO systems by allowing choice of input and output.
  • Added a phase_plot command that can be used to generate rudimentary phase portraits for 2D nonlinear systems (similar to the plots in Chapter 4 of Feedback Systems). See examples/geneticswitch.py for an example.
  • Updated many function names to be more consistent with python coding style. So StepResponse is now step_response. MATLAB module (control.matlab) interfaces are unaffected (continue to use step).
  • New function to compute frequencies at which transfer function crosses real axis (phase_crossover_frequencies). Contributed by Steffen Waldherr

python-control 0.4c (19 Jun 2011)

  • Added matrix solvers from LTH (Ola Johnsson, Jerker Nordh, Bjorn Olofsson, Vanessa Romero Segovia. These implement the lyap, dlyap, care and dare functions using slycot.
  • Added tfvis, Simple GUI application for visualizing how the poles/zeros of the transfer function effects the Bode, Nyquist and step response of a SISO system. Contributed by Vanessa Romero Segovia, Ola Johnsson, Jerker Nordh.

python-control 0.4b (2 Apr 2011)

  • Initial implementation of model reduction functions: hsvd, modred, balred, courtesy of Brandt Belson, Steve Brunton, Kevin Chen, and Lauren Padilla.

  • Changes to (eventually) support MIMO transfer functions. These should be transparent to users of the MATLAB interface (control.matlab), but control functions now use a separate class structure. Courtesy randt Belson, Steve Brunton, Kevin Chen, and Lauren Padilla.

  • Updated functionality for Nichols charts, courtesy Allan McInnes.

  • Improvements in unwrap function, courtesy Sawyer Fuller.

python-control 0.3d (12 Feb 2011)

  • New function: rlocus(), courtesy Ryan Krauss
  • New function: pade(), courtesy Sawyer Fuller
  • New functions: nichols(), ngrid(), courtesy Allan McInnes
  • Added lsim wrapper to allow systems with poles at origin. Still need to fix this for step() and impulse()

python-control 0.3c (10 June 2010)

  • Added place and lqr commands, using the SLICOT library (via Enrico Avventi's slycot wrappers). LQR works on MIMO systems.
  • Frequency range for Bode plots are now computed using the poles and zeros of the system.
  • Bode plots can how accept a list of systems: bode(sys1, ..., sysN)
  • Put in docstrings for all user accessible functions