UserLimit directly sets a command position sample application.
- Warning
- This is a sample program to assist in the integration of the RMP motion controller with your application. It may not contain all of the logic and safety features that your application requires. We recommend that you wire an external hardware emergency stop (e-stop) button for safety when using our code sample apps. Doing so will help ensure the safety of you and those around you and will prevent potential injury or damage.
The sample apps assume that the system (network, axes, I/O) are configured prior to running the code featured in the sample app. See the Configuration page for more information.
📜 User Limit Trigger: Digital Input Conditions: 1
This sample code is done in AKD Drive with one Actual axis. There are a lots of available/free firmware address. Some are suggested in comment. Avaiable/free firmware addess can be found using vm3 as long as there is no label on address, it can be used.
const int INPUT_INDEX = 0;
const int OUTPUT_INDEX = 1;
int userLimitNumber = 0;
int condition = 0;
uint test = (uint)input0.
MaskGet();
uint inputMask = (uint)input0.
MaskGet();
uint limtValue = (uint)input0.
MaskGet();
condition,
logic,
inputAddress,
inputMask,
limtValue);
int axisNumber = 0;
int duration = 0;
triggerType,
action,
axisNumber,
duration);
uint andMask = (uint)output0.
MaskGet();
uint orMask = (uint)output0.
MaskGet();
bool enableOutput = true;
andMask,
orMask,
outputAddress,
enableOutput);
{
Assert.That(output0.
Get(), Is.False,
"We expect the output to NOT be triggered");
}
Assert.That(output0.
Get(), Is.True,
"We expect the output to be triggered");
Learn more in the concept page.
📜 User Limit Trigger: Digital Input Conditions: 2
This sample code shows how to configure the RMP controller's User Limits to compare an two different input bits to a specific signal (high signal (1) OR low signal (0)). If the (2 conditions) patterns match, then the specified output bit is activated (turns high).
In this example we configure a user limit to trigger when both our INPUTS turns high(1). Once the INPUTS turn high(1) then our user limit will set the OUTPUT to high(1). The INPUTS are specified in two different UserLimitConditionSet() The OUTPUT is specified in UserLimitOutputSet()
In this example Beckhoff IO Terminals (Model EL1088 for Inputs and Model EL2008 for outputs) were used to control the Digital IO signals.
Make sure to check the correct digital IO signal indexes of your system in: RapidSetup -.Tools -.NetworkIO
const int INPUT_INDEX0 = 0;
const int INPUT_INDEX1 = 1;
const int OUTPUT_INDEX = 2;
int userLimitNumber = 0;
int condition0 = 0;
uint input0Mask = (uint)input0.
MaskGet();
uint limitValue0 = (uint)input0.
MaskGet();
int condition1 = 1;
uint input1Mask = (uint)input1.
MaskGet();
uint limitValue1 = (uint)input1.
MaskGet();
condition0,
logic,
input0Address,
input0Mask,
limitValue0);
condition1,
logic,
input1Address,
input1Mask,
limitValue1);
int axis = 0;
int duration = 0;
triggerType,
action,
axis,
duration);
uint andMask = (uint)output0.
MaskGet();
uint orMask = (uint)output0.
MaskGet();
bool enableOutput = true;
andMask,
orMask,
outputAddress,
enableOutput);
{
Assert.That(output0.
Get(), Is.False,
"We expect the output to NOT be triggered");
Assert.That(output0.
Get(), Is.False,
"We expect the output to NOT be triggered");
Assert.That(output0.
Get(), Is.False,
"We expect the output to NOT be triggered");
}
Learn more in the concept page.
📜 User Limit Trigger: Digital Input Conditions: 1 Event: EStop
This sample code shows how to configure a RMP controller's User Limit to compare an input bit to a specific signal (high signal (1) OR low signal (0)).
If the (1 condition) pattern matches, then the specified input bit has been activated (turned high) and a User limit Event will trigger. In this example we configure a user limit to trigger when our INPUT turns high(1). Once the INPUT turns high(1) then our user limit will command an E-Stop action on the Axis and store the Axis Command Position. The INPUT is specified in UserLimitConditionSet() The User Limit configuration is done on UserLimitConfigSet() The specified address to record on User Limit Event is specified in UserLimitInterruptUserDataAddressSet() The Data from the speficified addres is retrieved by calling InterruptUserDataGet() In this example Beckhoff IO Terminals (Model EL1088 for Inputs) were used to control the Digital IO signals. Make sure to check the correct digital IO signal indexes of your system in: RapidSetup -. Tools -. NetworkIO
const int AXIS_INDEX = 0;
const int INPUT_INDEX = 0;
const int AXIS_COUNT = 1;
const int USER_LIMIT = 0;
const int CONDITION = 0;
const int LIMIT_VALUE = 1;
const double DURATION = 0.125;
const int USER_DATA_INDEX = 0;
axis = CreateAndReadyAxis(Constants.AXIS_NUMBER);
axis.MoveVelocity(10.0, 20.0);
USER_DATA_INDEX,
{
}
Console.WriteLine("TRIGGERED - User Limit Interrupt Position = " + interruptPosition / axis.UserUnitsGet());
Learn more in the concept page.
📜 User Limit Trigger: Position Conditions: 1 Event: FeedRate
Configure a UserLimit to change the FeedRate when the axis has reached a specified position.
const int USER_LIMIT = 0;
const int USER_LIMIT_COUNT = 1;
const int AXIS_COUNT = 1;
const int CONDITION = 0;
const double POSITION_TRIGGER_VALUE = 5;
const int DURATION = 0;
const double DEFAULT_FEED_RATE = 1.0;
const double DESIRED_FEED_RATE = 2.0;
UInt64 feedRateAddress;
axis = CreateAndReadyAxis(Constants.AXIS_NUMBER);
axis.FeedRateSet(DEFAULT_FEED_RATE);
controller.
UserLimitConfigSet(USER_LIMIT, TRIGGER_TYPE, ACTION, axis.NumberGet(), DURATION);
Learn more in the concept page.
📜 User Limit Trigger: Position Conditions: 1 Event: Abort
Configure a User Limit to call abort when a specified position is reached.
const int AXIS_COUNT = 1;
const int USER_LIMIT_COUNT = 1;
const int USER_LIMIT_NUMBER = 0;
const double TRIGGER_POSITION = 0.05;
const double MOVE_POSITION = 1.0;
const int OUTPUT_INDEX = 1;
const int WAIT_FOR_TRIGGER_MILLISECONDS = 100;
axis = CreateAndReadyAxis(Constants.AXIS_NUMBER);
int condition = 0;
double limitValue = TRIGGER_POSITION;
condition,
limitValue);
int duration = 0;
triggerType,
action,
axis.NumberGet(),
duration);
uint andMask = (uint)output0.
MaskGet();
uint orMask = (uint)output0.
MaskGet(); ;
bool enableOutput = true;
andMask,
orMask,
outputAddress,
enableOutput);
Assert.That(output0.
Get(), Is.False,
"We expect the output to NOT be triggered");
axis.MoveSCurve(MOVE_POSITION);
{
Assert.That(controller.
InterruptSourceNumberGet(), Is.EqualTo(USER_LIMIT_NUMBER + AXIS_COUNT),
"We got a USER_LIMIT interrupt but it was the wrong one.");
Assert.That(output0.
Get(), Is.True,
"We expect the output to be turned on when the user limit triggers.");
}
else
{
Assert.Fail("We expected a USER_LIMIT interrupt when the trigger position was exceeded but instead got " + interruptType.ToString());
}
axis.AmpEnableSet(false);
Learn more in the concept page.
📜 Two User Limits Custom
Configure two UserLimits. The first will trigger on a digital input and copy the Axis Actual Position to the UserBuffer and decelerate to zero velocity with TRIGGERED_MODIFY. The second UserLimit will trigger after the first UserLimit triggers and the Axis gets to IDLE stae and it will directly set the command position of an Axis from the position stored in the UserBuffer.
const int AXIS_COUNT = 1;
const int USER_LIMIT_FIRST = 0;
const int USER_LIMIT_SECOND = 1;
const int USER_LIMIT_COUNT = 2;
const int DURATION = 0;
const bool ONE_SHOT = true;
const int COMMAND_POSITION_INDEX = 0;
const int ACTUAL_POSITION_INDEX = 1;
const int TC_COMMAND_POSITION_INDEX = 2;
const int TC_ACTUAL_POSITION_INDEX = 3;
public void UserLimitCommandPositionDirectSet()
{
axis = CreateAndReadyAxis(Constants.AXIS_NUMBER);
axis.
MoveVelocity(Constants.VELOCITY, Constants.ACCELERATION);
ConfigureUserLimitInterrupts(USER_LIMIT_FIRST);
ConfigureUserLimitInterrupts(USER_LIMIT_SECOND);
WaitForInterrupts();
}
public void ConfigureUserLimitInterrupts(int userLimitIndex)
{
}
public void WaitForInterrupts()
{
bool done = false;
int timeout_millseconds = 10;
while (!done)
{
switch (eventType)
{
break;
done = true;
break;
default:
break;
}
}
}
Learn more in the concept page.
📜 User Limit Using Math Blocks Trigger: Math Block Process Value Conditions: 1 Event: Abort
This sample code demonstrates how to use a MathBlock to calculate the difference of in position between two axes and trigger a UserLimit when the difference exceeds a certain value.
Console.WriteLine("📜 MathBlock: Difference of Position UserLimit");
const int INDEX_ZERO = 0;
try
{
Axis axis0 = controller.
AxisGet(Constants.AXIS_0_INDEX);
Axis axis1 = controller.
AxisGet(Constants.AXIS_1_INDEX);
mbConfig.Operation = SUBTRACT;
mbConfig.InputAddress0 = axis0PositionAddr;
mbConfig.InputAddress1 = axis1PositionAddr;
mbConfig.InputDataType0 = DOUBLE;
mbConfig.InputDataType1 = DOUBLE;
mbConfig.ProcessDataType = DOUBLE;
number: INDEX_ZERO,
conditionNumber: 0,
addressOfDouble: mbProcessValueAddr,
limitValueDouble: 5 * Constants.AXIS_0_USER_UNITS);
number: INDEX_ZERO,
actionAxis: Constants.AXIS_0_INDEX,
duration: 0);
relativePosition: 10,
vel: 1,
accel: 1,
decel: 1,
jerkPct: 0);
Console.WriteLine($"Axis 0 state: {axis0State} (expected: {RSIState.RSIStateERROR})");
if (axis0State !=
RSIState.RSIStateERROR)
throw new Exception("❌ UserLimit did not trigger correctly - both axes should be in error state.");
}
finally
{
}
static void CheckErrors(RapidCodeObject rsiObject)
Checks for errors in the given RapidCodeObject and throws an exception if any non-warning errors are ...
Helpers class provides static methods for common tasks in RMP applications.
uint64_t AddressGet(RSIAxisAddressType addressType)
Get the an address for some location on the Axis.
void ErrorLimitActionSet(RSIAction action)
Set the action that will occur when the Error Limit Event triggers.
void PositionSet(double position)
Set the Command and Actual positions.
void MoveRelative(double relativePosition, double vel, double accel, double decel, double jerkPct)
Command a relative point-to-point S-Curve motion.
Represents a single axis of motion control. This class provides an interface for commanding motion,...
Axis * AxisGet(int32_t axisNumber)
AxisGet returns a pointer to an Axis object and initializes its internals.
void UserLimitDisable(int32_t number)
Disable the processing of a User Limit.
void MathBlockCountSet(int32_t mathBlockCount)
Set the number of processed MathBlocks in the MotionController.
void UserLimitConditionSet(int32_t number, int32_t conditionNumber, RSIUserLimitLogic logic, uint64_t addressOfUInt32, uint32_t userLimitMask, uint32_t limitValueUInt32)
Set the conditions for a User Limit with a 32-bit integer trigger value.
static MotionController * Get()
Get an already running RMP EtherCAT controller.
uint64_t AddressGet(RSIControllerAddressType type)
Get the an address for some location on the MotionController.
void SampleWait(uint32_t samples)
Wait for controller firmware to execute samples.
void UserLimitConfigSet(int32_t number, RSIUserLimitTriggerType triggerType, RSIAction action, int32_t actionAxis, double duration, bool singleShot)
Configure a User Limit.
void Delete(void)
Delete the MotionController and all its objects.
void UserLimitCountSet(int32_t userLimitCount)
Set the number of processed UserLimits in the MotionController.
Represents the RMP soft motion controller. This class provides an interface to general controller con...
MathBlockConfig MathBlockConfigGet(int32_t mathBlockNumber)
Get a MathBlock configuration.
void MathBlockConfigSet(int32_t mathBlockNumber, MathBlockConfig &config)
Set a MathBlock configuration.
void ClearFaults()
Clear all faults for an Axis or MultiAxis.
void Abort()
Abort an axis.
int32_t MotionDoneWait()
Waits for a move to complete.
RSIState StateGet()
Get the Axis or MultiAxis state.
int32_t AmpEnableSet(bool enable, int32_t ampActiveTimeoutMilliseconds=AmpEnableTimeoutMillisecondsDefault, bool overrideRestrictedState=false)
Enable all amplifiers.
RSIMathBlockOperation
MathBlock operations.
RSIControllerAddressType
Used to get firmware address used in User Limits, Recorders, etc.
RSIDataType
Data types for User Limits and other triggers.
RSIUserLimitLogic
Logic options for User Limits.
RSIAction
Action to perform on an Axis.
RSIAxisAddressType
Used to get firmware address used in User Limits, Recorders, etc.
RSIUserLimitTriggerType
Trigger types for UserLimits.
Learn more in the concept page.