问题
I'm trying to simulate Coulomb friction in Modelica. The basic concept is to check if relative velocity speed between to surfaces is less than a constant and the external force which tried to slid surfaces against each other is less than maximum static friction force (normalForce * staticFrictionCoefficient) then the friction force is equal to negative of the external shear force. otherwise, the friction force is equal to the kinetic friction force (normalForce * kineticFrictionCoefficient)in the opposite direction of the sliding direction. I implemented this concept in Modelica as below:
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;
but when I call this function from a model as below:
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;
I see the error:
Translation Error
post-optimization module findZeroCrossings (simulation) failed.
If I remove the abs
function from the defined function, it solves the compiling problem, but the model is wrong! I would appreciate if you could help me know:
- how can I solve this problem?
- how to model friction otherwise?
回答1:
You can use noEvent on the conditions that might generate events in the function. Note that you don't need to extend the model with the function. It should actually not work (to extend a model from a function), but it seems we don't check for it.
The model that compiles for me is below:
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;
回答2:
Your model does work with the 1.11 release. The issue is the extends coulombFriction;
statement. Once you removed it, it should work fine even without the noEvent
calls:
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;
回答3:
I'd recommend to reuse the friction state machine available in the Modelica Standard Library. An example, that works in OpenModelica and other tools, is given by https://github.com/dzimmer/ZimmersModelicaTutorial/blob/master/Tutorial2015/BaseComponents/Friction/IdealDryFriction.mo.
回答4:
Actually, the model I have developed above for Columb friction is wrong. Thanks to this post I could find the correct version:
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;
来源:https://stackoverflow.com/questions/42090222/openmodelica-modelling-coulomb-friction-translation-error-post-optimization-mo