Actin
Version 5.5.5
Software for Robotics Simulation and Control

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:
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.
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.
All member functions besides constructors and destructors begin with a lowercase letter and use the camelhump 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 camelhump 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.)
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.
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.
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 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.
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 is not used in the toolkit.
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 and macrolike functions are all named starting with “Ec” followed by uppercase letters. For example a macro to warn the user would be EcWARN.
Raster data is ordered consistently using one of two methods.
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 lowercase letter.
Microsoftspecific extensions are avoided in the toolkit, which builds under Windows and Linux.
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.
The use of friend classes is avoided in the toolkit. Friendship is not inherited, complicating reuse.
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.
A vector data structure is a container of any data type that allows constanttime 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, endeffectors, and so forth.
A tensor is an array of ndimensional data that allows access in constant time for fixed n. A vector is a substitute for a onedimensional tensor, but it is given its own category above because of its importance. Another important type of tensor is the array, which is a twodimensional 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, linkcollision maps, and so forth.
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.
A map data structure represents a onetoone 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 logtime (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.
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 logtime (depending on the implementation) access to a given value in the set. Sets are used sparingly in the toolkit for organization.
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 depthfirst or breadthfirst ordering. Trees are used widely in the toolkit to implement control systems that can be configured at run time.
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.
Class  Description 

EcReal  64bit floatingpoint value. 
EcU32  32bit unsigned integer. 
EcInt32  32bit signed integer. 
EcU16  16bit unsigned integer. 
EcInt16  16bit signed integer. 
EcU8  8bit unsigned integer. 
EcInt8  8bit signed integer. 
EcAngle  A floatingpoint value in the range (π, π]. The sine and cosine of the angle are stored in the class for fast trigonometric processing. 
EcNonNegReal  Nonnegative 64bit floating point value. 
EcString  A variablelength array of Unicode characters. 
EcBoolean  A Boolean value. 
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 rigidbody motion will be described in detail.
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.
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=bc;  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 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.
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 preexisting 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. 
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.
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.
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.
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. 
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.
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=bc;  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 referenceframe coordinates, and vQdot be a lengthfour 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.
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.
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.
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=bc;  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. 
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.
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=bc;  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 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.
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 threedimensional 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 offdiagonal 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.
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=bc;  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.
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=bc;  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. 
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 
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 