A Python tool for validating whether an LQR controller satisfies performance requirements in a multivariable control system. The program checks state constraints, computes the maximum control effort, and prints a clear console summary with visual pass/fail indicators.
This project was developed as support material for Linear Control II / Multivariable Systems, especially for analyzing and comparing LQR designs obtained from different weighting matrices Q and R.
- Overview
- Controlled System
- Features
- Requirements
- Installation
- Usage
- Verification Logic
- Console Output
- Recommended Project Structure
- Suggested
requirements.txt - Future Improvements
- License
The program evaluates two main conditions of the controller:
-
State constraint compliance
It verifies whether the maximum system states after a specified analysis time remain below the limits defined by the user. -
Control input / force constraint compliance
It computes the maximum absolute value of the control inputs during the simulation and checks whether they remain within the allowed range.
The final result gives a quick indication of whether the LQR design is feasible in terms of both dynamic performance and actuator effort.
The controller is tested on a multivariable cart-pendulum mechanical system composed of two moving carts, two actuators, coupling elements, and a pendulum attached to the second cart. The diagram below helps connect the mathematical model with the physical variables used in the simulation.
Figure 1. Multivariable cart-pendulum system with two translational coordinates, two control forces, coupling dynamics, and pendulum motion.
Main physical elements represented in the system:
| Symbol | Meaning |
|---|---|
M1, M2 |
Moving cart masses. |
x1, x2 |
Translational positions of the carts. |
F1, F2 |
Control forces generated by the actuators. |
d1, d2 |
Damping elements. |
k12 |
Coupling stiffness between the carts. |
m_p |
Pendulum mass. |
theta |
Pendulum angular displacement. |
L |
Pendulum length. |
Including the physical diagram makes the repository easier to understand because the reader can relate the code variables, state constraints, and control-input limits to the actual system being controlled.
- Automatic verification of state constraints.
- Maximum absolute control effort calculation.
- Direct comparison against user-defined limits.
- Clean console output using green/red background indicators.
- Compatible with
NumPyarrays. - Useful for iterative tuning of the LQR weighting matrices
QandR. - Includes a system diagram to make the physical setup easier to understand.
- Simple, readable, and easy to adapt to other multivariable systems.
Basic dependencies:
numpy
coloramaOptional dependencies, depending on the complete version of the project:
matplotlib
scipy
controlThese libraries may be required if the project includes simulations, plots, state-space modeling, or direct computation of LQR gains.
Clone the repository:
git clone https://github.com/your-username/your-repository.git
cd your-repositoryCreate a virtual environment:
python -m venv venvActivate the virtual environment.
On Windows:
venv\Scripts\activateOn Linux or macOS:
source venv/bin/activateInstall the required dependencies:
pip install numpy coloramaIf your project also includes simulations, plots, or the python-control package, install:
pip install matplotlib scipy controlRun the main project file:
python main.pyIf your main file has a different name, replace main.py with the correct filename:
python your_file_name.pyThe program prints a validation summary similar to the following:
----------------------------------------
LQR Control Requirements Check:
State limits:
[...]
Maximum states after 2 seconds:
[...]
States requirement OK?
true
Force limits:
[...]
Maximum forces:
[...]
Force requirement OK?
false
In compatible terminals, true is displayed with a green background and false with a red background.
State validation is performed by comparing the maximum state values obtained after the analysis time against the allowed limits:
state_ok = np.all(max_state_after_2s <= xi_max)Force or control-input validation first computes the maximum absolute value of each control input:
max_forces = np.max(np.abs(u_history), axis=1)
forces_ok = np.all(max_forces <= u_max)Where:
| Variable | Description |
|---|---|
xi_max |
Maximum allowed limits for the system states. |
max_state_after_2s |
Maximum state values reached after the analysis time. |
u_history |
Time history of the control inputs or actuator forces. |
u_max |
Maximum allowed limits for the control inputs or actuator forces. |
state_ok |
Boolean result of the state constraint verification. |
forces_ok |
Boolean result of the force/control-input constraint verification. |
max_forces |
Vector containing the maximum absolute values of the applied forces. |
To improve readability, the project uses a helper function that prints boolean indicators with colored backgrounds:
from colorama import init
init(autoreset=True)
def bg_rgb(r, g, b):
return f"\033[48;2;{r};{g};{b}m"
RESET = "\033[0m"
def print_colorama(ok):
if ok:
print(f"{bg_rgb(35, 100, 65)} true {RESET}")
else:
print(f"{bg_rgb(120, 45, 45)} false {RESET}")Note: ANSI terminal backgrounds do not support real transparency. The function uses soft RGB colors to create a cleaner and more modern appearance instead of saturated solid backgrounds.
For a simple version of the project:
.
├── assets/
│ └── cartpole_multivariable_system.png
├── main.py
├── requirements.txt
└── README.md
For a more organized version:
.
├── assets/
│ └── cartpole_multivariable_system.png
├── src/
│ ├── controller.py
│ ├── simulation.py
│ └── utils.py
├── results/
│ └── figures/
├── main.py
├── requirements.txt
└── README.md
A possible file separation would be:
assets/: Static images used by the README and documentation.controller.py: LQR gain computation and system matrix definitions.simulation.py: Time-domain simulation of the controlled system.utils.py: Helper functions, output formatting, and validation logic.results/figures/: Generated plots and analysis figures.
numpy
colorama
matplotlib
scipy
controlIf your project does not use one of these libraries, remove it from the file to keep the environment lighter.
- Add automatic plots for states and control inputs.
- Export validation results to
.csvfiles. - Compare multiple LQR designs in a single execution.
- Automatically save the
Q,R,K, and simulation results. - Add command-line arguments for limits, analysis time, or controller parameters.
- Implement unit tests for the validation logic.
- Generate automatic reports with tables and figures.
- Include additional diagrams for the mathematical model, state variables, and control architecture.
This project can be distributed under the MIT License. Modify this section if your course, laboratory, or repository requires a different license.
