我想知道是否有办法“调试”modelica 代码,我的意思是逐行调试代码,您可以看到变量如何变化,诸如此类?
我知道modelica代码被翻译成C,我只是想知道是否有可能以某种方式做到这一点,如果有,我相信这对任何模拟环境都会有很大的改进。谢谢。
HY
这是一个很好的问题,而且经常出现。但首先,让我们退后一步。
“逐行”调试的想法来自命令式编程语言。“命令式”是指程序只是按指定顺序执行的一系列指令。
当有人调试 Java 或 Python 时,这种“逐行”方法是有意义的,因为语句是表示行为的基本方式。这种“逐行”方法也可以扩展到像框图(例如 Simulink)这样的建模形式,因为虽然是图形化的,但它们也是命令式的(即它们构成了按指定顺序执行的步骤)。
但是 Modelica不是命令式语言。没有步骤、陈述或说明的概念。相反,我们有无所不在的方程式。所以线性思考调试在 Modelica 中是行不通的。确实,您可以考虑调试从 Modelica 生成的 C 代码,但这通常不是很有用,因为它与方程式只有部分相似之处。
那么如何调试 Modelica 代码呢?好吧,调试 Modelica 代码实际上就是调试 Modelica 方程。通常,Modelica 模型由组件组成。连接组件时生成的方程式是自动生成的,因此让我们规定 Modelica 编译器正确生成这些方程式。所以剩下的是组件模型中的方程。
解决这个问题的最简单方法是单独测试每个组件(或至少在尽可能小的模型中)。我经常说,尝试通过将 Modelica 组件放在一个大模型中来调试它们就像在听管弦乐队并试图找出一个走调的乐器。Modelica 中的这些方程倾向于形成联立方程组这一事实意味着,当它们发生时,错误可以立即传播到许多变量。
因此,最好的办法是为每个单独的组件创建测试并验证组件的行为。我的经验是,当你这样做时,你可以很容易地追踪和消除错误。
更新:您不需要将输出添加到其他人的组件模型来调试它们。可以在任何级别创建输出,例如
model SystemModel
SomeoneElsesComponent a;
SomeOtherGuysComponent b;
end SystemModel;
model SystemModel_Debug
extends SystemModel;
output Real someNestedSignalFromA = a.someSubsystem.someSubcomponent.someSignal;
output Real someOtherNestedSignalFromB = b.anotherSubsystem.anotherSignal;
end SystemModel_Debug;
当然,如果您有多个信号分量的实例化,这将变得不切实际。在这些情况下,我承认修改底层模型更容易。但是,如果他们制作了他们的模型replaceable
,您可以使用与上述相同的技巧(扩展他们的模型,添加一堆自定义输出,然后用redeclare
您的模型代替原始模型)。
OpenModelica 现在有一个转换调试器。您可以在此处找到从哪个方程评估哪个变量。