Drake

The most fundamental object in multibody mechanics is the coordinate frame, or just frame.
Unless specified otherwise, all frames we use are righthanded Cartesian frames with orthogonal unitvector axes x, y, and z forming a basis that represents the frame's orientation, and an origin point O serving as the location of the frame. We use capital letters to denote frames, such as A and B. Here is a typical Drake frame F:
Fz ^ Fy  /  / Frame F  / o > Fx Fo
Frame F's origin point is \(F_O\) (Fo
in code) and its basis is the set of three mutually orthogonal unit vectors \(F_x, F_y, F_z\) (Fx
, Fy
, Fz
). The basis is righthanded because \(F_z = F_x \times F_y\).
There is a unique inertial frame commonly called the World frame W, sometimes called Ground G or the Newtonian Frame N. (Inertial here means not rotating and not accelerating; any frame that has a fixed pose in W is also inertial.) Drake supports the notion of a Model frame, fixed in W and hence inertial, so that a simulation may be built up from multiple independent models each defined with respect to its own Model frame. This corresponds to the <model>
tag in an .sdf
file.
To simplify notation, we allow a frame to be specified in unambiguous contexts where only a point or a basis is required. In those cases, either the frame origin point, or the frame basis formed by its axes, are understood instead. You can infer what is being used by looking at the quantity symbol. For example, for a position vector p_AB
we are using points Ao
and Bo
, while for an angular velocity vector w_AB
we are using the bases Ax,Ay,Az
and Bx,By,Bz
.
A body is fundamentally a frame, so we use the same symbol for both a body and its body frame. For example, a body B has an associated body frame B. When we speak of the "location" or "pose" of a body, we really mean the location of the body frame origin Bo or pose of the body frame B, respectively. Body properties such as inertia and geometry are given with respect to the body frame. We denote a body's center of mass point as \(B_{cm}\) (Bcm
); its location on the body is specified by a position vector from Bo to Bcm. For a rigid body, any frames attached to it are fixed with respect to the body frame. For a flexible body, deformations are measured with respect to the body frame.
When a user initially specifies a body, such as in a <link>
tag of an .sdf
or .urdf
file, there is a link frame L that may be distinct from the body frame B that is used by Drake internally for computation. However, frames L and B are always related by a constant transform that does not change during a simulation. Usersupplied information such as mass properties, visual geometry, and collision geometry are given with respect to frame L; Drake transforms those internally so that they are maintained with respect to B instead.
Given a frame F, we commonly need to work with another frame that is rigidly fixed to frame F, with all axes aligned, but with its origin shifted from Fo to some other point R. We call that an offset frame. In our mathematical notation we would write that \( F_R \). In code we don't have subscripts so we lowercase the point name to make it look like one: Fr
is the closest we can come. Recall that we also permit frame names and body names to serve as points (by using their origins), so if we have a frame E or body B we can create Fe
(rigidly aligned with F but with origin at Eo) or Fb
(rigidly aligned with F but with origin at Bo). Here is a typical example to clarify the use of this notation:
We have the spatial velocity V_WP ( \( ^WV^P \)) of frame P in World, and the spatial velocity V_PB of a frame B that moves with respect to P. We would like to get V_WB, the spatial velocity of frame B in World. To do that we must shift V_WP to get V_WPb ( \( ^WV^{P_B} \)), where Pb is a frame rigidly aligned with P but with its origin at Bo.
This notation is not fully satisfactory since you may not always have available a convenient oneletter name for the point. In that case we suggest that you first define the offset frame by explaining where its origin is to be placed, and give it a locallymeaningful frame name. Then work with the newlynamed frame rather than deriving the name from the original frame. When in doubt, use comments to clarify your precise meaning. That's a good idea even if the notation fits since some readers of your code may not be facile with this notation.
Next topic: Multibody Quantities