modelica - Modelica 可扩展连接器最佳实践
问题描述
这是我的模型中出现的一些可扩展连接器使用的最小工作示例:
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;
这工作正常,这里没有问题。
请注意,通常此模型将在图表层中创建,其中包含图形对象以及总线和组件之间的连接(在这种情况下为增益)。
虽然上面的例子是微不足道的,但在许多现实世界的例子中,我从那个可扩展的连接器中出现了许多连接。这很快会在图表层变得混乱,我正在尝试在这里学习/开发一些最佳实践来清理图表。
一种选择似乎是以几乎等同于 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)在 contolBus 声明之前定位realExpressions 的声明(这第二个解决方案有点对我来说很奇怪)。
总的来说,从整理我的图表的角度来看,我对这些解决方案相当满意,但它们也至少感觉有点“hacky”。我在这个问题上的基本目标是询问这种方法是否可行或是否是个坏主意?此外,如果关于如何处理大型模型中所有连接的组织(尤其是可扩展连接器)有任何其他建议,我会全力以赴。作为一个额外的想法,在我看来,Modelica 语言的更专用的“From/Goto”功能在 Modelica 中可能非常好,纯粹是为了整理图表,但完全等同于引擎盖下的连接语句。
解决方案
迪莫拉抱怨说
变量 controlBus.signal1 是可扩展连接器的一部分,仅在连接之外使用。这是不合法的,因为我们无法确定其因果关系。
只要您使用连接语句在某处写入信号,您修改后的解决方案就可以工作。下面我进一步将您的示例简化为仅包含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
使用了实数表达式,以减少较大模型中的行数。
推荐阅读
- gradle - Gradle 包装器如何确定它使用的是哪个 Groovy 版本?
- python-3.x - 从不同的帧更改 Tkinter 帧
- arrays - 如何修复随机数量的 for 循环?
- javascript - 分页将显示第一页,但不显示第二页或第三页
- python-3.x - 根据下面变化的行数添加列
- bootstrap-4 - Bootstrap 4中如何防止表格超出卡体宽度?
- javascript - 在无序列表的行之间添加一个 div
- node.js - 想要尾随文件时无法启动节点 js 服务器
- amazon-ec2 - 如何在 AWS(cloudformation 或其他)中参数化 Tableau 中的数据连接?
- android - Unity IL2CPP Android 构建崩溃 Mac