Control Systems is a Python-first engineering toolkit for studying, reproducing, and extending continuous-time control systems workflows. The project is organized as a collection of focused command-line packages aligned with Ogata, Modern Control Engineering (5th ed.) and related classical and modern control systems topics.
Each package is designed to be practical, reproducible, and easy to run from the terminal. Inputs live in dedicated in/ folders, outputs are written to out/, and each tool includes copy-paste runnable examples through its local RUNS.md file.
The full Sphinx documentation is published here:
https://pablomarcel.github.io/control-systems/
This is a large, package-by-package documentation site. The links below point directly to the published documentation for each tool.
- control_systems/canonicalTool — Controllable and observable canonical-form transformations
- control_systems/converterTool — Transfer-function and state-space conversion workflows
- control_systems/mimoTool — MIMO interconnections, assembly helpers, and system coupling utilities
- control_systems/systemTool — SISO system construction, representation helpers, and workflow scaffolding
- frequency_response/bodeTool — Bode plots, gain margin, phase margin, bandwidth, and frequency-response helpers
- frequency_response/compensatorTool — Frequency-domain lead, lag, and lead-lag compensator design helpers
- frequency_response/experimentTool — Empirical frequency-response experiment scaffolding and FRF-oriented workflows
- frequency_response/plotTool — Nichols, polar, and frequency-response plotting utilities
- pid_controllers/pidTool — PID controller forms, gain handling, and response-oriented PID workflows
- pid_controllers/rootLocusTool — PID effects on root-locus behavior
- pid_controllers/tuningTool — PID tuning workflows including rule-based controller settings
- pid_controllers/zeroPoleTool — Pole-zero editing, interpretation, and visualization helpers
- root_locus_analysis/compensatorTool — Lead, lag, and lead-lag compensator design helpers
- root_locus_analysis/rootLocusTool — Root-locus generation, gain sweeps, and pole migration analysis
- root_locus_analysis/systemResponseTool — Closed-loop response comparisons for candidate gains and compensators
- state_space_analysis/canonicalTool — State-space canonical-form transformations
- state_space_analysis/converterTool — Transfer-function/state-space conversion tools
- state_space_analysis/mimoTool — MIMO state-space assembly and analysis helpers
- state_space_analysis/stateRepTool — State representation utilities
- state_space_analysis/stateSolnTool — State-transition solutions and
Phi(t)-style workflows - state_space_analysis/stateTool — Matrix parsing, invariants, ranks, controllability, observability, and norms
- state_space_analysis/stateTransTool — Similarity transforms and state-coordinate transformation helpers
- state_space_design/controllerTool — Full-state feedback controller design
- state_space_design/gainMatrixTool — Pole placement and gain-matrix workflows
- state_space_design/lqrTool — Linear quadratic regulator design workflows
- state_space_design/minOrdTfTool — Minimal-order transfer-function synthesis helpers
- state_space_design/minOrdTool — Minimal-order observer workflows
- state_space_design/observerGainMatrixTool — Luenberger observer gain design
- state_space_design/observerStatePlotTool — Measured-vs-estimated state plotting
- state_space_design/regulatorTool — Regulator forms, tracking structures, and integral-action workflows
- state_space_design/robustTool — Robust-control-oriented scaffolding and design templates
- state_space_design/servoTool — Augmented servo design and command-tracking workflows
- state_space_design/statePlotsTool — State-space plotting utilities
- transient_analysis/hurwitzTool — Hurwitz determinants, leading minors, and stability checks
- transient_analysis/icTool — Initial-condition handling for state and output response workflows
- transient_analysis/responseTool — Step, impulse, ramp, and transient-response metrics
- transient_analysis/routhTool — Routh-Hurwitz arrays, sign-change checks, symbolic stability regions, and verification helpers
This repository is built around a simple idea: control systems calculations should be reproducible, inspectable, and scriptable.
The project aims to provide:
- Clean Python implementations of common control systems workflows
- CLI tools for repeatable analysis and design runs
- JSON/CSV-based input and output conventions
- Plot exports for reports, documentation, and engineering review
- Testable package boundaries for incremental development
- A study-friendly structure that follows the progression of modern control systems topics
- Package-level Sphinx documentation published through GitHub Pages
The intent is not only to compute answers, but to make the modeling, analysis, and design process visible through structured inputs, transparent outputs, and repeatable commands.
The repository is organized by control systems topic. The package folder names match the published GitHub Pages documentation paths.
control_systems/
canonicalTool/
converterTool/
mimoTool/
systemTool/
frequency_response/
bodeTool/
compensatorTool/
experimentTool/
plotTool/
pid_controllers/
pidTool/
rootLocusTool/
tuningTool/
zeroPoleTool/
root_locus_analysis/
compensatorTool/
rootLocusTool/
systemResponseTool/
state_space_analysis/
canonicalTool/
converterTool/
mimoTool/
stateRepTool/
stateSolnTool/
stateTool/
stateTransTool/
state_space_design/
controllerTool/
gainMatrixTool/
lqrTool/
minOrdTfTool/
minOrdTool/
observerGainMatrixTool/
observerStatePlotTool/
regulatorTool/
robustTool/
servoTool/
statePlotsTool/
transient_analysis/
hurwitzTool/
icTool/
responseTool/
routhTool/
Each subfolder is intended to behave as a cohesive package with:
- A CLI entry point
- Example input files
- Reproducible output conventions
- Local
RUNS.mdcommands - Tests where applicable
- Sphinx documentation hooks for GitHub Pages
Depending on the package, the tools can support workflows such as:
- Building transfer-function and state-space representations
- Converting between transfer functions and state-space forms
- Constructing canonical forms
- Assembling MIMO systems
- Computing transient responses
- Extracting step-response metrics
- Building Routh arrays and Hurwitz determinant checks
- Generating root-locus plots
- Comparing closed-loop candidate gains
- Designing lead, lag, and lead-lag compensators
- Generating Bode, Nichols, and polar plots
- Estimating gain margin, phase margin, and bandwidth
- Tuning PID controllers
- Designing state-feedback controllers
- Computing observer gains
- Building regulator and servo configurations
- Solving LQR design cases
- Exporting plots, tables, JSON manifests, and CSV data
The project emphasizes command-line execution so that analysis runs can be copied, reviewed, versioned, and repeated.
Typical workflows are built around commands such as:
python cli.py --help
python cli.py run --infile in/example.json --outfile out/example_out.json --prettyWhere possible, tools also support running from the repository root with module-style invocation:
python -m root_locus_analysis.rootLocusTool.cli --help
python -m transient_analysis.routhTool.cli run --coeffs "1,5,6,K" --symbol K --solve-for KMost packages follow a consistent file convention:
in/ # Input files: JSON, CSV, YAML, TXT, or other supported formats
out/ # Output files: JSON, CSV, PNG, HTML, and generated artifacts
RUNS.md # Copy-paste commands for the package
This keeps examples inspectable and makes it easier to compare results across revisions.
Numerical results are intended to be useful both in the terminal and in downstream workflows. Many tools support some combination of:
- Console summaries
- JSON output manifests
- CSV tables
- Matplotlib PNG exports
- Plotly HTML exports
- Logs suitable for debugging and review
JSON output is generally treated as the primary machine-readable result. CSV exports are used for tabular data, while PNG and HTML exports are used for plots and engineering review artifacts.
# 1) Clone the repository
git clone https://github.com/pablomarcel/control-systems.git
cd control-systems
# 2) Create and activate a virtual environment
python -m venv .venv
source .venv/bin/activate # macOS/Linux
# .venv\Scripts\activate # Windows PowerShell/CMD
# 3) Install dependencies
pip install -U pip
pip install -r requirements.txt
# 4) Enter a package and inspect the CLI
cd root_locus_analysis/rootLocusTool
python cli.py --help
# 5) Use the local RUNS.md for copy-paste examples
cat RUNS.mdcd transient_analysis/routhTool
python cli.py run \
--coeffs "1,5,6,K" \
--symbol K \
--solve-for K \
--hurwitz \
--export cubic_gaincd root_locus_analysis/rootLocusTool
python cli.py --helpcd frequency_response/bodeTool
python cli.py --helpcd state_space_design/gainMatrixTool
python cli.py --helpRun tests for a specific tool from the repository root:
pytest root_locus_analysis/rootLocusTool/tests \
--cov \
--cov-config=root_locus_analysis/rootLocusTool/.coveragerc \
--cov-report=term-missingFor broader refactors, run the relevant package test suites before committing changes.
The documentation is generated with Sphinx and published to GitHub Pages.
The live site is:
https://pablomarcel.github.io/control-systems/
The GitHub Actions workflow for documentation publishing lives here:
https://github.com/pablomarcel/control-systems/actions/workflows/pages.yml
When package APIs, CLI behavior, examples, or docstrings change, update the package documentation and verify the docs build before pushing.
Typical package layout:
someTool/
cli.py
apis.py
core.py
io.py
utils.py
in/
example_input.json
out/
example_output.json
tests/
RUNS.md
docs/
Common conventions:
- Input files are stored in
in/ - Generated outputs are stored in
out/ - CLI examples are documented in
RUNS.md - JSON output is treated as the primary machine-readable result
- CSV exports are used for tabular data
- PNG and HTML exports are used for plots and reports
- Sphinx documentation is kept package-focused and published through the main GitHub Pages site
Depending on the package, the tools may generate:
- Transfer functions
- State-space matrices
- Pole-zero summaries
- Stability tables
- Routh arrays
- Hurwitz determinant tables
- Response metrics
- Gain and compensator tables
- Time-history data
- Frequency-response data
- Static plots as PNG
- Interactive plots as HTML
- JSON manifests for repeatable analysis
The project has been developed primarily with:
- Python 3.13
- NumPy 2.x
- SciPy 1.15.x
- SymPy 1.13.x
- matplotlib 3.10.x
- plotly 5.x
- python-control 0.10.x
- macOS 13.7
- Windows 10/11
See requirements.txt for dependency details.
When adding or modifying a tool:
- Keep the CLI behavior explicit and documented
- Add or update examples in
in/ - Keep generated artifacts under
out/ - Update the local
RUNS.md - Add tests for new solver behavior
- Keep JSON outputs stable where possible
- Keep documentation links aligned with the published GitHub Pages paths
- Prefer focused modules over large, tightly coupled scripts
Suggested pull request checklist:
- CLI command documented in
RUNS.md -
python cli.py --helpreflects new or changed flags - New example input added under
in/ - Output behavior verified under
out/ - Tests added or updated
- Relevant documentation updated
- Sphinx build verified
- README documentation links still point to
https://pablomarcel.github.io/control-systems/
Planned and ongoing areas of development include:
- Expanded textbook example coverage
- More complete MIMO workflows
- Improved state-space design utilities
- Additional compensator design helpers
- More robust plotting and export options
- Expanded GitHub Pages documentation
- Additional validation tests against known examples
- More consistent package-level examples, command manifests, and Sphinx pages
Released under the MIT License. See LICENSE for details.
This project is informed by standard control systems education and references, especially:
- K. Ogata, Modern Control Engineering (5th ed.)
- The Python scientific computing ecosystem, including NumPy, SciPy, SymPy, matplotlib, plotly, and python-control