Skip to content
LIBRARY
Examples.LinearMPCPreviewExample.md

Examples.LinearMPCPreviewExample ​

Reference and disturbance preview with LinearMPCController over a horizon of Np steps. The reference is known Np + 1 samples ahead and runs through a DelayLine of Np + 1 taps; tap i of the line is the reference delayed Np + 1 - i samples and feeds r[i], so r[Np] carries the value furthest ahead (the undelayed last tap is not used). The Np disturbance inputs carry a known constant input disturbance that also acts on the plant. Exercises Bd, reference_preview and disturbance_preview.

Usage ​

MPCComponents.Examples.LinearMPCPreviewExample()

Parameters: ​

NameDescriptionUnitsDefault value
NpPrediction horizon–3
output_trajectoriesRecord the predicted trajectories and the QP statistics of the controller, for mpc_gui–false

Variables ​

NameDescriptionUnits
y1Position–
u1Control signal–

Behavior ​

Behavior of this component cannot be rendered because it includes path variables.

Source ​

dyad
"""
Reference and disturbance preview with `LinearMPCController` over a horizon of `Np` steps. The
reference is known `Np + 1` samples ahead and runs through a `DelayLine` of `Np + 1` taps; tap
`i` of the line is the reference delayed `Np + 1 - i` samples and feeds `r[i]`, so `r[Np]`
carries the value furthest ahead (the undelayed last tap is not used). The `Np` disturbance
inputs carry a known constant input disturbance that also acts on the plant. Exercises `Bd`,
`reference_preview` and `disturbance_preview`.
"""
example component LinearMPCPreviewExample
  periodicclock = DiscreteComponents.PeriodicClock(dt = 0.1) {
    "Dyad": {"placement": {"diagram": {"x1": 585, "x2": 685, "y1": 380, "y2": 480}}}
  }
  vel = BlockComponents.Continuous.Integrator(x0 = 0.0) {
    "Dyad": {"placement": {"diagram": {"x1": 40, "x2": 140, "y1": 160, "y2": 260}}}
  }
  pos = BlockComponents.Continuous.Integrator(x0 = 0.0) {
    "Dyad": {"placement": {"diagram": {"x1": 180, "x2": 280, "y1": 160, "y2": 260}}}
  }
  s1 = DiscreteComponents.Sampler() {
    "Dyad": {"placement": {"diagram": {"x1": 314, "x2": 414, "y1": 160, "y2": 260}}}
  }
  zoh = DiscreteComponents.ZeroOrderHold() {
    "Dyad": {"placement": {"diagram": {"x1": 584, "x2": 684, "y1": 140, "y2": 240}}}
  }
  add = BlockComponents.Math.Add() {
    "Dyad": {"placement": {"diagram": {"x1": 720, "x2": 820, "y1": 170, "y2": 270}}}
  }
  disturbance = BlockComponents.Sources.Constant(k = 0.3) {
    "Dyad": {"placement": {"diagram": {"x1": 580, "x2": 680, "y1": 260, "y2": 360}}}
  }
  sd = [DiscreteComponents.Sampler() for i in 1:Np] {"Dyad": {"placement": {"diagram": {"x1": 24, "x2": 124, "y1": 20, "y2": 120}}}}
  "Reference, known Np + 1 samples ahead of the current sample"
  ref = BlockComponents.Sources.Step(start_time = 2.0 - 0.1 * (Np + 1), height = 1.0) {
    "Dyad": {"placement": {"diagram": {"x1": 150, "x2": 250, "y1": 20, "y2": 120}}}
  }
  sr = DiscreteComponents.Sampler() {
    "Dyad": {"placement": {"diagram": {"x1": 284, "x2": 384, "y1": 20, "y2": 120}}}
  }
  "Delay line producing the reference preview taps"
  dline = MPCComponents.DelayLine(final N = Np + 1) {
    "Dyad": {"placement": {"diagram": {"x1": 420, "x2": 520, "y1": 20, "y2": 120}}}
  }
  mpc = MPCComponents.LinearMPCController(A = [[1.0, 0.1], [0.0, 1.0]], B = [[0.005], [0.1]], Bd = [[0.005], [0.1]], C = [[1.0, 0.0]], Q1 = [1.0], Q2 = [0.1], umin = [-1.0], umax = [1.0], Np = Np, reference_preview = true, disturbance_preview = true, R1 = [0.01, 0.01], R2 = [0.01], output_trajectories = output_trajectories) {
    "Dyad": {"placement": {"diagram": {"x1": 450, "x2": 550, "y1": 160, "y2": 260}}}
  }
  "Prediction horizon"
  structural parameter Np::Integer = 3
  "Record the predicted trajectories and the QP statistics of the controller, for mpc_gui"
  structural parameter output_trajectories::Boolean = false
  "Position"
  variable y1::Real
  "Control signal"
  variable u1::Real
relations
  y1 = pos.y
  u1 = mpc.u[1]
  connect(zoh.y, add.u1) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(disturbance.y, add.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 700, "y": 310}, {"x": 700, "y": 250}], "E": 2}],
      "path": {}
    }
  }
  connect(add.y, vel.u) {
    "Dyad": {
      "edges": [
        {
          "S": 1,
          "M": [
            {"x": 840, "y": 220},
            {"x": 840, "y": 530},
            {"x": 10, "y": 530},
            {"x": 10, "y": 210}
          ],
          "E": 2
        }
      ],
      "path": {}
    }
  }
  connect(vel.y, pos.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(pos.y, s1.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(s1.y, mpc.y[1], periodicclock.y) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {"S": -1, "M": [], "E": 2},
        {"S": -1, "M": [{"x": 430, "y": 430}], "E": 3}
      ],
      "junctions": [{"x": 430, "y": 210}],
      "path": {}
    }
  }
  connect(ref.y, sr.u)
  connect(sr.y, dline.u)
  for i in 1:Np
    connect(dline.y[i], mpc.r[i])
    connect(disturbance.y, sd[i].u)
    connect(sd[i].y, mpc.d[i])
  end
  connect(mpc.u[1], zoh.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
metadata {"Dyad": {"tests": {"case1": {"stop": 5}}, "doc": {"behavior": false}}}
end
Flattened Source
dyad
"""
Reference and disturbance preview with `LinearMPCController` over a horizon of `Np` steps. The
reference is known `Np + 1` samples ahead and runs through a `DelayLine` of `Np + 1` taps; tap
`i` of the line is the reference delayed `Np + 1 - i` samples and feeds `r[i]`, so `r[Np]`
carries the value furthest ahead (the undelayed last tap is not used). The `Np` disturbance
inputs carry a known constant input disturbance that also acts on the plant. Exercises `Bd`,
`reference_preview` and `disturbance_preview`.
"""
example component LinearMPCPreviewExample
  periodicclock = DiscreteComponents.PeriodicClock(dt = 0.1) {
    "Dyad": {"placement": {"diagram": {"x1": 585, "x2": 685, "y1": 380, "y2": 480}}}
  }
  vel = BlockComponents.Continuous.Integrator(x0 = 0.0) {
    "Dyad": {"placement": {"diagram": {"x1": 40, "x2": 140, "y1": 160, "y2": 260}}}
  }
  pos = BlockComponents.Continuous.Integrator(x0 = 0.0) {
    "Dyad": {"placement": {"diagram": {"x1": 180, "x2": 280, "y1": 160, "y2": 260}}}
  }
  s1 = DiscreteComponents.Sampler() {
    "Dyad": {"placement": {"diagram": {"x1": 314, "x2": 414, "y1": 160, "y2": 260}}}
  }
  zoh = DiscreteComponents.ZeroOrderHold() {
    "Dyad": {"placement": {"diagram": {"x1": 584, "x2": 684, "y1": 140, "y2": 240}}}
  }
  add = BlockComponents.Math.Add() {
    "Dyad": {"placement": {"diagram": {"x1": 720, "x2": 820, "y1": 170, "y2": 270}}}
  }
  disturbance = BlockComponents.Sources.Constant(k = 0.3) {
    "Dyad": {"placement": {"diagram": {"x1": 580, "x2": 680, "y1": 260, "y2": 360}}}
  }
  sd = [DiscreteComponents.Sampler() for i in 1:Np] {"Dyad": {"placement": {"diagram": {"x1": 24, "x2": 124, "y1": 20, "y2": 120}}}}
  "Reference, known Np + 1 samples ahead of the current sample"
  ref = BlockComponents.Sources.Step(start_time = 2.0 - 0.1 * (Np + 1), height = 1.0) {
    "Dyad": {"placement": {"diagram": {"x1": 150, "x2": 250, "y1": 20, "y2": 120}}}
  }
  sr = DiscreteComponents.Sampler() {
    "Dyad": {"placement": {"diagram": {"x1": 284, "x2": 384, "y1": 20, "y2": 120}}}
  }
  "Delay line producing the reference preview taps"
  dline = MPCComponents.DelayLine(final N = Np + 1) {
    "Dyad": {"placement": {"diagram": {"x1": 420, "x2": 520, "y1": 20, "y2": 120}}}
  }
  mpc = MPCComponents.LinearMPCController(A = [[1.0, 0.1], [0.0, 1.0]], B = [[0.005], [0.1]], Bd = [[0.005], [0.1]], C = [[1.0, 0.0]], Q1 = [1.0], Q2 = [0.1], umin = [-1.0], umax = [1.0], Np = Np, reference_preview = true, disturbance_preview = true, R1 = [0.01, 0.01], R2 = [0.01], output_trajectories = output_trajectories) {
    "Dyad": {"placement": {"diagram": {"x1": 450, "x2": 550, "y1": 160, "y2": 260}}}
  }
  "Prediction horizon"
  structural parameter Np::Integer = 3
  "Record the predicted trajectories and the QP statistics of the controller, for mpc_gui"
  structural parameter output_trajectories::Boolean = false
  "Position"
  variable y1::Real
  "Control signal"
  variable u1::Real
relations
  y1 = pos.y
  u1 = mpc.u[1]
  connect(zoh.y, add.u1) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(disturbance.y, add.u2) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 700, "y": 310}, {"x": 700, "y": 250}], "E": 2}],
      "path": {}
    }
  }
  connect(add.y, vel.u) {
    "Dyad": {
      "edges": [
        {
          "S": 1,
          "M": [
            {"x": 840, "y": 220},
            {"x": 840, "y": 530},
            {"x": 10, "y": 530},
            {"x": 10, "y": 210}
          ],
          "E": 2
        }
      ],
      "path": {}
    }
  }
  connect(vel.y, pos.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(pos.y, s1.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(s1.y, mpc.y[1], periodicclock.y) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [], "E": -1},
        {"S": -1, "M": [], "E": 2},
        {"S": -1, "M": [{"x": 430, "y": 430}], "E": 3}
      ],
      "junctions": [{"x": 430, "y": 210}],
      "path": {}
    }
  }
  connect(ref.y, sr.u)
  connect(sr.y, dline.u)
  for i in 1:Np
    connect(dline.y[i], mpc.r[i])
    connect(disturbance.y, sd[i].u)
    connect(sd[i].y, mpc.d[i])
  end
  connect(mpc.u[1], zoh.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
metadata {"Dyad": {"tests": {"case1": {"stop": 5}}, "doc": {"behavior": false}}}
end


Test Cases ​

Test Case case1 ​

  • Examples

  • Experiments

  • Analyses