Включение причинно-следственной связи в симуляцию Modelica приводит к ошибке перевода при выравнивании модели.

Я хочу смоделировать контроллер для модели масса-пружина, которая работает на основе энергии:

model model
//constants
  parameter Real m = 1;
  parameter Real k = 1;
  parameter Real Fmax = 3;
  parameter Real x0 = 1;
  parameter Real x1 = 2;
  parameter Real t1 = 1;
  
//variables
  Real x, v, a, xy, vm;
  
initial equation
  x = x0;
  v = 2;
  
equation
  v = der(x);
  a = der(v);
  m * a + k * x = F;
  
algorithm
  vm := sign(xy - x)*sqrt(2 * (Fmax * abs(xy - x) + k * (xy^2 - x^2) / 2) / m);

  // step signal
  if time  < t1 then
    xy := x0;
  else 
    xy := x1;
  end if;
  
  if xy == x then
    F := k * x;
  else
    F := sign(vm - v) * Fmax;
  end if;
end model;

Но это приводит к сообщению об ошибке:

Ошибка перевода

Произошла ошибка при выравнивании модели

Я был бы признателен, если бы вы могли помочь мне узнать, в чем проблема и как я могу ее исправить.

P.S.1. SIMULINK также не может завершиться!

P.S.2. Новую версию кода можно увидеть здесь.


person Foad    schedule 20.02.2019    source источник
comment
Кажется, вы забыли определить F, если я добавлю его к //variables, код будет работать в Dymola. В качестве примечания: xy==y рекомендуется делать с некоторым допуском. Также может быть опасно давать модели имя model...   -  person Markus A.    schedule 20.02.2019
comment
@МаркусА. ах какая глупая ошибка! Спасибо, что указали на это. что вы понимаете под толерантностью? как мне это сделать?   -  person Foad    schedule 20.02.2019
comment
Теперь я получаю предупреждение Translation Warning In component <NO COMPONENT>, in relation xy == x, == on Real numbers is only allowed inside functions., и оно застревает на 18%!   -  person Foad    schedule 20.02.2019
comment
Замена if xy == x then на if abs(xy - x) < 1e-6 then должна выполнить работу, которую вы планировали. Конечно, вы можете настроить 1e-6 под свои нужды. Один документ, который я нашел после быстрого поиска, это docs.microsoft.com/en-us/dotnet/api/. Это должно объяснить проблему довольно хорошо (хотя я не прочитал ее полностью)...   -  person Markus A.    schedule 20.02.2019
comment
@МаркусА. Благодарю. достаточно забавно, я много лет назад задавал тот же вопрос здесь : ). ваши предложения устраняют предупреждение, но симуляции все еще застревают на 17%. Любая идея, почему это происходит и как я могу это решить?   -  person Foad    schedule 20.02.2019
comment
У меня симуляция застряла на отметке 1,8 с. Кажется, это происходит, когда v и vm имеют одинаковые значения. Трудно сказать, не полностью понимая модель (что не совсем просто, просто глядя на уравнения)...   -  person Markus A.    schedule 20.02.2019
comment
@МаркусА. vm — максимальная скорость массы, при которой кинетическая энергия может быть поглощена пружиной и внешней силой до достижения цели xy. в основном контроллер проверяет кинетическую энергию, если она меньше, чем требуется, чтобы добраться до точки так быстро, как может двигаться система, он наливает энергию, в противном случае, если ее слишком много, он замедляется, чтобы достичь этой максимальной скорости.   -  person Foad    schedule 20.02.2019
comment
Модель кажется немного сомнительной с численной точки зрения. Это в основном заставляет решатели с контролируемым размером шага останавливаться, поскольку они не могут выполнить свои локальные критерии ошибки (в зависимости от того, какой допуск вы допускаете). Я предполагаю, что это результат объединения уравнения и части алгоритма. В качестве обходного пути: для меня изменение решателя на Forward Euler с размером шага 1 мс заставило модель работать. Тем не менее, это не очень хорошее решение и должно быть просто первым шагом для улучшения модели - что я оставляю на ваше усмотрение :) Одним из способов может быть использование контроллера с тактовой частотой...   -  person Markus A.    schedule 20.02.2019
comment
@МаркусА. Не могли бы вы перевести эти параметры Dymola в графический интерфейс OpenModelica? это 1. Simulation Interval > Interval > 0.01 2. Integration > euler   -  person Foad    schedule 20.02.2019
comment
В основном должно быть правильно, но используйте интервал 1e-3 = 0,001. Метод интеграции Эйлера должен быть в порядке (Эйлер = Форвард Эйлер)   -  person Markus A.    schedule 20.02.2019
comment
@МаркусА. теперь он завершается, но результат кажется неправильным!   -  person Foad    schedule 20.02.2019
comment
Модель выглядит не так. У вас есть ma+kx=F, а затем в операторе if у вас есть F=kx, противодействующая части этого. Обычный подход состоял бы в том, чтобы вычесть kx из F - в качестве альтернативы иметь два члена в F и сложить их вместе.   -  person Hans Olsson    schedule 20.02.2019
comment
Кроме того, кажется, что x0 и x1 являются своего рода стопами. Таким образом, вы должны использовать не abs(x-xy)‹1e-6, а x‹x0 или x›x1.   -  person Hans Olsson    schedule 20.02.2019
comment
@HansOlsson модель неверна. Я пытаюсь создать новую версию здесь. в основном, если общая энергия системы больше, чем она должна быть, внешняя сила рассеивает энергию, в противном случае она перекачивается в систему. но пока не получается.   -  person Foad    schedule 20.02.2019
comment
@МаркусА. и Ганс большое спасибо. Я проверил код на другом компьютере, и он просто работает! окончательную версию можно увидеть здесь. Преимущество этого контроллера по сравнению с ПИД-регулятором заключается в том, что он быстрее и имеет меньше перерегулирований или вообще не имеет их. недостатком, это требует больших вычислительных ресурсов, требует модели и обратной связи по скорости. ваши мысли и комментарии высоко ценятся. Следующий шаг - добавить трение и демпфер.   -  person Foad    schedule 21.02.2019
comment
По какой-то причине, когда я ввожу трение href="https://i.imgur.com/w5LiL1S.png" rel="nofollow noreferrer">нестабильно!   -  person Foad    schedule 21.02.2019
comment
Я написал об этой идее здесь, на Reddit   -  person Foad    schedule 21.02.2019
comment
Я более подробно объяснил математическую подоплеку этой идеи -time-of-a-ma">здесь   -  person Foad    schedule 22.02.2019