OpenModelica建模库仑摩擦:翻译错误,后优化模块findZeroCrossings(模拟)失败

时间:2017-02-07 12:44:00

标签: simulation modelica openmodelica

我试图在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. 如何塑造摩擦力呢?

4 个答案:

答案 0 :(得分:3)

您可以在可能在函数中生成事件的条件上使用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;

答案 1 :(得分: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;

答案 2 :(得分:2)

我建议重复使用Modelica标准库中提供的摩擦状态机。在OpenModelica和其他工具中有效的示例由https://github.com/dzimmer/ZimmersModelicaTutorial/blob/master/Tutorial2015/BaseComponents/Friction/IdealDryFriction.mo提供。

答案 3 :(得分:0)

实际上,我上面为Columb摩擦开发的模型是错误的。感谢this post,我可以找到正确的版本:

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;