You can download this example as a Python script: orientation.py or Jupyter Notebook: orientation.ipynb .
import sympy as sm sm.init_printing(use_latex='mathjax')
After completing this chapter readers will be able to:
In the study of multibody dynamics, we are interested in observing motion of connected and interacting objects in three dimensional space. This observation necessitates the concept of a frame of reference, or reference frame. A reference frame is an abstraction which we define as the set of all points in Euclidean space that are carried by and fixed to the observer of any given state of motion. Practically speaking, it is useful to imagine your eye as an observer of motion. Your eye can orient itself in 3D space to view the motion of objects from any direction and the motion of objects will appear differently in the set of points associated with the reference frame attached to your eye depending on your eye’s orientation.
It is important to note that a reference frame is not equivalent to a coordinate system. Any number of coordinate systems (e.g., Cartesian or spherical) can be used to describe the motion of points or objects in a reference frame. The coordinate system offers a system of measurement in a reference frame. We will characterize a reference frame by a right-handed set of mutually perpendicular unit vectors that can be used to describe its orientation relative to other reference frames and we will align a Cartesian coordinate system with the unit vectors to allow for easy measurement of points fixed or moving in the reference frame.
Vectors have a magnitude, direction, and sense ( \(\pm\) ) but notably not a position. Unit vectors have a magnitude of 1. Unit vectors can be fixed, orientation-wise, to a reference frame. For a reference frame named \(N\) we will define the three mutually perpendicular unit vectors as \(\hat_x, \hat_y, \hat_z\) where these right-handed cross products hold:
(11)¶ \[\begin\hat_x \times \hat_y & = \hat_z \\ \hat_y \times \hat_z & = \hat_x \\ \hat_z \times \hat_x & = \hat_y\end\]
Unit vectors will be designated using the “hat”, e.g. \(\hat\) .
These unit vectors are fixed in the reference frame \(N\) . If a second reference frame \(A\) is defined, also with its set of right-handed mutually perpendicular unit vectors \(\hat_x, \hat_y, \hat_z\) then we can establish the relative orientation of these two reference frames based on the angles among the two frames’ unit vectors.
Starting with two reference frames \(N\) and \(A\) in which their sets of unit vectors are initially aligned, the \(A\) frame can then be simply oriented about the common parallel \(z\) unit vectors of the two frames. We then say “reference frame \(A\) is oriented with respect to reference frame \(N\) about the shared \(z\) unit vectors through an angle \(\theta\) . A visual representation of this orientation looking from the direction of the positive \(z\) unit vector is:
From the above figure these relationships between the \(\hat\) and \(\hat\) unit vectors can be deduced:
These equations can also be written in a matrix form:
This matrix uniquely describes the orientation between the two reference frames and so we give it its own variable:
This matrix \(<>^A\mathbf^N\) maps vectors expressed in the \(N\) frame to vectors expressed in the \(A\) frame. This matrix has an important property, which we will demonstrate with SymPy. Start by creating the matrix:
theta = sm.symbols('theta') A_C_N = sm.Matrix([[sm.cos(theta), sm.sin(theta), 0], [-sm.sin(theta), sm.cos(theta), 0], [0, 0, 1]]) A_C_N\[\begin
If we’d like the inverse relationship between the two sets of unit vectors and \(<>^A\mathbf^N\) is invertible, then:
SymPy can find this matrix inverse:
sm.trigsimp(A_C_N.inv())\[\begin
SymPy can also find the transpose of this matrix;
A_C_N.transpose()\[\begin
Notably, the inverse and the transpose are the same here. This indicates that this matrix is a special orthogonal matrix. All matrices that describe the orientation between reference frames are orthogonal matrices. Following the notation convention, this holds:
(16)¶ \[<>^N\mathbf^A = \left(<>^A\mathbf^N\right)^ = \left(<>^A\mathbf^N\right)^T\]For a \(x\) orientation:
(17)¶ \[\begin\begin 1 & 0 & 0 \\ 0 & \cos & \sin \\ 0 & -\sin & \cos \end\end\]For a \(y\) orientation:
(18)¶ \[\begin\begin \cos & 0 & -\sin \\ 0 & 1 & 0 \\ \sin & 0 & \cos \end\end\]Similar to the simple example above, we can write these equations if the \(\alpha_y\) and \(\alpha_z\) angles relate the \(\hat_y\) and \(\hat_z\) unit vectors to those of \(N\) :
Since we are working with unit vectors the cosine of the angle between each pair of vectors is equivalent to the dot product between the two vectors, so this also holds:
Now the matrix relating the orientation of \(A\) with respect to \(N\) can be formed:
We call \(<>^A\mathbf^N\) the “direction cosine matrix” as a general description of the relative orientation of two reference frames. This matrix uniquely defines the relative orientation between reference frames \(N\) and \(A\) , it is invertible, and its inverse is equal to the transpose, as shown above in the simple example. The determinant of the matrix is also always 1, to ensure both associated frames are right-handed. The direction cosine matrix found in the prior section for a simple orientation is a specific case of this more general definition. The direction cosine matrix is also referred to as a “rotation matrix” or “orientation matrix” in some texts.
Successive orientations of a series of reference frames provides a convenient way to manage orientation among more than a single pair. Below, an additional auxiliary reference frame \(B\) is shown that is simply oriented with respect to \(A\) in the same way that \(A\) is from \(N\) above in the prior section.
We know from the prior sections that we can define these two relationships between each pair of reference frames as follows:
Now, substitute (23) into (24) to get:
(25)¶ \[\begin\begin \hat_x \\ \hat_y \\ \hat_z \end = <>^B\mathbf^A <>^A\mathbf^N \begin \hat_x \\ \hat_y \\ \hat_z \end\end\]
showing that the direction cosine matrix between \(B\) and \(N\) results from matrix multiplying the intermediate direction cosine matrices.
(26)¶ \[<>^B\mathbf^N = <>^B\mathbf^A <>^A\mathbf^N\]This holds for any series of general three dimensional successive orientations and the relation is shown in the following theorem:
(27)¶ \[<>^Z\mathbf^A = <>^Z\mathbf^Y <>^Y\mathbf^X \ldots <>^C\mathbf^B <>^B\mathbf^A\]where frames \(A\) through \(Z\) are succesively oriented.
Using Fig. 4 as an explicit example of this property, we start with the already defined \(<>^A\mathbf^N\) :
A_C_N