APIs, concepts, guides, and more
10#include <map>
12#include "SampleAppsHelper.h" // Import our helper functions.
13#include "rsi.h" // Import our RapidCode Library.
15using namespace RSI::RapidCode; // Import our RapidCode namespace
17// Map of the RSIState enum to string
18static const std::map<RSIState, std::string> RSIStateMap = {
19 {RSIState::RSIStateIDLE, "RSIStateIDLE"},
20 {RSIState::RSIStateMOVING, "RSIStateMOVING"},
24 {RSIState::RSIStateERROR, "RSIStateERROR"}
27int main()
29 const std::string SAMPLE_APP_NAME = "Math Blocks: Difference of Position User Limit";
31 // Print a start message to indicate that the sample app has started
32 SampleAppsHelper::PrintHeader(SAMPLE_APP_NAME);
35 // *NOTICE* The following constants must be configured before attempting to run with hardware.
37 // User Limit Configuration
38 const double MAX_POSITION_DIFFERENCE = 0.5 * SampleAppsConfig::AXIS_X_USER_UNITS; // the maximum position difference before the user limit triggers
39 const RSIAction USER_LIMIT_ACTION = RSIAction::RSIActionABORT; // the action to take when the user limit is triggered
40 const int USER_LIMIT_DURATION = 0; // the time delay before the action is executed after the User Limit has triggered
42 // Motion Parameters
43 const double RELATIVE_POSITION = 2 * MAX_POSITION_DIFFERENCE; // the relative position to move the axes
44 const double VELOCITY = 1; // the velocity to move the axes
45 const double ACCELERATION = 10; // the acceleration of the axes movement
46 const double DECELERATION = 10; // the deceleration of the axes movement
47 const double JERK_PCT = 0; // the jerk percentage of the axes movement
51 // Create the controller
53 MotionController *controller = MotionController::Create(&params);
55 int exitCode = -1; // Set the exit code to an error value.
56 try // Ensure that the controller is deleted if an error occurs.
57 {
60 // Prepare the controller and axes as defined in SampleAppsHelper.h
65 /* Configure the controller object counts */
70 // Get the axes
71 Axis *axisX = controller->AxisGet(SampleAppsConfig::AXIS_X_INDEX);
74 Axis *axisY = controller->AxisGet(SampleAppsConfig::AXIS_Y_INDEX);
77 // Configure a multiaxis for the two axes
78 MultiAxis *multiAxis = controller->MultiAxisGet(SampleAppsConfig::AXIS_COUNT);
81 multiAxis->AxisRemoveAll();
82 multiAxis->AxisAdd(axisX);
83 multiAxis->AxisAdd(axisY);
85 multiAxis->Abort(); // make sure the multiaxis is not moving
86 multiAxis->ClearFaults();
88 // Read the configuration of the MathBlock
89 const int MATHBLOCK_INDEX = SampleAppsConfig::MATH_BLOCK_COUNT;
90 MotionController::MathBlockConfig mathBlockConfig = controller->MathBlockConfigGet(MATHBLOCK_INDEX);
92 // Determine which axis address type to use based on the config USE_HARDWARE flag
93 RSIAxisAddressType INPUT_AXIS_ADDRESS_TYPE = (SampleAppsConfig::USE_HARDWARE) ? (RSIAxisAddressType::RSIAxisAddressTypeACTUAL_POSITION)
94 : (RSIAxisAddressType::RSIAxisAddressTypeCOMMAND_POSITION);
96 // Configure the MathBlock to subtract the position of the second axis from the position of the first axis
97 mathBlockConfig.InputAddress0 = axisX->AddressGet(INPUT_AXIS_ADDRESS_TYPE);
98 mathBlockConfig.InputDataType0 = RSIDataType::RSIDataTypeDOUBLE;
99 mathBlockConfig.InputAddress1 = axisY->AddressGet(INPUT_AXIS_ADDRESS_TYPE);
100 mathBlockConfig.InputDataType1 = RSIDataType::RSIDataTypeDOUBLE;
101 mathBlockConfig.ProcessDataType = RSIDataType::RSIDataTypeDOUBLE;
102 mathBlockConfig.Operation = RSIMathBlockOperation::RSIMathBlockOperationSUBTRACT;
104 // Set the MathBlock configuration
105 controller->MathBlockConfigSet(MATHBLOCK_INDEX, mathBlockConfig);
107 // Wait a sample so we know the RMP is now processing the newly configured MathBlocks
108 controller->SampleWait(1);
109 std::cout << "MathBlock configured to subtract the position of the second axis from the position of the first axis." << std::endl;
111 // Get the address of the MathBlock's ProcessValue to use in the UserLimit
112 uint64_t mathBlockProcessValueAddress =
113 controller->AddressGet(RSIControllerAddressType::RSIControllerAddressTypeMATHBLOCK_PROCESS_VALUE, MATHBLOCK_INDEX);
115 // Configure the UserLimit to trigger when the absolute position difference is greater than MAX_POSITION_DIFFERENCE
116 const int USER_LIMIT_INDEX = SampleAppsConfig::USER_LIMIT_COUNT;
117 controller->UserLimitConditionSet(
118 USER_LIMIT_INDEX, 0, RSIUserLimitLogic::RSIUserLimitLogicABS_GT, mathBlockProcessValueAddress, MAX_POSITION_DIFFERENCE
119 );
121 // Set the UserLimit action to abort motion (Note: since the axes are in a multiaxis, the other axis will also be aborted)
122 controller->UserLimitConfigSet(
125 );
126 std::cout << "UserLimit configured to trigger when the absolute position difference is greater than " << MAX_POSITION_DIFFERENCE
127 << " and abort motion." << std::endl;
129 // Command motion to trigger the UserLimit
130 std::cout << "Moving the axes to trigger the UserLimit..." << std::endl;
131 axisX->AmpEnableSet(true); // Enable the motor.
132 axisX->MoveRelative(RELATIVE_POSITION, VELOCITY, ACCELERATION, DECELERATION, JERK_PCT); // Move the axis to trigger the UserLimit.
133 axisX->MotionDoneWait();
135 // Disable the motor and the UserLimit
136 axisX->AmpEnableSet(false); // Disable the motor.
137 controller->UserLimitDisable(USER_LIMIT_INDEX);
139 // The motion should have been aborted and both axes should be in an error state
140 if ((axisX->StateGet() == RSIState::RSIStateERROR) && (axisY->StateGet() == RSIState::RSIStateERROR))
141 {
142 std::cout << "Both axes are in the error state after the UserLimit triggered (This is the intended behavior)." << std::endl;
143 exitCode = 0;
144 }
145 else
146 {
147 std::cout << "Error: The axes should be in an error state after the UserLimit triggers, but they are not." << std::endl;
148 std::cout << "First Axis State: " << RSIStateMap.at(axisX->StateGet()) << std::endl;
149 std::cout << "Second Axis State: " << RSIStateMap.at(axisY->StateGet()) << std::endl;
150 exitCode = -1;
151 }
152 }
153 catch (const std::exception &ex)
154 {
155 std::cerr << ex.what() << std::endl;
156 exitCode = -1;
157 }
158 // Delete the controller as the program exits to ensure memory is deallocated in the correct order
159 controller->Delete();
162 // Print a message to indicate the sample app has finished and if it was successful or not
163 SampleAppsHelper::PrintFooter(SAMPLE_APP_NAME, exitCode);
165 return exitCode;
uint64_t AddressGet(RSIAxisAddressType addressType)
Get the an address for some location on the Axis.
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,...
Definition rsi.h:5513
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.
void MotionCountSet(int32_t motionCount)
Set the number of processed Motion Supervisors in the controller.
uint64_t AddressGet(RSIControllerAddressType type)
Get the an address for some location on the MotionController.
static MotionController * Create()
Initialize and start the RMP EtherCAT controller.
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.
MultiAxis * MultiAxisGet(int32_t motionSupervisorNumber)
MultiAxisGet returns a pointer to a MultiAxis object and initializes its internals.
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...
Definition rsi.h:794
MathBlockConfig MathBlockConfigGet(int32_t mathBlockNumber)
Get a MathBlock configuration.
void MathBlockConfigSet(int32_t mathBlockNumber, MathBlockConfig &config)
Set a MathBlock configuration.
void AxisRemoveAll()
Remove all axes from a MultiAxis group.s.
void AxisAdd(Axis *axis)
Add an Axis to a MultiAxis group.
Represents multiple axes of motion control, allows you to map two or more Axis objects together for e...
Definition rsi.h:10208
void ClearFaults()
Clear all faults for an Axis or MultiAxis.
void AmpEnableSet(bool enable)
Enable all amplifiers.
void Abort()
Abort an axis.
int32_t MotionDoneWait()
Waits for a move to complete.
RSIState StateGet()
Get the Axis or MultiAxis state.
Action to perform on an Axis.
Definition rsienums.h:1061
Used to get firmware address used in User Limits, Recorders, etc.
Definition rsienums.h:433
static void PrintFooter(std::string sampleAppName, int exitCode)
Print a message to indicate the sample app has finished and if it was successful or not.
static void CheckErrors(RapidCodeObject *rsiObject)
Checks for errors in the given RapidCodeObject and throws an exception if any non-warning errors are ...
static void PrintHeader(std::string sampleAppName)
Print a start message to indicate that the sample app has started.
static void SetupController(MotionController *controller)
Setup the controller with user defined axis counts and configuration.
static MotionController::CreationParameters GetCreationParameters()
Returns a MotionController::CreationParameters object with user-defined parameters.
CreationParameters for MotionController::Create.
Definition rsi.h:855
RSIDataType ProcessDataType
Data type for processing.
Definition rsi.h:3642
MathBlock configuration structure.
Definition rsi.h:3635
uint64_t InputAddress0
Host memory address for Input0. Represents the left-hand side operand in math operations.
Definition rsi.h:3636
RSIDataType InputDataType0
Data type for Input0. This is the data type of the left-hand side operand in math operations.
Definition rsi.h:3637
uint64_t InputAddress1
Host memory address for Input1. Represents the right-hand side operand in math operations.
Definition rsi.h:3638
RSIDataType InputDataType1
Data type for Input1. This is the data type of the right-hand side operand in math operations.
Definition rsi.h:3639
RSIMathBlockOperation Operation
Math operation to be performed. (+, -, *, /, etc) use RSIMathBlockOperationNONE to disable a MathBloc...
Definition rsi.h:3643
static constexpr int AXIS_COUNT
Number of axes to configure on the controller.
static constexpr int USER_LIMIT_COUNT
Number of user limits to configure on the controller.
static constexpr int AXIS_X_INDEX
Index of the first axis to use in the sample apps.
static constexpr int MATH_BLOCK_COUNT
Number of math block objects to configure on the controller.
static constexpr bool USE_HARDWARE
Flag for whether to use hardware or phantom axes.
static constexpr int AXIS_X_USER_UNITS
User units for the first axis.
static constexpr int AXIS_Y_INDEX
Index of the second axis to use in the sample apps.