modelica: разные результаты для раздела уравнения и раздела алгоритма

Следующая простая модель верна и работает в дымоле:

model new_timer

  Modelica.Blocks.Logical.Timer timer;
  Real my_time( start=0);

equation 
    timer.u=true;

    my_time=timer.y;

end new_timer;

Однако приведенный ниже пример верен во время «проверки» с помощью dymola, но не работает во время моделирования:

model new_timer

  Modelica.Blocks.Logical.Timer timer;
  Real my_time( start=0);

algorithm 
    timer.u:=true;
    my_time:=timer.y;

end new_timer;

Я задавался вопросом и искал способ заставить последнее работать. Ошибка, о которой сообщает dymola, выглядит следующим образом:

Failed to generate code for an algebraic loop
involving when equations or algorithms with when parts.
Unknowns:
my_time
timer.entryTime
timer.u
timer.y

Equations:
when timer.u then
timer.entryTime = time;
end when;
timer.y = (if timer.u then time-timer.entryTime else 0.0);
algorithm 
    timer.u := true;
    my_time := timer.y;

You may be able to cut the loop 
by putting 'pre' around some of the references to
unknown continuous time variables in when parts or when conditions.

Translation aborted.

person user3237603    schedule 26.01.2014    source источник


Ответы (2)


Это странная проблема, и я подозреваю, что это ошибка в Dymola (причины, которые я объясню через секунду).

Оказывается, вы столкнулись с этой проблемой, хотя ее нет В данной ситуации все очевидно, почему так должно быть.

Итак, одно из решений - использовать несколько иную реализацию модели Timer, которая выглядит так:

block Timer 
  "Timer measuring the time from the time instant where the Boolean input became true" 

  extends Modelica.Blocks.Interfaces.partialBooleanBlockIcon;
  Modelica.Blocks.Interfaces.BooleanInput u "Connector of Boolean input signal"
    annotation (extent=[-140,-20; -100,20]);
  Modelica.Blocks.Interfaces.RealOutput y "Connector of Real output signal" 
    annotation (extent=[100,-10; 120,10]);
protected 
  discrete Modelica.SIunits.Time entryTime "Time instant when u became true";
initial equation 
  pre(entryTime) = 0;
equation 
  when pre(u) then
    entryTime = time; 
  end when;
  y = if u then time - entryTime else 0.0;
end Timer;

Обратите внимание на присутствие оператора pre вокруг условия в предложении when.

В общем, использование оператора pre - хорошая идея (как я объясняю в другие выпуск). Почему это необходимо в вашем конкретном случае, я не могу объяснить. Условное выражение в вашем случае просто true, что означает, что оно должно запускать предложение when в начале моделирования. Я не вижу алгебраической петли, о которой здесь говорит Димола. Я подозреваю, что это как-то связано с тем, что Димола пытается организовать все вещи, которые должны произойти в начале симуляции, и наталкивается на некоторые сложности. Но это не очевидно, и всего этого можно избежать с помощью упомянутой мной альтернативной модели Timer.

person Michael Tiller    schedule 26.01.2014

Хорошо. Это хороший пример того, почему вам следует по возможности использовать разделы с уравнениями.

Следующий...

algorithm 
    timer.u:=true;
    my_time:=timer.y;

... примерно равно:

algorithm 
    (timer.u,my_time) := f(timer.y);

И теперь стало более понятно, что timer.u выглядит так, будто это зависит от timer.y. Так получится петля.

Следующее создает два раздела алгоритма, что означает, что зависимости более разбросаны (немного больше похоже на раздел уравнения):

algorithm 
    timer.u:=true;
algorithm
    my_time:=timer.y;

Старайтесь всегда использовать как можно более короткие разделы алгоритмов.

person sjoelund.se    schedule 27.01.2014