Обнаружение изменения в переменной RealInput в Dymola

#modelica #dymola

#modelica #dymola

Вопрос:

Мне нужно обнаруживать всякий раз, когда происходит изменение в значении RealInput X. Я пытался проверить, является ли X == pre (X), но получаю только ошибку и предупреждение о том, что Real нельзя сравнить на равенство. Я также думал об использовании производной от X, но для этого нет явного выражения.

Другие мои мысли заключались в том, чтобы попытаться преобразовать непрерывный ввод в дискретные переменные, которые я могу сравнить. Может ли это каким-то образом сработать?

Комментарии:

1. Если вы используете pre (X) в a, X должно быть выражением с дискретным временем. Что означает, что, вероятно, она уже была выбрана. Используйте change() , как предложено в ответах.

Ответ №1:

Попробуйте change() оператор. Это описано в $ 3.7.3.1 спецификации Modelica. Согласно спецификации, она будет расширена до X<>pre(X) , так что это тоже может сработать.

Комментарии:

1. Как я указываю в другом ответе, <> оператор не определен для Real . Кроме того, это все еще по существу то же самое, что и в OP, X==pre(X) в том смысле, что для этого требуется, чтобы X была переменная с дискретным временем.

Ответ №2:

change() Оператор практически полезен только для не Real сигналов. Причина в том, что <> не определено для Real типов. Вместо этого вам нужно будет создать модель, которая проверяет, отклоняется ли сигнал от последнего записанного значения более чем на заданный «эпсилон». Я не тестировал это, но код будет выглядеть примерно так:

 model DetectChange
  parameter Real eps;
  input Real signal;
  output Boolean change;
protected
  Real last_value;
initial algorithm
  last_value = signal;
algorithm
  when pre(change) then
    last_value := signal;
  end when;
  change := abs(signal-last_value)>=eps;
end DetectChange;
  

Опять же, я это не тестировал. Но это дает вам некоторое представление.

Комментарии:

1. Почему реальные типы нельзя сравнивать на предмет равенства? Похоже, что это был бы обычный вариант использования.

2. Причина связана с тем, как типы с плавающей запятой представлены внутри. На самом деле это дискретные значения, хотя мы редко воспринимаем их таким образом. Причина, по которой равенство не допускается, заключается в том, что оно на самом деле не делает того, чего ожидают люди. Например, зайдите в оболочку Python на 64-разрядной машине Intel и выполните оценку 2.7*3==8.1 . Оно вернется False . Это происходит потому, что 2.7*3 вычисляется как 8.10000000000000142 , 8.1 в то время как 8.09999999999999964 вычисляется как в,,. Итак, по иронии судьбы, ни один из них на самом деле не представляет 8.1 точно.

3. Итак, могу ли я использовать Constants.small, значение меньше, чем сравнение, и больше, чем сравнение, для проверки приблизительного равенства?

4. Я бы избегал eps и small , потому что они предоставляют информацию о степени детализации чисел с плавающей запятой для данной платформы. Это не имеет никакого инженерного значения. Также имейте в виду, что при интегрировании дифференциальных уравнений вы получите числовой «шум», который заставит одиночные значения прыгать вверх и вниз. eps , который я использую в приведенном выше коде, должен представлять некоторый значимый инженерный порог. Другими словами, насколько велико изменение (в инженерных терминах), достаточно большое, чтобы оправдать принятие мер. Это eps выше.