Actin®  Version 5.2.0
Software for Robotics Simulation and Control
Guiding Software Principles

Actin C++ Coding Standard

Overview

Though Actin® comes with a number of applications, it is primarily a software toolkit that can be integrated into any application. This section gives principles used in developing the toolkit.

This document is intended to guide the reader in understanding the Actin code and how to use it to develop C++ software. It assumes that the reader has familiarity with C++ and the language used to describe its constructs. To make it readable, this document is not comprehensive. The many details left out of this document can be found in the class documentation, which is also provided with the toolkit.

Quantities are represented in this document as described below:

  • Class names are italicized, for example: EcVector.
  • Variable names are italicized, for example: m_Position.
  • Filenames are quoted, for example: “ecVector.h”.
  • Code is represented with a fixed font, for example: vector.setX(2.0);

In developing this software toolkit, Developers have defined and adhered to a set of guiding principles to make it easier to understand and use the toolkit. These are described below.

Classes

With few exceptions, classes include implementation of the “big four” methods: the constructor, the destructor, the copy constructor, and the equal operator. The copy constructor and equal operator are deep (e.g., the contents of a pointer are copied, not the pointer value itself) except where noted in the class documentation and header files. If any of the big four are not implemented, they are protected in the header file.

Where relevant, classes have a clone operator. This is also called a virtual constructor—it returns a new’ed copy of itself as a pointer of its appropriate base class. Clone methods make a deep copy. This allows objects to be used as prototypes. Most classes also implement operator==() for testing.

Identifiers

All member functions besides constructors and destructors begin with a lower-case letter and use the camel-hump style, with each word in the name beginning with a capital, for example, printResults.

All member variables begin with the prefix “m_”, followed by a capital letter if the variable represents a member object or basic type. For example, m_Range.

Static member variables begin with the prefix “m_the”. For example, m_theCount. Class names begin with the prefix “Ec” followed by a capital and use the camel-hump style. For example, EcPolygonRootFinder.

Accessors use const type& variableName() or getVariableName(const type& var). Mutators use setVariableName(const type& var). (Basic types, like int and double, are typically passed by value, but objects are passed by reference.)

Protection

Member variables are always protected—no variables or methods are private. This allows you more flexibility when subclassing. Whenever there is a chance a method might be correctly called within another object, it is declared public, even if it is not used in a public manner in the toolkit code.

Virtualness

Member functions as a rule are declared virtual. This provides maximum flexibility in subclassing. A few special, basic classes (EcVector, EcOrientation, and EcXmlBasicType, EcXmlVector, EcXmlOrientation, EcCoordinateSystemTransformation EcGeneralForce, and EcGeneralMotion) are nonvirtual to improve runtime.

Constness

All member functions that do not modify member data are declared const. It can be appropriate to have both const and nonconst versions of a method, such as when returning const and nonconst pointers or references. Accessors that return member variables return const references. Mutators pass const references. Static member variables that are not basic types (int, double, etc.) are const.

Pointers

Pointers are always set to EcNULL (which equals 0) when they are not valid. Note it is always safe to delete a null pointer to an object. It is not always safe to delete[] a null array pointer, and these should be checked first. Member pointer variables are prefixed with "m_p”, for example m_pImage.

Factory Methods

Objects are created in virtual factory methods. That is, “new” is rarely used outside of methods specifically for creating objects. Generally, factory methods should be prefixed with “new”. For example, EcImage* newImage(). The use of factory methods allows you to subclass an object and replace member variables with subclassed versions.

Multiple Inheritance

Multiple inheritance is not used in the toolkit.

Units

All units are SI unless the variable or method name includes the units. For example, lengthInches would be the length in inches, while length would be the length in meters.

Macros

Macros and macro-like functions are all named starting with “Ec” followed by upper-case letters. For example a macro to warn the user would be EcWARN.

Raster Data

Raster data is ordered consistently using one of two methods.

  • Image and image-like raster data are ordered such that image(x,y) has x incrementing left to right and y incrementing top to bottom (i.e., [column,row]). Position (0,0) is always in the upper left-hand corner.
  • Matrices and other non-image mathematical formulations are ordered such that matrix(i,j) has i incrementing top to bottom and j incrementing left to right (i.e., [row,column]). As with images, position (0,0) is the upper left-hand corner entry.

Filenames

Classes are defined in .h files and implemented in .cpp files. Each set of .h and .cpp files defines only one class. Filenames should be similar to class names, with “ec” as a prefix. So, “ecJointActuator.h” would be the filename for class EcJointActuator, and “ecPolygon.h” would be the filename for EcPolygon. In all cases, filenames start with a lower-case letter.

Extension Avoidance

Microsoft-specific extensions are avoided in the toolkit, which builds under Windows and Linux.

Exception Handling

In the toolkit, exception handling is avoided in favor of null pointer return in most cases. This allows general good practice (checking pointers) to overlap with error handling and leads to less cluttered, faster code. There are three areas in which exception handling may be used.

  • When it is required by other (third party) software.
  • When there is no appropriate return type to flag an error.
  • When an error condition requires a lot of information or information that is different from nonexception cases.

Friends

The use of friend classes is avoided in the toolkit. Friendship is not inherited, complicating reuse.

Fundamental Classes

Data Structures

The data structures that will be used in the description of the Actin toolkit include the vector, tensor, list, map and tree. In the description below, constant time refers to the ability to perform an operation in a fixed amount of time regardless of the number of elements in the data structure. The term linear time refers to the ability to perform a task in a time that is proportional to the number of elements in the data structure. The term NULL refers to any symbol representing emptiness—for C++ pointers this is usually the zero value.

Vector

A vector data structure is a container of any data type that allows constant-time access to any element. Inserting or deleting elements requires linear time. It is equivalent to a standard array as used in C++, with the addition that part of this data structure is its size. Characteristically, data in a vector cannot be easily inserted or deleted. Vectors are used widely in the toolkit for storing and accessing data that is fixed in size, such as joint positions, joint rates, vertices, end-effectors, and so forth.

Tensor

A tensor is an array of n-dimensional data that allows access in constant time for fixed n. A vector is a substitute for a one-dimensional tensor, but it is given its own category above because of its importance. Another important type of tensor is the array, which is a two-dimensional tensor. Data in a tensor cannot be easily inserted or deleted. Tensors are used widely in the toolkit for multidimensional data, such as images, Jacobians, link-collision maps, and so forth.

List

A list data structure is a linear sequence of elements each of which holds a reference or pointer to its predecessor and its successor. The head of the list has a NULL predecessor and the tail has a NULL successor. All elements can be accessed sequentially in linear time, though linear time is also required to access any particular element. Elements can be inserted and deleted in constant time. Lists are not used widely in the toolkit.

Map

A map data structure represents a one-to-one mapping between data types, often using a hash table. For example, a map might provide integers (the values) as a function of strings (the keys). A map represents this data in a way that allows constant- or log-time (depending on the implementation) access to a value given its key. Maps are used widely in the toolkit for organization. After loading, for each manipulator, links are mapped with string labels as keys.

Set

A set data structure represents a collection of unique types. If a type is added to a set more than once, only one resides in the set. A set represents this data in a way that allows constant- or log-time (depending on the implementation) access to a given value in the set. Sets are used sparingly in the toolkit for organization.

Tree

A tree data structure is a collection of elements into a hierarchy such that each element has a unique parent but may have multiple children. The root of the tree has a NULL parent. Accessing any particular element in the tree may require log or linear time, depending on organization. Searches and operations can proceed in depth-first or breadth-first ordering. Trees are used widely in the toolkit to implement control systems that can be configured at run time.

Basic Types

The table below lists the basic data types used in the toolkit and their description. More complex classes are created by composing these. Note that all class names in this document are prefixed with “Ec”. This parallels their implementation in code to avoid namespace conflicts with other source code.

Basic data types.
Class Description
EcReal 64-bit floating-point value.
EcU32 32-bit unsigned integer.
EcInt32 32-bit signed integer.
EcU16 16-bit unsigned integer.
EcInt16 16-bit signed integer.
EcU8 8-bit unsigned integer.
EcInt8 8-bit signed integer.
EcAngle A floating-point value in the range (-π, π]. The sine and cosine of the angle are stored in the class for fast trigonometric processing.
EcNonNegReal Non-negative 64-bit floating point value.
EcString A variable-length array of Unicode characters.
EcBoolean A Boolean value.

Basic Kinematics

For the most part, class details will not be described in this document, but rather in the class documentation. However, because of their importance throughout the toolkit, position, orientation, coordinate system transformations, and rigid-body motion will be described in detail.

Position

Position is defined using the EcVector class. This class holds three real values representing x, y, and z coordinates. It also provides a number of methods for working with vectors. Given three EcVector*s, *a, b, and c, the following table shows some of the more useful methods.

Select methods in the EcVector class. For a complete description, please see the class documentation.
Method Examples Description
EcVector a(x, y, z); This constructor creates a vector holding the three specified values.
a+=b; a-=b; a=b+c; a=b-c; Various math operators are defined among vectors.
a*=r; a=r*b; a=b*r; a=b/r; Various math operations with scalars are also defined.
a==b; Equality is defined, which returns EcTrue if both vectors are equal.
a.approxEq(b,tol); Fuzzy equality is defined, which returns EcTrue if all the elements are within the tolerance of each other.
r=a.dot(b); a=b.cross(c); Dot and cross product are defined.
r=a.mag(); r=a.magSquared(); r=a.distanceTo(b); r=distanceSquaredTo(b); Various Euclidean norms are defined. The squared values are faster to calculate because they do not require a square root.
a=b.unitVector(); a.normalize(); Methods are included for normalizing vectors.
r=a.x(); r=a.y(); r=a.z(); Accessors for the three elements.
a.setX(r); a.setY(r); a.setZ(r); Mutators for the three elements.
r=a[0]; r=a[1]; r=a[2]; Indexing can be used to get nonconst references to the three elements. These can be used for accessing the elements or setting them.
a=EcVector::zeroVector(); This method returns a const reference to a static member variable. It can be used for error recovery from a method that returns a reference to a vector.

Orientation

Orientation is defined using the EcOrientation class. Each member of this class holds four values, {w, x, y, and z} that define a quaternion that represents the orientation of an outboard frame, j, with respect to an inboard frame, i. This quaternion translates into a direction cosine matrix through the following formula:

\[R = \left[ {\begin{array}{*{20}{c}}{1 - 2{y^2} - 2{z^2}}&{2xy - 2wz}&{2xz + 2wy}\\{2xy + 2wz}&{1 - 2{x^2} - 2{z^2}}&{2yz - 2wx}\\{2xz - 2wy}&{2yz + 2wx}&{1 - 2{x^2} - 2{y^2}}\end{array}} \right]\]

Note that, with this formalism, Q={1,0,0,0} corresponds to the identity matrix and the negative of a quaternion gives the same rotation as the original. (This formalism can be easily converted to the other common form by ordering the entries {x, y, z, and w}.)

The EcOrientation class provides a number of methods for extracting information about orientation, transforming orientations, and working with vectors. Its methods are defined in the table below. Given three EcOrientations, a, b, and c, the following table shows some of the more useful methods that can be used.

Select methods in the EcOrientation class. For a complete description, please see the class documentation.
Method Examples **Description**
EcOrientation a(w, x, y, z); This constructor creates an orientation with the specified quaternion values. The four values are normalized to a unit vector.
a.set(w, x, y, z); This assigns the specified quaternion values to a pre-existing orientation. The four values are normalized to a unit vector.
a*=b; a=b*c; Various operators are defined among orientations. Orientation multiplication is not commutative.
w=a*v; Transformation of vectors is defined.
a==b; Equality is defined, which returns EcTrue if both quaternions are equal.
a.approxEq(b,tol); Fuzzy equality is defined, which returns EcTrue if all the quaternion elements are within the tolerance of each other.
a.invert(); a=b.inverse(); Inversion routines are defined.
a.setFrom321Euler(psi,th,phi); a.get321Euler(psi,th,phi); a.setFromAngleAxis(angle,axis); a.getAngleAxis(angle,axis); a.setFromDcmRows(r0,r1,r2); a.getDcmRows(r0,r1,r2); Various methods are available for setting the orientation from other representations and calculating the equivalent in other representations. More conversions are available than those shown here—please see the class documentation for more.
a=EcOrientation::identity(); This method returns a const reference to a static member variable representing no orientation change. It can be used for error recovery from a method that returns a reference to a vector.

Coordinate System Transformation

A coordinate system transformation includes both translation and reorientation. Our implementation class is EcCoordinateSystemTransformation, which holds one EcVector object and one EcOrientation object. These represent the position and orientation of a new frame (the outboard frame) expressed in a reference frame (the inboard frame). There are a number of ways to interpret the meaning of a coordinate system transformation. Our primary interpretation in this document is the following: It is a device for transforming quantities represented in the outboard frame to be represented in the inboard frame.

actinSoftwarePrinciples_image1.png
A coordinate system transformation is represented using the EcCoordinateSystemTransformation class, which includes an EcVector translation and an EcOrientation orientation. The EcCoordinateSystemTransformation can be viewed as representing frame 2 in frame 1 as shown above. The translation is represented in frame 1 coordinates. A vector represented in frame 2 can be multiplied by a coordinate system transformation to give the same point in frame 1 coordinates.

To increase speed, simplified states of an EcCoordinateSystemTransformation are tracked and used when transforming quantities. Each EcCoordinateSystemTransformation has a mode, with four options as shown in the table below.

The EcCoordinateSystemTransformation mode. This value is used to optimize calculations performed with the object.
EcCoordinateSystemTransformation Mode Description
ARBITRARY The translation and orientation may take on any values.
NO_TRANSLATION There is no change in translation. The translation vector equals {0,0,0}.
NO_ROTATION There is no change in orientation. The orientation quaternion equals {1,0,0,0}.
NO_CHANGE There is no change in position or orientation.

The most common methods provided by the EcCoordinateSystemTransformation class are shown in the table below, where a, b, and c represent EcCoordinateSystemTransformation objects.

Select methods in the EcCoordinateSystemTransformation class. For a complete description, please see the class documentation.
Method Examples **Description**
EcCoordinateSystemTransformation(translation, orientation); This constructor creates a coordinate system transformation with the specified position and orientation.
v=a.translation(); a.setTranslation(v);
q=a.orientation(); a.setOrientation(q);
Methods to get and set the position (an EcVector) and the orientation (an EcOrientation).
a.mode(); Access to the mode (as described through Table 5‑3).
a*=b; c=a*b; Transformation combination. If a represents frame A in reference coordinates and b represents frame B in frame A coordinates, then c=a*b represents frame B in reference coordinates.
a==b; Equality is defined, which returns EcTrue if both transformations are equal.
a.approxEq(b,tol); Fuzzy equality is defined, which returns EcTrue if all the position and orientation elements vary by less than the tolerance.
a.invert(); a=b.inverse(); Inversion routines are defined.
a=EcOrientation::identity(); This method returns a const reference to a static member variable representing no translation or orientation change. It can be used for error recovery from a method that returns a reference to a vector.

Rigid-Body Velocity

The motion of rigid bodies and reference frames is described in the toolkit using the EcGeneralMotion class. EcGeneralMotion is typedef’ed to EcGeneralVelocity to represent frame velocity. Each EcGeneralVelocity object has one EcVector representing linear velocity of a point and one EcVector representing angular velocity about that point. Each EcGeneralVelocity object must have a point of application and a frame of representation—these are implicit. This is illustrated in the figure below.

actinSoftwarePrinciples_image2.png
Reference-frame and rigid-body velocity are represented using EcGeneralVelocity objects, which comprise vectors of linear and angular velocities (\(\vec v\) and \(\vec \omega \), respectively). These quantities are defined in an implicit reference frame at the origin of the moving frame or at an implicit point on a moving rigid body. EcGeneralAcceleration has a similar form.
Select methods in the EcGeneralMotion class. EcGeneralVelocity shares this interface. For a complete description, please see the class documentation.
Method Examples Description
EcGeneralVelocity(linear, angular); This constructor creates a general velocity from a linear and an angular component.
a.linear(); a.setLinear(v);
a.angular(); a.setAngular(w);
Methods to get and set the linear and angular components (both EcVector*s).
a+=b; a-=b; a=b+c; a=b-c; Various math operators are defined among *EcGeneralVelocity objects.
a*=r; a=r*b; a=b*r; Various math operations with scalars are also defined.
a==b; Equality is defined, which returns EcTrue if both objects are equal.
a.approxEq(b,tol); Fuzzy equality is defined, which returns EcTrue if all the position and orientation elements vary by less than the tolerance.
a.transformBy(xform); a.transformBy(orient); a.transformBy(vector); Routines to transform the EcGeneralVelocity object by moving the point of application, changing the reference frame, or both.

Tools are also provided for integrating EcGeneralMotion objects. Integrating EcGeneralVelocity to get an EcCoordinateSystemTransformation describing the position and orientation requires some calculation.

Let \({[{Q_0},{Q_1},{Q_2},{Q_3}]^T}\) represent a quaternion describing the position of a moving coordinate system and \({[{\omega _0},{\omega _1},{\omega _2}]^T}\)represent the angular velocity of the moving coordinate system in reference frame (not moving frame) coordinates. The time derivative of the quaternion can be calculated using the following formula, which is a consequence of (1):

\[\left[ {\begin{array}{*{20}{c}}{{{\dot Q}_0}}\\{{{\dot Q}_1}}\\{{{\dot Q}_2}}\\{{{\dot Q}_3}}\end{array}} \right] = \frac{1}{2}\left[ {\begin{array}{*{20}{c}}{ - {Q_1}}&{ - {Q_2}}&{ - {Q_3}}\\{{Q_0}}&{{Q_3}}&{ - {Q_2}}\\{ - {Q_3}}&{{Q_0}}&{{Q_1}}\\{{Q_2}}&{ - {Q_1}}&{{Q_0}}\end{array}} \right]\,\left[ {\begin{array}{*{20}{c}}{{\omega _0}}\\{{\omega _1}}\\{{\omega _2}}\end{array}} \right]\]

As a user of the toolkit, you do not need to work with this or other quaternion formulas. Equation (2) is implemented in the EcOrientation class. Let q be an EcOrientation object, w be angular velocity represented in reference-frame coordinates, and vQdot be a length-four real vector. Then q.quaternionRateFromReferenceFrameAngularVelocity(w,vQdot); will calculate the quaternion rate as shown in (2). Methods for calculating the quaternion rate from angular velocity represented in moving coordinates, calculating angular velocity from quaternion rates, and integrating angular velocity are all part of the implementation of EcOrientation in the toolkit—details are given in the class documentation.

Basic Dynamics

Just as with kinematics, for the most part, class details will not be described in this document, but rather in the class documentation. However, because of their importance, acceleration, force, and mass properties will be described in detail.

Rigid-Body Acceleration

As was mentioned previously, the motion of rigid bodies and reference frames is described in the toolkit using the EcGeneralMotion class. EcGeneralMotion is typedef’ed to EcGeneralAcceleration to represent acceleration. Each EcGeneralAcceleration object has one EcVector representing linear acceleration of a point and one EcVector representing angular acceleration about that point. Each As with EcGeneralVelocity, each EcGeneralAcceleration object must have an implicit point of application and a frame of representation. EcGeneralAcceleration is illustrated in the figure below.

actinSoftwarePrinciples_image3.png
Reference-frame and Rigid-body acceleration are represented using EcGeneralAcceleration objects, which contain vectors for linear and angular velocity (\(\vec a\) and \(\vec \alpha \), respectively). These are defined in an implicit reference frame at the origin of the moving frame or at an implicit point on a moving rigid body.
Select methods in the EcGeneralAcceleration class. These are the same methods as for EcGeneralVelocity. For a complete description, please see the class documentation.
Method Examples Description
EcGeneralAcceleration(linear, angular); This constructor creates a general acceleration from a linear and an angular component.
a.linear(); a.setLinear(a);
a.angular(); a.setAngular(alpha);
Methods to get and set the linear and angular components (both EcVector*s).
a+=b; a-=b; a=b+c; a=b-c; Various math operators are defined among *EcGeneralAcceleration objects.
a*=r; a=r*b; a=b*r; Various math operations with scalars are also defined.
a==b; Equality is defined, which returns EcTrue if two objects are equal.
a.approxEq(b,tol); Fuzzy equality is defined, which returns EcTrue if all the position and orientation elements vary by less than the tolerance.
a.transformBy(xform);
a.transformBy(orient);
a.transformBy(vector);
Routines to transform the EcGeneralAcceleration object by moving the point of application, changing the reference frame, or both.

Rigid-Body Force

The sum of forces applied to a rigid body can be represented through a vector linear force and a vector moment applied to a point of application. This is illustrated in the figure below.

actinSoftwarePrinciples_image4.png
The force applied to a body is represented using EcGeneralForce objects, which contain vectors for linear force and angular moment (\(\vec f\) and \(\vec n\), respectively). These are defined in an implicit reference frame at an implicit point of application.
Select methods in the EcGeneralForce class. These are similar to those for EcGeneralVelocity and EcGeneralAcceleration.
Method Examples Description
EcGeneralForce(linear, angular); This constructor creates a general force from a linear and an angular component.
a.linear(); a.setLinear(f);
a.angular(); a.setAngular(n);
Methods to get and set the linear and angular components (both EcVector*s).
a+=b; a-=b; a=b+c; a=b-c; Various math operators are defined among *EcGeneralForce objects.
a*=r; a=r*b; a=b*r; Various math operations with scalars are also defined.
a==b; Equality is defined, which returns EcTrue if both are equal.
a.approxEq(b,tol); Fuzzy equality is defined, which returns EcTrue if all the position and orientation elements vary by less than the tolerance.
a.transformBy(xform); a.transformBy(orient); a.transformBy(vector); Routines to transform the EcGeneralMotion object by moving the point of application, changing the reference frame, or both.
a.addLinear(f); a.addAngular(n); Routines to add linear and angular components.

Rigid Body Mass Properties

Rigid body mass properties include the 10 parameters needed for dynamics calculation: the scalar mass, the vector first moment of inertia, and the 3×3 symmetric second moment of inertia. For the first and second moments of inertia, there is an implied reference frame. The second moment is represented with point of application at the origin of the reference frame, not at the center of mass.

actinSoftwarePrinciples_image5.png
Rigid-body inertia includes the scalar mass m, the first moment of inertia, which is defined as the center of mass times the mass, and the second moment of inertia.

The mass of rigid body defined over volume V is given by

\[m = \int\limits_V {\rho \,dV} \]

where \(\rho \) is the mass density for the differential volume dV. This is a single scalar.

The first moment is given by

\[\vec h = \int\limits_V {\vec r\rho \,dV} \]

where \(\vec r\)is the vector pointing to the differential volume dV. The second moment is defined through a three-dimensional vector and is equal to \(m\vec c\), where \(\vec c\) is the center of mass.

Second moment of inertia is defined through a symmetric 3x3 matrix:

\[I = \left[ {\begin{array}{*{20}{c}}{{I_{xx}}}&{{I_{xy}}}&{{I_{xz}}}\\{{I_{xy}}}&{{I_{yy}}}&{{I_{yz}}}\\{{I_{xz}}}&{{I_{yz}}}&{{I_{zz}}}\end{array}} \right] \]

The values \(I_{xx} \), \(I_{yy} \), and \(I_{zz} \) are the diagonal elements, given by

\[\begin{array}{*{20}{c}}{{I_{xx}} = \int\limits_V {({y^2} + {z^2})\rho \,dV} }\\{{I_{yy}} = \int\limits_V {({x^2} + {z^2})\rho \,dV} }\\{{I_{zz}} = \int\limits_V {({x^2} + {y^2})\rho \,dV} }\end{array}\]

The off-diagonal elements are defined as follows:

\[\begin{array}{*{20}{c}}{{I_{xy}} = - \int\limits_V {xy\rho \,dV} }\\{{I_{xz}} = - \int\limits_V {xz\rho \,dV} }\\{{I_{yz}} = - \int\limits_V {yz\rho \,dV} }\end{array}\]

The second moment of inertia is represented through the class EcSecondMoment.

Select methods in the EcSecondMoment class.
Method Examples Description
EcSecondMoment(jxx,jyy,jzz,jxy,jxz,jyz); This constructor creates a second moment from the entries in the matrix representation.
a.jxx(); a.jyy(); a.jzz(); a.jxy(); a.jxz(); a.jyz(); Methods to get individual components.
a.set(jxx,jyy,jzz,jxy,jxz,jyz); Method to set values.
a+=b; a-=b; a=b+c; a=b-c; Various math operators are defined.
a*=r; a=r*b; a=b*r; Various math operations with scalars are also defined.
a==b; Equality is defined, which returns EcTrue if both are equal.
a.approxEq(b,tol); Fuzzy equality is defined, which returns EcTrue if all the position and orientation elements vary by less than the tolerance.
a.transformBy(orient); Routines to transform the object through rotation.
a.spatialMatrix(); Gets the inertia as a 3x3 matrix.
a.getPrincipalAxes(); Gets the orientation of the frame aligned with the principal moments.

The complete mass properties are represented by combining a scalar for mass, an EcVector for first moment, and an EcSecondMoment for second moment. This class, EcRigidBodyMassProperties, includes the methods shown in the table below.

Select methods in the EcRigidBodyMassProperties class.
Method Examples Description
EcRigidBodyMassProperties(mass, firstMoment, secondMoment); This constructor creates a second moment from components.
a.mass(); a.firstMoment(); a.secondMoment(); Methods to get individual components.
a.set(mass, firstMoment, secondMoment); Method to set values.
a+=b; a-=b; a=b+c; a=b-c; Various math operators are defined.
a==b; Equality is defined, which returns EcTrue if both are equal.
a.approxEq(b,tol); Fuzzy equality is defined, which returns EcTrue if all the position and orientation elements vary by less than the tolerance.
a.transformBy(orientation); a.transformBy(translation);
a.transformBy(xform);
Routines to transform the object through rotation, translation, or general coordinate system transformation.
a.calculateForce(velocity, acceleration); Calculates the force required to produce the specified frame velocity and frame acceleration.
a.calculateAcceleration(velocity, force); Calculates the acceleration produced by the specified force when the body has the specified velocity.

Motion Constraint Placement

List of end effectors and related placement elements.
End Effector Placement Element Degree of Contraints
accelerometerEndEffector placement.coordSysXForm.orientation 3
axisRotateEndEffector placement.coordSysXForm.translation.z 1
centerOfMassEndEffector placement.coordSysXForm.translation 3
coordinatedJointEndEffector placement.data number of active joints
directionalFrameEndEffector placement.coordSysXForm 6
fixedOrientationPointEndEffector placement.coordSysXForm number of active axes
flexGeneralSpatialEndEffector placement.coordSysXForm number of active axes
frameEndEffector placement.coordSysXForm 6
freeSpinInZEndEffector placement.coordSysXForm 5
generalSpatialEndEffector placement.coordSysXForm number of active axes
linearConstraintEndEffector placement.coordSysXForm.translation.z 1
lookAtEndEffector placement.coordSysXForm.translation 2
oneDofGripperEndEffector placement.coordSysXForm.translation.z 1 + number of slave joints
orientationEndEffector placement.coordSysXForm.orientation 3
planarEndEffector placement.coordSysXForm 3
pointDistanceEndEffector placement.coordSysXForm.translation.z 1
pointEndEffector placement.coordSysXForm.translation 3
pointRotateEndEffector placement.coordSysXForm 4
projectedCenterOfMassEndEffector placement.coordSysXForm.translation 2
rcmEndEffector placement.coordSysXForm.translation 2
sagEndEffector placement.data number of active joints
sewAngleEndEffector placement.coordSysXForm.translation.z 1
slideXSpinZEndEffector placement.coordSysXForm 4
slidingEndEffector placement.coordSysXForm 5
spatialMomentumEndEffector placement.coordSysXForm 3/6
xEndEffector placement.coordSysXForm.translation 1
xyEndEffector placement.coordSysXForm.translation 2
Note
The differences between EcPositionState.jointPositions and EcEndEffectorPlacement.data:
The EcPositionState.jointPositions describes the joint positions of all joints of a manipulator, while the EcEndEffectorPlacement.data describes the joint positions of the joints activated by an end effector (EcCoordinatedJointEndEffector / EcSagEndEffector).
Example 1: We have a 12-DoF manipulator, which is a 5-DoF tool attached to a 7-DoF arm. Then the manipulator's positionState.jointPositions will contain the joint positions of all 12 joints. And we want to joint control only the arm separately. So we will have a coordinatedJointEndEffector which only activates the arm joints. Then the data of the related endEffectorPlacement only contain the joint positions of the 7 joints of the arm.
Example 2: We have a manipulator with mechanical redundancy, eg. a 4-bar linkage, so some joints are active and some are passive. The positionState.jointPositions will contain the joint positions of both active and passive joints, while the endEffectorPlacement.data should only contain the joint positions of the active joints, since the related joint controller can only control these joints.
Created by Energid Technologies www.energid.com
Copyright © 2016 Energid. All trademarks mentioned in this document are property of their respective owners.