Skip to content
LIBRARY
PlanarMechanics.DetachableMount.md

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:

NameDescriptionUnitsDefault value
renderfalse
colorMultibodyCo...ing_color()
specular_coefficient1.5
c_xSpring constant in x dirN/m1e6
c_ySpring constant in y dirN/m1e6
c_phiSpring constant in phi dirN.m/rad1e4
m_aMass attached on the frame_a sidekg1
m_bMass attached on the frame_b side (Inf = grounded/rigid side)kgInf
J_aRotational inertia on the frame_a sidekg.m21
J_bRotational inertia on the frame_b side (Inf = grounded/rigid side)kg.m2Inf
zetaDamping ratio (1 = critical damping)1
s_relx0Unstretched spring lengthm0
s_rely0Unstretched spring lengthm0
phi_rel0Unstretched spring anglerad0
radiusRadius of spring coil when renderedMultibodyCo...rce_width()
num_windingsNumber of spring coil windings6
NNumber of points used to render each winding200
end_ratioFraction of total length used for the tapered ends0.1
z_positionz-position of the spring in animations0

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

NameDescriptionUnits
s_relxRelative x positionm
s_relyRelative y positionm
phi_relRelative anglerad
v_relxRelative velocity in x directionm/s
v_relyRelative velocity in y directionm/s
w_relRelative angular velocityrad/s
f_xForce in x directionN
f_yForce in y directionN
tauTorqueN.m

Behavior

Dict{MIME{Symbol("text/plain")}, String} with 1 entry: MIME type text/plain => "Error displaying result"

Source

dyad
"""
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"}}
}
end
Flattened Source
dyad
"""
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"}}
}
end


Test Cases

No test cases defined.

  • Examples

  • Experiments

  • Analyses