调试Modelica代码

调试Modelica代码,modelica,dymola,Modelica,Dymola,我想知道是否有“调试”modelica代码的方法,我的意思是逐行调试代码,您可以看到变量是如何变化的,诸如此类的事情 我知道modelica代码被翻译成了C,我只是想知道是否有可能以某种方式做到这一点,如果有,我相信这对任何模拟环境都是一个巨大的改进。谢谢 这是一个很好的问题,涉及面很广。但首先,让我们退一步 “逐行”调试的思想来自命令式编程语言。所谓“命令式”,我的意思是,一个程序仅仅是一系列按照指定顺序执行的指令 当有人调试Java或Python时,这种“逐行”的方法是有意义的,因为语句是表

我想知道是否有“调试”modelica代码的方法,我的意思是逐行调试代码,您可以看到变量是如何变化的,诸如此类的事情

我知道modelica代码被翻译成了C,我只是想知道是否有可能以某种方式做到这一点,如果有,我相信这对任何模拟环境都是一个巨大的改进。谢谢


这是一个很好的问题,涉及面很广。但首先,让我们退一步

“逐行”调试的思想来自命令式编程语言。所谓“命令式”,我的意思是,一个程序仅仅是一系列按照指定顺序执行的指令

当有人调试Java或Python时,这种“逐行”的方法是有意义的,因为语句是表示行为的基本方式。这种“逐行”的方法也可以扩展到模块图(如Simulink)之类的建模形式,因为虽然它们是图形化的,但它们也是必需的(即它们构成按指定顺序执行的步骤)

但是Modelica不是命令式语言。没有步骤、语句或说明的概念。相反,我们有无所不在的方程。因此,线性地考虑调试在Modelica中不起作用。的确,您可以考虑调试从Modelica生成的C代码,但这通常不是很有用,因为它与方程式只有部分相似

那么如何调试Modelica代码呢?调试Modelica代码实际上就是调试Modelica方程。通常,Modelica模型由组件组成。组件连接时生成的方程式是自动生成的,因此让我们规定Modelica编译器正确生成这些方程式。剩下的就是组件模型中的方程

实现这一点的最简单方法是单独测试每个组件(或至少在最小的可能模型中测试)。我经常说,通过将Modelica组件全部放在一个大模型中来调试它们,就像听管弦乐队演奏,试图找出一个不协调的乐器。Modelica中的这些方程往往形成联立方程组,这一事实意味着错误在发生时可以立即传播到多个变量

因此,最好的办法是为每个单独的组件进行测试并创建测试,并验证组件的行为。我的经验是,当你这样做的时候,你可以很容易地追踪并消除bug

更新:您不需要向其他人的组件模型添加输出来调试它们。可以在任何级别创建输出,例如

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;

当然,如果您有一个信号组件的多个实例,这将变得不切实际。在这些情况下,我承认修改底层模型更容易。但是,如果他们让他们的模型可替换,你可以使用与上面相同的技巧(扩展他们的模型,添加一堆自定义输出,然后重新声明你的模型以代替原来的模型)。

OpenModelica中现在有一个转换调试器。你可以在这里找到哪个变量是从哪个方程计算出来的。

非常感谢Micheal,我从你的回答中学到了很多,这就是我来这里发帖的原因。我同意你的观点,让每个单独的组件(低到最低级别)正常工作是最好的方法,问题是我大部分时间都在顶层工作,而底层代码大多来自其他人。我花了大量的“调试”时间来理解别人的代码。所以我真的希望有一天我能通过调试“看到”变量是如何变化的。现在我所做的只是复制他们的模型并向其中添加一个额外的输出。这是可行的,但修改原始代码需要相当多的时间。请记住……您不应该向其他人的模型添加输出。请看我上面的更新。非常感谢Micheal,这比修改其他代码要聪明得多。我一个月前开始使用Dymola,还有很多东西要学。谢谢你的帮助!顺便说一句,我很期待你的新书。假设你有两个子系统,每个子系统都有10个描述行为所需的非线性方程,但是当将它们连接在一起时,会出现由非线性引起的初始化失败。在上述情况下,我如何确切地知道哪个方程导致发散?另请参见本文: