Булева переменная Modelica в непрерывном времени - PullRequest
1 голос
/ 08 марта 2019

Следующая модель 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;

В реальном коде функция имеет больше входных данных и более длинное имя и имеет длину в несколько строк, и одна и та же проверка используется несколько раз, поэтому для удобства чтения я хотел бы ввести промежуточную переменную, как показано в защищенном разделе с комментариями, но это приводит к ошибке «Нереальное уравнение в непрерывном времени не является законным».

Какие-нибудь предложения для элегантного обходного пути?

Ответы [ 3 ]

3 голосов
/ 11 марта 2019

Работает в SimulationX (с защищенной логической переменной isInReg), если функция inRegionCheck аннотирована annotation(GenerateEvents=true);. В Dymola вам нужно установить annotation(Inline=true,GenerateEvents=true);, чтобы он работал.

1 голос
/ 11 марта 2019

Исходя из того факта, что нет функции для преобразования в логическое значение, а есть только блок, я бы сказал, что ответ Марко - это путь.

С помощью обходного пути вы все равно можете делать это внутри функции, но не с типом 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;
1 голос
/ 08 марта 2019

Вызов функции вводит 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;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...