MultiAxis PT streaming motion

In order to use PT motion, do I have to call this function repeatedly, in a loop perhaps?

axis.MovePT(RSIMotionType.RSIMotionTypePT, first, time1, points, emptyCount, false, false);

For a 2 axis system, Axis X and Axis Y which one will applly?

Option 1
axisX.MovePT(RSIMotionType.RSIMotionTypePT, firstX, time1, points, emptyCount, false, false);
axisY.MovePT(RSIMotionType.RSIMotionTypePT, firstY, time1, points, emptyCount, false, false);

Or Option 2: I am combining the positions

// Create a combined positions array
std::vector positions;

for (int i = 0; i < TOTAL_POINTS; ++i) {
    positions.push_back(positionsX[i]);  // Axis X position
    std::cout << "Positions X: " << positionsX[i] << std::endl;
    positions.push_back(positionsY[i]);  // Axis Y position
    std::cout << "Positions Y: " << positionsY[i] << std::endl;
}

for (int i = 0; i < TOTAL_POINTS; ++i) {
multiAxis->MovePT(
RSIMotionType::RSIMotionTypeBSPLINE, // Motion type
&positions[i], // Pointer to the first element of combined positions
&times[i], // Pointer to the first element of times
TOTAL_POINTS, // Number of time slices (common for both axes)
EMPTY_CT, // E-stop empty count threshold
false, // Whether points are kept or not
true // Specify if this is the last MovePT
);
}

MovePT(...) takes a flattened, 2-D array of waypoints:

[ x_0, y_0,
  x_1, y_1,
  x_2, y_2,
  ...,
  x_n, y_n ]

The array should have TOTAL_POINTS Ă— multiAxis->AxisCountGet() elements in it.

The sample code doesn’t really illustrate this very well, though the function description does better.

*position Array of positions (p) to move through. (positions are in the UserUnits for each Axis)
Axis: [p0, p1, p2, …, pn]

2 Likes

Hi @rdhillon,
Either method would work, but I’d almost certainly use the 2nd if the two streams of motion are supposed to be coordinated. Synchronizing the two with the first method could be done with a motion hold but that seems needless complicated.

Thank you Todd.

Quick question. Does x_0, y_0 ( or the first element pairs) for the array represent the starting point or first end points. If I am starting from 0, then should I write 0,0 as the first elements. Its a 2 axis system.

When streaming, you’re sending a series of waypoints to RMP to execute.
The first x,y pair you send is the first point to pass through. It should probably be the current position of the motors, though that’s not a strict requirement.

Continuing on the discussion. I think I am doing it right. I have two axis so number of elements in positions array is twice the number of elements in time array. I have generated 3 arrays. arrayAxisX, arrayAxisY and arrayTime. Each has 100 values.

I am then interleaving the axisX and axisY elements so I have a flat array as suggested in the documentation.

Here is the code snippet I am using to test the theory.

const int TOTAL_POINTS = 100;
const int POINTS_PER_CALL = 10;
const int AXIS_COUNT = 2;  // 2 axes: X and Y

std::vector<double> arrayAxisX(TOTAL_POINTS);  // Simulating 100 X-axis positions
std::vector<double> arrayAxisY(TOTAL_POINTS);  // Simulating 100 Y-axis positions
std::vector<double> arrayTime(TOTAL_POINTS);   // Simulating 100 time points

// Filling the arrays with some data (for illustration purposes)
for (int i = 0; i < TOTAL_POINTS; i++) {
    arrayAxisX[i] = i * 0.01;  // Example X-axis values
    arrayAxisY[i] = i * 1;  // Example Y-axis values
    arrayTime[i] = i * 0.01;   // Example time values
}

// Iterate over the total points in chunks of POINTS_PER_CALL
for (int i = 0; i < 100; i += POINTS_PER_CALL) 
 {
   // Interleave the position data for both axes
   std::vector<double> positions;
   for (int j = 0; j < POINTS_PER_CALL; j++) {
        positions.push_back(arrayAxisX[i + j]);
        positions.push_back(arrayAxisY[i + j]);
   }

    // Pointer to the time data for this chunk
    const double* time = &arrayTime[i];

    // Determine if this is the final motion call
    bool final = (i + POINTS_PER_CALL >= 100);

    // Visualization: Print the position and time data
    std::cout << "Iteration " << i / POINTS_PER_CALL + 1 << ":\n";
    std::cout << "Positions: [ ";
    for (double p : positions) {
        std::cout << p << " ";
    }
    std::cout << "]\n" << "Positions Array Size: " << positions.size() << "\n" ;

    std::cout << "Time: [ ";
    for (int j = 0; j < POINTS_PER_CALL; j++) {
        std::cout << time[j] << " ";
    }
    std::cout << "]\n" ;

    std::cout << "Final: " << std::boolalpha << final << "\n\n";

    // Execute motion with multiAxis->MovePT
    multiAxis->MovePT(RSIMotionType::RSIMotionTypePT, &positions[0], time, POINTS_PER_CALL, 20, true, final);
    multiAxis->MotionDoneWait();
}

Here is the screenshot of what I am getting in the output. Its not iterating beyond 1 and giving this error. Not sure why its saying non positive time delta in points[index].

I am trying to pass the points in chunks of 10 elements in this example until I have exhausted all 100 points when the “final” parameter becomes true and I exit out of loop.

The error message,

Parameter invalid :: {motion.c, line 13082} : Non-positive timeDelta in points[index] : index = 0 : timeDelta = 0 (Error 2) (RapidCodeMotion::MovePT_PVT) (Object 2) (File rapidcodemotion.cpp) (Line 1291) (Version 10.5.5.0)

notes that you have a non-positive time delta.

per the MovePT documentation:

*time	Array of time durations for each point in seconds.
Minimum value is your MotionController sample period. Values must be a multiple of the sample period.
If each point should take one millisecond, your array would be: [0.001, 0.001, 0.001, etc.]

You cannot have a value of 0 for the time. In your case, I think you just want each element to be 0.001. (Not incrementing).

Since you’re working with vectors, you can also can just pass in positions.data() like this:

multiAxis->MovePT(RSIMotionType::RSIMotionTypePT, positions.data(), etc

Thank you Scott.

I changed my arrays to have fixed increments of time for time being.

// Filling the arrays with some data (for illustration purposes)
for (int i = 0; i < TOTAL_POINTS; i++) {
arrayAxisX[i] = i * 0.01; // Example X-axis values
arrayAxisY[i] = i * 1; // Example Y-axis values
arrayTime[i] = .01; // Example time values
}

The non positive time delta error is gone but there is a new one now.

the loop iterates 2 times and then it throws the following error.

Use hardware is set to false.