UpdateBufferPoints.cpp

Hi community

I am currently experimenting with UpdateBufferPoints.cpp. I have modified the code slightly so that my AXIS_COUNT = 2.

Instead of using the default code as given in the example which creates two arrays namely positions and times I am using my own method to create two arrays. The difference is in my method the number of elements in the positions array is twice the number of elements in the time array because it is a 2 axis system.

//Original:

// populate the positions and times 
std::vector<double> positions, times;
for (int i = 0; i < TOTAL_POINTS; i += AXIS_COUNT)
{
  positions.push_back(i * TIME_SLICE * RPS);
  times.push_back(TIME_SLICE);
}

//Modified for 2 Axis

// 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] = TIME_SLICE;       // Example time values
}

// Interleave the position data for both axes into positions array
for (int i = 0; i < arrayAxisX.size(); ++i)
{
  positions.push_back(arrayAxisX[i]);
  positions.push_back(arrayAxisY[i]);
}

Everything else in the code is pretty much the same. Now when I run the code, it gives me the following error:

However if I am debugging the code using F5 with some breakpoints to see what is triggering the error, it does not give me an error and runs all the way through. Could someone please be able to tell why that would happen?

TIA !

Hi @rdhillon ,

The error you are seeing is due to trying trying append points after a final bool has been set to true. We generally handle a move by starting a new move or appending to an existing one based on the state of the motion (Moving or not).

I think you in a state where the delays debugging/breakpoints are allowing the move to finish out. When running normally you are right at the edge of still moving.

I’m not sure if you are stuck in a moving state due to settling criteria so the follow up move call complains that you’ve already set it to final or not. The unmodified UpdateBufferPoints has 4 MovePT calls. Which one are you seeing the error at? Have you made any other changes beyond the axis count?

I am not using the hardware for testing. USE_HARDWARE is set to False.

Following are the areas where I have changed things. The original code had 2000 TOTAL_POINTS with 0.001 seconds TIME DELTA. My code has 100 total points and time delta is set to 0.1 seconds. Changes are pretty much in the arrays but the rest of the code is untouched.

Following are the areas where I have done changes in comparison to the original code.

  1. Original>

// Motion parameters
const double TIME_SLICE = 0.001; // 0.001s = 1ms
const int REVS = 2; // number of revolutions
const int RPS = 1; // revs / sec
const int TOTAL_POINTS = (int)(REVS / TIME_SLICE / RPS); // total number of points
const int BUFFER_SZ = 100; // Number of points to send in a buffer
const int EMPTY_CT = 10; // Number of points that remains in the beffer before an e-stop

// populate the positions and times 
std::vector<double> positions, times;
for (int i = 0; i < TOTAL_POINTS; i += AXIS_COUNT)
{
  positions.push_back(i * TIME_SLICE * RPS);
  times.push_back(TIME_SLICE);
}
  1. Modified:
// Multiaxis motion ######################################
const int AXIS_COUNT = 2;  

// Motion parameters
const double TIME_SLICE = 0.1;                          // 0.001s = 1ms
const int    TOTAL_POINTS = 100; // total number of points
const int    BUFFER_SZ = 8;     
const int    percentageNum = 10;                       // Number of points to send in a buffer
const int    EMPTY_CT =  BUFFER_SZ * AXIS_COUNT / percentageNum; 


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
std::vector<double> positions;

// 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] = TIME_SLICE;       // Example time values
}

// Interleave the position data for both axes into positions array
for (int i = 0; i < arrayAxisX.size(); ++i)
{
  positions.push_back(arrayAxisX[i]);
  positions.push_back(arrayAxisY[i]);
}

At the first MovePT Call
Original:

// reset the motion ID to 0
multiAxis->MovePT(RSIMotionType::RSIMotionTypePT, &positions[0], &times[0], 1, -1, false, true);
multiAxis->MotionIdSet(0);

Modified:

std::vector<double> initXY, initTime;
initXY = {0, 0};
initTime = {TIME_SLICE};

// reset the motion ID to 0
multiAxis->MovePT(RSIMotionType::RSIMotionTypePT, initXY.data(), initTime.data(), 1, -1, false, true);
multiAxis->MotionIdSet(0);

Second MovePT call is exactly the same as in the example.

In the while loop where MovePT is finally called again everything is exactly the same as it is in the original code.

Hi @rdhillon ,

Your buffer size of 8 isn’t a factor of the 100 total points. Could you adjust TOTAL_POINTS or BUFFER_SZ so the loops aligns?

Thanks. Is that a hard requirement? I was under the impression that it wont matter as long as number of points to process is equal to no of points passed as positions and times as shown in some examples. For example in this one on the website 3 points are passed for processing.

  int points         = 3;                     // Specify the total number of streamed points.
  int emptyCount     = 2;                     // E-stop generated if there are this number or fewer frames loaded. (Typically for PT motion there are two frames per PT point)
  double[] positions = { 1.0, 0.5, 0.75 };    // Specify the positions that you want to reach. (it can be n number)
  double[] times     = { 0.2, 0.3, 0.1 };     // Specify the times in which you want to reach each position. (velocity and acceleration is calculated by the RMP)

  axis.MovePT(RSIMotionType.RSIMotionTypePT,  // Specify the type of PT Motion that you want to perform. (RSIMotionType.RSIMotionTypePT, RSIMotionType.RSIMotionTypeBSPLINE, RSIMotionType.RSIMotionTypeBSPLINE2)
                  positions,                  // Specify the positions that you want to reach. (it can be n number)
                  times,                      // Specify the times in which you want to reach each position. (velocity and acceleration is calculated by the RMP)
                  points,                     // Specify the total number of streamed points.
                  emptyCount,                 // E-stop generated if there are this number or fewer frames loaded. (Typically for PT motion there are two frames per PT point)
                  false,                      // Specify whether points are kept, or are not kept.
                  true);                      // Specify if this is the last MovePT. (If True, this is the final point. If False, more points expected.)
  
  axis.MotionDoneWait();                      // Wait for motion to be completed.    

But I have made the change nevertheless. I made the buffer count to 10 instead of 8. It failed unfortunately. Same error message upon running the code.

Hi @rdhillon ,

I’m sorry it isn’t a issue. This section handles it by lowering the buffer count. It looks like its fine for MultiAxes too.

 if (TOTAL_POINTS <= (endOfLastSent + BUFFER_SZ))
 {
    numPointsToSend = TOTAL_POINTS - endOfLastSent; // send the remaining points
    exitCondition = true;
 }

Okay. I am really puzzled why it wont work. Based on my testing, its failing at the movePT function call.

Now, I am trying to understand this first initiation of the movePT call w.r.t the original example code.

// Establish how to keep track of what blocks have been sent
int curMotionElementID = 0, curMotionID = 0, finalMotionID = 0;
int numPointsToSend = BUFFER_SZ;
int endOfLastSent = 0;
bool exitCondition = false;

// Set up a motion hold gate so we can start buffering blocks
const int motionHoldGate = 3;
controller->MotionHoldGateSet(motionHoldGate, true);
multiAxis->MotionHoldGateSet(motionHoldGate);

for (int i = 0; i < 2; ++i)
{
  multiAxis->MovePT(RSIMotionType::RSIMotionTypePT, &positions[0] + endOfLastSent * AXIS_COUNT, &times[0] + endOfLastSent, numPointsToSend, EMPTY_CT, false, exitCondition);
  endOfLastSent += numPointsToSend;
  ++finalMotionID;
}

In the for loop, when the loop iterates for the first time, the value of
endOfLastSent = 0. Now within the movePT function call, when this get multiplied by axis count which could be anything should result in 0. That would mean only first element of the position array is passed because &positions[0] + endOfLastSent * AXIS_COUNT = &positions[0] + 0* 1. But number of elements passed are written as numPointsToSend which is 10. Isn’t this a mismatch?

Hi @rdhillon ,

I set up a project and was able to reproduce your issue. The first move has the final flag set. I added a MotionDoneWait(yourTimeout) after this line. Alternatively you could set it to false and forgot the MotionDoneWait(yourTimeout) .

The issue is related to not finishing the first MovePT before calling the second one.