PlanarMechanics.DetachableMount
Detachable 2D spring-damper mount whose force and torque are scaled by the attached input signal.
Behaves like a planar spring-damper between frame_a and frame_b with x, y, and phi stiffness, but every force and torque term is multiplied by the attached input. With attached = 1 the mount is a stiff (but compliant, not rigid) connection; with attached = 0 it transmits no force or torque, so the two frames are mechanically decoupled. Driving attached with a smooth/binary release signal lets a connection be switched off mid-simulation without changing the model structure.
The damping is not set directly. Instead, supply the masses and rotational inertias attached on each side; the translational and rotational dampers are then computed for critical damping (or a chosen damping ratio zeta) using the reduced mass 1/(1/m_a + 1/m_b) and reduced inertia 1/(1/J_a + 1/J_b) seen by the relative coordinates. A near-rigid mount damped this way does not ring at its high natural frequency. Leave the opposite side at its default Inf to model a grounded/rigid side, in which case the reduced quantity collapses to the finite mass/inertia.
This component extends from PartialTwoFrames This component extends from MultibodyComponents.Renderable
Usage
MultibodyComponents.PlanarMechanics.DetachableMount(render=false, color=MultibodyComponents.world_default_spring_color(), specular_coefficient=1.5, c_x=1e6, c_y=1e6, c_phi=1e4, m_a=1, m_b=Inf, J_a=1, J_b=Inf, zeta=1, mu=1 / (1 / m_a + 1 / m_b), J_red=1 / (1 / J_a + 1 / J_b), d_x=2 * zeta * sqrt(c_x * mu), d_y=2 * zeta * sqrt(c_y * mu), d_phi=2 * zeta * sqrt(c_phi * J_red), s_relx0=0, s_rely0=0, phi_rel0=0, radius=MultibodyComponents.world_default_force_width(), num_windings=6, N=200, end_ratio=0.1, z_position=0)
Parameters:
| Name | Description | Units | Default value |
|---|---|---|---|
render | – | false | |
color | – | MultibodyCo...ing_color() | |
specular_coefficient | – | 1.5 | |
c_x | Spring constant in x dir | N/m | 1e6 |
c_y | Spring constant in y dir | N/m | 1e6 |
c_phi | Spring constant in phi dir | N.m/rad | 1e4 |
m_a | Mass attached on the frame_a side | kg | 1 |
m_b | Mass attached on the frame_b side (Inf = grounded/rigid side) | kg | Inf |
J_a | Rotational inertia on the frame_a side | kg.m2 | 1 |
J_b | Rotational inertia on the frame_b side (Inf = grounded/rigid side) | kg.m2 | Inf |
zeta | Damping ratio (1 = critical damping) | – | 1 |
s_relx0 | Unstretched spring length | m | 0 |
s_rely0 | Unstretched spring length | m | 0 |
phi_rel0 | Unstretched spring angle | rad | 0 |
radius | Radius of spring coil when rendered | – | MultibodyCo...rce_width() |
num_windings | Number of spring coil windings | – | 6 |
N | Number of points used to render each winding | – | 200 |
end_ratio | Fraction of total length used for the tapered ends | – | 0.1 |
z_position | z-position of the spring in animations | – | 0 |
Connectors
frame_a- Coordinate system (2-dim.) fixed to the component with one cut-force and cut-torque.
All variables are resolved in the planar world frame. (Frame2D)
frame_b- Coordinate system (2-dim.) fixed to the component with one cut-force and cut-torque.
All variables are resolved in the planar world frame. (Frame2D)
attached- This connector represents a real signal as an input to a component (RealInput)
Variables
| Name | Description | Units |
|---|---|---|
s_relx | Relative x position | m |
s_rely | Relative y position | m |
phi_rel | Relative angle | rad |
v_relx | Relative velocity in x direction | m/s |
v_rely | Relative velocity in y direction | m/s |
w_rel | Relative angular velocity | rad/s |
f_x | Force in x direction | N |
f_y | Force in y direction | N |
tau | Torque | N.m |
Behavior
Dict{MIME{Symbol("text/plain")}, String} with 1 entry: MIME type text/plain => "Error displaying result"
Source
"""
Detachable 2D spring-damper mount whose force and torque are scaled by the
`attached` input signal.
Behaves like a planar spring-damper between `frame_a` and `frame_b` with
x, y, and phi stiffness, but every force and torque term is multiplied by the
`attached` input. With `attached = 1` the mount is a stiff (but compliant, not
rigid) connection; with `attached = 0` it transmits no force or torque, so the
two frames are mechanically decoupled. Driving `attached` with a smooth/binary
release signal lets a connection be switched off mid-simulation without changing
the model structure.
The damping is not set directly. Instead, supply the masses and rotational
inertias attached on each side; the translational and rotational dampers are
then computed for critical damping (or a chosen damping ratio `zeta`) using the
reduced mass `1/(1/m_a + 1/m_b)` and reduced inertia `1/(1/J_a + 1/J_b)` seen by
the relative coordinates. A near-rigid mount damped this way does not ring at its
high natural frequency. Leave the opposite side at its default `Inf` to model a
grounded/rigid side, in which case the reduced quantity collapses to the finite
mass/inertia.
"""
component DetachableMount
extends PartialTwoFrames
extends MultibodyComponents.Renderable(color = MultibodyComponents.world_default_spring_color(), render = false)
"Gating signal scaling all mount forces and torques (1 = engaged, 0 = released)"
attached = RealInput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": -50, "x2": 550, "y2": 50, "rot": 90}
},
"tags": []
}
}
"Visualization shape for the mount"
shape = MultibodyComponents.SpringShape(render = render, color = color, num_windings = num_windings, N = N, end_ratio = end_ratio, r = [frame_a.x, frame_a.y, z_position], length_direction = [s_relx, s_rely, 0], width_direction = [0, 0, 1], length = sqrt(s_relx ^ 2 + s_rely ^ 2), width = radius)
"Spring constant in x dir"
parameter c_x::TranslationalSpringConstant = 1e6
"Spring constant in y dir"
parameter c_y::TranslationalSpringConstant = 1e6
"Spring constant in phi dir"
parameter c_phi::RotationalSpringConstant = 1e4
"Mass attached on the frame_a side"
parameter m_a::Mass = 1
"Mass attached on the frame_b side (Inf = grounded/rigid side)"
parameter m_b::Mass = Inf
"Rotational inertia on the frame_a side"
parameter J_a::Inertia = 1
"Rotational inertia on the frame_b side (Inf = grounded/rigid side)"
parameter J_b::Inertia = Inf
"Damping ratio (1 = critical damping)"
parameter zeta::Real = 1
"Reduced translational mass seen by the relative coordinate"
final parameter mu::Mass = 1 / (1 / m_a + 1 / m_b)
"Reduced rotational inertia seen by the relative angle"
final parameter J_red::Inertia = 1 / (1 / J_a + 1 / J_b)
"Damping constant in x dir, critical for the given mass and stiffness"
final parameter d_x::Real = 2 * zeta * sqrt(c_x * mu)
"Damping constant in y dir, critical for the given mass and stiffness"
final parameter d_y::Real = 2 * zeta * sqrt(c_y * mu)
"Damping constant in phi dir, critical for the given inertia and stiffness"
final parameter d_phi::Real = 2 * zeta * sqrt(c_phi * J_red)
"Unstretched spring length"
parameter s_relx0::Length = 0
"Unstretched spring length"
parameter s_rely0::Length = 0
"Unstretched spring angle"
parameter phi_rel0::Angle = 0
"Radius of spring coil when rendered"
parameter radius::Real = MultibodyComponents.world_default_force_width()
"Number of spring coil windings"
parameter num_windings::Real = 6
"Number of points used to render each winding"
parameter N::Integer = 200
"Fraction of total length used for the tapered ends"
parameter end_ratio::Real = 0.1
"z-position of the spring in animations"
parameter z_position::Real = 0
"Relative x position"
variable s_relx::Length(statePriority = 10, initial = 0.0)
"Relative y position"
variable s_rely::Length(statePriority = 10, initial = 0.0)
"Relative angle"
variable phi_rel::Angle(statePriority = 10, initial = 0.0)
"Relative velocity in x direction"
variable v_relx::Velocity(statePriority = 10, initial = 0.0)
"Relative velocity in y direction"
variable v_rely::Velocity(statePriority = 10, initial = 0.0)
"Relative angular velocity"
variable w_rel::AngularVelocity(statePriority = 10, initial = 0.0)
"Force in x direction"
variable f_x::Dyad.Force
"Force in y direction"
variable f_y::Dyad.Force
"Torque"
variable tau::Torque
relations
s_relx = frame_b.x - frame_a.x
s_rely = frame_b.y - frame_a.y
phi_rel = frame_b.phi - frame_a.phi
v_relx = der(s_relx)
v_rely = der(s_rely)
w_rel = der(phi_rel)
tau = attached * (c_phi * (phi_rel - phi_rel0) + d_phi * w_rel)
frame_a.tau = -tau
frame_b.tau = tau
f_x = attached * (c_x * (s_relx - s_relx0) + d_x * v_relx)
f_y = attached * (c_y * (s_rely - s_rely0) + d_y * v_rely)
frame_a.fx = -f_x
frame_b.fx = f_x
frame_a.fy = -f_y
frame_b.fy = f_y
metadata {
"Dyad": {"icons": {"default": "dyad://MultibodyComponents/DetachableMount.svg"}}
}
endFlattened Source
"""
Detachable 2D spring-damper mount whose force and torque are scaled by the
`attached` input signal.
Behaves like a planar spring-damper between `frame_a` and `frame_b` with
x, y, and phi stiffness, but every force and torque term is multiplied by the
`attached` input. With `attached = 1` the mount is a stiff (but compliant, not
rigid) connection; with `attached = 0` it transmits no force or torque, so the
two frames are mechanically decoupled. Driving `attached` with a smooth/binary
release signal lets a connection be switched off mid-simulation without changing
the model structure.
The damping is not set directly. Instead, supply the masses and rotational
inertias attached on each side; the translational and rotational dampers are
then computed for critical damping (or a chosen damping ratio `zeta`) using the
reduced mass `1/(1/m_a + 1/m_b)` and reduced inertia `1/(1/J_a + 1/J_b)` seen by
the relative coordinates. A near-rigid mount damped this way does not ring at its
high natural frequency. Leave the opposite side at its default `Inf` to model a
grounded/rigid side, in which case the reduced quantity collapses to the finite
mass/inertia.
"""
component DetachableMount
frame_a = Frame2D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 50, "y1": 450, "x2": 150, "y2": 550, "rot": 0}
},
"tags": []
}
}
frame_b = Frame2D() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 850, "y1": 450, "x2": 950, "y2": 550, "rot": 0}
},
"tags": []
}
}
parameter render::Boolean = true
parameter color::Real[4] = [0.5, 0.5, 0.5, 1.0]
parameter specular_coefficient::Real = 1.5
"Gating signal scaling all mount forces and torques (1 = engaged, 0 = released)"
attached = RealInput() {
"Dyad": {
"placement": {
"diagram": {"iconName": "default", "x1": 450, "y1": -50, "x2": 550, "y2": 50, "rot": 90}
},
"tags": []
}
}
"Visualization shape for the mount"
shape = MultibodyComponents.SpringShape(render = render, color = color, num_windings = num_windings, N = N, end_ratio = end_ratio, r = [frame_a.x, frame_a.y, z_position], length_direction = [s_relx, s_rely, 0], width_direction = [0, 0, 1], length = sqrt(s_relx ^ 2 + s_rely ^ 2), width = radius)
"Spring constant in x dir"
parameter c_x::TranslationalSpringConstant = 1e6
"Spring constant in y dir"
parameter c_y::TranslationalSpringConstant = 1e6
"Spring constant in phi dir"
parameter c_phi::RotationalSpringConstant = 1e4
"Mass attached on the frame_a side"
parameter m_a::Mass = 1
"Mass attached on the frame_b side (Inf = grounded/rigid side)"
parameter m_b::Mass = Inf
"Rotational inertia on the frame_a side"
parameter J_a::Inertia = 1
"Rotational inertia on the frame_b side (Inf = grounded/rigid side)"
parameter J_b::Inertia = Inf
"Damping ratio (1 = critical damping)"
parameter zeta::Real = 1
"Reduced translational mass seen by the relative coordinate"
final parameter mu::Mass = 1 / (1 / m_a + 1 / m_b)
"Reduced rotational inertia seen by the relative angle"
final parameter J_red::Inertia = 1 / (1 / J_a + 1 / J_b)
"Damping constant in x dir, critical for the given mass and stiffness"
final parameter d_x::Real = 2 * zeta * sqrt(c_x * mu)
"Damping constant in y dir, critical for the given mass and stiffness"
final parameter d_y::Real = 2 * zeta * sqrt(c_y * mu)
"Damping constant in phi dir, critical for the given inertia and stiffness"
final parameter d_phi::Real = 2 * zeta * sqrt(c_phi * J_red)
"Unstretched spring length"
parameter s_relx0::Length = 0
"Unstretched spring length"
parameter s_rely0::Length = 0
"Unstretched spring angle"
parameter phi_rel0::Angle = 0
"Radius of spring coil when rendered"
parameter radius::Real = MultibodyComponents.world_default_force_width()
"Number of spring coil windings"
parameter num_windings::Real = 6
"Number of points used to render each winding"
parameter N::Integer = 200
"Fraction of total length used for the tapered ends"
parameter end_ratio::Real = 0.1
"z-position of the spring in animations"
parameter z_position::Real = 0
"Relative x position"
variable s_relx::Length(statePriority = 10, initial = 0.0)
"Relative y position"
variable s_rely::Length(statePriority = 10, initial = 0.0)
"Relative angle"
variable phi_rel::Angle(statePriority = 10, initial = 0.0)
"Relative velocity in x direction"
variable v_relx::Velocity(statePriority = 10, initial = 0.0)
"Relative velocity in y direction"
variable v_rely::Velocity(statePriority = 10, initial = 0.0)
"Relative angular velocity"
variable w_rel::AngularVelocity(statePriority = 10, initial = 0.0)
"Force in x direction"
variable f_x::Dyad.Force
"Force in y direction"
variable f_y::Dyad.Force
"Torque"
variable tau::Torque
relations
s_relx = frame_b.x - frame_a.x
s_rely = frame_b.y - frame_a.y
phi_rel = frame_b.phi - frame_a.phi
v_relx = der(s_relx)
v_rely = der(s_rely)
w_rel = der(phi_rel)
tau = attached * (c_phi * (phi_rel - phi_rel0) + d_phi * w_rel)
frame_a.tau = -tau
frame_b.tau = tau
f_x = attached * (c_x * (s_relx - s_relx0) + d_x * v_relx)
f_y = attached * (c_y * (s_rely - s_rely0) + d_y * v_rely)
frame_a.fx = -f_x
frame_b.fx = f_x
frame_a.fy = -f_y
frame_b.fy = f_y
metadata {
"Dyad": {"icons": {"default": "dyad://MultibodyComponents/DetachableMount.svg"}}
}
endTest Cases
No test cases defined.
Related
Examples
Experiments
Analyses