User Limit (Immediate) Re-Use

Just to verify, should I be able to configure a one-shot user limit, then, when the event comes (via MotionController::InterruptWait()) in, immediately reconfigure and enable it?

In this instance, I’m trying to act when an axis position enters a range of positions and when it exits. So, I set the UL to trigger when (pos>=low && pos<=high). When that happens, I reconfigure so that the UL should trigger when (pos<low || pos>high). I’m configuring these as single shot, duration=0.

What I’m observing is that when I enter the region, the user limit fires and everything’s OK. As soon as I leave the region, I get user limit trigger loop: outside → inside → outside → inside → …

On manual inspection, I think I’m configuring the conditions correctly (described above). When I look at the user limit in RapidSetup after the leave user limit triggers and reconfigures, the conditions look correct, and the real-time value shown should not trigger the user limit. However, InterruptWait() still returns a user limit event for that user limit.

Is there something about user limits that I am misunderstanding? Should I be able to do this?

I made a minimal working example that exhibits this behavior.

Here are the config pieces of code.

Configuring for ENTER REGION:

mc->UserLimitConditionSet(userlim,
						  0,
						  RSI::RapidCode::RSIUserLimitLogicGE,
						  actual_pos_host_addr,
						  pos_low_rmp);
mc->UserLimitConditionSet(userlim,
						  1,
						  RSI::RapidCode::RSIUserLimitLogicLE,
						  actual_pos_host_addr,
						  pos_high_rmp);


const double TRIGGER_IMMEDIATELY = 0.0;
const bool SINGLE_SHOT_EVENT = true;
mc->UserLimitConfigSet(userlim,
					   RSI::RapidCode::RSIUserLimitTriggerTypeCONDITION_AND,
					   RSI::RapidCode::RSIActionNONE, // don't do anything, just create an interrupt/event
					   TARGET_AXIS_IDX,
					   TRIGGER_IMMEDIATELY,
					   SINGLE_SHOT_EVENT);

Configuring for EXIT REGION:

mc->UserLimitConditionSet(userlim,
						  0,
						  RSI::RapidCode::RSIUserLimitLogicLT,
						  actual_pos_host_addr,
						  pos_low_rmp);

mc->UserLimitConditionSet(userlim,
						  1,
						  RSI::RapidCode::RSIUserLimitLogicGT,
						  actual_pos_host_addr,
						  pos_high_rmp);

const double TRIGGER_IMMEDIATELY = 0.0;
const bool SINGLE_SHOT_EVENT = true;
// int32 number, RSIUserLimitTriggerType triggerType, RSIAction action, int32 actionAxis, double duration, bool singleShot
mc->UserLimitConfigSet(userlim,
					   RSI::RapidCode::RSIUserLimitTriggerTypeCONDITION_OR,
					   RSI::RapidCode::RSIActionNONE, // don't do anything, just create an interrupt/event
					   TARGET_AXIS_IDX,
					   TRIGGER_IMMEDIATELY,
					   SINGLE_SHOT_EVENT);

When I run the program, it enters fine. As soon as I leave the region: loop!

Moving to start outside the region.
. Finished.
(->inside) UL 0: *(92871272) >= -1.31072e+06
AND
(->inside) UL 1: *(92871272) <= -655360
Curr: -400000
user limit configured.
.
Moving inside the region. (curr: -400000)
…User Limit #10 triggered! (2)
(->outside) UL 0: *(92871272) < -1.31072e+06
OR
(->outside) UL 1: *(92871272) > -655360
Curr: -657744
. Finished.

Moving outside the region. (curr: -799999)
…User Limit #10 triggered! (1)
(->inside) UL 0: *(92871272) >= -1.31072e+06
AND
(->inside) UL 1: *(92871272) <= -655360
Curr: -653403
User Limit #10 triggered! (2)
(->outside) UL 0: *(92871272) < -1.31072e+06
OR
(->outside) UL 1: *(92871272) > -655360
Curr: -651295
User Limit #10 triggered! (1)
(->inside) UL 0: *(92871272) >= -1.31072e+06
AND
(->inside) UL 1: *(92871272) <= -655360
Curr: -649509

(continues indefinitely)

I don’t know why I’m getting user limit events when I reconfigure it for re-entry. The current position clearly does not meet the (new) criteria for the user limit.

Can you help me figure out what’s going on here?

I think you understand it correctly.

I may be parsing your logs incorrectly. You are showing a Move, A Trigger, the Next Conditions, then the Current Position at time of last trigger.

Curr: -657744 Looks like a correctly detected on move in.
Curr: -653403 Looks like a correctly detected on move out.
Curr: -651295 Looks like an incorrect trigger.
Curr: -649509 Looks like a correctly detected.

Can you reverse the order of the Or (Outside) Conditions as an experiment.

When I’m back in the office on Monday, I’ll setup a test to see if I can reproduce it.

“reverse the order”

Do you mean change the condition numbers for the UserLimitConditionSet() calls (and the order in which they’re called)?

I switched the order in which UserLimitConditionSet() was called (and the condition numbers). I still see the same behavior. (I updated the gist, too.)

Also, as a test, I switched to using one user limit for entry and another for exit, and I don’t see the problem.