Welcome to harold’s documentation!¶
harold
is an open-source control systems library for Python 3.6 and greater.
It implements operations to create, manipulate, and analyse dynamic models for
feedback control systems.
In addition to this documentation, you can also find Jupyter notebooks under
notebooks
folder.
Contents:¶
Introduction¶
This is the documentation for the harold
control systems toolbox. harold
is a package for Python3 designed to be completely open-source in order to
serve the mantra reproducible research.
The main goal of harold
is to provide accessible computation algorithms for
common control engineering tasks. For the academic use, the functions are
documented as much as possible with proper citations and inline comments to
demonstrate the strength and weaknesses(if any) for future improvements or
debugging convenience. More importantly, if an algorithm is flawed or lacking
performance, the user can directly modify since everything under the hood is
visible to the user.
Prerequisites¶
harold
works with Python with version >= 3.6
. It depends on the
packages numpy
, scipy>=1.0.0
, tabulate
, and matplotlib
.
Though harold
can be made to work on Python 3.5 too, by removing, mostly,
f-strings and related details, Python 3.6 is recommended to work with anyways.
Not only it would bring a lot of extras but also keeyword handling behavior is better and especially Windows systems would benefit from Unicode handling.
Installation¶
Installing harold is a straightforward package installation: you can install
the most recent harold
version using pip:
>>> pip install harold
If you have cloned the project from the GitHub repository for the latest development version then you can also install locally via
>>> python setup.py install
which will install the dev
version. To generate the documentation locally,
you will need Sphinx >=1.7.4
and cloud-sptheme>=1.9.4
. Then change the
directory to ../docs/
and then run
>>> make html
on a terminal/command prompt.
In order to benefit from harold
some acquaintance with NumPy and SciPy is
necessary. However, it is strongly recommended to get versed in these
impressive tools in any case.
Tip : An almost exhaustive NumPy cheat sheet
The following link is actually one of the first hits on any search engine but here it is for completeness. Please have some time spared to check out the differences between numpy and matlab syntax. It might even teach you a thing or two about matlab.
Development¶
The official development lives on harold GitHub repository. Please open an issue or submit your pull requests there. Feedback is always welcome. You can also leave a message on the Gitter chatroom
Please let the developers know about the problems you have encountered or features that you feel missing. That would help the roadmap greatly.
Function reference¶
harold
is a Python package that provides tools for analyzing feedback
control systems and designing controllers.
System creation¶
State (a[, b, c, d, dt]) |
A class for creating State space models. |
Transfer (num[, den, dt]) |
A class for creating Transfer functions. |
random_state_model (n[, p, m, dt, prob_dist, …]) |
Generates a continuous or discrete State model with random data. |
transfer_to_state (G[, output]) |
Converts a Transfer to a State |
state_to_transfer (*state_or_abcd[, output]) |
Converts a State to a Transfer |
Discretization¶
discretize (G, dt[, method, prewarp_at, q]) |
Continuous- to discrete-time model conversion. |
undiscretize (G[, method, prewarp_at, q]) |
Discrete- to continuous-time model conversion. |
Controller Design¶
lqr (G, Q[, R, S, weight_on]) |
A full-state static feedback control design solver for which the following quadratic cost function is integrated (summed) over all positive time axis |
ackermann (G, loc) |
Pole placement using Ackermann’s polynomial method. |
Model Functions¶
transmission_zeros (A, B, C, D) |
Computes the transmission zeros of State data arrays A , B , C , D |
system_norm (G[, p, hinf_tol, eig_tol]) |
Computes the system p-norm. |
cancellation_distance (F, G) |
Computes the upper and lower bounds of the perturbation needed to render the pencil \([F-pI | G]\) rank deficient. |
Kalman tests¶
controllability_matrix (G[, compress]) |
Computes the Kalman controllability and the transformation matrix. |
observability_matrix (G[, compress]) |
Computes the Kalman controllability and the transformation matrix. |
is_kalman_controllable (G) |
Tests the rank of the Kalman controllability matrix and compares it with the A matrix size, returns a boolean depending on the outcome. |
is_kalman_observable (G) |
Tests the rank of the Kalman observability matrix and compares it with the A matrix size, returns a boolean depending on the outcome. |
Time domain simulation¶
simulate_linear_system (sys, u[, t, x0, …]) |
Compute the linear model response to an input array sampled at given time instances. |
simulate_step_response (sys[, t]) |
Compute the linear model response to an Heaviside function (or all-ones array) sampled at given time instances. |
simulate_impulse_response (sys[, t]) |
Compute the linear model response to an Dirac delta pulse (or all-zeros array except the first sample being 1/dt at each channel) sampled at given time instances. |
impulse_response_plot (sys[, t]) |
Plots the impulse response of a model. |
step_response_plot (sys[, t]) |
Plots the step response of a model. |
Frequency domain simulation¶
frequency_response (G[, w, samples, w_unit, …]) |
Computes the frequency response of a State() or Transfer() representation. |
bode_plot (G[, w, use_db, use_hz, use_degree]) |
Draws the Bode plot of the system G. |
nyquist_plot (G[, w]) |
Draws the Nyquist plot of the system G. |
Model simplification tools¶
feedback (G, H[, negative]) |
Feedback interconnection of two models in the following configuration |
minimal_realization (G[, tol]) |
Given system realization G, this computes minimal realization such that if a State representation is given then the returned representation is controllable and observable within the given tolerance tol . |
hessenberg_realization (G[, compute_T, form, …]) |
A state transformation is applied in order to get the following form where A is a Hessenberg matrix and B (or C if ‘form’ is set to ‘o’ ) is row/col compressed |
staircase (A, B, C[, compute_T, form, …]) |
Given a state model data A, B, C, Returns the so-called staircase form State realization to assess the controllability/observability properties. |
kalman_decomposition (G[, compute_T, output, …]) |
By performing a sequence of similarity transformations the State representation is transformed into a special structure such that if the system has uncontrollable/unobservable modes, the corresponding rows/columns of the B/C matrices have zero blocks and the modes are isolated in the A matrix. |
Polynomial Operations¶
haroldgcd (*args) |
Takes 1D numpy arrays and computes the numerical greatest common divisor polynomial. |
haroldlcm (*args[, compute_multipliers, …]) |
Takes n-many 1D numpy arrays and computes the numerical least common multiple polynomial. |
haroldpolyadd (*args[, trim_zeros]) |
Similar to official polyadd from numpy but allows for multiple args and doesn’t invert the order, |
haroldpolymul (*args[, trim_zeros]) |
Simple wrapper around the NumPy convolve() function for polynomial multiplication with multiple args. |
haroldpolydiv (dividend, divisor) |
Polynomial division wrapped around scipy deconvolve function. |
haroldcompanion (somearray) |
Takes a 1D numpy array or list and returns the companion matrix of the monic polynomial of somearray. |
haroldker (N[, side]) |
This function is a straightforward basis computation for the right/left nullspace for rank deficient or fat/tall matrices. |
Auxillary Functions¶
matrix_slice (M, corner_shape[, corner]) |
Takes a two dimensional array M and slices into four parts dictated by the corner_shape and the corner string corner . |
e_i (width[, nth, output]) |
Returns the nth column(s) of the identity matrix with shape (width,width) . |
concatenate_state_matrices (G) |
Takes a State() model as input and returns the A, B, C, D matrices combined into a full matrix. |
haroldsvd (A[, also_rank, rank_tol]) |
This is a wrapper/container function of both the SVD decomposition and the rank computation. |
Additional Information¶
ChangeLog ============ v.1.0.1 ——- + Restructured documentation, now has a function reference template. + State and Transfer conversion with static cols/rows bugs fixed. + minimal_realization and staircase bugs fixed + random model creation in continuous and discrete time is possible. + pole placement via ackermann
v.1.0.0¶
- First public release
- Time domain plots and auto time sequence generation.
- Unit tests are significantly improved(>80%)
- Lots and lots of bug fixes.
- Change the documentation theme to guzzle
- Added first order hold discretization method
- Removed FAQ from docs
v.0.1.1rc1¶
- Unified State, Transfer checks via arg_utils
- Fixed transfer_to_state argument signature
- Added discretization and undiscretization funcs
- Separated the frequency domain computations and plotting
- Rewritten the frequency grid generation
- Fixed some of the unwrapping bugs
- Added lqr, dlqr, lqry and dlqry with a single signature
- Refactored minimal_realization related funcs.
- Fixed hinf-norm bugs
- Started time domain plots.
v0.1.1b5¶
- Requirement of NumPy is changed to 1.13 and above. Among others, we need __array_ufunc__ override mechanism for representation algebra. This should not be an issue since noone seems to use this.
- The representations can now be sliced with G[:,1:3] etc.
v0.1.1b4¶
- Sanitized the circular dependencies a bit more
- minimal_realization is changed to accept models instead of A,B,C triplet
- minimal_realization for Transfer uses the pole zero cancellation check
- more housekeeping and bug fixes
- added damping, natural frequency properties of poles
- state_to_transfer does not return minimal realizations (per request)
v0.1.1b3¶
- More tests
- bode, nyquist plots with matplotlib
- Rewritten the transmission_zeros to improve accuracy
- Removed the single file and replaced it with modular files.
- Refactored Riccati solvers to SciPy official repo
- Lyapunov solver safety net is moot. Created PR #6775 in SciPy
v0.1.1b2¶
- Added Riccati solvers
- More documentation
- Added safety net for lyapunov solvers in case there is no solution
v0.1.1b1¶
- Added Lyapunov solvers
- Fixed many bugs
- Removed block diag and switched to scipy version
v0.1.1a¶
- Initial versioning and packaging.
- Adding documentation and Sphinx integration.
- Basically everything there is.