Modelica 中的抽象开关

Abstract switch in Modelica

我想提出一个我之前问过的关于 Modelica array of partial model 的问题。考虑以下 2 个控制器之间的切换模型。

model Switch
  input Real u;
  input Integer sel;
  output Real y;
protected 
  Real x;
equation 
  if sel == 1 then
    y = 0.1 * (0 - u);
    der(x) = 0;
  else
    y = 0.1 * (0 - u) + 0.2 * x;
    der(x) = 0 - u;
  end if;
end Switch;

我们先忽略PI控制器可能因为x的发散在一段时间内没有被选中而崩溃的事实。这可以通过在选择 PI 控制器时重置 x 来解决。不过,这不是重点。

我想用两种方式抽象这个开关。首先,在参数数量的控制器之间切换。其次,使用部分模型来抽象控制器。设 Ctrl 为控制器的部分模型。

partial model Ctrl
  input Real u;
  output Real y;
end Ctrl;

我们可以实例化嵌入在开关中的两个控制器,如下所示。

model P extends Ctrl;
equation 
  y = 0.1 * (0 - u);
end P;

model PI extends Ctrl;
protected 
  Real x;
equation 
  y = 0.1 * (0 - u) + 0.2 * x;
  der(x) = 0 - u;
end PI;

开关的抽象版本应该是这样的:

model Switch
  parameter Integer N(min=1);
  Ctrl c[N];
  input Real u;
  input Integer sel(min=1, max=N);
  output Real y;
equation 
  for i in 1:N loop
    c[i].u = u;
  end for;
  y = c[sel].y;
end Switch;

但是,这个模型有一些问题。首先,尚不清楚如何实例化该模型,例如带有一个 P 和一个 PI 控制器。其次,我收到一个令我吃惊的警告,即:以下输入缺少绑定方程:c[<a href="">1</a>].u

是否可以用某种方式在 Modelica 中表达这个抽象开关?

我想它应该与类似的东西一起工作:

model GenericSwitch
  parameter Integer N(min=1);
  replaceable model MyCtlr = Ctrl constrainedby Ctrl;
  MyCtlr c[N](each u = u);
  input Real u;
  input Integer sel(min=1, max=N);
  output Real y;
equation 
  y = c[sel].y;
end GenericSwitch;

model PSwitch = GenericSwitch(redeclare model MyCtrl = P);
model PISwitch = GenericSwitch(redeclare model MyCtrl = PI);

这不适用于模型数组,因为您无法通过修改将其绑定到不同的模型。您需要指定您在 GenericSwitch 中拥有的所有控制器。如果需要,您可以自动生成 GenericSwitch 和 Switch 模型。

partial model Ctrl
  input Real u;
  output Real y;
end Ctrl;

model P 
  extends Ctrl;
equation 
  y = 0.1 * (0 - u);
end P;

model PI 
  extends Ctrl;
protected 
  Real x;
equation 
  y = 0.1 * (0 - u) + 0.2 * x;
  der(x) = 0 - u;
end PI;

model GenericSwitch
  replaceable model MyCtrl1 = Ctrl;
  replaceable model MyCtrl2 = Ctrl;
  MyCtrl1 c1(u = u);
  MyCtrl2 c2(u = u);
  input Real u;
  input Integer sel;
  output Real y;
equation 
  y = if sel == 1 then c1.y else c2.y;
end GenericSwitch;

model Switch = GenericSwitch(
  redeclare model MyCtrl1 = P, 
  redeclare model MyCtrl2 = PI);