Modelica布尔变量在连续时间内

问题描述 投票:1回答:3

以下Modelica模型检查和模拟。

model boolCheck_OK1
  Real a = sin(time);
  Real b = cos(time);
  Real c;
//protected 
//  Boolean isInReg = inRegionCheck(a, b);
equation 
  c = if inRegionCheck(a, b) then 1.3*a^b else 0.7*b^a;
end boolCheck_OK1;

函数inRegionCheck()返回一个布尔值,这里是一个简化版本:

function inRegionCheck
  input Real a;
  input Real b;
  output Boolean c;
algorithm 
   c := a>b;
end inRegionCheck;

在实际代码中,函数有更多的输入和更长的名称,并且有几行长,并且多次使用相同的检查,因此为了便于阅读,我想引入一个中间变量,如注释的受保护部分所示,但结果错误“连续时间内的非实数方程式不合法”。

有关优雅解决方法的任何建议吗?

time boolean modelica continuous
3个回答
3
投票

如果函数inRegionCheck由annotation(GenerateEvents=true);注释,则在SimulationX中工作(带有受保护的布尔变量isInReg)。在Dymola中,您需要设置annotation(Inline=true,GenerateEvents=true);才能使其正常工作。


1
投票

函数调用在noEvent的等式中引入了isInReg

如果使用布尔值,这就是Dymola 2019 FD01报告的:

Non-real equation in continuous time are not legal:
isInReg = noEvent(a > b);

因此,你的等式减少到

isInReg = noEvent(a > b)

这是不允许的,因为布尔值只能在事件上改变。你必须摆脱函数调用,从而摆脱noEvent。

也许有更好的解决方案,但您可以尝试在块中而不是函数中定义检查。至少对于你的最小例子它完全正常。

然后你的代码看起来像这样:

model boolCheck_OK1
  Real a = sin(time);
  Real b = cos(time);
  Real c;
protected 
  InRegionCheck check(a=a, b=b);
  Boolean isInReg=check.c;
equation 
  c = if isInReg then 1.3*a^b else 0.7*b^a;
end boolCheck_OK1;

block InRegionCheck
  input Real a;
  input Real b;
  output Boolean c;
equation 
   c = a>b;
end InRegionCheck;

1
投票

基于没有函数转换为布尔值但只有一个块的事实,我建议marco的答案是要走的路。

通过解决方法,您仍然可以在函数内部执行此操作,但不能使用Boolean类型。而是使用Real并在if子句中进行比较,如果它更大的零。为了显示布尔值的切换行为,这很好。如果您依赖于该函数并且不经常使用布尔值,那么这可能是一个选项。

model boolCheck_OK1
  Real a = sin(time);
  Real b = cos(time);
  Real c;

function inRegionCheck
  input Real a;
  input Real b;
  output Real c;
algorithm 
  c := if a>b then 1 else 0;
end inRegionCheck;
protected
  Real isInReg = inRegionCheck(a, b);

equation 
  c = if inRegionCheck(a, b)>Modelica.Constants.eps then 1.3*a^b else 0.7*b^a;
end boolCheck_OK1;
© www.soinside.com 2019 - 2024. All rights reserved.