Моделирование OpenModelica Кулоновское трение: Ошибка трансляции, модуль постоптимизации findZeroCrossings (моделирование) не выполнен

Я пытаюсь смоделировать кулоновское трение в Modelica. основная концепция состоит в том, чтобы проверить, меньше ли относительная скорость между поверхностями, чем постоянная, а внешняя сила, которая пыталась скользить поверхности друг против друга, меньше максимальной статической силы трения (normalForce * staticFrictionCoefficient), то сила трения равна отрицательной внешней силы сдвига. в противном случае сила трения равна кинетической силе трения (normalForce * kineticFrictionCoefficient) в направлении, противоположном направлению скольжения. Я реализовал эту концепцию в Modelica, как показано ниже:

function coulombFriction

  input Real relVel;
  input Real shearForce;
  input Real normalForce;
  input Real statfricco;
  input Real kinfricco;
  output Real fricForce;

algorithm
  if relVel==0 and abs(shearForce)<statfricco*normalForce then
    fricForce:=shearForce;
  else
    fricForce:=kinfricco*normalForce*sign(relVel);
  end if;
end coulombFriction;

но когда я вызываю эту функцию из модели, как показано ниже:

model fricexample_1

  extends coulombFriction;

  //parameters
  parameter Real kco=0.3;
  parameter Real sco=0.4;
  parameter Real nfo=1.0;

  Real sfo;
  Real ffo;
  Real x;
  Real v;

  initial equation
  x=0;
  v=0;

  equation
  v=der(x);
  der(v)=sfo-ffo;
  sfo=time;
  ffo=coulombFriction(relVel=v, shearForce=sfo, normalForce=nfo, statfricco=sco, kinfricco=kco);

  end fricexample_1;

Я вижу ошибку:

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

модуль постоптимизации findZeroCrossings (симуляция) не выполнен.

Если я удаляю функцию abs из определенной функции, это решает проблему компиляции, но модель неверна! Буду признателен, если вы поможете мне узнать:

  1. Как я могу решить эту проблему?
  2. как иначе моделировать трение?

3 ответа

Решение

Ваша модель работает с версией 1.11. Проблема заключается в extends coulombFriction; заявление. После того, как вы удалили его, он должен работать нормально даже без noEvent звонки:

package Friction
  function coulombFriction
    input Real relVel;
    input Real shearForce;
    input Real normalForce;
    input Real statfricco;
    input Real kinfricco;
    output Real fricForce;
  algorithm
    if relVel==0 and abs(shearForce)<statfricco*normalForce then
      fricForce:=shearForce;
    else
      fricForce:=kinfricco*normalForce*sign(relVel);
    end if;
  end coulombFriction;

  model fricexample_1
    parameter Real kco=0.3;
    parameter Real sco=0.4;
    parameter Real nfo=1.0;

    Real sfo;
    Real ffo;
    Real x;
    Real v;

  initial equation
    x = 0;
    v = 0;

  equation
    v = der(x);
    der(v) = sfo-ffo;
    sfo = time;
    ffo = coulombFriction(relVel=v, shearForce=sfo, normalForce=nfo, statfricco=sco, kinfricco=kco);
  end fricexample_1;
end Friction;

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

Модель, которая компилируется для меня ниже:

package Friction

  function coulombFriction
    input Real relVel;
    input Real shearForce;
    input Real normalForce;
    input Real statfricco;
    input Real kinfricco;
    output Real fricForce;
  algorithm
    if noEvent(relVel==0) and noEvent(abs(shearForce)<statfricco*normalForce) then
      fricForce:=shearForce;
    else
      fricForce:=kinfricco*normalForce*sign(relVel);
    end if;
  end coulombFriction;

  model fricexample_1

    //parameters
    parameter Real kco=0.3;
    parameter Real sco=0.4;
    parameter Real nfo=1.0;

    Real sfo;
    Real ffo;
    Real x;
    Real v;

  initial equation
    x = 0;
    v = 0;

  equation
    v = der(x);
    der(v) = sfo-ffo;
    sfo = time;
    ffo = coulombFriction(relVel=v, shearForce=sfo, normalForce=nfo, statfricco=sco, kinfricco=kco);
  end fricexample_1;

end Friction;

Я бы рекомендовал повторно использовать конечный автомат трения, доступный в стандартной библиотеке Modelica. Пример, который работает в OpenModelica и других инструментах, приведен в https://github.com/dzimmer/ZimmersModelicaTutorial/blob/master/Tutorial2015/BaseComponents/Friction/IdealDryFriction.mo.

На самом деле, модель трения Колумба, которую я разработал выше, неверна. Благодаря этому посту я смог найти правильную версию:

package friction1D

  final constant Real eps=1.e-15 "Biggest number such that 1.0 + eps = 1.0";

  function sgn
    input Real inputVar;
    output Real outputVar;
  algorithm
    if noEvent(inputVar < 0) then
     outputVar := -1;
    else
      outputVar := 1;
    end if;
  end sgn;

  function coulombFriction
    input Real relVel;
    input Real shearForce;
    input Real normalForce;
    input Real statfricco;
    input Real kinfricco;
    output Real fricForce;
  algorithm
      if noEvent(abs(relVel) < eps) and noEvent(abs(shearForce) < statfricco * normalForce) then
        fricForce := shearForce;
    else
      fricForce := kinfricco * normalForce * sgn(relVel);
    end if;
  end coulombFriction;

  model fricexample_1
    //parameters
    parameter Real kco = 0.3;
    parameter Real sco = 0.4;
    parameter Real nfo = 1.0;
    parameter Real mass = 1.0;

    Real sfo;
    Real ffo;
    Real x;
    Real v;

  initial equation
    x = 0;
    v = 0;

  algorithm
    sfo := 0.7 * sin(time);
    ffo := coulombFriction(relVel = v, shearForce = sfo, normalForce = nfo, statfricco = sco, kinfricco = kco);

  equation
    v = der(x);
    mass * der(v) = sfo - ffo;

  annotation(
      experiment(StartTime = 0, StopTime = 10, Tolerance = 1e-8, Interval = 0.02),
      __OpenModelica_simulationFlags(lv = "LOG_STATS", outputFormat = "mat", s = "dassl"));

  end fricexample_1;

end friction1D;
Другие вопросы по тегам