org.firstinspires.ftc.robotcore.external.navigation

## Class Orientation

- java.lang.Object
- - org.firstinspires.ftc.robotcore.external.navigation.Orientation

-     public class Orientation
      extends java.lang.Object

  Instances of `Orientation` represent a rotated stance in three-dimensional space by way of a set of three successive rotations.

  There are several ways that a particular orientation in three-space can be represented. One way is by specifying a (unit) directional vector about which the orientation is to occur, together with a rotation angle about that axis. This representation is unique up to the sign of the direction and angle; that is a rotation `a` about a vector `v` produces the same rotation as a rotation `-a` about the vector `-v`. While this manner of specifying a rotation is easy to visualize if the vector in question is one of the cardinal axes (ie: X,Y, or Z), many find it more difficult to visualize more complex rotations in this manner.

  An alternative, more common, way to represent a particular orientation in three-space is by means of indicating three angles of rotation about three successive axes. You might for example be familiar with the notions of heading, elevation, and bank angles for aircraft. Unfortunately, there are 24 different yet equivalent ways that a set of three rotational angles about three axes can represent the same effective rotation. As might be expected, this can be the source of much confusion. The 24 different representations break down as follows.

  First is the matter of the axes reference: is the coordinate system in which the referred-to rotational axes reside a coordinate system that moves with (and so remains fixed relative to) the object being rotated, or do the axes remain fixed relative to the world around the object and are unaffected by the object's rotational motion? The former situation is referred to as an `intrinsic` reference perspective while the latter is an `extrinsic` perspective. Both points of view are equally valid methodologies, but one or the other may be more understandable or useful in a given application situation.

  The extrinsic-vs-intrinsic difference accounts for a factor of two in our list of 24 different representations. The remaining factor of 12 breaks down into whether the three rotations all use different axes (and so are a permutation of X, Y, and Z, of which there are six in number), or whether the first and last axes are the same and the middle one different (e.g. Z-Y-Z); this has three choices for the first axis (which is also used for the last) and two remaining choices for the second axis, for a total, again, of six possibilities. The geometry of three-space is such that these twelve choices are the only distinct representational possibilities. As with the extrinsic-vs- intrinsic difference, all twelve of these axis `order`s are equally valid ways of indicating orientation, but in any given application, one way may be more useful or easier to understand than another.

  Even on top of all that, for a given intrinsic-vs-extrinsic distinction, and a given axes ordering, there are two sets of angle rotation that will produce the same orientation. For example, an extrinsic, XZX rotation of (in degrees) 90, -90, 0 is equivalent to an extrinsic, XZX rotation of -90, 90, -180.

  As was mentioned, much confusion has historically arisen from talking about an orientation as a set of three angles without also clearly indicating which of the 24 representational possibilities one is working within. One aim of `Orientation` is to reduce that confusion by being explicitly clear about this issue: an `Orientation` always carries along with it the indication of the `AxesReference` and `AxesOrder` of the orientation. Methods are provided for converting an `Orientation` to and from its associated rotation matrix.

  See Also:
    Euler Angles, Axis-Angle Representation, Axes Conventions, Rotation Matrix

- - ### Nested Class Summary

    Nested Classes
    Modifier and Type | Class and Description
    --- | ---
    `static class` | `Orientation.AngleSet` `Orientation.AngleSet` is used to distinguish between the two sets of angles that will produce a given rotation in a given axes reference and a given axes order

  - ### Field Summary

    Fields
    Modifier and Type | Field and Description
    --- | ---
    `long` | `acquisitionTime` the time on the System.nanoTime() clock at which the data was acquired.
    `AngleUnit` | `angleUnit` the unit in which the angles are expressed
    `AxesOrder` | `axesOrder` the order of axes around which our three rotations occur
    `AxesReference` | `axesReference` whether we have extrinsic or intrinsic rotations
    `float` | `firstAngle` the chronologically first rotation made in the `AxesOrder`
    `float` | `secondAngle` the chronologically second rotation made in the `AxesOrder`
    `float` | `thirdAngle` the chronologically third rotation made in the `AxesOrder`

  - ### Constructor Summary

    Constructors
    Constructor and Description
    `Orientation()`
    `Orientation(AxesReference axesReference, AxesOrder axesOrder, AngleUnit angleUnit, float firstAngle, float secondAngle, float thirdAngle, long acquisitionTime)`

  - ### Method Summary

    All Methods Static Methods Instance Methods Concrete Methods
    Modifier and Type | Method and Description
    --- | ---
    `static Orientation` | `getOrientation(MatrixF rot, AxesReference axesReference, AxesOrder axesOrder, AngleUnit unit)` Given a rotation matrix, and an `AxesReference` and `AxesOrder`, returns an orientation that would produce that rotation matrix.
    `static Orientation` | `getOrientation(MatrixF rot, AxesReference axesReference, AxesOrder axesOrder, AngleUnit unit, Orientation.AngleSet angleSet)` Given a rotation matrix, and an `AxesReference` and `AxesOrder`, returns an orientation that would produce that rotation matrix.
    `OpenGLMatrix` | `getRotationMatrix()` Returns the rotation matrix associated with the receiver `Orientation`.
    `static OpenGLMatrix` | `getRotationMatrix(AxesReference axesReference, AxesOrder axesOrder, AngleUnit unit, float firstAngle, float secondAngle, float thirdAngle)` Returns the rotation matrix associated with a particular set of three rotational angles.
    `Orientation` | `toAngleUnit(AngleUnit angleUnit)` Converts this `Orientation` to one with the indicated angular units.
    `Orientation` | `toAxesOrder(AxesOrder axesOrder)` Converst the `Orientation` to an equivalent one with the indicated ordering of axes
    `Orientation` | `toAxesReference(AxesReference axesReference)` Converts the `Orientation` to an equivalent one with the indicted point of view.
    `java.lang.String` | `toString()`

    - ### Methods inherited from class java.lang.Object

      `clone, equals, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait`

- - ### Field Detail

    - #### axesReference

          public AxesReference axesReference

      whether we have extrinsic or intrinsic rotations
      See Also:
        `axesOrder`

    - #### axesOrder

          public AxesOrder axesOrder

      the order of axes around which our three rotations occur
      See Also:
        `axesReference`

    - #### angleUnit

          public AngleUnit angleUnit

      the unit in which the angles are expressed

    - #### firstAngle

          public float firstAngle

      the chronologically first rotation made in the `AxesOrder`

    - #### secondAngle

          public float secondAngle

      the chronologically second rotation made in the `AxesOrder`

    - #### thirdAngle

          public float thirdAngle

      the chronologically third rotation made in the `AxesOrder`

    - #### acquisitionTime

          public long acquisitionTime

      the time on the System.nanoTime() clock at which the data was acquired. If no timestamp is associated with this particular set of data, this value is zero.

  - ### Constructor Detail

    - #### Orientation

          public Orientation()

    - #### Orientation

          public Orientation(AxesReference axesReference,
                             AxesOrder axesOrder,
                             AngleUnit angleUnit,
                             float firstAngle,
                             float secondAngle,
                             float thirdAngle,
                             long acquisitionTime)

  - ### Method Detail

    - #### toAngleUnit

          public Orientation toAngleUnit(AngleUnit angleUnit)

      Converts this `Orientation` to one with the indicated angular units.
      Parameters:
        `angleUnit` - the units to use in the returned [@link Orientation}
      Returns:
        a new [@link Orientation} with the same data but in the indicated units

    - #### toAxesReference

          public Orientation toAxesReference(AxesReference axesReference)

      Converts the `Orientation` to an equivalent one with the indicted point of view.
      Parameters:
        `axesReference` - whether we wish to consider rotations from an extrinsic or intrinsic point of view
      Returns:
        an equivalent orientation but with the indicated point of view.

    - #### toAxesOrder

          public Orientation toAxesOrder(AxesOrder axesOrder)

      Converst the `Orientation` to an equivalent one with the indicated ordering of axes
      Parameters:
        `axesOrder` - the desired ordering of axes
      Returns:
        an equivalent orientation with the indicated axes order

    - #### toString

          public java.lang.String toString()

      Overrides:
        `toString` in class `java.lang.Object`

    - #### getRotationMatrix

          public OpenGLMatrix getRotationMatrix()

      Returns the rotation matrix associated with the receiver `Orientation`.
      Returns:
        the rotation matrix associated with the receiver `Orientation`.
      See Also:
        `getRotationMatrix(AxesReference, AxesOrder, AngleUnit, float, float, float)`, Rotation Matrix

    - #### getRotationMatrix

          public static OpenGLMatrix getRotationMatrix(AxesReference axesReference,
                                                       AxesOrder axesOrder,
                                                       AngleUnit unit,
                                                       float firstAngle,
                                                       float secondAngle,
                                                       float thirdAngle)

      Returns the rotation matrix associated with a particular set of three rotational angles.
      Returns:
        the rotation matrix associated with a particular set of three rotational angles.
      See Also:
        `getRotationMatrix()`, Rotation Matrix

    - #### getOrientation

          public static Orientation getOrientation(MatrixF rot,
                                                   AxesReference axesReference,
                                                   AxesOrder axesOrder,
                                                   AngleUnit unit)

      Given a rotation matrix, and an `AxesReference` and `AxesOrder`, returns an orientation that would produce that rotation matrix.
      Parameters:
        `rot` - the matrix whose orientation is to be determined
        `axesReference` - whether wish an extrinsic or intrinsic reference for the axes
        `axesOrder` - the order in which the axes are to be rotated
        `unit` - the angle units in which the orientation is to be returned
      Returns:
        an orientation that will produce the given rotation matrix
      See Also:
        `Orientation`, `getOrientation(MatrixF, AxesReference, AxesOrder, AngleUnit, AngleSet)`, Rotation Matrix

    - #### getOrientation

          public static Orientation getOrientation(MatrixF rot,
                                                   AxesReference axesReference,
                                                   AxesOrder axesOrder,
                                                   AngleUnit unit,
                                                   Orientation.AngleSet angleSet)

      Given a rotation matrix, and an `AxesReference` and `AxesOrder`, returns an orientation that would produce that rotation matrix.
      Parameters:
        `rot` - the matrix whose orientation is to be determined
        `axesReference` - whether wish an extrinsic or intrinsic reference for the axes
        `axesOrder` - the order in which the axes are to be rotated
        `unit` - the angle units in which the orientation is to be returned
        `angleSet` - which of the two sets angles which can produce the rotation matrix is desired
      Returns:
        an orientation that will produce the given rotation matrix
      See Also:
        `getRotationMatrix(AxesReference, AxesOrder, AngleUnit, float, float, float)`, Rotation Matrix