Переменная Modelica не объявлена ​​в этой области

Модель 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], симуляция заработает.


person Sameer Puri    schedule 03.12.2019    source источник
comment
В Dymola 2020x это работает.   -  person marco    schedule 03.12.2019
comment
Я использовал Wolfram SystemModeler, но не был уверен, что это проблема с моей стороны. Я попробую с OpenModelica, не уверен, что смогу получить Dymola.   -  person Sameer Puri    schedule 03.12.2019


Ответы (2)


Просто идея, публикация в качестве ответа, потому что это слишком долго для комментария: возможно, встроенные циклы работают немного лучше, а не

  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};

См. Также https://github.com/mtiller/ModelicaBook/issues/338.

person matth    schedule 03.12.2019
comment
Встроенный цикл успешно моделируется с помощью SystemModeler. Мне все еще непонятно, почему оригинал не моделируется, но вместо этого я могу использовать этот синтаксис. - person Sameer Puri; 04.12.2019

В целом рекомендуется избегать алгоритмов в 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]) в правой части, тогда как для алгоритмов это обрабатывается автоматически.

person Hans Olsson    schedule 03.12.2019
comment
Вы правы, это могло быть просто уравнение. У меня есть более сложный императивный код, поэтому я просто пытался показать упрощенный случай, когда моделирование не запускается. Насколько я могу судить, SystemModeler вообще не поддерживает циклы в разделе алгоритмов. Если я разверну цикл, он работает отлично. - person Sameer Puri; 03.12.2019