未在此范围内声明的 Modelica 变量
Modelica variable not declared in this scope
下面的Modelica模型通过了验证:
model TestController
parameter Real off[4] = fill(20, 4) "Radiator turn off threshold";
parameter Real on[4] = fill(19, 4) "Radiator turn on threshold";
discrete Modelica.Blocks.Interfaces.RealInput x[4];
output Modelica.Blocks.Interfaces.BooleanOutput h[4];
protected
Boolean has_heater[4];
equation
has_heater = {false, true, true, false};
algorithm
for j in 1:4 loop
h[j] := has_heater[j] and ((not h[j] and x[j] <= on[j]) or (h[j] and x[j] < off[j]));
end for;
end TestController;
但是当我尝试模拟它时,编译代码出现错误:
sme.12.0.0_1575385723_1403176131_main.cpp: In function ‘int function_zeroCrossing(f2c_integer*, double*, double*, f2c_integer*, double*, double*, f2c_integer*)’:
sme.12.0.0_1575385367_109695398_main.cpp:347:35: error: ‘$i1_j’ was not declared in this scope
349 | base_array_range_check1(&$tmp0, $i1_j - 1, "[:0:0-0:0]", "x[$i1_j]");
|
肯定有一些基本的东西我不明白,为什么这个循环不模拟?如果我删除 h 值的第二个子句并使其简单地 h[j] := has_heater[j]
模拟工作。
通常最好避免在 Modelica 中使用算法,而是使用方程式。我相信这可能适用于 System Modeler(这和 Dymola 中的原始作品)。
model TestController
parameter Real off[4] = fill(20, 4) "Radiator turn off threshold";
parameter Real on[4] = fill(19, 4) "Radiator turn on threshold";
discrete Modelica.Blocks.Interfaces.RealInput x[4];
output Modelica.Blocks.Interfaces.BooleanOutput h[4];
protected
Boolean has_heater[4];
equation
has_heater = {false, true, true, false};
for j in 1:4 loop
h[j] := has_heater[j] and ((not pre(h[j]) and x[j] <= on[j]) or (pre(h[j]) and x[j] < off[j]));
end for;
end TestController;
在这种情况下,这并不完全是微不足道的,因为您必须在右侧使用 pre(h[j])
,而算法会自动处理它。
只是一个想法,作为答案发布,因为评论太长了:
也许内联 for 循环工作得更好一些,而不是
for j in 1:4 loop
h[j] := has_heater[j] and ((not h[j] and x[j] <= on[j]) or (h[j] and x[j] < off[j]));
end for;
试一试
h := {has_heater[j] and ((not h[j] and x[j] <= on[j]) or (h[j] and x[j] < off[j])) for j in 1:4};
下面的Modelica模型通过了验证:
model TestController
parameter Real off[4] = fill(20, 4) "Radiator turn off threshold";
parameter Real on[4] = fill(19, 4) "Radiator turn on threshold";
discrete Modelica.Blocks.Interfaces.RealInput x[4];
output Modelica.Blocks.Interfaces.BooleanOutput h[4];
protected
Boolean has_heater[4];
equation
has_heater = {false, true, true, false};
algorithm
for j in 1:4 loop
h[j] := has_heater[j] and ((not h[j] and x[j] <= on[j]) or (h[j] and x[j] < off[j]));
end for;
end TestController;
但是当我尝试模拟它时,编译代码出现错误:
sme.12.0.0_1575385723_1403176131_main.cpp: In function ‘int function_zeroCrossing(f2c_integer*, double*, double*, f2c_integer*, double*, double*, f2c_integer*)’:
sme.12.0.0_1575385367_109695398_main.cpp:347:35: error: ‘$i1_j’ was not declared in this scope
349 | base_array_range_check1(&$tmp0, $i1_j - 1, "[:0:0-0:0]", "x[$i1_j]");
|
肯定有一些基本的东西我不明白,为什么这个循环不模拟?如果我删除 h 值的第二个子句并使其简单地 h[j] := has_heater[j]
模拟工作。
通常最好避免在 Modelica 中使用算法,而是使用方程式。我相信这可能适用于 System Modeler(这和 Dymola 中的原始作品)。
model TestController
parameter Real off[4] = fill(20, 4) "Radiator turn off threshold";
parameter Real on[4] = fill(19, 4) "Radiator turn on threshold";
discrete Modelica.Blocks.Interfaces.RealInput x[4];
output Modelica.Blocks.Interfaces.BooleanOutput h[4];
protected
Boolean has_heater[4];
equation
has_heater = {false, true, true, false};
for j in 1:4 loop
h[j] := has_heater[j] and ((not pre(h[j]) and x[j] <= on[j]) or (pre(h[j]) and x[j] < off[j]));
end for;
end TestController;
在这种情况下,这并不完全是微不足道的,因为您必须在右侧使用 pre(h[j])
,而算法会自动处理它。
只是一个想法,作为答案发布,因为评论太长了: 也许内联 for 循环工作得更好一些,而不是
for j in 1:4 loop
h[j] := has_heater[j] and ((not h[j] and x[j] <= on[j]) or (h[j] and x[j] < off[j]));
end for;
试一试
h := {has_heater[j] and ((not h[j] and x[j] <= on[j]) or (h[j] and x[j] < off[j])) for j in 1:4};