Skip to content
LIBRARY
PlanarMechanics.PlanarToMultiBody.md

PlanarMechanics.PlanarToMultiBody

Adapter between a 2D planar frame (frame_a) and a full 3D frame (frame_b).

The planar position (x, y) and orientation angle phi are lifted into 3D: the 3D origin is placed at [x, y, z_position] and the 3D orientation is a rotation about the world z-axis by phi. Planar forces (fx, fy) and torque tau are transmitted to the 3D side; the out-of-plane reactions (normal force and tilting torques) are absorbed by the plane.

This component fully determines the orientation and position of frame_b, so it acts as a root element for the attached 3D subtree.

Usage

MultibodyComponents.PlanarMechanics.PlanarToMultiBody(z_position=MultibodyComponents.world_default_z_position())

Parameters:

NameDescriptionUnitsDefault value
z_positionOut-of-plane position where frame_b sits in the 3D worldmMultibodyCo..._position()

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 - Frame3D is the fundamental 3D connector used for 6DOF motion. Most components have one or several Frame

connectors that can be connected together (Frame3D)

Variables

NameDescriptionUnits
fzOut-of-plane (normal) reaction force
tau_perpOut-of-plane reaction torques (about the in-plane axes)
R_rel3D orientation matrix lifted from the planar angle

Behavior

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

Source

dyad
"""
Adapter between a 2D planar frame (`frame_a`) and a full 3D frame (`frame_b`).

The planar position `(x, y)` and orientation angle `phi` are lifted into 3D: the
3D origin is placed at `[x, y, z_position]` and the 3D orientation is a rotation
about the world z-axis by `phi`. Planar forces `(fx, fy)` and torque `tau` are
transmitted to the 3D side; the out-of-plane reactions (normal force and
tilting torques) are absorbed by the plane.

This component fully determines the orientation and position of `frame_b`, so it
acts as a root element for the attached 3D subtree.
"""
component PlanarToMultiBody
  "Planar frame"
  frame_a = Frame2D() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": -50, "y1": 450, "x2": 50, "y2": 550, "rot": 0}
      },
      "tags": []
    }
  }
  "3D frame"
  frame_b = Frame3D() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 950, "y1": 450, "x2": 1050, "y2": 550, "rot": 0}
      },
      "tags": []
    }
  }
  "Out-of-plane position where `frame_b` sits in the 3D world"
  parameter z_position::Length = MultibodyComponents.world_default_z_position()
  "Out-of-plane (normal) reaction force"
  variable fz::Real
  "Out-of-plane reaction torques (about the in-plane axes)"
  variable tau_perp::Real[2]
  "3D orientation matrix lifted from the planar angle"
  variable R_rel::Real[3, 3]
relations
  R_rel = MultibodyComponents.RR(MultibodyComponents.planar_rotation([0, 0, 1], frame_a.phi, der(frame_a.phi)))
  # position: lift the planar point into 3D
  frame_b.r_0 = planar_world_position() + transpose(planar_world_orientation()) * [frame_a.x, frame_a.y, z_position]
  # orientation: rotation about the world z-axis by phi
  frame_b.R = R_rel * planar_world_orientation()
  # force balance (fz absorbs the out-of-plane reaction)
  [frame_a.fx, frame_a.fy, fz] + transpose(R_rel) * frame_b.f = [0, 0, 0]
  # torque balance (tau_perp absorbs the out-of-plane reactions)
  [tau_perp[1], tau_perp[2], frame_a.tau] + transpose(R_rel) * frame_b.tau = [0, 0, 0]
metadata {
  "Dyad": {
    "icons": {"default": "dyad://MultibodyComponents/PlanarToMultiBody.svg"},
    "labels": [
      {
        "label": "$(instance)",
        "x": 500,
        "y": 150,
        "rot": 0,
        "attrs": {"font-size": "160"}
      }
    ]
  }
}
end
Flattened Source
dyad
"""
Adapter between a 2D planar frame (`frame_a`) and a full 3D frame (`frame_b`).

The planar position `(x, y)` and orientation angle `phi` are lifted into 3D: the
3D origin is placed at `[x, y, z_position]` and the 3D orientation is a rotation
about the world z-axis by `phi`. Planar forces `(fx, fy)` and torque `tau` are
transmitted to the 3D side; the out-of-plane reactions (normal force and
tilting torques) are absorbed by the plane.

This component fully determines the orientation and position of `frame_b`, so it
acts as a root element for the attached 3D subtree.
"""
component PlanarToMultiBody
  "Planar frame"
  frame_a = Frame2D() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": -50, "y1": 450, "x2": 50, "y2": 550, "rot": 0}
      },
      "tags": []
    }
  }
  "3D frame"
  frame_b = Frame3D() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 950, "y1": 450, "x2": 1050, "y2": 550, "rot": 0}
      },
      "tags": []
    }
  }
  "Out-of-plane position where `frame_b` sits in the 3D world"
  parameter z_position::Length = MultibodyComponents.world_default_z_position()
  "Out-of-plane (normal) reaction force"
  variable fz::Real
  "Out-of-plane reaction torques (about the in-plane axes)"
  variable tau_perp::Real[2]
  "3D orientation matrix lifted from the planar angle"
  variable R_rel::Real[3, 3]
relations
  R_rel = MultibodyComponents.RR(MultibodyComponents.planar_rotation([0, 0, 1], frame_a.phi, der(frame_a.phi)))
  # position: lift the planar point into 3D
  frame_b.r_0 = planar_world_position() + transpose(planar_world_orientation()) * [frame_a.x, frame_a.y, z_position]
  # orientation: rotation about the world z-axis by phi
  frame_b.R = R_rel * planar_world_orientation()
  # force balance (fz absorbs the out-of-plane reaction)
  [frame_a.fx, frame_a.fy, fz] + transpose(R_rel) * frame_b.f = [0, 0, 0]
  # torque balance (tau_perp absorbs the out-of-plane reactions)
  [tau_perp[1], tau_perp[2], frame_a.tau] + transpose(R_rel) * frame_b.tau = [0, 0, 0]
metadata {
  "Dyad": {
    "icons": {"default": "dyad://MultibodyComponents/PlanarToMultiBody.svg"},
    "labels": [
      {
        "label": "$(instance)",
        "x": 500,
        "y": 150,
        "rot": 0,
        "attrs": {"font-size": "160"}
      }
    ]
  }
}
end


Test Cases

No test cases defined.