Modelica 可扩展连接器最佳实践

Modelica Expandable Connector Best Practices

这是我的模型中出现的一些可扩展连接器用法的最小工作示例:

model TestExpandableConnector
  expandable connector ControlBus
    extends Modelica.Icons.SignalBus;
    Real signal1;
    Real signal2;
  end ControlBus;

  ControlBus controlBus;

  // example models to connect signals to
  Modelica.Blocks.Math.Gain gain1;
  Modelica.Blocks.Math.Gain gain2;
  // and so on
equation 
  connect(controlBus.signal1, gain1.u);
  connect(controlBus.signal2, gain2.u);
  // and so on
end TestExpandableConnector;

这很好用,不用担心。

请注意,通常此模型将在图表层中创建,其中包含图形对象以及总线与组件之间的连接(在本例中为增益)。

虽然上面的例子很简单,但在许多现实世界的例子中,我有许多连接来自那个可扩展的连接器。这很快就会在图表层中变得混乱,我正在尝试 learn/develop 此处的一些最佳实践来清理图表。

一个选项似乎是以几乎等同于 Simulink 的 From/Goto 元素的方式使用 RealExpression 块。例如:

model TestExpandableConnectorRevised
  expandable connector ControlBus
    extends Modelica.Icons.SignalBus;
    Real signal1;
    Real signal2;
  end ControlBus;

  ControlBus controlBus;

  // example models to connect signals to
  Modelica.Blocks.Math.Gain gain1;
  Modelica.Blocks.Math.Gain gain2;
  // and so on

  // using RealEpressions like goto tags
  Modelica.Blocks.Sources.RealExpression realExpression1(y=controlBus.signal1);
  Modelica.Blocks.Sources.RealExpression realExpression2(y=controlBus.signal2);
  // and so on
equation 
  connect(realExpression1.y, gain1.u);
  connect(realExpression2.y, gain2.u);
  // and so on
end TestExpandableConnectorRevised;

现在进行此更改后,Dymola 抱怨这是非法的,因为无法确定因果关系。我似乎能够通过以下任一方式解决最后一个问题:1) 在总线中的 signal1 和 signal2 声明中添加“输入”前缀,或者 2) 将 realExpressions 的声明定位在 before contolBus 声明(第二个解决方案对我来说有点奇怪)。

总的来说,从整理图表的角度来看,我对这些解决方案相当满意,但它们至少也让人觉得有点“hacky”。我在这个问题上的基本目标是询问这种方法是否可行还是一个坏主意?此外,如果有关于如何处理大型模型中所有连接的组织的任何其他建议(尤其是使用可扩展连接器),我会洗耳恭听。作为一个额外的想法,在我看来,Modelica 语言的更专用的“From/Goto”功能在 Modelica 中可能非常好,纯粹是为了整理图表的目的,但完全等同于引擎盖。

Dymola 抱怨

The variable controlBus.signal1 is part of an expandable connector, and was only used outside of connect. That is not legal since we cannot determine its causality.

只要您使用连接在某处写入信号,您修改后的解决方案就可以工作 陈述。下面我进一步减少了你的例子只包含 signal1。一个附加的实数表达式用于设置它的值。

model TestExpandableConnectorRevised
  expandable connector ControlBus
     Real signal1;
  end ControlBus;

  ControlBus controlBus;
  Modelica.Blocks.Math.Gain gain1;
  Modelica.Blocks.Sources.RealExpression realExpression1(y=controlBus.signal1);

  // Added to write the bus signal
  Modelica.Blocks.Sources.RealExpression realExpression3(y=1);

equation 
  connect(realExpression1.y, gain1.u);

  // Added to write the bus signal
  connect(realExpression3.y, controlBus.signal1);
end TestExpandableConnectorRevised;

这个例子在 Dymola pedantic 模式和 OpenModelica 下编译,所以它应该是完美的。

使用总线适配器的替代方法

如您所见,可扩展连接器充满了陷阱。如果您决定将可扩展连接器上的 signal1 重命名为 mysignal,但忘记将连接语句更新为 connect(realExpression3.y, controlBus.mysignal).

,则上述问题也很容易发生

因此一些 Modelica 库决定只通过总线适配器读写总线信号。您必须为每个变量创建 2 个额外的块:一个用于读取,一个用于写入其值。这是很多无聊的工作,但它避免了上面的问题。

这是一个读写的最小示例signal1

package BusAdapters
  partial block BusWriter
    // Dialog allows to set the value of y in the parameter window, like for the real expression
    Modelica.Blocks.Interfaces.RealInput u annotation (Dialog);
    ControlBus controlBus;
  end BusWriter;

  block Write_signal1
    extends BusWriter;
  equation 
    connect(u, controlBus.signal1);
  end Write_signal1;

  partial block BusReader
    Modelica.Blocks.Interfaces.RealOutput y;
    ControlBus controlBus;
  end BusReader;

  block Read_signal1
    extends BusReader;
  equation 
    connect(y, controlBus.signal1);
  end Read_signal1;

  expandable connector ControlBus
    extends Modelica.Icons.SignalBus;
    Real signal1;
  end ControlBus;

  model TestBusConnectors
    ControlBus controlBus;
    Modelica.Blocks.Math.Gain gain1;

    // setting bus variables: using modifiers in write blocks
    Write_signal1 write1(u=sin(time));

    // accessing bus variables part 1: creating instance of reader
    Read_signal1 read1;
  equation 
    // connect all read and write blocks to the same bus instance
    connect(write1.controlBus, controlBus);
    connect(read1.controlBus, controlBus);

    // accessing bus variables part 2: connecting reader with component of interest
    connect(read1.y, gain1.u);
  end TestBusConnectors;
end BusAdapters;

从图形上看,这将如下所示。 x 直接使用总线适配器写入。 y 使用真实表达式,以减少较大模型中的行数。