VelocityMove Axis moving after stop() command

We have an axis where we are commanding a MoveVelocitySCurve() move. Sometimes this axis gets stuck during the move and a large position error builds up. We are okay with this. But when we command another MoveVelocitySCurve() to 0 deg/s and then Stop() the axis, the Commanded Velocity goes to 0 but the Actual Velocity is maintained and the axis keeps moving for about half a second until we get a Motor Foldback fault on the Kollmorgen Drive.

How can I configure this axis to bring the actual velocity to 0 immediately even when there is a large position error? My understanding is that the axis is trying to finish the move and bring the position error under the the position tolerance, even after I send a Stop() command.

rotAxis->AmpEnableSet(true, 1000);
if(rotAxis.isFaulted()) return false;
rotAxis->MoveVelocitySCurve(rotVel, rotAccel, rotJerk);
if(!rotAxis.waitUntilVelocityMoveComplete()) return false;

// some other stuff happens

rotAxis->MoveVelocitySCurve(0, rotAccel, rotJerk);
rotAxis->Stop();
if(!rotAxis.waitUntilMotionComplete()) return false;
rotAxis->AmpEnableSet(false, 1000);

@edco ,

Thank you for the detailed description and graphs.

To get the Axis to bring the the actual velocity to 0, you need to get its CommandPosition equal to its ActualPosition. Assuming you do not want the Axis to go into the error state, RSIStateERROR, you could simply command a move to the ActualPosition:

double actualPosition = rotAxis->ActualPositionGet();
rotAxis->MoveSCurve(actualPosition, reallyHighVel, reallyHighAccel, reallyHighDecel, rotJerk);

This will immediately on-the-fly modify the currently executing MoveVelocitySCurve(…) with the updated trajectory values, which will cause the CommandPosition to return to the ActualPosition.

If you want this to happen automatically and are ok ending up in the ERROR state, you could set rotAxis->ErrorLimitActionSet(RSIActionE_STOP_CMD_EQ_ACT) (assuming you configure ErrorLimitTriggerValueSet() so that the position error limit would trigger) which would decelerate the in-progress MoveSCurveVelocity() (in the time specified by EStopTimeSet()), transition to the ERROR state and then set the Axis CommandPosition equal to its ActualPosition (automatically in the RMP firmware). With this action, the amplifier will remain enabled so you will only need to ClearFaults(), not AmpEnableSet(true), to recover.

Let us know if either of these solutions will work for you, or if you have other constraints.

I think commanding a position move to the current ActualPosition will work for this case. But it would be even nicer if we could set the ErrorLimit Action to do a full stop and set command position equal to actual position without going to an ERROR state.

Is there a way to configure a callback function to automatically clear the error in this case?

We’re investigating if a STOP_CMD_EQ_ACT action is doable.

We don’t have interrupt callbacks, but if you have a thread waiting for Axis interrupts, you could do something like:

RSIEventType type = rotAxis->InterruptWait(...);
if (type == RSIEventTypeLIMIT_ERROR)
{
  rotAxis->MotionDoneWait();
  rotAxis->ClearFaults();
}

For safety, we usually recommend using ESTOP_ABORT or ABORT for position error limit. An alternative could be to use a UserLimit that’s set up to monitor the position error with a tighter limit value (smaller than rotAxis->ErrorLimitTriggerValueGet()) using RSIUserLimitLogicABS_GT, then use that (MotionController) interrupt to to notify your software to do the MoveSCurve() to the ActualPosition. This way you’d avoid all ERROR states.