Skip to content

Small fixes for 0.9.4 release #880

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 7 commits into from
Mar 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 19 additions & 9 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,17 @@ 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.

.. image:: https://mybinder.org/badge_logo.svg
:target: https://mybinder.org/v2/gh/python-control/python-control/HEAD

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

!pip install control
import control as ct

Features
--------
Expand All @@ -44,17 +47,16 @@ Features
- Nonlinear systems: optimization-based control, describing functions, differential flatness

Links
=====
-----

- Project home page: http://python-control.org
- Source code repository: https://github.com/python-control/python-control
- Documentation: http://python-control.readthedocs.org/
- Issue tracker: https://github.com/python-control/python-control/issues
- Mailing list: http://sourceforge.net/p/python-control/mailman/


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
Expand All @@ -64,6 +66,7 @@ functionality is limited or absent, and installation of slycot is recommended

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


Installation
============

Expand All @@ -73,7 +76,7 @@ Conda and conda-forge
The easiest way to get started with the Control Systems library is
using `Conda <https://conda.io>`_.

The Control Systems library has been packages for the `conda-forge
The Control Systems library has packages available using the `conda-forge
<https://conda-forge.org>`_ Conda channel, and as of Slycot version
0.3.4, binaries for that package are available for 64-bit Windows,
OSX, and Linux.
Expand All @@ -83,6 +86,10 @@ 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
---

Expand All @@ -92,7 +99,8 @@ To install using pip::
pip install control

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

Installing from source
----------------------
Expand All @@ -106,11 +114,13 @@ toplevel `python-control` directory::
Article and Citation Information
================================

An `article <https://ieeexplore.ieee.org/abstract/document/9683368>`_ about the library is available on IEEE Explore. If the Python Control Systems Library helped you in your research, please cite::
An `article <https://ieeexplore.ieee.org/abstract/document/9683368>`_ 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},
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},
Expand Down
5 changes: 0 additions & 5 deletions control/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ def set_defaults(module, **keywords):
>>> ct.defaults['freqplot.number_of_samples']
100
>>> # do some customized freqplotting
>>> ct.reset_defaults()

"""
if not isinstance(module, str):
Expand Down Expand Up @@ -209,7 +208,6 @@ def use_matlab_defaults():
--------
>>> ct.use_matlab_defaults()
>>> # do some matlab style plotting
>>> ct.reset_defaults()

"""
set_defaults('freqplot', dB=True, deg=True, Hz=False, grid=True)
Expand All @@ -229,7 +227,6 @@ def use_fbs_defaults():
--------
>>> ct.use_fbs_defaults()
>>> # do some FBS style plotting
>>> ct.reset_defaults()

"""
set_defaults('freqplot', dB=False, deg=True, Hz=False, grid=False)
Expand Down Expand Up @@ -263,7 +260,6 @@ class and functions. If flat is `False`, then matrices are
--------
>>> ct.use_numpy_matrix(True, False)
>>> # do some legacy calculations using np.matrix
>>> ct.reset_defaults()

"""
if flag and warn:
Expand All @@ -285,7 +281,6 @@ def use_legacy_defaults(version):
>>> ct.use_legacy_defaults("0.9.0")
(0, 9, 0)
>>> # do some legacy style plotting
>>> ct.reset_defaults()

"""
import re
Expand Down
3 changes: 3 additions & 0 deletions control/ctrlutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
from . import lti
import numpy as np
import math
import warnings

__all__ = ['unwrap', 'issys', 'db2mag', 'mag2db']

Expand Down Expand Up @@ -99,6 +100,8 @@ def issys(obj):
False

"""
warnings.warn("issys() is deprecated; use isinstance(obj, ct.LTI)",
FutureWarning, stacklevel=2)
return isinstance(obj, lti.LTI)

def db2mag(db):
Expand Down
21 changes: 14 additions & 7 deletions control/freqplot.py
Original file line number Diff line number Diff line change
Expand Up @@ -558,21 +558,21 @@ def nyquist_plot(
List of linear input/output systems (single system is OK). Nyquist
curves for each system are plotted on the same graph.

plot : boolean
If True, plot magnitude

omega : array_like
omega : array_like, optional
Set of frequencies to be evaluated, in rad/sec.

omega_limits : array_like of two values
omega_limits : array_like of two values, optional
Limits to the range of frequencies. Ignored if omega is provided, and
auto-generated if omitted.

omega_num : int
omega_num : int, optional
Number of frequency samples to plot. Defaults to
config.defaults['freqplot.number_of_samples'].

color : string
plot : boolean, optional
If True (default), plot the Nyquist plot.

color : string, optional
Used to specify the color of the line and arrowhead.

return_contour : bool, optional
Expand Down Expand Up @@ -690,6 +690,13 @@ def nyquist_plot(
to `none` will turn off indentation. If `return_contour` is True, the
exact contour used for evaluation is returned.

3. For those portions of the Nyquist plot in which the contour is
indented to avoid poles, resuling in a scaling of the Nyquist plot,
the line styles are according to the settings of the `primary_style`
and `mirror_style` keywords. By default the scaled portions of the
primary curve use a dotted line style and the scaled portion of the
mirror image use a dashdot line style.

Examples
--------
>>> G = ct.zpk([], [-1, -2, -3], gain=100)
Expand Down
4 changes: 2 additions & 2 deletions control/matlab/wrappers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
import numpy as np
from ..iosys import ss
from ..xferfcn import tf
from ..ctrlutil import issys
from ..lti import LTI
from ..exception import ControlArgument
from scipy.signal import zpk2tf
from warnings import warn
Expand Down Expand Up @@ -124,7 +124,7 @@ def _parse_freqplot_args(*args):
i = 0
while i < len(args):
# Check to see if this is a system of some sort
if issys(args[i]):
if isinstance(args[i], LTI):
# Append the system to our list of systems
syslist.append(args[i])
i += 1
Expand Down
8 changes: 7 additions & 1 deletion control/tests/ctrlutil_test.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
"""ctrlutil_test.py"""

import numpy as np

import pytest
import control as ct
from control.ctrlutil import db2mag, mag2db, unwrap

class TestUtils:
Expand Down Expand Up @@ -58,3 +59,8 @@ def test_mag2db(self):
def test_mag2db_array(self):
db_array = mag2db(self.mag)
np.testing.assert_array_almost_equal(db_array, self.db)

def test_issys(self):
sys = ct.rss(2, 1, 1)
with pytest.warns(FutureWarning, match="deprecated; use isinstance"):
ct.issys(sys)
2 changes: 1 addition & 1 deletion control/tests/flatsys_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ def test_kinematic_car_ocp(
elif re.match("Iteration limit.*", traj_ocp.message) and \
re.match(
"conda ubuntu-3.* Generic", os.getenv('JOBNAME', '')) and \
re.match("1.24.[01]", np.__version__):
re.match("1.24.[012]", np.__version__):
pytest.xfail("gh820: iteration limit exceeded")

else:
Expand Down
15 changes: 8 additions & 7 deletions doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,12 @@
import re
import control

# Get the version number for this commmit (including alpha/beta/rc tags)
release = re.sub('^v', '', os.popen('git describe').read().strip())

# The short X.Y.Z version
version = re.sub(r'(\d+\.\d+\.\d+)(.*)', r'\1', control.__version__)
version = re.sub(r'(\d+\.\d+\.\d+(.post\d+)?)(.*)', r'\1', release)

# The full version, including alpha/beta/rc tags
release = control.__version__
print("version %s, release %s" % (version, release))

# -- General configuration ---------------------------------------------------
Expand Down Expand Up @@ -206,11 +207,10 @@ def linkcode_resolve(domain, info):
linespec = ""

base_url = "https://github.com/python-control/python-control/blob/"
if 'dev' in control.__version__:
if release != version: # development release
return base_url + "main/control/%s%s" % (fn, linespec)
else:
return base_url + "%s/control/%s%s" % (
control.__version__, fn, linespec)
else: # specific version
return base_url + "%s/control/%s%s" % (version, fn, linespec)

# Don't automaticall show all members of class in Methods & Attributes section
numpydoc_show_class_members = False
Expand Down Expand Up @@ -282,4 +282,5 @@ def linkcode_resolve(domain, info):
import control as ct
import control.optimal as obc
import control.flatsys as fs
ct.reset_defaults()
"""
Loading