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, contrary to the ElastoBacklash model)"
parameter Modelica.SIunits.RotationalSpringConstant c(final min = Modelica.Constants.small, start = 100000) "Spring constant (c > 0 required)";
parameter Modelica.SIunits.RotationalDampingConstant d(final min = 0, start = 0) "Damping constant";
parameter Modelica.SIunits.Angle b(final min = 0) = 0 "Total backlash";
parameter Modelica.SIunits.Angle phi_rel0 = 0 "Unstretched spring angle";
extends Modelica.Mechanics.Rotational.Interfaces.PartialCompliantWithRelativeStates;
extends Modelica.Thermal.HeatTransfer.Interfaces.PartialElementaryConditionalHeatPortWithoutT;
protected
final parameter Modelica.SIunits.Angle bMax = 0.5 * b "Backlash in range bMin <= phi_rel - phi_rel0 <= bMax";
final parameter Modelica.SIunits.Angle bMin = -bMax "Backlash in range bMin <= phi_rel - phi_rel0 <= bMax";
Modelica.SIunits.Torque tau_c;
Modelica.SIunits.Torque tau_d;
Modelica.SIunits.Angle phi_diff = phi_rel - phi_rel0;
constant Modelica.SIunits.Angle bEps = 1e-10 "Minimum backlash";
equation
if initial() then
tau_c = if 1.5 * bMax < phi_diff then c * (phi_diff - bMax) else if phi_diff < 1.5 * bMin then c * (phi_diff - bMin) else 0.333333333333333 * c * phi_diff;
tau_d = d * w_rel;
tau = tau_c + tau_d;
lossPower = tau_d * w_rel;
else
tau_c = if abs(b) <= bEps then c * phi_diff else if bMax < phi_diff then c * (phi_diff - bMax) else if phi_diff < bMin then c * (phi_diff - bMin) else 0;
tau_d = d * w_rel;
tau = if abs(b) <= bEps then tau_c + tau_d else if bMax < phi_diff then if tau_c + tau_d <= 0 then 0 else tau_c + tau_d else if phi_diff < bMin then if 0 <= tau_c + tau_d then 0 else tau_c + tau_d else 0;
lossPower = if abs(b) <= bEps then tau_d * w_rel else if bMax < phi_diff then if tau_c + tau_d <= 0 then 0 else tau_d * w_rel else if phi_diff < bMin then if 0 <= tau_c + tau_d then 0 else tau_d * w_rel else 0;
end if;
annotation (
defaultComponentName = "elastoBacklash",
Documentation(info = "<html>\n<p>\nThis element consists of a <strong>backlash</strong> element <strong>connected in series</strong>\nto a <strong>spring</strong> and <strong>damper</strong> element which are <strong>connected in parallel</strong>.\nThe spring constant shall be non-zero, otherwise the component cannot be used.\n</p>\n\n<p>\nIn combination with components IdealGear, the ElastoBacklash2 model\ncan be used to model a gear box with backlash, elasticity and damping.\n</p>\n\n<p>\nDuring initialization, the backlash characteristic is replaced by a continuous\napproximation in the backlash region, in order to reduce problems during\ninitialization, especially for inverse models.\n</p>\n\n<p>\nIf the backlash b is smaller as 1e-10 rad (especially, if b=0),\nthen the backlash is ignored and the component reduces to a spring/damper\nelement in parallel.\n</p>\n\n<p>\nIn the backlash region (-b/2 ≤ flange_b.phi - flange_a.phi - phi_rel0 ≤ b/2) no torque\nis exerted (flange_b.tau = 0). Outside of this region, contact is present and\nthe contact torque is basically computed with a linear\nspring/damper characteristic:\n</p>\n\n<pre>\n desiredContactTorque = c*phi_contact + d*<strong>der</strong>(phi_contact)\n\n phi_contact = phi_rel - phi_rel0 - b/2 <strong>if</strong> phi_rel - phi_rel0 > b/2\n = phi_rel - phi_rel0 + b/2 <strong>if</strong> phi_rel - phi_rel0 < -b/2\n\n phi_rel = flange_b.phi - flange_a.phi;\n</pre>\n\n<p>\nThis torque characteristic leads to the following difficulty:\n</p>\n\n<ul>\n<li> If the damper torque becomes larger as the spring torque and with opposite sign,\n the contact torque would be \"pulling/sticking\" which is unphysical, since during\n contact only pushing torques can occur.</li>\n</ul>\n\n<p>\nIn the literature this issue seems to be not discussed. For this reason, the most simple\napproach is used in the ElastoBacklash2 model, by slightly changing\nthe linear spring/damper characteristic to:\n</p>\n\n<pre>\n // Torque characteristic when phi_rel > phi_rel0\n <strong>if</strong> phi_rel - phi_rel0 < b/2 <strong>then</strong>\n tau_c = 0; // spring torque\n tau_d = 0; // damper torque\n flange_b.tau = 0;\n <strong>else</strong>\n tau_c = c*(phi_rel - phi_rel0); // spring torque\n tau_d = d*<strong>der</strong>(phi_rel); // damper torque\n flange_b.tau = <strong>if</strong> tau_c + tau_d ≤ 0 <strong>then</strong> 0 <strong>else</strong> tau_c + tau_d;\n <strong>end if</strong>;\n</pre>\n\n<p>\nNote, when sticking would occur (tau_c + tau_d ≤ 0), then the contact torque\nis explicitly set to zero.\n</p>\n\n\n<p>\nThis model of backlash is slightly different to the\n<a href=\"modelica://Modelica.Mechanics.Rotational.Components.ElastoBacklash\">ElastoBacklash</a>\ncomponent:\n</p>\n\n<ul>\n<li> An event occurs when contact occurs or when contact is released (contrary to the ElastoBacklash component).</li>\n<li> When contact occurs, the torque changes discontinuously, due to the damping.\n The damping is larger as for the ElastoBacklash component (for the same damping coefficient),\n because the ElastoBacklash component has a heuristic to avoid the discontinuity of the torque when contact occurs.</li>\n<li> For some models, the ElastoBacklash2 component leads to faster simulations\n (as compared when using the ElastBacklash component).</li>\n</ul>\n\n\n<p>\nSee also the discussion\n<a href=\"modelica://Modelica.Mechanics.Rotational.UsersGuide.StateSelection\">State Selection</a>\nin the User's Guide of the Rotational library.\n</p>\n</html>"),
Icon(
coordinateSystem(
preserveAspectRatio = false,
extent = {
{-100, -100},
{100, 100}}),
graphics = {
Line(points = {
{-80, 32},
{-58, 32},
{-48, 0},
{-34, 61},
{-20, 0},
{-8, 60},
{0, 30},
{20, 30}}),
Rectangle(
extent = {
{-60, -10},
{-10, -50}},
fillColor = {192, 192, 192},
fillPattern = FillPattern.Solid),
Line(points = {
{-60, -50},
{0, -50}}),
Line(points = {
{-60, -10},
{0, -10}}),
Line(points = {
{-10, -30},
{20, -30}}),
Line(points = {
{-80, -30},
{-60, -30}}),
Line(points = {
{-80, 32},
{-80, -30}}),
Line(points = {
{20, 30},
{20, -30}}),
Line(points = {
{-90, 0},
{-80, 0}}),
Line(points = {
{90, 0},
{80, 0}}),
Line(points = {
{20, 0},
{60, 0},
{60, -30}}),
Line(points = {
{40, -12},
{40, -40},
{80, -40},
{80, 0}}),
Text(
extent = {
{-150, -130},
{150, -90}},
textString = "b=%b"),
Text(
extent = {
{-150, 100},
{150, 60}},
lineColor = {0, 0, 255},
textString = "%name"),
Text(
extent = {
{-152, -92},
{148, -52}},
textString = "c=%c"),
Line(
visible = useHeatPort,
points = {
{-100, -100},
{-100, -43},
{-34, -43}},
color = {191, 0, 0},
pattern = LinePattern.Dot),
Text(
extent = {
{20, 48},
{80, 10}},
lineColor = {95, 95, 95},
textString = "2")}),
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}},
thickness = 0.5),
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(
points = {
{70, 95},
{80, 92},
{70, 89},
{70, 95}},
lineColor = {128, 128, 128},
fillColor = {128, 128, 128},
fillPattern = FillPattern.Solid),
Text(
extent = {
{-34, 77},
{40, 90}},
lineColor = {128, 128, 128},
textString = "phi_rel"),
Rectangle(
extent = {
{-60, -20},
{-10, -80}},
lineThickness = 0.5,
fillColor = {192, 192, 192},
fillPattern = FillPattern.Solid),
Line(
points = {
{-52, -80},
{0, -80}},
thickness = 0.5),
Line(
points = {
{-52, -20},
{0, -20}},
thickness = 0.5),
Line(
points = {
{-10, -50},
{20, -50}},
thickness = 0.5),
Line(
points = {
{-80, -50},
{-60, -50}},
thickness = 0.5),
Line(
points = {
{-80, 32},
{-80, -50}},
thickness = 0.5),
Line(
points = {
{20, 30},
{20, -50}},
thickness = 0.5),
Line(points = {
{-96, 0},
{-80, 0}}),
Line(
points = {
{96, 0},
{80, 0}},
thickness = 0.5),
Line(
points = {
{20, 0},
{60, 0},
{60, -30}},
thickness = 0.5),
Line(
points = {
{40, -12},
{40, -40},
{80, -40},
{80, 0}},
thickness = 0.5),
Line(
points = {
{30, 0},
{30, 64}},
color = {128, 128, 128}),
Line(
points = {
{30, 60},
{80, 60}},
color = {128, 128, 128}),
Polygon(
points = {
{70, 63},
{80, 60},
{70, 57},
{70, 63}},
lineColor = {128, 128, 128},
fillColor = {128, 128, 128},
fillPattern = FillPattern.Solid),
Text(
extent = {
{39, 60},
{68, 46}},
lineColor = {160, 160, 164},
textString = "b")}));
end ElastoBacklash2;