Intermittent exception from MoveSCurve

We get a very low frequency exception (approx once a week) when calling MoveSCurve for a geared move. It only occurs on one system and the other two systems have not experienced the fault.
The error we capture is as follows (the part after the first colon is the actual RSI exception data):
“Error executing command GearedZMove on ZL axis to 0.0908751 mm at 0.1 mm/s with accel/decel 50/50 and jerk 5 : Motion: MPIStateERROR :: {motion.c, line 15204} (Error 3851) (RSI::RapidCode::Impl::Axis::MoveSCurve) (Object 2) (File …\…\source\axis.cpp) (Line 369) (Version 8.1.6 for 04.04.02.RMP)”
I presume there is a mechanical issue on our system since it only happens on one system but it would be useful to know why the exception occurs.

This error is telling us that the Axis is in an ERROR state when the MoveSCurve(…) is called.

When in an ERROR state, you can use SourceGet() and SourceNameGet() to determine the source of the error.

Thanks for the feedback. So we should call SourceGet() and SourceNameGet() in our exception catcher?

Is there something we should be doing before calling MoveSCurve to verify it’s not in an error state? The RSI functions we call before MoveSCurve are:
pLeader->MotionDelaySet(0.0)
pLeader->MotionAttributeMaskOnSet(…RELATIVE)
pFollower1->GearingEnable(pLeader, , ACTUAL_POSITION, 1,1)
pFollower2->GearingEnable(pLeader, , ACTUAL_POSITION, 1,1)
pFollower3->GearingEnable(pLeader, , ACTUAL_POSITION, 1,1)
pLeader->MoveSCurve

None of the functions before MoveSCurve throw an exception.

I’m not sure if the exception catcher is the best place for those.

The MoveSCurve is throwing the exception because you’ve tried to move the Axis when it is impossible to do so (because the Axis is in ERROR state).

Before commanding motion, you could check the state (StateGet()), then also check the SourceGet() and SourceNameGet() if it is in ERROR or STOPPING_ERROR or STOPPING state.

Of course there’s always the slight chance that the condition that causes the error occurs in the microsecond between when you check the state and command the move. In that case you’re stuck with the exception, so your handler could get more info, clear the state and retry… but the proper procedure will be dictated by your application.

Here’s some sample code for using those three methods:
https://support.roboticsys.com/rmp/_axis_status_8cs-example#a2

We added the check for the state, and collected the information when the state was RSIStateERROR. Here is what we got:
RSI state:5 source axis:1 error:Amplifier Fault\n\n131: Secondary feedback A/B line break.\r\n132: Secondary feedback Z line break.\r\n134: Secondary feedback illegal state.\r\n
Axis 1 is the lead, and Axis 0,2,3 are the followers. Axis is called Z.
What does this mean? The move worked during the previous 70 cycles.
Since the state was in error before the MoveSCurve does this mean one of the Gearing calls actually failed?

No, the Gearing calls will succeed regardless of the Axis state.

It seems like you’ll need to monitor the Axis state more regularly, to determine when the secondary feedback fault occurs. You could do this with an extra thread, either polling Axis.StateGet() or using Axis interrupts, where you can put the thread to sleep and call Axis.InterruptWait(). When the fault occurs, we would expect InterruptWait() to return RSIEventTypeAMP_FAULT.

Thanks, I will look into adding a thread. Can I ask a follow up question. When we get the fault on the geared SMove we find that after that the axis stay geared to together even when we reload our application and reinitialize the EtherCAT network. We call clear faults in the code but clearly that doesn’t turn off the gearing. We find we have to restart INtime. I notice there are two MotorController functions Reset() and Refresh(), Reset seems to for a Delta Robot but what about Refresh(), does that clear the gearing? If not, I guess we have to specifically disable gearing on each axis during our initiation?

Yes, the gearing will remain active until you call GearingDisable() on the slave axis, so long as the RMP firmware is running.

MotionController.Reset() will shutdown the RMP firmware and restart it (this would disable gearing). Refresh() just re-initializes the software and does not mess with the RMP firmware.

Disabling gearing on initialization sounds like a safe precaution for your application.