Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions snippets/1023_AIAssistedPIDTuning/brainstorm.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# Brainstorm: AI-Assisted PID Tuning for a Simple Thermal Plant

---

## Overview

**Topic:** AI-Assisted PID Tuning for a Simple Thermal Plant

**Why a thermal system?**
- Intuitive — everyone understands heating something to a target temperature
- No control engineering background needed to follow along
- Simple first-order dynamics
- Relatable real-world application (ovens, heated chambers, industrial processes)

**What is PID Tuning?**
A PID controller adjusts a system output (e.g. heater power) to match a desired setpoint (e.g. target temperature) using three terms:
- **P (Proportional):** reacts to current error
- **I (Integral):** corrects accumulated past error
- **D (Derivative):** anticipates future error

Tuning = finding the right Kp, Ki, Kd values so the system responds well (fast, stable, minimal overshoot).

---

## Plant Model

**First-order thermal system with dead time:**

G(s) = K · e^(-θs) / (τs + 1)

**Parameters:**
- **K** — steady-state gain (°C per % heater power), e.g. 1.5
- **τ (tau)** — time constant (system sluggishness), e.g. 200 seconds
- **θ (theta)** — dead time (delay before response), e.g. 20 seconds

Exact parameter values to be finalized during the planning phase.

---

## Tool Split

| Role | Tool | Mode |
|------|------|------|
| Planning, outlining, clarifying questions | DeepSeek-V4-Pro | Expert mode, DeepThink enabled |
| Code generation, implementation | Claude Sonnet 4.6 | Medium Extended Thinking |

---

## Implementation Phases

1. **DeepSeek:** Model the thermal plant, define transfer function parameters
2. **DeepSeek:** Plan the full implementation structure, ask clarifying questions
3. **Claude:** Simulate open-loop step response
4. **Claude:** Implement closed-loop PID controller, plot response vs. setpoint reference line
5. **Claude:** Implement automatic tuning algorithm (Claude decides the method)
6. **Claude:** Build interactive UI with configurable Kp, Ki, Kd and performance metrics display

---

## Simulation & Visualization

**Plot will include:**
- Flat horizontal reference line at the setpoint
- PID controller temperature response curve tracking the setpoint

**Performance metrics to display:**
- Overshoot (%)
- Rise time
- Settling time

**Interactive UI:**
- Configurable Kp, Ki, Kd inputs/sliders
- Plot updates on parameter change
- Performance metrics update accordingly

---

## Important Framing Note

"AI-assisted" in this context means the AI wrote the code — not that the tuning algorithm itself is intelligent.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# Phase 1: Project Setup & Open-Loop Step Response Simulation

## Objective
Set up the project environment, implement the thermal plant model as a transfer function, and simulate its open-loop step response. The result is a plot showing how the plant’s temperature naturally evolves when the heater is turned on to full power, with no controller.

---

## 1. Project Structure
Create the following directory layout:

thermal_pid_tuner/
├── plant.py # Thermal plant model
├── utils.py # Performance metric functions (for later phases)
├── main.py # Entry point for open-loop simulation
├── requirements.txt # Python dependencies
└── plots/ # Directory for saved figures

---

## 2. Dependencies (`requirements.txt`)

numpy>=1.24
scipy>=1.10
matplotlib>=3.7
control>=0.9

All simulations and control objects will use the `control` library (also known as `python-control`).

---

## 3. Thermal Plant Model (`plant.py`)

### Plant Parameters

| Parameter | Symbol | Value | Unit |
|-----------|--------|--------|------------------|
| Steady‑state gain | K | 1.5 | °C / % heater |
| Time constant | τ | 200.0 | seconds |
| Dead time | θ | 20.0 | seconds |
| Ambient temperature | T_amb | 20.0 | °C |

The transfer function from heater power deviation (Δu in %) to temperature deviation (ΔT in °C) is:

K · e^(-θs)
G(s) = ───────────────
τ s + 1

The absolute temperature is:
`T(t) = T_amb + output of G(s) for a given heater input u(t).`

Heater input is bounded between 0 % and 100 %.

### Implementation

Create a class `ThermalPlant` with:
- **`__init__(self, K=1.5, tau=200.0, theta=20.0, T_amb=20.0)`** – stores parameters.
- **`transfer_function(self)`** – returns a `control.TransferFunction` object using a **2nd‑order Padé approximation** for the dead time.
- **`step_response(self, u_step=100.0, t_end=800.0, dt=0.5)`** – simulates the step response (heater jumps from 0 to `u_step` at t=0) and returns `(t, T)` where `T` is the absolute temperature.

**Important details:**

- The `control` library does not directly support pure dead time. Use `control.pade(θ, n=2)` to obtain numerator/denominator polynomials, then multiply the rational part `K / (τ s + 1)` by the Padé approximation. The `control.series()` function can help.
- For simulation, use `control.step_response()` or `control.forced_response()` with a step input signal.
- Ensure the initial temperature is `T_amb` (output starts at 0 deviation, then add `T_amb`).
- The time vector should span 0 to `t_end` with step `dt`; ensure the output array covers the full simulation.

---

## 4. Main Script (`main.py`)

The script should:
1. Import `ThermalPlant` from `plant.py`.
2. Instantiate the plant with default parameters.
3. Call `step_response(u_step=100.0, t_end=800.0)`.
4. Create a publication‑quality plot:
- X‑axis: Time (s)
- Y‑axis: Temperature (°C)
- Title: **Open‑Loop Step Response (Heater 0→100%)**
- Grid on, tight layout.
- Include a dashed horizontal line at the steady‑state temperature (ambient + K·100) as a visual reference.
5. Save the figure as `plots/open_loop_response.png` (the `plots` directory must exist; create it if necessary).
6. Print a summary line: `"Steady-state temperature: X °C"`

---

## 5. Acceptance Criteria

- Running `python main.py` produces no errors.
- The plot shows a smooth, delayed S‑shaped rise from 20 °C to the steady‑state value.
- The delay (~20 s before any noticeable change) and the time constant (~200 s for 63% of the rise) are visually coherent.
- The steady‑state temperature equals 20 + 1.5×100 = 170 °C; the dashed line matches this value.

---

## 6. Notes for the Coding Assistant

- Use `control.pade(theta, 2)` → returns `(num_pade, den_pade)` as 1D arrays of polynomial coefficients (descending powers). Then create `control.TransferFunction` objects for the Padé part and the first‑order lag, and multiply them.
- Ensure all vectors (time, input, output) are plain NumPy arrays or lists that `matplotlib` can handle directly.
- Avoid complex numbers leaking into the temperature output – the Padé approximation yields real coefficients, so output should remain real.
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# Phase 2: Closed-Loop PID Control Simulation

## Objective
Implement a PID controller as a transfer function, close the feedback loop with the thermal plant, simulate the step response to a 60 °C setpoint, plot the temperature tracking, and compute basic performance metrics.

---

## 1. PID Controller Module (`controller.py`)

Create a new file `controller.py` in the project root with a class `PIDController`.

### Class Interface

- **`__init__(self, Kp=1.0, Ki=0.0, Kd=0.0)`** – stores the three gains.
- **`transfer_function(self)`** – returns a `control.TransferFunction` object representing the ideal PID controller in the Laplace domain:

Gc(s) = Kp + Ki/s + Kd*s

Use the `control.TransferFunction` constructor directly. For example:

control.TransferFunction([Kd, Kp, Ki], [1, 0])

gives numerator `Kd s^2 + Kp s + Ki` and denominator `s`.

- No derivative filtering and no anti‑windup at this stage — pure ideal PID.

---

## 2. Performance Metrics (`utils.py`)

Replace the stubs in the existing `utils.py` with fully implemented functions. All functions must accept NumPy arrays for time `t` and output `y`, and return a single float.

### Required Functions

1. **`overshoot(y, setpoint)`**
- Returns `(max(y) - setpoint) / setpoint * 100` (percentage).
- If the maximum is less than or equal to the setpoint, return 0.0.

2. **`rise_time(t, y, setpoint, low=0.1, high=0.9)`**
- Assumes the system starts at an initial temperature below the setpoint and rises.
- Finds the first time `y` crosses `setpoint * low` and the first time it crosses `setpoint * high`, then returns `t_high - t_low`.
- If either bound is never reached, return `float('inf')`.

3. **`settling_time(t, y, setpoint, band=0.02)`**
- Returns the smallest time `t_s` such that for all `t >= t_s`,
`|y - setpoint| <= band * setpoint`.
- If the signal never settles within the simulation time, return `float('inf')`.
- Search backwards from the end of the array for efficiency.

All functions should handle the case where `y` is a 1D array. Use NumPy indexing and boolean masking.

---

## 3. Closed-Loop Simulation Script (`closed_loop.py`)

Create a new script `closed_loop.py` that ties everything together.

### 3.1 Imports
Import the following:
- `numpy as np`
- `matplotlib.pyplot as plt`
- `control` (python‑control)
- `plant` (ThermalPlant)
- `controller` (PIDController)
- `utils` (all three metric functions)

### 3.2 Parameters
Define:
- `SETPOINT = 60.0` (°C)
- `T_AMBIENT = 20.0` (°C)
- Placeholder PID gains:
`Kp = 1.8`
`Ki = 0.008`
`Kd = 30.0`
- Simulation end time: 800 s.

### 3.3 Build the Closed‑Loop System
1. Instantiate `ThermalPlant` with default parameters → `Gp = plant.transfer_function()`.
2. Instantiate `PIDController` with the placeholder gains → `Gc = pid.transfer_function()`.
3. Form the open‑loop series: `G_ol = Gc * Gp` (using `control.series()` or `*`).
4. Build the closed‑loop transfer function from reference (setpoint deviation) to output deviation:
`G_cl = control.feedback(G_ol, 1, sign=-1)`
(unity negative feedback).
5. The step magnitude from ambient to setpoint is `SETPOINT - T_AMBIENT = 40.0`.

### 3.4 Simulate Step Response
- Use `control.step_response(G_cl, T=800)` which returns `(t, y_dev)` — `y_dev` is the **temperature deviation** for a unit step input.
- Multiply `y_dev` by 40 to obtain the deviation for a 40 °C command, then add ambient:
`T_abs = T_AMBIENT + 40.0 * y_dev`
- Ensure `t` has enough points; the default from `step_response` is usually fine, but you can specify a `T_num` parameter for smoothness.

### 3.5 Plot
- Create a figure (size 10×6 recommended).
- Plot `t` vs `T_abs` with a solid line (label "Temperature").
- Add a dashed horizontal line at `SETPOINT` (label "Setpoint 60 °C", color grey or red).
- Label axes: `Time (s)` and `Temperature (°C)`.
- Title: `Closed-Loop PID Response to 60°C Setpoint`.
- Enable grid, use `tight_layout()`.
- Save the plot to `plots/closed_loop_pid_response.png` (create the directory if needed).

### 3.6 Compute and Print Metrics
- `overshoot_val = utils.overshoot(T_abs, SETPOINT)`
- `rise_t = utils.rise_time(t, T_abs, SETPOINT)`
- `settle_t = utils.settling_time(t, T_abs, SETPOINT)`
- Print one metric per line, formatted to two decimal places:
- `Overshoot: X.XX %`
- `Rise time: X.XX s`
- `Settling time: X.XX s`

### 3.7 Run
The script must be executable with `python closed_loop.py`.

---

## 4. Acceptance Criteria

- `python closed_loop.py` runs without errors.
- The plot shows the temperature rising from 20 °C, approaching 60 °C, possibly overshooting, then settling near the setpoint.
- The reference line at 60 °C is visible.
- The three metrics are printed and are physically plausible (rise time between 50–400 s, overshoot 0–50 %, settling time ≤800 s).
- The plot is saved to `plots/closed_loop_pid_response.png`.
Loading