Skip to content
LIBRARY
PrismaticWithLengthConstraint.md

PrismaticWithLengthConstraint

Prismatic joint whose translational distance is computed analytically from a length constraint (1 degree of freedom, no potential state). Companion of RevoluteWithLengthConstraint, used to build the prismatic-side assembly joints (JointUSP, JointRRP, JointSSP). The two frames stay parallel and frame_b is translated along axis n by distance = s + s_offset, where s is solved so that the rod length constraint of the enclosing assembly is fulfilled. The parent assembly sets r_a, r_b (the constraint endpoints) and supplies the rod-force projection through the length-constraint element's constraint_residue.

The quadratic length constraint has two solutions. Which one the mechanism is assembled in is determined automatically at initialization: branch_sign is solved for from the initial geometry as the solution closest to s_offset + s_guess, and stays fixed for the rest of the simulation. Set positive_branch to bypass that and force a branch.

This component extends from PartialTwoFrames

Usage

MultibodyComponents.PrismaticWithLengthConstraint(branch_sign=missing, n=[1, 0, 0], s_offset=0, s_guess=0, length_constraint=1, e=n / norm_(n))

Parameters:

NameDescriptionUnitsDefault value
positive_branchForce the larger (true) or smaller (false) root of the length constraint instead of selecting it automatically from s_guessmissing
branch_signSign of the square-root term picking the branch of the loop-closure solution. Determined at initialization, do not set (use s_guess, or positive_branch to force a branch)missing
nAxis of translation, resolved in frame_a (= same as in frame_b)[1, 0, 0]
s_offsetRelative distance offset (distance = s + s_offset)0
s_guessGuess value for the prismatic distance, used to select the configuration0
length_constraintFixed length of the length constraint1

Connectors

  • frame_a - Frame3D is the fundamental 3D connector used for 6DOF motion. Most components have one or several Frame

connectors that can be connected together (Frame3D)

  • frame_b - Frame3D is the fundamental 3D connector used for 6DOF motion. Most components have one or several Frame

connectors that can be connected together (Frame3D)

  • axis - This connector represents a mechanical flange with position and force as the potential and flow variables, respectively. (Flange)

  • bearing - This connector represents a mechanical flange with position and force as the potential and flow variables, respectively. (Flange)

Variables

NameDescriptionUnits
fDriving force in direction of axis of translationN
sRelative distance between frame_a and frame_b along the axism
distance= s + s_offsetm
r_rel_aPosition vector from frame_a to frame_b, resolved in frame_am
r_aPosition vector to the frame_a side of the length constraint, resolved in frame_am
r_bPosition vector to the frame_b side of the length constraint, resolved in frame_bm

Behavior

julia
using MultibodyComponents #hide
using ModelingToolkit #hide
@variables branch_sign #hide
@variables n #hide
@variables s_offset #hide
@variables s_guess #hide
@variables length_constraint #hide
@named sys = MultibodyComponents.PrismaticWithLengthConstraint(branch_sign=branch_sign, n=n, s_offset=s_offset, s_guess=s_guess, length_constraint=length_constraint) #hide
let eqs = full_equations(sys); Base.length(eqs) > 25 ? nothing : eqs end #hide
<< @example-block not executed in draft mode >>

Source

dyad
"""
Prismatic joint whose translational distance is computed analytically from a
length constraint (1 degree of freedom, no potential state). Companion of
`RevoluteWithLengthConstraint`, used to build the prismatic-side assembly joints
(`JointUSP`, `JointRRP`, `JointSSP`). The two frames stay parallel and `frame_b`
is translated along axis `n` by `distance = s + s_offset`, where `s` is solved so
that the rod length constraint of the enclosing assembly is fulfilled. The parent
assembly sets `r_a`, `r_b` (the constraint endpoints) and supplies the rod-force
projection through the length-constraint element's `constraint_residue`.

The quadratic length constraint has two solutions. Which one the mechanism is
assembled in is determined automatically at initialization: `branch_sign` is
solved for from the initial geometry as the solution closest to
`s_offset + s_guess`, and stays fixed for the rest of the simulation. Set
`positive_branch` to bypass that and force a branch.
"""
component PrismaticWithLengthConstraint
  extends PartialTwoFrames()
  axis = Flange() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 710, "y1": 950, "x2": 810, "y2": 1050, "rot": 0}
      },
      "tags": []
    }
  }
  bearing = Flange() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 180, "y1": 950, "x2": 280, "y2": 1050, "rot": 0}
      },
      "tags": []
    }
  }
  "Force the larger (`true`) or smaller (`false`) root of the length constraint instead of selecting it automatically from `s_guess`"
  structural parameter positive_branch::Boolean = missing
  "Sign of the square-root term picking the branch of the loop-closure solution. Determined at initialization, do not set (use `s_guess`, or `positive_branch` to force a branch)"
  parameter branch_sign::Real = missing
  "Axis of translation, resolved in frame_a (= same as in frame_b)"
  parameter n::Real[3] = [1, 0, 0]
  "Relative distance offset (distance = s + s_offset)"
  parameter s_offset::Real = 0
  "Guess value for the prismatic distance, used to select the configuration"
  parameter s_guess::Real = 0
  "Fixed length of the length constraint"
  parameter length_constraint::Real = 1
  final parameter e::Real[3] = n / norm_(n)
  "Driving force in direction of axis of translation"
  variable f::Dyad.Force
  "Relative distance between frame_a and frame_b along the axis"
  variable s::Length
  "= s + s_offset"
  variable distance::Length
  "Position vector from frame_a to frame_b, resolved in frame_a"
  variable r_rel_a::Position[3]
  "Position vector to the frame_a side of the length constraint, resolved in frame_a"
  variable r_a::Position[3]
  "Position vector to the frame_b side of the length constraint, resolved in frame_b"
  variable r_b::Position[3]
relations
  guess s = s_guess
  guess branch_sign = 1
  initial branch_sign = select_branch_position(length_constraint, e, r_a, r_b, s_offset + s_guess, positive_branch)
  axis.s = s
  axis.f = f
  bearing.s = 0
  distance = s_offset + s
  r_rel_a = e * distance
  frame_b.r_0 = frame_a.r_0 + resolve1(frame_a.R, r_rel_a)
  RotationMatrix(frame_b.R) = absolute_rotation(frame_a, planar_rotation(e, 0, 0))
  [0, 0, 0] = frame_a.f + frame_b.f
  [0, 0, 0] = frame_a.tau + frame_b.tau + cross(r_rel_a, frame_b.f)
  distance = compute_position(length_constraint, e, r_a, r_b, branch_sign)
metadata {
  "Dyad": {
    "icons": {"default": "dyad://MultibodyComponents/PrismaticWithLengthConstraint.svg"},
    "labels": [
      {
        "label": "$(instance)",
        "x": 500,
        "y": 200,
        "rot": 0,
        "attrs": {"font-size": "160"}
      }
    ]
  }
}
end
Flattened Source
dyad
"""
Prismatic joint whose translational distance is computed analytically from a
length constraint (1 degree of freedom, no potential state). Companion of
`RevoluteWithLengthConstraint`, used to build the prismatic-side assembly joints
(`JointUSP`, `JointRRP`, `JointSSP`). The two frames stay parallel and `frame_b`
is translated along axis `n` by `distance = s + s_offset`, where `s` is solved so
that the rod length constraint of the enclosing assembly is fulfilled. The parent
assembly sets `r_a`, `r_b` (the constraint endpoints) and supplies the rod-force
projection through the length-constraint element's `constraint_residue`.

The quadratic length constraint has two solutions. Which one the mechanism is
assembled in is determined automatically at initialization: `branch_sign` is
solved for from the initial geometry as the solution closest to
`s_offset + s_guess`, and stays fixed for the rest of the simulation. Set
`positive_branch` to bypass that and force a branch.
"""
component PrismaticWithLengthConstraint
  frame_a = Frame3D() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": -50, "y1": 450, "x2": 50, "y2": 550, "rot": 0}
      },
      "tags": []
    }
  }
  frame_b = Frame3D() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 950, "y1": 450, "x2": 1050, "y2": 550, "rot": 0}
      },
      "tags": []
    }
  }
  axis = Flange() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 710, "y1": 950, "x2": 810, "y2": 1050, "rot": 0}
      },
      "tags": []
    }
  }
  bearing = Flange() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 180, "y1": 950, "x2": 280, "y2": 1050, "rot": 0}
      },
      "tags": []
    }
  }
  "Force the larger (`true`) or smaller (`false`) root of the length constraint instead of selecting it automatically from `s_guess`"
  structural parameter positive_branch::Boolean = missing
  "Sign of the square-root term picking the branch of the loop-closure solution. Determined at initialization, do not set (use `s_guess`, or `positive_branch` to force a branch)"
  parameter branch_sign::Real = missing
  "Axis of translation, resolved in frame_a (= same as in frame_b)"
  parameter n::Real[3] = [1, 0, 0]
  "Relative distance offset (distance = s + s_offset)"
  parameter s_offset::Real = 0
  "Guess value for the prismatic distance, used to select the configuration"
  parameter s_guess::Real = 0
  "Fixed length of the length constraint"
  parameter length_constraint::Real = 1
  final parameter e::Real[3] = n / norm_(n)
  "Driving force in direction of axis of translation"
  variable f::Dyad.Force
  "Relative distance between frame_a and frame_b along the axis"
  variable s::Length
  "= s + s_offset"
  variable distance::Length
  "Position vector from frame_a to frame_b, resolved in frame_a"
  variable r_rel_a::Position[3]
  "Position vector to the frame_a side of the length constraint, resolved in frame_a"
  variable r_a::Position[3]
  "Position vector to the frame_b side of the length constraint, resolved in frame_b"
  variable r_b::Position[3]
relations
  guess s = s_guess
  guess branch_sign = 1
  initial branch_sign = select_branch_position(length_constraint, e, r_a, r_b, s_offset + s_guess, positive_branch)
  axis.s = s
  axis.f = f
  bearing.s = 0
  distance = s_offset + s
  r_rel_a = e * distance
  frame_b.r_0 = frame_a.r_0 + resolve1(frame_a.R, r_rel_a)
  RotationMatrix(frame_b.R) = absolute_rotation(frame_a, planar_rotation(e, 0, 0))
  [0, 0, 0] = frame_a.f + frame_b.f
  [0, 0, 0] = frame_a.tau + frame_b.tau + cross(r_rel_a, frame_b.f)
  distance = compute_position(length_constraint, e, r_a, r_b, branch_sign)
metadata {
  "Dyad": {
    "icons": {"default": "dyad://MultibodyComponents/PrismaticWithLengthConstraint.svg"},
    "labels": [
      {
        "label": "$(instance)",
        "x": 500,
        "y": 200,
        "rot": 0,
        "attrs": {"font-size": "160"}
      }
    ]
  }
}
end


Test Cases

No test cases defined.

  • Examples

  • Experiments

  • Analyses