Skip to content
LimPIDTest.md

LimPIDTest ​

Test bench for a limited PID controller connected to a plant model with step input.

This test component connects a limited PID controller to a plant model and applies a step input as setpoint and a constant feedforward signal. The PID controller includes derivative, integral, and proportional actions with anti-windup and output limitations. The system response can be observed through the plant output and controller signals.

Usage ​

BlockComponents.LimPIDTest()

Behavior ​

[connect(signal+y,pid+us)connect(plant+y,pid+um)connect(pid+y,plant+u)connect(signalff+y,pid+uff)pid.us(t)=pid.addp.u1(t)pid.us(t)=pid.addi.u1(t)pid.us(t)=pid.addd.u1(t)pid.um(t)=pid.addp.u2(t)pid.um(t)=pid.addi.u2(t)pid.um(t)=pid.addd.u2(t)pid.uff(t)=pid.addff.u2(t)pid.y(t)=pid.limiter.y(t)connect(addp+y,proportional+u)connect(addd+y,derivative+u)connect(addi+y,integrator+u)connect(proportional+y,addpid+u1)connect(derivative+y,addpid+u2)connect(integrator+y,addpid+u3)connect(addpid+y,gainpid+u)connect(gainpid+y,addff+u1)connect(addff+y,addsat+u2)connect(addff+y,limiter+u)connect(limiter+y,addsat+u1)connect(addsat+y,gaintrack+u)connect(gaintrack+y,addi+u3)pid.addp.y(t)=pid.addp.k1⋅pid.addp.u1(t)+pid.addp.k2⋅pid.addp.u2(t)pid.addd.y(t)=pid.addd.k1⋅pid.addd.u1(t)+pid.addd.k2⋅pid.addd.u2(t)pid.addi.y(t)=pid.addi.k1⋅pid.addi.u1(t)+pid.addi.k2⋅pid.addi.u2(t)+pid.addi.k3⋅pid.addi.u3(t)pid.proportional.y(t)=pid.proportional.k⋅pid.proportional.u(t)d⋅pid.derivative.x(t)dt=−pid.derivative.x(t)+pid.derivative.u(t)pid.derivative.Tpid.derivative.y(t)=pid.derivative.k⋅(−pid.derivative.x(t)+pid.derivative.u(t))pid.derivative.Td⋅pid.integrator.x(t)dt=pid.integrator.k⋅pid.integrator.u(t)pid.integrator.y(t)=pid.integrator.x(t)pid.addpid.y(t)=pid.addpid.k1⋅pid.addpid.u1(t)+pid.addpid.k2⋅pid.addpid.u2(t)+pid.addpid.k3⋅pid.addpid.u3(t)pid.gainpid.y(t)=pid.gainpid.k⋅pid.gainpid.u(t)pid.addff.y(t)=pid.addff.k1⋅pid.addff.u1(t)+pid.addff.k2⋅pid.addff.u2(t)pid.limiter.y(t)=clamp(pid.limiter.u(t),pid.limiter.ymin,pid.limiter.ymax)pid.addsat.y(t)=pid.addsat.k1⋅pid.addsat.u1(t)+pid.addsat.k2⋅pid.addsat.u2(t)pid.gaintrack.y(t)=pid.gaintrack.k⋅pid.gaintrack.u(t)d⋅plant.x1(t)dt=plant.x2(t)d⋅plant.x2(t)dt=−0.5⋅plant.x2(t)−plant.x1(t)+plant.u(t)plant.y(t)=plant.x2(t)+0.5⋅plant.x1(t)signal.y(t)=ifelse(t≥signal.starttime,signal.height+signal.offset,signal.offset)signalff.y(t)=signalff.k]

Source ​

dyad
"""
Test bench for a limited PID controller connected to a plant model with step input.

This test component connects a limited PID controller to a plant model and applies a step input as
setpoint and a constant feedforward signal. The PID controller includes derivative, integral, and
proportional actions with anti-windup and output limitations. The system response can be observed
through the plant output and controller signals.
"""
test component LimPIDTest
  "Limited PID controller with configurable parameters"
  pid = LimPID(Td = 0.1, Ti = 0.5, y_max = 1, y_min = -1, wp = 1, wd = 0, Nd = 10, Ni = 0.9, k_ff = 1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 340, "y1": 60, "x2": 440, "y2": 160, "rot": 0}
      }
    }
  }
  "Plant model to be controlled"
  plant = Plant() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 50, "y1": 170, "x2": 150, "y2": 270, "rot": 0}
      }
    }
  }
  "Step input signal used as setpoint for the controller"
  signal = Step(height = 1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 40, "y1": 10, "x2": 140, "y2": 110, "rot": 0}
      }
    }
  }
  "Constant signal for feedforward control"
  signal_ff = Constant(k = 1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 50, "y1": 340, "x2": 150, "y2": 440, "rot": 0}
      }
    }
  }
relations
  "Initial condition for the first state of the plant"
  initial plant.x1 = 0
  "Initial condition for the plant output"
  initial plant.y = 0
  "Connect step signal to controller setpoint input"
  connect(signal.y, pid.u_s) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 280, "y": 60}, {"x": 280, "y": 87}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  "Connect plant output to controller measurement input"
  connect(plant.y, pid.u_m) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 280, "y": 220}, {"x": 280, "y": 133}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  "Connect controller output to plant input"
  connect(pid.y, plant.u) {
    "Dyad": {
      "edges": [
        {
          "S": 1,
          "M": [
            {"x": 500, "y": 111},
            {"x": 500, "y": 500},
            {"x": 20, "y": 500},
            {"x": 20, "y": 220}
          ],
          "E": 2
        }
      ],
      "renderStyle": "standard"
    }
  }
  "Connect feedforward signal to controller feedforward input"
  connect(pid.u_ff, signal_ff.y) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 410, "y": 390}], "E": 2}],
      "renderStyle": "standard"
    }
  }
metadata {
  "Dyad": {
    "icons": {"default": "dyad://BlockComponents/Example.svg"},
    "tests": {"case1": {"stop": 10, "expect": {"signals": ["plant.y", "pid.y"]}}}
  }
}
end
Flattened Source
dyad
"""
Test bench for a limited PID controller connected to a plant model with step input.

This test component connects a limited PID controller to a plant model and applies a step input as
setpoint and a constant feedforward signal. The PID controller includes derivative, integral, and
proportional actions with anti-windup and output limitations. The system response can be observed
through the plant output and controller signals.
"""
test component LimPIDTest
  "Limited PID controller with configurable parameters"
  pid = LimPID(Td = 0.1, Ti = 0.5, y_max = 1, y_min = -1, wp = 1, wd = 0, Nd = 10, Ni = 0.9, k_ff = 1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 340, "y1": 60, "x2": 440, "y2": 160, "rot": 0}
      }
    }
  }
  "Plant model to be controlled"
  plant = Plant() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 50, "y1": 170, "x2": 150, "y2": 270, "rot": 0}
      }
    }
  }
  "Step input signal used as setpoint for the controller"
  signal = Step(height = 1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 40, "y1": 10, "x2": 140, "y2": 110, "rot": 0}
      }
    }
  }
  "Constant signal for feedforward control"
  signal_ff = Constant(k = 1) {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 50, "y1": 340, "x2": 150, "y2": 440, "rot": 0}
      }
    }
  }
relations
  "Initial condition for the first state of the plant"
  initial plant.x1 = 0
  "Initial condition for the plant output"
  initial plant.y = 0
  "Connect step signal to controller setpoint input"
  connect(signal.y, pid.u_s) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 280, "y": 60}, {"x": 280, "y": 87}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  "Connect plant output to controller measurement input"
  connect(plant.y, pid.u_m) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 280, "y": 220}, {"x": 280, "y": 133}], "E": 2}],
      "renderStyle": "standard"
    }
  }
  "Connect controller output to plant input"
  connect(pid.y, plant.u) {
    "Dyad": {
      "edges": [
        {
          "S": 1,
          "M": [
            {"x": 500, "y": 111},
            {"x": 500, "y": 500},
            {"x": 20, "y": 500},
            {"x": 20, "y": 220}
          ],
          "E": 2
        }
      ],
      "renderStyle": "standard"
    }
  }
  "Connect feedforward signal to controller feedforward input"
  connect(pid.u_ff, signal_ff.y) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 410, "y": 390}], "E": 2}],
      "renderStyle": "standard"
    }
  }
metadata {
  "Dyad": {
    "icons": {"default": "dyad://BlockComponents/Example.svg"},
    "tests": {"case1": {"stop": 10, "expect": {"signals": ["plant.y", "pid.y"]}}}
  }
}
end


Test Cases ​

Test Case case1 ​

julia
plt

julia
plt