model Spring "Linear 2D translational spring"
extends BaseClasses.TwoConnectorShapes;
parameter StateSelect stateSelect = StateSelect.default "Priority to use phi and w as states"
annotation (
HideResult = true,
Dialog(tab = "Advanced"));
parameter SI.TranslationalSpringConstant c_x(final min = 0, start = 1) "Spring constant in x dir";
parameter SI.TranslationalSpringConstant c_y(final min = 0, start = 1) "Spring constant in y dir";
parameter SI.RotationalSpringConstant c_phi(final min = 0, start = 100000) "Spring constant";
parameter SI.Position s_relx0 = 0 "Unstretched spring length";
parameter SI.Position s_rely0 = 0 "Unstretched spring length";
parameter SI.Angle phi_rel0 = 0 "Unstretched spring angle";
SI.Position s_relx(final stateSelect = stateSelect, start = 0) "Spring length"
annotation (Dialog(
group = "Initialization",
showStartAttribute = true));
SI.Position s_rely(final stateSelect = stateSelect, start = 0) "Spring length"
annotation (Dialog(
group = "Initialization",
showStartAttribute = true));
SI.Angle phi_rel(final stateSelect = stateSelect, start = 0) "Spring angle"
annotation (Dialog(
group = "Initialization",
showStartAttribute = true));
SI.Force f_x "Force in x direction";
SI.Force f_y "Force in y direction";
parameter SI.Position s_small = 1e-10 "Prevent zero-division if distance between frame_a and frame_b is zero"
annotation (Dialog(tab = "Advanced"));
parameter Boolean enableAssert = true "Cause an assert when the distance between frame_a and frame_b < s_small"
annotation (Dialog(tab = "Advanced"));
parameter Integer numberOfWindings = 5 "Number of spring windings"
annotation (Dialog(
tab = "Animation",
group = "Spring coil (if animation = true)",
enable = animate));
input SI.Length width = planarWorld.defaultJointWidth "Width of spring"
annotation (Dialog(
tab = "Animation",
group = "Spring coil (if animation = true)",
enable = animate));
input SI.Length coilWidth = 0.1 * width "Width of spring coil"
annotation (Dialog(
tab = "Animation",
group = "Spring coil (if animation = true)",
enable = animate));
input MB.Types.Color color = Types.Defaults.SpringColor "Color of spring"
annotation (
HideResult = true,
Dialog(
tab = "Animation",
group = "Spring coil (if animation = true)",
enable = animate,
colorSelector = true));
SI.Length length "Distance between the origin of frame_a and the origin of frame_b";
SI.Position r_rel_0[3] "Position vector (3D) from frame_a to frame_b resolved in multibody world frame";
Real e_rel_0[3](each final unit = "1") "Unit vector (3D) in direction from frame_a to frame_b, resolved in multibody world frame";
protected
MB.Visualizers.Advanced.Shape shapeCoil(shapeType = "spring", color = color, specularCoefficient = specularCoefficient, length = length, width = width, height = coilWidth * 2, lengthDirection = e_rel_0, widthDirection = {0, 1, 0}, extra = numberOfWindings, r = MB.Frames.resolve1(planarWorld.R, {frame_a.x, frame_a.y, zPosition}) + planarWorld.r_0, R = planarWorld.R) if planarWorld.enableAnimation and animate;
equation
if enableAssert then
assert(noEvent(s_small < length), "\nThe distance between the origin of frame_a and the origin of frame_b\nof a Spring component became smaller as parameter s_small\n(= a small number, defined in the \"Advanced\" menu). The distance is\nset to s_small, although it is smaller, to avoid a division by zero\nwhen computing the direction of the line force. Possible reasons\nfor this situation:\n- At initial time the distance may already be zero: Change the initial\n positions of the bodies connected by this element.\n- Hardware stops are not modeled or are modeled not stiff enough.\n Include stops, e.g., stiff springs, or increase the stiffness\n if already present.\n- Another error in your model may lead to unrealistically large forces\n and torques that would in reality destroy the stops.\n- The flange_b connector might be defined by a pre-defined motion,\n e.g., with Modelica.Mechanics.Translational.Position and the\n predefined flange_b.s is zero or negative.\n", level = AssertionLevel.warning);
end if;
e_rel_0 = r_rel_0 / Modelica.Mechanics.MultiBody.Frames.Internal.maxWithoutEvent(length, s_small);
f_x = c_x * (s_relx - s_relx0);
f_y = c_y * (s_rely - s_rely0);
length = Modelica.Math.Vectors.length(r_rel_0);
phi_rel = frame_b.phi - frame_a.phi;
r_rel_0 = {s_relx, s_rely, 0};
s_relx = frame_b.x - frame_a.x;
s_rely = frame_b.y - frame_a.y;
frame_a.t = 0;
frame_a.fx = -f_x;
frame_a.fy = -f_y;
frame_b.t = 0;
frame_b.fx = f_x;
frame_b.fy = f_y;
annotation (
Documentation(
revisions = "<html>\n<p>\n<img src=\"modelica://PlanarMechanics/Resources/Images/dlr_logo.png\" alt=\"DLR logo\">\n<strong>Developed 2010 at the DLR Institute of System Dynamics and Control</strong>\n</p>\n</html>",
info = "<html>\n<p>A <em>linear translational spring</em>. x- and y direction stiffness can be parameterized.</p>\n</html>"),
Icon(
coordinateSystem(
preserveAspectRatio = true,
extent = {
{-100, -100},
{100, 100}},
grid = {2, 2}),
graphics = {
Line(
points = {
{-100, 0},
{-58, 0},
{-43, -30},
{-13, 30},
{17, -30},
{47, 30},
{62, 0},
{100, 0}},
thickness = 0.5),
Line(
points = {
{-70, -76},
{-70, 0}},
color = {128, 128, 128}),
Line(
points = {
{70, -78},
{70, 0}},
color = {128, 128, 128}),
Line(
points = {
{-70, -70},
{70, -70}},
color = {128, 128, 128}),
Polygon(
points = {
{60, -67},
{70, -70},
{60, -73},
{60, -67}},
lineColor = {128, 128, 128},
fillColor = {128, 128, 128},
fillPattern = FillPattern.Solid),
Text(
extent = {
{-40, -66},
{40, -42}},
textColor = {128, 128, 128},
textString = "phi_rel"),
Text(
extent = {
{-150, 80},
{150, 40}},
textString = "%name",
textColor = {0, 0, 255})}),
Diagram(
coordinateSystem(
preserveAspectRatio = true,
extent = {
{-100, -100},
{100, 100}},
grid = {2, 2}),
graphics = {
Line(
points = {
{-100, 0},
{-58, 0},
{-43, -30},
{-13, 30},
{17, -30},
{47, 30},
{62, 0},
{100, 0}},
thickness = 0.5),
Line(
points = {
{-68, 0},
{-68, 65}},
color = {128, 128, 128}),
Line(
points = {
{72, 0},
{72, 65}},
color = {128, 128, 128}),
Line(
points = {
{-68, 60},
{72, 60}},
color = {128, 128, 128}),
Polygon(
points = {
{62, 63},
{72, 60},
{62, 57},
{62, 63}},
lineColor = {128, 128, 128},
fillColor = {128, 128, 128},
fillPattern = FillPattern.Solid),
Text(
extent = {
{-20, 40},
{20, 65}},
textColor = {0, 0, 255},
textString = "phi_rel")}));
end Spring;