A C++ simulation of a 1D mass-spring-damper system with PID control and anti-windup. Python scripts handle visualization and automated parameter sweeps to find optimal gains.
The plant simulates a mass-spring-damper governed by:
where
The controller computes the input force as:
where
├── CMakeLists.txt # Build system (C++17, CMake 3.16+)
├── include/
│ ├── plant.hpp # MassSpringDamper class and State struct
│ └── export_data.hpp # Sample struct and CSV export function
├── src/
│ ├── main.cpp # Simulation entry point, PID logic, CLI parsing
│ ├── plant.cpp # RK4 integration and system dynamics
│ └── export_data.cpp # CSV writer
├── scripts/
│ ├── plot_results.py # Plot position/force, compute response metrics, rank results
│ └── sweep.py # Automated parameter sweep over kp/kd/ki ranges
└── data/ # Output CSV files
mkdir build && cd build
cmake ..
make./build/sim --sp 1 --kp 20 --kd 3 --ki 5Results are written to data/simulation_data.csv.
| Flag | Description | Default |
|---|---|---|
--x0 |
Initial position (m) | 0.0 |
--k |
Spring constant (N/m) | 5.0 |
--c |
Damping coefficient (Ns/m) | 0.5 |
--sp |
Setpoint (m) | 1.0 |
--kp |
Proportional gain | 20.0 |
--ki |
Integral gain | 5.0 |
--kd |
Derivative gain | 3.0 |
--output |
Output CSV filename | simulation_data.csv |
Sweeps over a grid of kp, kd, and ki values, runs a simulation for each combination, then ranks and plots the best results:
python scripts/sweep.pyPlot one or more CSV files. Computes overshoot, settling time (5% band), and steady-state error, then ranks results by a weighted cost function and plots the top 20:
python scripts/plot_results.py file1.csv file2.csv- C++: CMake 3.16+, C++17 compiler
- Python: pandas, matplotlib, numpy