This example is interactive. Click the play button on any cell to execute it, or run all cells in sequence.

Cascade Controller

Demonstration of a two-loop cascade PID control system with inner and outer loops.

You can also find this example as a single file in the GitHub repository.

System Architecture

The cascade controller consists of:

  • An outer loop (primary controller) that regulates the main process variable
  • An inner loop (secondary controller) that controls an intermediate variable
  • A plant modeled as a subsystem with two cascaded transfer functions and noise disturbances

The inner loop responds faster to disturbances, improving the overall system response.

block diagram of cascade controller

First let's import the Simulation, Connection, Subsystem, and Interface classes along with the required blocks:

Python
Loading...

Plant Definition

We define the plant as a Subsystem containing two cascaded transfer functions with noise disturbances. The plant uses TransferFunctionZPG blocks (zero-pole-gain representation) and WhiteNoise blocks for disturbances.

Python
Loading...

Control Loops

We set up two PID controllers:

- c1: Outer loop PID controller (primary) - c2: Inner loop PID controller (secondary)

The inner controller is typically tuned to be faster than the outer controller. The setpoint changes at different time intervals to demonstrate the tracking performance.

Python
Loading...

We initialize the simulation with all blocks and connections. We use the RKCK54 solver (Runge-Kutta-Cash-Karp 5(4) method) with adaptive time-stepping for accurate integration of the transfer function dynamics.

Python
Loading...
12:43:21 - INFO - LOGGING (log: True)
12:43:21 - INFO - BLOCKS (total: 9, dynamic: 3, static: 6, eventful: 0)
12:43:21 - INFO - GRAPH (nodes: 9, edges: 14, alg. depth: 5, loop depth: 0, runtime: 0.127ms)

Now let's run the simulation for 100 seconds:

Python
Loading...
12:43:21 - INFO - STARTING -> TRANSIENT (Duration: 100.00s)
12:43:21 - INFO - --------------------   1% | 0.0s<2.2s | 731.2 it/s
12:43:22 - INFO - ####----------------  20% | 0.5s<03:34:07 | 747.4 it/s
12:43:22 - INFO - ########------------  40% | 1.0s<1.0s | 703.7 it/s
12:43:22 - INFO - ############--------  60% | 1.5s<01:04:33 | 735.9 it/s
12:43:23 - INFO - ################----  80% | 1.9s<0.3s | 730.4 it/s
12:43:23 - INFO - #################### 100% | 2.3s<--:-- | 718.0 it/s
12:43:23 - INFO - FINISHED -> TRANSIENT (total steps: 1662, successful: 1229, runtime: 2325.23 ms)

The Simulation class has a convenient plot method that plots all Scope blocks in the simulation:

Python
Loading...
Output
Output
Output