A RetroSearch Logo

Home - News ( United States | United Kingdom | Italy | Germany ) - Football scores

Search Query:

Showing content from https://python-control.readthedocs.io/en/stable/develop.html below:

Website Navigation


Developer Notes — Python Control Systems Library 0.10.2 documentation

Developer Notes

This chapter contains notes for developers who wish to contribute to the Python Control Systems Library (python-control). It is mainly a listing of the practices that have evolved over the course of development since the package was created in 2009.

Package Structure

The python-control package is maintained on GitHub, with documentation hosted by ReadTheDocs and a mailing list on SourceForge:

GitHub repository file and directory layout:
Naming Conventions

Generally speaking, standard Python and NumPy naming conventions are used throughout the package.

Filenames Class names Function names Parameter names

Parameter names are not (yet) very uniform across the package. A few general patterns are emerging:

System-creating commands:

System arguments:

Signal arguments:

Order of arguments for functions taking inputs, outputs, state, time, frequency, etc:

Time and frequency responses:

Parameter aliases

As described above, parameter names are generally longer strings that describe the purpose of the parameter. Similar to matplotlib (e.g., the use of lw as an alias for linewidth), some commonly used parameter names can be specified using an “alias” that allows the use of a shorter key.

Named parameter and keyword variable aliases are processed using the config._process_kwargs() and config._process_param() functions. These functions allow the specification of a list of aliases and a list of legacy keys for a given named parameter or keyword. To make use of these functions, the _process_kwargs() is first called to update the kwargs variable by replacing aliases with the full key:

_process_kwargs(kwargs, aliases)

The values for named parameters can then be assigned to a local variable using a call to _process_param() of the form:

var = _process_param('param', param, kwargs, aliases)

where param is the named parameter used in the function signature and var is the local variable in the function (may also be param, but doesn’t have to be).

For example, the following structure is used in input_output_response:

def input_output_response(
        sys, timepts=None, inputs=0., initial_state=0., params=None,
        ignore_errors=False, transpose=False, return_states=False,
        squeeze=None, solve_ivp_kwargs=None, evaluation_times='T', **kwargs):
    """Compute the output response of a system to a given input.

    ... rest of docstring ...

    """
    _process_kwargs(kwargs, _timeresp_aliases)
    T = _process_param('timepts', timepts, kwargs, _timeresp_aliases)
    U = _process_param('inputs', inputs, kwargs, _timeresp_aliases, sigval=0.)
    X0 = _process_param(
        'initial_state', initial_state, kwargs, _timeresp_aliases, sigval=0.)

Note that named parameters that have a default value other than None must given the signature value (sigval) so that _process_param can detect if the value has been set (and issue an error if there is an attempt to set the value multiple times using alias or legacy keys).

The alias mapping is a dictionary that returns a tuple consisting of valid aliases and legacy aliases:

alias_mapping = {
    'argument_name_1': (['alias', ...], ['legacy', ...]),
     ...}

If an alias is present in the dictionary of keywords, it will be used to set the value of the argument. If a legacy keyword is used, a warning is issued.

The following tables summarize the aliases that are currently in use through the python-control package:

Time response aliases (via timeresp._timeresp_aliases):

Key

Aliases

Legacy keys

Comment

evaluation_times

t_eval

List of times to evaluate the time response (defaults to timepts).

final_output

yfinal

Final value of the output (used for step_info())

initial_state

X0

x0

Initial value of the state variable.

input_indices

input

Index(es) to use for the input (used in step_response(), impulse_response().

inputs

U

u

Value(s) of the input variable (time trace or individual point).

output_indices

output

Index(es) to use for the output (used in step_response(), impulse_response().

outputs

Y

y

Value(s) of the output variable (time trace or individual point).

return_states

return_x

Return the state when accessing a response via a tuple.

timepts

T

List of time points for time response functions.

timepts_num

T_num

Number of points to use (e.g., if timepts is just the final time).

Optimal control aliases (via optimal._optimal_aliases:

Key

Aliases

Comment

final_state

xf

Final state for trajectory generation problems (flatsys, optimal).

final_input

uf

Final input for trajectory generation problems (flatsys).

initial_state

x0, X0

Initial state for optimization problems (flatsys, optimal).

initial_input

u0, U0

Initial input for trajectory generation problems (flatsys).

initial_time

T0

Initial time for optimization problems.

integral_cost

trajectory_cost, cost

Cost function that is integrated along a trajectory.

return_states

return_x

Return the state when accessing a response via a tuple.

trajectory_constraints

constraints

List of constraints that hold along a trajectory (flatsys, optimal)

Documentation Guidelines

The python-control package is documented using docstrings and Sphinx. Reference documentation (class and function descriptions, with details on parameters) should all go in docstrings. User documentation in more narrative form should be in the rst files in doc/, where it can be incorporated into the User Guide. All significant functionality should have a narrative description in the User Guide in addition to docstrings.

Generally speaking, standard Python and NumPy documentation conventions are used throughout the package:

General docstring info

The guiding principle used to guide how docstrings are written is similar to NumPy (as articulated in the numpydoc style guide):

A guiding principle is that human readers of the text are given precedence over contorting docstrings so our tools produce nice output. Rather than sacrificing the readability of the docstrings, we have written pre-processors to assist Sphinx in its task.

To that end, docstrings in python-control should use the following guidelines:

Examples of different styles:

Function docstrings

Follow numpydoc format with the following additional details:

For functions that return a named tuple, bundle object, or class instance, the return documentation should include the primary elements of the return value:

Returns
-------
resp : `TimeResponseData`
    Input/output response data object.  When accessed as a tuple, returns
    ``time, outputs`` (default) or ``time, outputs, states`` if
    `return_states` is True.  The `~TimeResponseData.plot` method can be
    used to create a plot of the time response(s) (see `time_response_plot`
    for more information).
resp.time : array
    Time values of the output.
resp.outputs : array
    Response of the system.  If the system is SISO and `squeeze` is not
    True, the array is 1D (indexed by time).  If the system is not SISO or
    `squeeze` is False, the array is 2D (indexed by output and time).
resp.states : array
    Time evolution of the state vector, represented as a 2D array indexed by
    state and time.
resp.inputs : array
    Input(s) to the system, indexed by input and time.
Class docstrings

Follow numpydoc format with the follow additional details:

I/O system classes:

User Guide

The purpose of the User Guide is provide a narrative description of the key functions of the package. It is not expected to cover every command, but should allow someone who knows about control system design to get up and running quickly.

The User Guide consists of chapters that are each their own separate rst file and each of them generates a separate page. Chapters are divided into sections whose names appear in the index on the left of the web page when that chapter is being viewed. In some cases a section may be in its own file, included in the chapter page by using the include directive (see nlsys.py for an example).

Sphinx files guidelines:

Reference Manual

The Reference Manual should provide a fairly comprehensive description of every class, function, and configuration variable in the package. All primary functions and classes bust be included here, since the Reference Manual generates the stub files used by Sphinx.

Modules and subpackages

When documenting (independent) modules and subpackages (refereed to here collectively as modules), use the following guidelines for documentation:

The main overarching principle should be to make sure that references to objects that have more detailed information should show up as a link, not as code.

Utility Functions

The following utility functions can be used to help with standard processing and parsing operations:

config._process_legacy_keyword(kwargs, ...)

Utility function for processing legacy keywords.

config._process_kwargs(kwargs, alias_mapping)

Process aliases and legacy keywords.

config._process_param(name, defval, kwargs, ...)

Process named parameter, checking aliases and legacy usage.

exception.cvxopt_check()

Return True if cvxopt is installed, otherwise False.

exception.pandas_check()

Return True if pandas is installed, otherwise False.

exception.slycot_check()

Return True if Slycot is installed, otherwise False.

iosys._process_iosys_keywords([keywords, ...])

Process iosys specification.

mateqn._check_shape(M, n, m[, square, ...])

Check the shape and properties of a 2D array.

statesp._convert_to_statespace(sys[, ...])

Convert a system to state space form (if needed).

statesp._ssmatrix(data[, axis, square, ...])

Convert argument to a (possibly empty) 2D state space matrix.

xferfcn._convert_to_transfer_function(sys[, ...])

Convert a system to transfer function form (if needed).

Sample Files Code template

The following file is a template for a python-control module. It can be found in python-control/doc/examples/template.py.

  1# template.py - template file for python-control module
  2# RMM, 3 Jan 2024
  3
  4"""Template file for python-control module.
  5
  6This file provides a template that can be used when creating a new
  7file/module in python-control.  The key elements of a module are included
  8in this template, following the suggestions in the Developer Guidelines.
  9
 10The first line of a module file should be the name of the file and a short
 11description.  The next few lines can contain information about who created
 12the file (your name/initials and date).  For this file I used the short
 13version (initials, date), but a longer version would be to do something of
 14the form::
 15
 16  # filename.py - short one line description
 17  #
 18  # Initial author: Full name
 19  # Creation date: date the file was created
 20
 21After the header comments, the next item is the module docstring, which
 22should be a multi-line comment, like this one.  The first line of the
 23comment is a one line summary phrase, starting with a capital letter and
 24ending in a period (often the same as the line at the very top).  The rest
 25of the docstring is an extended summary (this one is a bit longer than
 26would be typical).
 27
 28After the docstring, you should have the following elements (in Python):
 29
 30  * Package imports, using the `isort -m2` format (library, standard, custom)
 31  * __all__ command, listing public objects in the file
 32  * Class definitions (if any)
 33  * Public function definitions
 34  * Internal function definitions (starting with '_')
 35  * Function aliases (short = long_name)
 36
 37The rest of this file contains examples of these elements.
 38
 39"""
 40
 41import warnings                 # Python packages
 42
 43import numpy as np              # Standard external packages
 44
 45from . import config            # Other modules/packages in python-control
 46from .lti import LTI            # Public function or class from a module
 47
 48__all__ = ['SampleClass', 'sample_function']
 49
 50
 51class SampleClass():
 52    """Sample class in the python-control package.
 53
 54    This is an example of a class definition.  The docstring follows
 55    numpydoc format.  The first line should be a summary (which will show
 56    up in `autosummary` entries in the Sphinx documentation) and then an
 57    extended summary describing what the class does.  Then the usual
 58    sections, per numpydoc.
 59
 60    Additional guidelines on what should be listed in the various sections
 61    can be found in the 'Class docstrings' section of the Developer
 62    Guidelines.
 63
 64    Parameters
 65    ----------
 66    sys : InputOutputSystem
 67        Short description of the parameter.
 68
 69    Attributes
 70    ----------
 71    data : array
 72         Short description of an attribute.
 73
 74    """
 75    def __init__(self, sys):
 76        # No docstring required here
 77        self.sys = sys          # Parameter passed as argument
 78        self.data = sys.name    # Attribute created within class
 79
 80    def sample_method(self, data):
 81        """Sample method within a class.
 82
 83        This is an example of a method within a class.  Document using
 84        numpydoc format.
 85
 86        """
 87        return None
 88
 89
 90def sample_function(data, option=False, **kwargs):
 91    """Sample function in the template module.
 92
 93    This is an example of a public function within the template module.
 94    This function will usually be placed in the `control` namespace by
 95    updating `__init__.py` to import the function (often by importing the
 96    entire module).
 97
 98    Docstring should be in standard numpydoc format.  The extended summary
 99    (this text) should describe the basic operation of the function, with
100    technical details in the "Notes" section.
101
102    Parameters
103    ----------
104    data : array
105         Sample parameter for sample function, with short docstring.
106    option : bool, optional
107         Optional parameter, with default value `False`.
108
109    Returns
110    -------
111    out : float
112        Short description of the function output.
113
114    Additional Parameters
115    ---------------------
116    inputs : int, str, or list of str
117        Parameters that are less commonly used, in this case a keyword
118        parameter.
119
120    See Also
121    --------
122    function1, function2
123
124    Notes
125    -----
126    This section can contain a more detailed description of how the system
127    works.  OK to include some limited mathematics, either via inline math
128    directions for a short formula (like this: ..math:`x = \alpha y`) or via a
129    displayed equation:
130
131    ..math::
132
133        a = \int_0^t f(t) dt
134
135    The trick in the docstring is to write something that looks good in
136    pure text format but is also processed by sphinx correctly.
137
138    If you refer to parameters, such as the `data` argument to this
139    function, but them in single backticks (which will render them in code
140    style in Sphinx).  Strings that should be interpreted as Python code
141    use double backticks: ``mag, phase, omega = response``.  Python
142    built-in objects, like True, False, and None are written on their own.
143
144    """
145    inputs = kwargs['inputs']
146    if option is True:
147        return data
148    else:
149        return None
150
151#
152# Internal functions
153#
154# Functions that are not intended for public use can go anyplace, but I
155# usually put them at the bottom of the file (out of the way).  Their name
156# should start with an underscore.  Docstrings are optional, but if you
157# don't include a docstring, make sure to include comments describing how
158# the function works.
159#
160
161
162# Sample internal function to process data
163def _internal_function(data):
164    return None
165
166
167# Aliases (short versions of long function names)
168sf = sample_function
Documentation template

The following file is a template for a documentation file. It can be found in python-control/doc/examples/template.rst.

 1.. currentmodule:: control
 2
 3**************
 4Sample Chapter
 5**************
 6
 7This is an example of a top-level documentation file, which serves a
 8chapter in the User Guide or Reference Manual in the Sphinx
 9documentation.  It is not that likely we will create a lot more files
10of this sort, so it is probably the internal structure of the file
11that is most useful.
12
13The file in which a chapter is contained will usual start by declaring
14`currentmodule` to be `control`, which will allow text enclosed in
15backticks to be searched for class and function names and appropriate
16links inserted.  The next element of the file is the chapter name,
17with asterisks above and below.  Chapters should have a capitalized
18title and an introductory paragraph.  If you need to add a reference
19to a chapter, insert a sphinx reference (`.. _ch-sample:`) above
20the chapter title.
21
22.. _sec-sample:
23
24Sample Section
25==============
26
27A chapter is made of up of multiple sections.  Sections use equal
28signs below the section title.  Following FBS2e, the section title
29should be capitalized.  If you need to insert a reference to the
30section, put that above the section title (`.. _sec-sample:`), as
31shown here.
32
33
34Sample subsection
35-----------------
36
37Subsections use dashes below the subsection title.  The first word of
38the title should be capitalized, but the rest of the subsection title
39is lower case (unless it has a proper noun).  I usually leave two
40blank lines before the start up a subection and one blank line after
41the section markers.
42
43
44Mathematics
45-----------
46
47Mathematics can be uncluded using the `math` directive.  This can be
48done inline using `:math:short formula` (e.g. :math:`a = b`) or as a
49displayed equation, using the `.. math::` directive::
50
51.. math::
52
53     a(t) = \int_0^t b(\tau) d\tau
54
55
56Function summaries
57------------------
58
59Use the `autosummary` directive to include a table with a list of
60function sinatures and summary descriptions::
61
62.. autosummary::
63
64   input_output_response
65   describing_function
66   some_other_function
67
68
69Module summaries
70----------------
71
72If you have a docstring at the top of a module that you want to pull
73into the documentation, you can do that with the `automodule`
74directive:
75
76.. automodule:: control.optimal
77   :noindex:
78   :no-members:
79   :no-inherited-members:
80   :no-special-members:
81
82.. currentmodule:: control
83
84The `:noindex:` option gets rid of warnings about a module being
85indexed twice.  The next three options are used to just bring in the
86summary and extended summary in the module docstring, without
87including all of the documentation of the classes and functions in the
88module.
89
90Note that we `automodule` will set the current module to the one for
91which you just generated documentation, so the `currentmodule` should
92be reset to control afterwards (otherwise references to functions in
93the `control` namespace won't be recognized.

RetroSearch is an open source project built by @garambo | Open a GitHub Issue

Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo

HTML: 3.2 | Encoding: UTF-8 | Version: 0.7.4