Abstract
This article describes how to use the COM interface to calculate forward and inverse kinematics of a robot model.
Overview
The parts of a 3DCreate robot model that apply to kinematic calculation are as follows:
- A RobotController behaviour object. This object defines the joints, or axes, of the robot, as well as its predefined tools and bases. It also defines the root position and the flange position of the robot.
- A kinematics object. This is a behaviour object that implements the actual kinematic calculation of the robot. It can be of one of several types, depending on the type of robot being modelled.
- The node structure of the robot component. When creating the robot model, care must be taken to ensure that this exactly reflects the model that is implemented by the kinematics object.
The RobotController object extends the ServoController behaviour object, which contains a list of joints and their motion parameters, such as limits, velocity and acceleration. In addition, the RobotController implements a list of predefined base and tool frames. These frames are typically associated with the root or flange of the robot, but can be attached to any simulation node.
The kinematics object implements both forward and inverse calculation, and allows kinematics to be calculated without modifying the simulation model itself. It is associated with the controller through a reference parameter in the controller.
The example code in this article is written using C#, and assumes the following:
- The "Visual Components COM library" has been imported to the project.
- The following line is included in the source file:
using vcCOM;
Accessing kinematics calculation functions through COM
The COM interface to the kinematics calculation model is accessible through the RobotController behaviour, using the IvcRobot interface. This interface contains a method, createTarget(), that returns an instance of IvcMotionTarget. This object is a calculation object containing the complete state of the robot. It is independent from the simulation model, so it can be used to perform kinematic calculations without affecting the actual position of the robot in the layout.
// Assuming this has been initialized:
IvcApplication app = /*something*/;
IvcComponent component = app.findComponent("Robot"); // Substitute name of robot here
IvcRobot robot = component.findBehaviour("Controller"); // Substitute name of RobotController behaviour here
IvcMotionTarget target = robot.createTarget();
Motion target properties
The IvcMotionTarget interface extends the IvcKinCalculator interface, which defines the kinematic calculation functionality. In this interface, the kinematic functionality is implemented as a set of COM properties that define the current state of the calculation object. Most of these properties can be grouped as follows:
- Joint values. These include the robot joints, as well as any external joints that may be present.
- Target properties. These include the target matrix, as well as the currently selected base and tool frames.
- Configuration properties. These select the configuration of the robot. The available configurations are determined by the type of kinematics of the robot.
Depending on which properties have been set or read most recently, the calculator object can be in one of the following states:
- Solved state. This is the initial state of the calculator. In this state, all the properties have been calculated. Reading a joint value or the target matrix puts the calculator in this state.
- Forward mode. This state specifies that the calculator will perform a forward calculation before entering the solved state. This state is entered when a joint value is modified, or when the UseJointValues flag (see below) is explicitly set to true.
- Inverse mode. This state specifies that the calculator will perform an inverse calculation before entering the solved state. This state is entered when the target matrix is set, or when the UseJointValues flag is explicitly set to false.
Joint values
The joint values that affect kinematics are divided into robot joints, robot positioner joints and workpiece positioner joints, shown in the picture below.

The number of each type of joint is accessible through the COM properties RobotJointCount, RobotPositionerJointCount and WorkpiecePositionerJointCount. The total number of joints is accessible through the JointCount property.
The getJointValue() method is used to read these joint values, as shown in the example below:
// This example reads joint values into lists.
double[ ] allJoints, robotJoints, robotPositionerJoints, workpiecePositionerJoints;
int mainIndex;
// Cache this to improve performance.
int jointCount;
// Read all the joints.
// This is straightforward. The getJointValue() method accepts an index, which
// can be in the range 0 <= i < JointCount.
jointCount = target.JointCount;
allJoints = new double[jointCount];
// Note that the first time getJointValue() is called, if the calculator is in the
// inverse mode state, an inverse kinematic calculation is performed before the joint
// values are read.
for(int i = 0; i < jointCount; ++i)
allJoints[i] = target.getJointValue(i);
// Read the robot joints.
// To read the joint values of robot joints only, the main index for those
// joints must first be obtained, using getRobotJointIndex(). This index
// can then be passed to getJointValue()/setJointValue().
jointCount = target.RobotJointCount;
robotJoints = new double[jointCount];
for(int i = 0; i < jointCount; ++i)
{
mainIndex = target.getRobotJointIndex(i);
robotJoints[i] = target.getJointValue(mainIndex);
}
// Read the robot positioner joints.
// As with robot joints, the main index must first be obtained using getRobotPositionerJointIndex().
jointCount = target.RobotPositionerJointCount;
robotPositionerJoints = new double[jointCount];
for(int i = 0; i < jointCount; ++i)
{
mainIndex = target.getRobotPositionerJointIndex(i);
robotPositionerJoints[i] = target.getJointValue(mainIndex);
}
// Read the workpiece positioner joints.
// As with robot joints, the main index must first be obtained using getWorkpiecePositionerJointIndex().
jointCount = target.WorkpiecePositionerJointCount;
workpiecePositionerJoints = new double[jointCount];
for(int i = 0; i < jointCount; ++i)
{
mainIndex = target.getWorkpiecePositionerJointIndex(i);
workpiecePositionerJoints[i] = target.getJointValue(mainIndex);
}
To set a joint value, the setJointValue() method is used:
double[ jointValues = /* an array of joint values */;
int jointCount = target.JointCount;
// This will set the calculator object to forward mode.
for(int i = 0; i < jointCount; ++i)
target.setJointValue(i, jointValue[i]);
Target properties
The target properties consist of the target frame, base frame, tool frame, and the target mode settings.
The target frame is set by setting the TargetMatrix property:
// Set the target to X: 500, Y: 0, Z: 200, A: 0, B: 0, C: 0.
target.TargetMatrix = new double[ ] { 500, 0, 200, 0, 0, 0 };
// This forces the calculator to inverse mode.
The base and tool frames can be set either directly using a matrix, or by name. If a base or tool is set by name, the predefined setting in the controller with that name is used. In this case, the reference node of the base or tool is also included on the predefined setting.
If both the base and the tool frames are specified directly, the TargetMode property determines how they are interpreted.
TargetMode is a numerical property that determines how the target is specified, as follows:
- 0: Normal. The base frame is relative to the robot root point if it is not specified by name.
- 1: Robot root. The base frame is relative to the robot root point.
- 2: Static tool. The base frame is relative to the flange of the workpiece positioner, and the target matrix is inverted.
- 3: External base. The base matrix is relative to the flange of the workpiece positioner.
- 4: World target. The base matrix is relative to the simulation world origin.
The available named bases and tools can be traversed using the NamedBaseCount property and getNamedBaseName() method, and the NamedToolCount and getNamedToolName() methods, respectively.
The following example shows how to specify a target using named base and tool frames:
// This will set the TargetMode to 0 (Normal) automatically.
target.BaseName = "BASE[1]";
target.ToolName = "TOOL[1]";
target.TargetMatrix = new double[ ] {500, 0, 200, 0, 0, 0};
This example shows how to specify a target in absolute coordinates:
double[ ] identMatrix = new double[ ]{0,0,0,0,0,0};
target.TargetMode = 4; // World target
target.BaseMatrix = identMatrix; // relative to robot flange
target.ToolMatrix = identMatrix; // relative to world origin
// The target matrix is now specified in world coordinates.
target.TargetMatrix = new double[ ] {500, 0, 200, 0,0, 0};
Configuration properties
The configuration of the robot determines which solution is chosen of the potential solutions available. The number of potential solutions depends on the kinematic type. The ConfigCount property can be read to determine how many different configurations are supported. An articulated robot, for example, has 8 configurations.
A particular configuration can be specified as an index by setting the CurrentConfig property. This changes the joint values to reflect the new configuration.The special value of -1 can be specified to indicate that the nearest configuration should be chosen. The nearest configuration is the one that is closest to the previous joint values, and can be determined after setting the target matrix by reading the NearestConfig property.
Reachability can be determined by calling the getConfigWarning() method, which returns one of the following values:
- 0: Reachable. The target is reachable using the given configuration.
- 1: Unreachable. The target is out of reach of the robot in the given configuration.
- 2: Joint limit exceeded: The target is reachable, but only if joint limits are exceeded.
To determine whether a given target is reachable at all, the NearestConfig property can be used with getConfigWarning(), as follows:
switch(target.getConfigWarning(target.NearestConfig))
{
case 0: // Reachable
// The target is reachable
break;
case 1: // Unreachable
// The target is unreachable
break;
case 2: // Joint limits exceeded
// The target is reachable only if joint limits are exceeded
break;
}
Calculating forward kinematics using properties
To calculate forward kinematics using properties, the following steps need to be done:
- Set the base and tool matrices, either directly or by name.
- Set the joint values, using setJointValue().
- Read the target matrix.
- If you need to know which configuration the joint values specify, read NearestConfig.
Calculating inverse kinematics using properties
To calculate inverse kinematics using properties, the sequence is as follows:
- Set the base and tool matrices, either directly or by name.
- If you want to specify a configuration, set CurrentConfig to that configuration, otherwise set it to -1.
- Set the target matrix.
- Set all external joint values (that is, all joints that are not robot joints.)
- Read the robot joint values.
Using the IvcMotionTarget2 interface
The properties in the kinematic calculator object allow for precise control when doing kinematic calculations. However, the number of properties that need to be set each time can impact performance when a large number of calculations need to be done. Because of this, the IvcMotionTarget2 interface was added in 3DCreate 2007. This interface defines the forward() and inverse() methods, which can be used to do kinematic calculations in a single COM call. These methods do not affect the state of the calculator object.
The methods are used as follows:
// Obtain an IvcMotionTarget2 pointer.
IvcMotionTarget2 trg2 = (IvcMotionTarget2)target;
// Forward calculation
// The joint value array contains all joint values of the robot.
// The calculated target matrix is placed in the given output parameter.
// The configuration index is returned.
double[ ] jointValues = /* some joint values */;
object trgOut; // output parameter, can later be cast to double[ ]
int config = trg2.forward(jointValues, out trgOut);
// Inverse calculation
// The target matrix and external joints are supplied.
// The calculated robot joints are placed in an array in an output parameter.
// The returned value indicates reachability in the same way as that returned by getConfigWarning().
double[ ] trgMatrix = new double[ ] {500, 0, 200, 0, 0, 0};
double[ ] externalJoints = /* some external joint values */;
double[ ] robotJoints; // output parameter
long configWarning = trg2.inverse(trgMatrix, externalJoints, out robotJoints);
Note that these methods do not change the state of the target object; however, they do read some of the properties. The following properties affect the result of forward() and inverse():
- TargetMode, BaseName, BaseMatrix, ToolName, ToolMatrix: These are read by both methods. They determine how forward() calculates the target matrix, and how inverse() interprets the given matrix.
- CurrentConfig: This is read by inverse() to determine the desired robot configuration.