A GitHub startup repository for a project on LQR stabilization of a vibrating square membrane with a single localized actuator.
The mathematical heart is a controlled wave equation on the unit square,
with fixed boundary conditions ( u = 0 ) on the boundary. After expanding in sine eigenfunctions and truncating to finitely many modes, the PDE becomes a linear state-space system
for which one can design an infinite-horizon LQR feedback
This repository is set up so students can move from theory to code without having to build the whole scaffolding from scratch.
handout/handout.tex- project handout in LaTeXhandout/handout.pdf- compiled PDF handoutsrc/python/modal_lqr.py- Python starter library plus demo driversrc/python/run_demo.py- generate plots and optional animation framessrc/python/scan_actuator.py- compare actuator locationstests/test_coupling.py- basic coupling teststests/test_reconstruction.py- basic reconstruction testsPROJECT_TASKS.md- student-facing milestones and suggested checkpointsrequirements.txt- Python dependencies
For the unit square with Dirichlet boundary conditions, the Laplacian eigenfunctions are
with eigenvalues
If the actuator is idealized as a point actuator at ( (x_0,y_0) ), then the modal coupling coefficient is
A centered actuator at ( (1/2, 1/2) ) misses every mode with even ( m ) or even ( n ), so this repo uses an off-center default actuator at ( (0.37, 0.61) ).
- Read the handout and derive the modal equations.
- Build ( A ), ( B ), and the LQR gain ( K ).
- Simulate a closed-loop response for a chosen initial condition.
- Reconstruct the membrane shape on a grid.
- Compare at least two actuator locations.
- Discuss which modes are poorly actuated or completely missed.
The file PROJECT_TASKS.md turns this into a week-by-week sequence.
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
python -m src.python.run_demoThis will create an outputs/ directory containing:
- energy-vs-time plot
- control-vs-time plot
- membrane snapshots
- an optional GIF animation if Pillow is available
To compare actuator locations,
python -m src.python.scan_actuator- How does actuator location affect controllability of the truncated system?
- What happens if the actuator is placed at the center?
- How sensitive is the closed-loop performance to the weights in the LQR cost?
- How many modes are needed before the qualitative behavior stabilizes?
- How does a localized actuator patch compare with the ideal point-actuator model?
This repo deliberately sits in a sweet spot between PDEs and control:
- the PDE model is genuine,
- the eigenfunctions are explicit,
- the numerical implementation is manageable,
- symmetry obstructions show up clearly.
The project can be assigned at different levels:
- intro control / numerical methods: derive and simulate the truncated system,
- advanced PDE/control: discuss stabilizability and symmetry,
- computational project: compare point actuation and patch actuation, animate the membrane, and scan actuator locations.
.
├── handout
│ ├── handout.aux
│ ├── handout.log
│ ├── handout.out
│ ├── handout.pdf
│ └── handout.tex
├── outputs
│ ├── control.png
│ ├── energy.png
│ ├── membrane.gif
│ ├── snapshot_t_0.00.png
│ ├── snapshot_t_0.51.png
│ ├── snapshot_t_1.50.png
│ ├── snapshot_t_2.99.png
│ └── snapshot_t_6.00.png
├── PROJECT_TASKS.md
├── README.md
├── requirements.txt
├── src
│ └── python
│ ├── __init__.py
│ ├── modal_lqr.py
│ ├── __pycache__
│ │ ├── __init__.cpython-313.pyc
│ │ ├── modal_lqr.cpython-313.pyc
│ │ ├── run_demo.cpython-313.pyc
│ │ └── scan_actuator.cpython-313.pyc
│ ├── run_demo.py
│ └── scan_actuator.py
└── tests
├── conftest.py
├── __pycache__
│ ├── conftest.cpython-313-pytest-8.3.5.pyc
│ ├── conftest.cpython-313-pytest-9.0.2.pyc
│ ├── test_coupling.cpython-313-pytest-8.3.5.pyc
│ ├── test_coupling.cpython-313-pytest-9.0.2.pyc
│ ├── test_reconstruction.cpython-313-pytest-8.3.5.pyc
│ └── test_reconstruction.cpython-313-pytest-9.0.2.pyc
├── test_coupling.py
└── test_reconstruction.py
