Skip to content
LIBRARY
Examples.LinearMPCScheduledExample.md

Examples.LinearMPCScheduledExample ​

Level control of TankPlant by the three gain-scheduled controllers of MPCComponents.Experimental, on identical tanks and the same reference, so their trajectories and costs can be compared (benchmark_scheduled_controllers runs this model and reports the solve counts, solve times and closed-loop costs).

All three take the same bank of three controllers, built from the linearization of the tank at the levels 0.5, 1.5 and 3 (build_tank_mpc_bank), and are scheduled on the measured level, which is fed to each controller both as the measurement y and as the scheduling variable rho. The reference steps through the operating range, so the weights w move from one member to the next as the level rises and falls.

  • mpc (signals y1, u1) is LinearMPCScheduledController: it solves the quadratic programs of the members enclosing the level and interpolates their controls and Kalman filters.

  • mpc2 (y2, u2) is ACADOSScheduledController with the weights as online parameters of the interpolated model, held over the horizon: the same information as the bank, in one solve.

  • mpc3 (y3, u3) is ACADOSScheduledController with predict_scheduling, whose model follows the predicted level along the horizon (rho_C = [1], the level being the only state).

backend and acados_backend select the solver backends of the LinearMPC and acados controllers.

Usage ​

MPCComponents.Examples.LinearMPCScheduledExample()

Parameters: ​

NameDescriptionUnitsDefault value
bankBank of controllers linearized at the levels of the grid, shared by the three controllers–build_tank_mpc_bank()
backendQP solver backend of the LinearMPC-based controller–MPCComponen...kend.Auto()
acados_backendSolver backend of the two acados-based controllers–MPCComponen...kend.Auto()

Variables ​

NameDescriptionUnits
r1Level reference–
rsSampled level reference, the reference the controllers see (per tick)–
y1Level under the LinearMPC bank–
u1Inflow of the LinearMPC bank–
w1Weight of the first member (level 0.5)–
w2Weight of the second member (level 1.5)–
w3Weight of the third member (level 3)–
ys1Sampled level of the LinearMPC bank loop (per tick, what the cost is evaluated on)–
ys2Sampled level of the acados loop with the weights as parameters (per tick)–
ys3Sampled level of the acados loop predicting the scheduling variable (per tick)–
y2Level under the acados controller with the weights as parameters–
u2Inflow of the acados controller with the weights as parameters–
flag2acados status of that controller–
y3Level under the acados controller predicting the scheduling variable–
u3Inflow of the acados controller predicting the scheduling variable–
flag3acados status of that controller–

Behavior ​

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

Source ​

dyad
"""
Level control of `TankPlant` by the three gain-scheduled controllers of `MPCComponents.Experimental`,
on identical tanks and the same reference, so their trajectories and costs can be compared
(`benchmark_scheduled_controllers` runs this model and reports the solve counts, solve times and
closed-loop costs).

All three take the same bank of three controllers, built from the linearization of the tank at the
levels 0.5, 1.5 and 3 (`build_tank_mpc_bank`), and are scheduled on the measured level, which is fed
to each controller both as the measurement `y` and as the scheduling variable `rho`. The reference
steps through the operating range, so the weights `w` move from one member to the next as the level
rises and falls.

- `mpc` (signals `y1`, `u1`) is `LinearMPCScheduledController`: it solves the quadratic programs of the
  members enclosing the level and interpolates their controls and Kalman filters.
- `mpc2` (`y2`, `u2`) is `ACADOSScheduledController` with the weights as online parameters of the
  interpolated model, held over the horizon: the same information as the bank, in one solve.
- `mpc3` (`y3`, `u3`) is `ACADOSScheduledController` with `predict_scheduling`, whose model follows the
  predicted level along the horizon (`rho_C = [1]`, the level being the only state).

`backend` and `acados_backend` select the solver backends of the LinearMPC and acados controllers.
"""
example component LinearMPCScheduledExample
  periodicclock = DiscreteComponents.PeriodicClock(dt = 0.5) {
    "Dyad": {"placement": {"diagram": {"x1": 1050, "y1": 700, "x2": 1150, "y2": 800}}}
  }
  step1 = BlockComponents.Sources.Step(offset = 0.5, height = 1.0, start_time = 5.0) {
    "Dyad": {"placement": {"diagram": {"x1": 30, "y1": 260, "x2": 140, "y2": 370}}}
  }
  step2 = BlockComponents.Sources.Step(height = 1.5, start_time = 25.0) {
    "Dyad": {"placement": {"diagram": {"x1": 30, "y1": 390, "x2": 130, "y2": 490}}}
  }
  step3 = BlockComponents.Sources.Step(height = -2.5, start_time = 45.0) {
    "Dyad": {"placement": {"diagram": {"x1": 30, "y1": 510, "x2": 130, "y2": 610}}}
  }
  ref = BlockComponents.Math.Add3() {
    "Dyad": {"placement": {"diagram": {"x1": 350, "y1": 390, "x2": 460, "y2": 490}}}
  }
  sr = DiscreteComponents.Sampler() {
    "Dyad": {"placement": {"diagram": {"x1": 500, "y1": 390, "x2": 600, "y2": 490}}}
  }
  tank = TankPlant(h0 = 0.5) {
    "Dyad": {"placement": {"diagram": {"x1": 1290, "y1": 401.5, "x2": 1490, "y2": 601.5}}}
  }
  s1 = DiscreteComponents.Sampler() {
    "Dyad": {"placement": {"diagram": {"x1": 1150, "y1": 830, "x2": 1050, "y2": 930}}}
  }
  zoh = DiscreteComponents.ZeroOrderHold() {
    "Dyad": {"placement": {"diagram": {"x1": 1095, "y1": 451.5, "x2": 1195, "y2": 551.5}}}
  }
  mpc = MPCComponents.Experimental.LinearMPCScheduledController(mpc = bank, backend = backend) {
    "Dyad": {"placement": {"diagram": {"x1": 690, "y1": 411.5, "x2": 990, "y2": 711.5}}}
  }
  tank2 = TankPlant(h0 = 0.5) {
    "Dyad": {"placement": {"diagram": {"x1": 1290, "y1": 83.5, "x2": 1490, "y2": 283.5}}}
  }
  s2 = DiscreteComponents.Sampler() {
    "Dyad": {"placement": {"diagram": {"x1": 1110, "y1": -60, "x2": 1010, "y2": 40}}}
  }
  zoh2 = DiscreteComponents.ZeroOrderHold() {
    "Dyad": {"placement": {"diagram": {"x1": 1095, "y1": 133.5, "x2": 1195, "y2": 233.5}}}
  }
  mpc2 = MPCComponents.Experimental.ACADOSScheduledController(mpc = bank, backend = acados_backend) {
    "Dyad": {"placement": {"diagram": {"x1": 690, "y1": 71, "x2": 990, "y2": 371}}}
  }
  tank3 = TankPlant(h0 = 0.5) {
    "Dyad": {"placement": {"diagram": {"x1": 1290, "y1": 944, "x2": 1490, "y2": 1144}}}
  }
  s3 = DiscreteComponents.Sampler() {
    "Dyad": {"placement": {"diagram": {"x1": 1100, "y1": 1230, "x2": 1000, "y2": 1330}}}
  }
  zoh3 = DiscreteComponents.ZeroOrderHold() {
    "Dyad": {"placement": {"diagram": {"x1": 1095, "y1": 994, "x2": 1195, "y2": 1094}}}
  }
  mpc3 = MPCComponents.Experimental.ACADOSScheduledController(mpc = bank, backend = acados_backend, predict_scheduling = true, rho_C = [1.0]) {
    "Dyad": {"placement": {"diagram": {"x1": 690, "y1": 931.5, "x2": 990, "y2": 1231.5}}}
  }
  "Bank of controllers linearized at the levels of the grid, shared by the three controllers"
  structural parameter bank::MPCComponents.MPCRef = build_tank_mpc_bank()
  "QP solver backend of the LinearMPC-based controller"
  structural parameter backend::MPCComponents.Backend = MPCComponents.Backend.Auto()
  "Solver backend of the two acados-based controllers"
  structural parameter acados_backend::MPCComponents.Backend = MPCComponents.Backend.Auto()
  "Level reference"
  variable r1::Real
  "Sampled level reference, the reference the controllers see (per tick)"
  variable rs::Real
  "Level under the LinearMPC bank"
  variable y1::Real
  "Inflow of the LinearMPC bank"
  variable u1::Real
  "Weight of the first member (level 0.5)"
  variable w1::Real
  "Weight of the second member (level 1.5)"
  variable w2::Real
  "Weight of the third member (level 3)"
  variable w3::Real
  "Sampled level of the LinearMPC bank loop (per tick, what the cost is evaluated on)"
  variable ys1::Real
  "Sampled level of the acados loop with the weights as parameters (per tick)"
  variable ys2::Real
  "Sampled level of the acados loop predicting the scheduling variable (per tick)"
  variable ys3::Real
  "Level under the acados controller with the weights as parameters"
  variable y2::Real
  "Inflow of the acados controller with the weights as parameters"
  variable u2::Real
  "acados status of that controller"
  variable flag2::Real
  "Level under the acados controller predicting the scheduling variable"
  variable y3::Real
  "Inflow of the acados controller predicting the scheduling variable"
  variable u3::Real
  "acados status of that controller"
  variable flag3::Real
relations
  r1 = ref.y
  rs = sr.y
  ys1 = s1.y
  ys2 = s2.y
  ys3 = s3.y
  y1 = tank.y
  u1 = mpc.u[1]
  w1 = mpc.w[1]
  w2 = mpc.w[2]
  w3 = mpc.w[3]
  y2 = tank2.y
  u2 = mpc2.u[1]
  flag2 = mpc2.exitflag
  y3 = tank3.y
  u3 = mpc3.u[1]
  flag3 = mpc3.exitflag
  connect(step1.y, ref.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 250, "y": 315}, {"x": 250, "y": 410}], "E": 2}],
      "path": {}
    }
  }
  connect(step2.y, ref.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(step3.y, ref.u3) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 250, "y": 560}, {"x": 250, "y": 470}], "E": 2}],
      "path": {}
    }
  }
  connect(ref.y, sr.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(zoh.y, tank.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(tank.y, s1.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 1566.5, "y": 501.5}, {"x": 1566.5, "y": 880}], "E": 2}],
      "path": {}
    }
  }
  connect(s1.y, mpc.y[1], mpc.rho, periodicclock.y) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 640, "y": 880}, {"x": 640, "y": 681.5}], "E": 2},
        {"S": 2, "M": [{"x": 650, "y": 681.5}, {"x": 650, "y": 561.5}], "E": 3},
        {"S": 3, "M": [{"x": 630, "y": 561.5}, {"x": 630, "y": 750}], "E": 4}
      ],
      "path": {}
    }
  }
  connect(sr.y, mpc.r[1]) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 640, "y": 440}, {"x": 640, "y": 441.5}], "E": 2}],
      "path": {}
    }
  }
  connect(mpc.u[1], zoh.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(zoh2.y, tank2.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(tank2.y, s2.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 1520, "y": 183.5}, {"x": 1520, "y": -10}], "E": 2}],
      "path": {}
    }
  }
  connect(s2.y, mpc2.y[1], mpc2.rho) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 640, "y": -10}, {"x": 640, "y": 321.5}], "E": 2},
        {"S": 2, "M": [{"x": 650, "y": 321.5}, {"x": 650, "y": 221}], "E": 3}
      ],
      "path": {}
    }
  }
  connect(sr.y, mpc2.r[1]) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 612.5, "y": 440}, {"x": 612.5, "y": 441.5}], "E": -1},
        {"S": -1, "M": [{"x": 620, "y": 120.5}], "E": 2}
      ],
      "junctions": [{"x": 620, "y": 441.5}],
      "path": {}
    }
  }
  connect(mpc2.u[1], zoh2.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(zoh3.y, tank3.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(tank3.y, s3.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 1520, "y": 1044}, {"x": 1520, "y": 1280}], "E": 2}],
      "path": {}
    }
  }
  connect(s3.y, mpc3.y[1], mpc3.rho) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 640, "y": 1280}, {"x": 640, "y": 1182}], "E": 2},
        {"S": 2, "M": [{"x": 650, "y": 1182}, {"x": 650, "y": 1081.5}], "E": 3}
      ],
      "path": {}
    }
  }
  connect(sr.y, mpc3.r[1]) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 620, "y": 440}, {"x": 620, "y": 981}], "E": 2}],
      "path": {}
    }
  }
  connect(mpc3.u[1], zoh3.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
metadata {"Dyad": {"tests": {"case1": {"stop": 60}}, "doc": {"behavior": false}}}
end
Flattened Source
dyad
"""
Level control of `TankPlant` by the three gain-scheduled controllers of `MPCComponents.Experimental`,
on identical tanks and the same reference, so their trajectories and costs can be compared
(`benchmark_scheduled_controllers` runs this model and reports the solve counts, solve times and
closed-loop costs).

All three take the same bank of three controllers, built from the linearization of the tank at the
levels 0.5, 1.5 and 3 (`build_tank_mpc_bank`), and are scheduled on the measured level, which is fed
to each controller both as the measurement `y` and as the scheduling variable `rho`. The reference
steps through the operating range, so the weights `w` move from one member to the next as the level
rises and falls.

- `mpc` (signals `y1`, `u1`) is `LinearMPCScheduledController`: it solves the quadratic programs of the
  members enclosing the level and interpolates their controls and Kalman filters.
- `mpc2` (`y2`, `u2`) is `ACADOSScheduledController` with the weights as online parameters of the
  interpolated model, held over the horizon: the same information as the bank, in one solve.
- `mpc3` (`y3`, `u3`) is `ACADOSScheduledController` with `predict_scheduling`, whose model follows the
  predicted level along the horizon (`rho_C = [1]`, the level being the only state).

`backend` and `acados_backend` select the solver backends of the LinearMPC and acados controllers.
"""
example component LinearMPCScheduledExample
  periodicclock = DiscreteComponents.PeriodicClock(dt = 0.5) {
    "Dyad": {"placement": {"diagram": {"x1": 1050, "y1": 700, "x2": 1150, "y2": 800}}}
  }
  step1 = BlockComponents.Sources.Step(offset = 0.5, height = 1.0, start_time = 5.0) {
    "Dyad": {"placement": {"diagram": {"x1": 30, "y1": 260, "x2": 140, "y2": 370}}}
  }
  step2 = BlockComponents.Sources.Step(height = 1.5, start_time = 25.0) {
    "Dyad": {"placement": {"diagram": {"x1": 30, "y1": 390, "x2": 130, "y2": 490}}}
  }
  step3 = BlockComponents.Sources.Step(height = -2.5, start_time = 45.0) {
    "Dyad": {"placement": {"diagram": {"x1": 30, "y1": 510, "x2": 130, "y2": 610}}}
  }
  ref = BlockComponents.Math.Add3() {
    "Dyad": {"placement": {"diagram": {"x1": 350, "y1": 390, "x2": 460, "y2": 490}}}
  }
  sr = DiscreteComponents.Sampler() {
    "Dyad": {"placement": {"diagram": {"x1": 500, "y1": 390, "x2": 600, "y2": 490}}}
  }
  tank = TankPlant(h0 = 0.5) {
    "Dyad": {"placement": {"diagram": {"x1": 1290, "y1": 401.5, "x2": 1490, "y2": 601.5}}}
  }
  s1 = DiscreteComponents.Sampler() {
    "Dyad": {"placement": {"diagram": {"x1": 1150, "y1": 830, "x2": 1050, "y2": 930}}}
  }
  zoh = DiscreteComponents.ZeroOrderHold() {
    "Dyad": {"placement": {"diagram": {"x1": 1095, "y1": 451.5, "x2": 1195, "y2": 551.5}}}
  }
  mpc = MPCComponents.Experimental.LinearMPCScheduledController(mpc = bank, backend = backend) {
    "Dyad": {"placement": {"diagram": {"x1": 690, "y1": 411.5, "x2": 990, "y2": 711.5}}}
  }
  tank2 = TankPlant(h0 = 0.5) {
    "Dyad": {"placement": {"diagram": {"x1": 1290, "y1": 83.5, "x2": 1490, "y2": 283.5}}}
  }
  s2 = DiscreteComponents.Sampler() {
    "Dyad": {"placement": {"diagram": {"x1": 1110, "y1": -60, "x2": 1010, "y2": 40}}}
  }
  zoh2 = DiscreteComponents.ZeroOrderHold() {
    "Dyad": {"placement": {"diagram": {"x1": 1095, "y1": 133.5, "x2": 1195, "y2": 233.5}}}
  }
  mpc2 = MPCComponents.Experimental.ACADOSScheduledController(mpc = bank, backend = acados_backend) {
    "Dyad": {"placement": {"diagram": {"x1": 690, "y1": 71, "x2": 990, "y2": 371}}}
  }
  tank3 = TankPlant(h0 = 0.5) {
    "Dyad": {"placement": {"diagram": {"x1": 1290, "y1": 944, "x2": 1490, "y2": 1144}}}
  }
  s3 = DiscreteComponents.Sampler() {
    "Dyad": {"placement": {"diagram": {"x1": 1100, "y1": 1230, "x2": 1000, "y2": 1330}}}
  }
  zoh3 = DiscreteComponents.ZeroOrderHold() {
    "Dyad": {"placement": {"diagram": {"x1": 1095, "y1": 994, "x2": 1195, "y2": 1094}}}
  }
  mpc3 = MPCComponents.Experimental.ACADOSScheduledController(mpc = bank, backend = acados_backend, predict_scheduling = true, rho_C = [1.0]) {
    "Dyad": {"placement": {"diagram": {"x1": 690, "y1": 931.5, "x2": 990, "y2": 1231.5}}}
  }
  "Bank of controllers linearized at the levels of the grid, shared by the three controllers"
  structural parameter bank::MPCComponents.MPCRef = build_tank_mpc_bank()
  "QP solver backend of the LinearMPC-based controller"
  structural parameter backend::MPCComponents.Backend = MPCComponents.Backend.Auto()
  "Solver backend of the two acados-based controllers"
  structural parameter acados_backend::MPCComponents.Backend = MPCComponents.Backend.Auto()
  "Level reference"
  variable r1::Real
  "Sampled level reference, the reference the controllers see (per tick)"
  variable rs::Real
  "Level under the LinearMPC bank"
  variable y1::Real
  "Inflow of the LinearMPC bank"
  variable u1::Real
  "Weight of the first member (level 0.5)"
  variable w1::Real
  "Weight of the second member (level 1.5)"
  variable w2::Real
  "Weight of the third member (level 3)"
  variable w3::Real
  "Sampled level of the LinearMPC bank loop (per tick, what the cost is evaluated on)"
  variable ys1::Real
  "Sampled level of the acados loop with the weights as parameters (per tick)"
  variable ys2::Real
  "Sampled level of the acados loop predicting the scheduling variable (per tick)"
  variable ys3::Real
  "Level under the acados controller with the weights as parameters"
  variable y2::Real
  "Inflow of the acados controller with the weights as parameters"
  variable u2::Real
  "acados status of that controller"
  variable flag2::Real
  "Level under the acados controller predicting the scheduling variable"
  variable y3::Real
  "Inflow of the acados controller predicting the scheduling variable"
  variable u3::Real
  "acados status of that controller"
  variable flag3::Real
relations
  r1 = ref.y
  rs = sr.y
  ys1 = s1.y
  ys2 = s2.y
  ys3 = s3.y
  y1 = tank.y
  u1 = mpc.u[1]
  w1 = mpc.w[1]
  w2 = mpc.w[2]
  w3 = mpc.w[3]
  y2 = tank2.y
  u2 = mpc2.u[1]
  flag2 = mpc2.exitflag
  y3 = tank3.y
  u3 = mpc3.u[1]
  flag3 = mpc3.exitflag
  connect(step1.y, ref.u1) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 250, "y": 315}, {"x": 250, "y": 410}], "E": 2}],
      "path": {}
    }
  }
  connect(step2.y, ref.u2) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(step3.y, ref.u3) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 250, "y": 560}, {"x": 250, "y": 470}], "E": 2}],
      "path": {}
    }
  }
  connect(ref.y, sr.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(zoh.y, tank.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(tank.y, s1.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 1566.5, "y": 501.5}, {"x": 1566.5, "y": 880}], "E": 2}],
      "path": {}
    }
  }
  connect(s1.y, mpc.y[1], mpc.rho, periodicclock.y) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 640, "y": 880}, {"x": 640, "y": 681.5}], "E": 2},
        {"S": 2, "M": [{"x": 650, "y": 681.5}, {"x": 650, "y": 561.5}], "E": 3},
        {"S": 3, "M": [{"x": 630, "y": 561.5}, {"x": 630, "y": 750}], "E": 4}
      ],
      "path": {}
    }
  }
  connect(sr.y, mpc.r[1]) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 640, "y": 440}, {"x": 640, "y": 441.5}], "E": 2}],
      "path": {}
    }
  }
  connect(mpc.u[1], zoh.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(zoh2.y, tank2.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(tank2.y, s2.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 1520, "y": 183.5}, {"x": 1520, "y": -10}], "E": 2}],
      "path": {}
    }
  }
  connect(s2.y, mpc2.y[1], mpc2.rho) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 640, "y": -10}, {"x": 640, "y": 321.5}], "E": 2},
        {"S": 2, "M": [{"x": 650, "y": 321.5}, {"x": 650, "y": 221}], "E": 3}
      ],
      "path": {}
    }
  }
  connect(sr.y, mpc2.r[1]) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 612.5, "y": 440}, {"x": 612.5, "y": 441.5}], "E": -1},
        {"S": -1, "M": [{"x": 620, "y": 120.5}], "E": 2}
      ],
      "junctions": [{"x": 620, "y": 441.5}],
      "path": {}
    }
  }
  connect(mpc2.u[1], zoh2.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(zoh3.y, tank3.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
  connect(tank3.y, s3.u) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 1520, "y": 1044}, {"x": 1520, "y": 1280}], "E": 2}],
      "path": {}
    }
  }
  connect(s3.y, mpc3.y[1], mpc3.rho) {
    "Dyad": {
      "edges": [
        {"S": 1, "M": [{"x": 640, "y": 1280}, {"x": 640, "y": 1182}], "E": 2},
        {"S": 2, "M": [{"x": 650, "y": 1182}, {"x": 650, "y": 1081.5}], "E": 3}
      ],
      "path": {}
    }
  }
  connect(sr.y, mpc3.r[1]) {
    "Dyad": {
      "edges": [{"S": 1, "M": [{"x": 620, "y": 440}, {"x": 620, "y": 981}], "E": 2}],
      "path": {}
    }
  }
  connect(mpc3.u[1], zoh3.u) {"Dyad": {"edges": [{"S": 1, "M": [], "E": 2}], "path": {}}}
metadata {"Dyad": {"tests": {"case1": {"stop": 60}}, "doc": {"behavior": false}}}
end


Test Cases ​

Test Case case1 ​

  • Examples

  • Experiments

  • Analyses