Skip to content
LIBRARY
PartialOrientation.md

PartialOrientation

Partial component providing orientation state variables for a 3D frame.

Extends this to get frame_a, w_a, and z_a with the orientation parameterized by either Euler angles or quaternions.

Usage

MultibodyComponents.PartialOrientation(k=0.1)

Parameters:

NameDescriptionUnitsDefault value
orientation_stateOrientationState.None()
sequence[1, 2, 3]
statePriority10
k0.1

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)

Variables

NameDescriptionUnits
w_aAbsolute angular velocity of frame_a resolved in frame_arad/s
z_aAbsolute angular acceleration of frame_a resolved in frame_arad/s2
QUnit quaternion with [w,i,j,k]
Q_hatNon-unit quaternion with [w,i,j,k]
Q_hat_d
n_q
c_q
phiEuler anglesrad
phidrad/s
phiddrad/s2

Source

dyad
"""
Partial component providing orientation state variables for a 3D frame.

Extends this to get `frame_a`, `w_a`, and `z_a` with the orientation
parameterized by either Euler angles or quaternions.
"""
partial component PartialOrientation
  frame_a = Frame3D() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 0, "y1": 450, "x2": 100, "y2": 550, "rot": 0}
      },
      "tags": []
    }
  }
  structural parameter orientation_state::OrientationState = OrientationState.None()
  structural parameter sequence::Integer[3] = [1, 2, 3]
  structural parameter statePriority::Integer = 10
  "Absolute angular velocity of frame_a resolved in frame_a"
  variable w_a::AngularVelocity(statePriority = case(orientation_state, OrientationState.Quaternion) ? 10 : 0, initial = case(orientation_state, OrientationState.Quaternion) ? [0.0, 0, 0] : missing)[3]
  "Absolute angular acceleration of frame_a resolved in frame_a"
  variable z_a::AngularAcceleration[3]
  "Unit quaternion with [w,i,j,k]"
  variable Q::Real[4] if case(orientation_state, OrientationState.Quaternion)
  "Non-unit quaternion with [w,i,j,k]"
  variable Q_hat::Real(statePriority = statePriority, initial = [1.0, 0, 0, 0])[4] if case(orientation_state, OrientationState.Quaternion)
  variable Q_hat_d::Real[4] if case(orientation_state, OrientationState.Quaternion)
  variable n_q::Real if case(orientation_state, OrientationState.Quaternion)
  variable c_q::Real if case(orientation_state, OrientationState.Quaternion)
  parameter k::Real = 0.1 if case(orientation_state, OrientationState.Quaternion)
  "Euler angles"
  variable phi::Angle(statePriority = statePriority, initial = [0, 0, 0])[3] if case(orientation_state, OrientationState.Euler)
  variable phid::AngularVelocity(statePriority = statePriority, initial = [0, 0, 0])[3] if case(orientation_state, OrientationState.Euler)
  variable phidd::AngularAcceleration[3] if case(orientation_state, OrientationState.Euler)
  structural variable Rrel::Native = case(orientation_state, OrientationState.Euler) ? axes_rotations(sequence, phi, phid) : (case(orientation_state, OrientationState.Quaternion) ? from_Q(Q) : nullrotation())
relations
  z_a = der(w_a)
  switch orientation_state
    case Quaternion
      # guess Q_hat = Q # TODO: Ideally it should be possible to provide this guess, but due to dyad codegen to initial equations the guess propagation is not working correctly and ODEProblem gets stuck. Once the initial condition for Q codegens to __initial_conditions, we can start providing this guess again.
      n_q = dot(Q_hat, Q_hat)
      c_q = k * (1 - n_q)
      der(Q_hat) = Q_hat_d
      Q_hat_d = omega_matrix(w_a) * Q_hat / 2 + c_q * Q_hat
      Q = Q_hat / sqrt(n_q)
    case Euler
      phid = der(phi)
      phidd = der(phid)
      w_a = angular_velocity2(Rrel)
    case None
  end
end
Flattened Source
dyad
"""
Partial component providing orientation state variables for a 3D frame.

Extends this to get `frame_a`, `w_a`, and `z_a` with the orientation
parameterized by either Euler angles or quaternions.
"""
partial component PartialOrientation
  frame_a = Frame3D() {
    "Dyad": {
      "placement": {
        "diagram": {"iconName": "default", "x1": 0, "y1": 450, "x2": 100, "y2": 550, "rot": 0}
      },
      "tags": []
    }
  }
  structural parameter orientation_state::OrientationState = OrientationState.None()
  structural parameter sequence::Integer[3] = [1, 2, 3]
  structural parameter statePriority::Integer = 10
  "Absolute angular velocity of frame_a resolved in frame_a"
  variable w_a::AngularVelocity(statePriority = case(orientation_state, OrientationState.Quaternion) ? 10 : 0, initial = case(orientation_state, OrientationState.Quaternion) ? [0.0, 0, 0] : missing)[3]
  "Absolute angular acceleration of frame_a resolved in frame_a"
  variable z_a::AngularAcceleration[3]
  "Unit quaternion with [w,i,j,k]"
  variable Q::Real[4] if case(orientation_state, OrientationState.Quaternion)
  "Non-unit quaternion with [w,i,j,k]"
  variable Q_hat::Real(statePriority = statePriority, initial = [1.0, 0, 0, 0])[4] if case(orientation_state, OrientationState.Quaternion)
  variable Q_hat_d::Real[4] if case(orientation_state, OrientationState.Quaternion)
  variable n_q::Real if case(orientation_state, OrientationState.Quaternion)
  variable c_q::Real if case(orientation_state, OrientationState.Quaternion)
  parameter k::Real = 0.1 if case(orientation_state, OrientationState.Quaternion)
  "Euler angles"
  variable phi::Angle(statePriority = statePriority, initial = [0, 0, 0])[3] if case(orientation_state, OrientationState.Euler)
  variable phid::AngularVelocity(statePriority = statePriority, initial = [0, 0, 0])[3] if case(orientation_state, OrientationState.Euler)
  variable phidd::AngularAcceleration[3] if case(orientation_state, OrientationState.Euler)
  structural variable Rrel::Native = case(orientation_state, OrientationState.Euler) ? axes_rotations(sequence, phi, phid) : (case(orientation_state, OrientationState.Quaternion) ? from_Q(Q) : nullrotation())
relations
  z_a = der(w_a)
  switch orientation_state
    case Quaternion
      # guess Q_hat = Q # TODO: Ideally it should be possible to provide this guess, but due to dyad codegen to initial equations the guess propagation is not working correctly and ODEProblem gets stuck. Once the initial condition for Q codegens to __initial_conditions, we can start providing this guess again.
      n_q = dot(Q_hat, Q_hat)
      c_q = k * (1 - n_q)
      der(Q_hat) = Q_hat_d
      Q_hat_d = omega_matrix(w_a) * Q_hat / 2 + c_q * Q_hat
      Q = Q_hat / sqrt(n_q)
    case Euler
      phid = der(phi)
      phidd = der(phid)
      w_a = angular_velocity2(Rrel)
    case None
  end
metadata {}
end


Test Cases

No test cases defined.

  • Examples

  • Experiments

  • Analyses