PT motion is the simplest streaming motion requiring only Positions and Time deltas arrays.
🔹 What is PT Motion?
PT motion is the simplest streaming motion to use because it only requires an array of Positions and Time deltas. The controller is responsible for figuring out the velocity, and acceleration for each motion segment. MovePT currently supports several types of interpolation, as described in Streaming Motion.
| Simple PT Interpolation | Output Example |
|
RSIMotionTypePT is good for very closely spaced points (int time) or low accelerations. It is a very simple algorithm, requiring very few calculations; therefore, it is fast. If the points are spaced too far apart, the motion will be rough like shown in the example below. The acceleration between each point is instantaneous. It is best to keep the point spacing within a few samples.
Trapezoidal move example:
p1[0] = 050; t1[0] = 1.0;
p1[1] = 400; t1[1] = 3.5;
p1[2] = 450; t1[2] = 1.0;
Note: The Position array is direction sensitive meaning you must put a (-) sign on negative numbers.
|

|
| BSpline Interpolation | Output Example |
|
RSIMotionTypeBSPLINE interpolation is our recommended technique to blend transitions between segments. Use BSpline for smooth paths or systems with poor acceleration response.
Trapezoidal move example:
p[0] = 050; t[0] = 1.0;
p[1] = 400; t[1] = 3.5;
p[2] = 450; t[2] = 1.0;
Note: The Position array is direction sensitive meaning you must put a (-) sign on negative numbers.
|

|
🔹 PT Motion with Feedforward (PTF)
MovePTF extends PT motion by adding a feedforward term to each point. The feedforward value is a raw control output value applied directly to the control output, providing additional control authority beyond the PID controller.
When to Use Feedforward
Feedforward is useful when you need to compensate for known forces or apply model-based control:
- Gravity Compensation: For vertical axes, apply a constant feedforward to counteract gravitational force
- Friction Compensation: Add feedforward values to overcome static or dynamic friction
- Torque Feedforward: Provide additional torque for high-performance applications or dynamic loads
- Model-Based Control: Apply control outputs calculated from system dynamics models
Feedforward Units and Configuration
Feedforward values are raw control output values, not UserUnits:
- Typically 16-bit signed integers for torque control (-32768 to 32767)
- Typically 32-bit signed integers for velocity or position control
- The axis must be configured separately for the output type and PDO mapping via demand channel configuration
Feedforward Interpolation
The feedforward values are linearly interpolated between consecutive points during multi-sample segments:
- If a segment spans 10 firmware samples, the feedforward transitions smoothly by 10% per sample from the current point to the next
- For single-sample segments, the feedforward changes instantly at each point
Array Structure for PTF
For single Axis:
positions[] = [p₀, p₁, p₂, ..., pₙ]
times[] = [t₀, t₁, t₂, ..., tₙ]
feedforwards[] = [f₀, f₁, f₂, ..., fₙ] // raw control output values
For MultiAxis with 3 axes:
positions[] = [X₀, Y₀, Z₀, X₁, Y₁, Z₁, ..., Xₙ, Yₙ, Zₙ]
times[] = [t₀, t₁, ..., tₙ]
feedforwards[] = [Xf₀, Yf₀, Zf₀, Xf₁, Yf₁, Zf₁, ..., Xfₙ, Yfₙ, Zfₙ]
- Note
- The feedforwards array size must match the positions array size.
🔹 MultiAxis PT Motion
All motion streaming methods can be used for coordinated motion on MultiAxis objects. It is important that you setup your arrays appropriately for a MultiAxis object. See the examples below on how to structure your arrays for MultiAxis PT Motion.
Example 1: Three Axis Multi-Axis XYZ with MovePT
The position data for all three axes are combined into the array. The time array is shared for all axes. This is why you need 3x as many position points than you need time points. See the example below:
p[0] = 050; t[0] = 1;
p[1] = 025;
p[2] = 012.5;
p[3] = 400; t[1] = 3.5;
p[4] = 200;
p[5] = 100;
p[6] = 450; t[2] = 1;
p[7] = 225;
p[8] = 112.5;
📜 Sample Code
Basic Streaming PT Motion
- C#
Console.WriteLine("📜 Axis Streaming Motion: PT");
try
{
int points = 3;
int emptyCount = 2;
double[] positions = [1.0, 0.5, 0.75];
double[] times = [0.2, 0.3, 0.1];
positions,
times,
points,
emptyCount,
false,
true);
Console.WriteLine($"Final position: {axis.CommandPositionGet()}");
}
finally
{
controller.Delete();
}
Constants used in the C# sample apps.
const int AXIS_0_INDEX
Default: 0.
static void AbortMotionObject(RapidCodeMotion motionObject)
Aborts motion on the given RapidCodeMotion object (Axis or MultiAxis), waits for motion to stop,...
static void CheckErrors(RapidCodeObject rsiObject)
Checks for errors in the given RapidCodeObject and throws an exception if any non-warning errors are ...
static void PhantomAxisReset(Axis phantomAxis)
Configures a phantom axis on the controller.
Helpers class provides static methods for common tasks in RMP applications.
Represents a single axis of motion control. This class provides an interface for commanding motion,...
static MotionController * Get()
Get an already running RMP EtherCAT controller.
Represents the RMP soft motion controller. This class provides an interface to general controller con...
int32_t MotionDoneWait()
Waits for a move to complete.
int32_t AmpEnableSet(bool enable, int32_t ampActiveTimeoutMilliseconds=AmpEnableTimeoutMillisecondsDefault, bool overrideRestrictedState=false)
Enable all amplifiers.
void MovePT(RSIMotionType type, const double *const position, const double *const time, int32_t pointCount, int32_t emptyCount, bool retain, bool final)
A move commanded by a list of position and time points.
RSIMotionType
PT and PVT streaming motion types.
Stopping Streaming PT Motion
This code demonstrates that different actions that you can take after stopping a PT Streaming motion.
- C#
Console.WriteLine("📜 Axis Streaming Motion: PT While Stopping");
try
{
const int points = 3;
const int emptyCount = 2;
double[] first = [0.1, 0.2, 0.3];
double[] second = [0.4, 0.5, 0.6];
double[] third = [0.7, 0.8, 0.9];
double[] time1 = [0.3, 0.3, 0.3];
double[] time2 = [0.2, 0.2, 0.2];
double[] time3 = [0.25, 0.25, 0.25];
Console.WriteLine($"Final position: {axis.CommandPositionGet()}");
}
finally
{
controller.Delete();
}
void Resume()
Resume an axis.