model ElastoBacklash2 "Backlash connected in series to linear spring and damper (backlash is modeled with elasticity; at start of contact the flange torque can jump)"
parameter Modelica.SIunits.TranslationalSpringConstant c(final min = Modelica.Constants.small, start = 100000) "Spring constant (c > 0 required)";
parameter Modelica.SIunits.TranslationalDampingConstant d(final min = 0, start = 0) "Damping constant";
parameter Modelica.SIunits.Position b(final min = 0, displayUnit = "mm") = 0 "Total backlash";
parameter Modelica.SIunits.Position s_rel0(displayUnit = "mm") = 0 "Unstretched spring length";
extends Modelica.Mechanics.Translational.Interfaces.PartialCompliantWithRelativeStates;
extends Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT;
protected
final parameter Modelica.SIunits.Position bMax = 0.5 * b "Backlash in range bMin <= s_rel - s_rel0 <= bMax";
final parameter Modelica.SIunits.Position bMin = -bMax "Backlash in range bMin <= s_rel - s_rel0 <= bMax";
Modelica.SIunits.Force f_c;
Modelica.SIunits.Force f_d;
Modelica.SIunits.Position s_diff = s_rel - s_rel0;
constant Modelica.SIunits.Position bEps = 1e-8 "Minimum backlash";
equation
if initial() then
f_c = if 1.5 * bMax < s_diff then c * (s_diff - bMax) else if s_diff < 1.5 * bMin then c * (s_diff - bMin) else 0.333333333333333 * c * s_diff;
f_d = d * v_rel;
f = f_c + f_d;
lossPower = f_d * v_rel;
else
f_c = if abs(b) <= bEps then c * s_diff else if bMax < s_diff then c * (s_diff - bMax) else if s_diff < bMin then c * (s_diff - bMin) else 0;
f_d = d * v_rel;
f = if abs(b) <= bEps then f_c + f_d else if bMax < s_diff then if f_c + f_d <= 0 then 0 else f_c + f_d else if s_diff < bMin then if 0 <= f_c + f_d then 0 else f_c + f_d else 0;
lossPower = if abs(b) <= bEps then f_d * v_rel else if bMax < s_diff then if f_c + f_d <= 0 then 0 else f_d * v_rel else if s_diff < bMin then if 0 <= f_c + f_d then 0 else f_d * v_rel else 0;
end if;
annotation (
defaultComponentName = "elastoBacklash",
Documentation(info = "<html>\n <p>\n This element consists of a <strong>backlash</strong> element <strong>connected in series</strong>\n to a <strong>spring</strong> and <strong>damper</strong> element which are <strong>connected in parallel</strong>.\n The spring constant shall be non-zero, otherwise the component cannot be used.\n </p>\n <p>\n During initialization, the backlash characteristic is replaced by a continuous\n approximation in the backlash region, in order to reduce problems during\n initialization, especially for inverse models.\n </p>\n <p>\n If the backlash b is smaller as 1e-8 m (especially, if b=0),\n then the backlash is ignored and the component reduces to a spring/damper\n element in parallel.\n </p>\n <p>\n In the backlash region (-b/2 ≤ flange_b.s - flange_a.s - s_rel0 ≤ b/2) no force\n is exerted (flange_b.f = 0). Outside of this region, contact is present and\n the contact force is basically computed with a linear\n spring/damper characteristic:\n </p>\n <pre>\n desiredContactTorque = c*s_contact + d*<strong>der</strong>(s_contact)\n\n s_contact = s_rel - s_rel0 - b/2 <strong>if</strong> s_rel - s_rel0 > b/2\n = s_rel - s_rel0 + b/2 <strong>if</strong> s_rel - s_rel0 < -b/2\n\n s_rel = flange_b.s - flange_a.s;\n </pre>\n\n <p>\n This force characteristic leads to the following difficulty:\n </p>\n <ul>\n <li> If the damper force becomes larger as the spring force and with opposite sign,\n the contact force would be \"pulling/sticking\" which is unphysical, since during\n contact only pushing torques can occur.</li>\n </ul>\n <p>\n In the literature this issue seems to be not discussed. For this reason, the most simple\n approach is used in the ElastoBacklash2 model, by slightly changing\n the linear spring/damper characteristic to:\n </p>\n <pre>\n // Force characteristic when s_rel > s_rel0\n <strong>if</strong> s_rel - s_rel0 < b/2 <strong>then</strong>\n f_c = 0; // spring force\n f_d = 0; // damper force\n flange_b.f = 0;\n <strong>else</strong>\n f_c = c*(s_rel - s_rel0); // spring force\n f_d = d*<strong>der</strong>(s_rel); // damper force\n flange_b.f = <strong>if</strong> f_c + f_d ≤ 0 <strong>then</strong> 0 <strong>else</strong> f_c + f_d;\n <strong>end if</strong>;\n </pre>\n <p>\n Note, when sticking would occur (f_c + f_d ≤ 0), then the contact force\n is explicitly set to zero.\n </p>\n <p>\n This model of backlash is slightly different to the\n <a href=\"modelica://Modelica.Mechanics.Rotational.Components.ElastoBacklash\">ElastoBacklash</a>\n component:\n </p>\n <ul>\n <li> An event occurs when contact occurs or when contact is released.</li>\n <li> When contact occurs, the force changes discontinuously, due to the damping.</li>\n </ul>\n <p>\n See also the discussion\n <a href=\"modelica://Modelica.Mechanics.Rotational.UsersGuide.StateSelection\">State Selection</a>\n in the User's Guide of the Rotational library.\n </p>\n </html>"),
Icon(graphics = {
Line(
visible = useHeatPort,
points = {
{-100, -100},
{-100, -43},
{-34, -43}},
color = {191, 0, 0},
pattern = LinePattern.Dot),
Line(
points = {
{-12, -38},
{-12, 36}},
color = {0, 127, 0}),
Line(
points = {
{-12, -28},
{70, -28},
{70, 24}},
color = {0, 127, 0}),
Line(
points = {
{70, 0},
{98, 0}},
color = {0, 127, 0}),
Line(
points = {
{-12, 24},
{0, 24},
{6, 34},
{18, 14},
{30, 34},
{42, 14},
{54, 34},
{60, 24},
{70, 24}},
color = {0, 127, 0}),
Rectangle(
lineColor = {0, 127, 0},
fillColor = {192, 192, 192},
fillPattern = FillPattern.Solid,
extent = {
{10, -6},
{50, -50}}),
Line(
points = {
{-52, -70},
{28, -70}},
color = {95, 127, 95}),
Polygon(
lineColor = {95, 127, 95},
fillColor = {95, 127, 95},
fillPattern = FillPattern.Solid,
points = {
{58, -70},
{28, -60},
{28, -80},
{58, -70}}),
Line(
visible = useHeatPort,
points = {
{-100, -100},
{-100, -44},
{22, -44},
{22, -28}},
color = {191, 0, 0},
pattern = LinePattern.Dot),
Line(
points = {
{0, -50},
{50, -50},
{50, -6},
{0, -6}},
color = {0, 127, 0}),
Line(
origin = {-120, 0},
points = {
{108, 0},
{80, 0}},
color = {0, 127, 0}),
Line(
origin = {-120, 0},
points = {
{20, 0},
{60, 0},
{60, -30}},
color = {0, 127, 0}),
Line(
origin = {-120, 0},
points = {
{40, -12},
{40, -40},
{80, -40},
{80, 0}},
color = {0, 127, 0}),
Text(
extent = {
{-150, -125},
{150, -95}},
textString = "c=%c"),
Text(
extent = {
{-150, -160},
{150, -130}},
textString = "b=%b")}),
Diagram(
coordinateSystem(
preserveAspectRatio = true,
extent = {
{-100, -100},
{100, 100}}),
graphics = {
Line(points = {
{-80, 32},
{-58, 32},
{-48, 0},
{-34, 60},
{-20, 0},
{-8, 60},
{0, 30},
{20, 30}}),
Line(
points = {
{-68, 32},
{-68, 97}},
color = {128, 128, 128}),
Line(
points = {
{80, 0},
{80, 96}},
color = {128, 128, 128}),
Line(
points = {
{-68, 92},
{72, 92}},
color = {128, 128, 128}),
Polygon(
lineColor = {128, 128, 128},
fillColor = {128, 128, 128},
fillPattern = FillPattern.Solid,
points = {
{70, 95},
{80, 92},
{70, 89},
{70, 95}}),
Text(
textColor = {128, 128, 128},
extent = {
{-34, 77},
{40, 90}},
textString = "s_rel"),
Rectangle(
fillColor = {192, 192, 192},
fillPattern = FillPattern.Solid,
lineThickness = 0.5,
extent = {
{-60, -20},
{-10, -80}}),
Line(
points = {
{-52, -80},
{0, -80}},
thickness = 0.5),
Line(points = {
{-52, -20},
{0, -20}}),
Line(
points = {
{-10, -50},
{20, -50}},
thickness = 0.5),
Line(points = {
{-80, -50},
{-60, -50}}),
Line(
points = {
{-80, 32},
{-80, -50}},
thickness = 0.5),
Line(points = {
{20, 30},
{20, -50}}),
Line(points = {
{-96, 0},
{-80, 0}}),
Line(points = {
{96, 0},
{80, 0}}),
Line(points = {
{20, 0},
{60, 0},
{60, -30}}),
Line(points = {
{40, -12},
{40, -40},
{80, -40},
{80, 0}}),
Line(
origin = {10, 0},
points = {
{30, 0},
{30, 64}},
color = {128, 128, 128}),
Line(
points = {
{40, 60},
{80, 60}},
color = {128, 128, 128}),
Polygon(
lineColor = {128, 128, 128},
fillColor = {128, 128, 128},
fillPattern = FillPattern.Solid,
points = {
{70, 63},
{80, 60},
{70, 57},
{70, 63}}),
Text(
textColor = {160, 160, 164},
extent = {
{39, 60},
{68, 46}},
textString = "b")}));
end ElastoBacklash2;