APIs, concepts, guides, and more
DifferenceOfPositionUserLimit.cpp
1
10#include <map>
11
12#include "SampleAppsHelper.h" // Import our helper functions.
13#include "rsi.h" // Import our RapidCode Library.
14
15using namespace RSI::RapidCode; // Import our RapidCode namespace
16
17// Map of the RSIState enum to string
18static const std::map<RSIState, std::string> RSIStateMap = {
19 {RSIState::RSIStateIDLE, "RSIStateIDLE"},
20 {RSIState::RSIStateMOVING, "RSIStateMOVING"},
21 {RSIState::RSIStateSTOPPING, "RSIStateSTOPPING"},
22 {RSIState::RSIStateSTOPPED, "RSIStateSTOPPED"},
23 {RSIState::RSIStateSTOPPING_ERROR, "RSIStateSTOPPING_ERROR"},
24 {RSIState::RSIStateERROR, "RSIStateERROR"}
25};
26
27int main()
28{
29 // Print a start message to indicate that the sample app has started
30 const std::string SAMPLE_APP_NAME = "Math Blocks: Difference of Position User Limit";
31 SampleAppsHelper::PrintHeader(SAMPLE_APP_NAME);
32
34 /* CONSTANTS */
35 // *NOTICE* The following constants must be configured before attempting to run with hardware.
36 const int NUM_AXES = 2; // The number of axes to configure
37 const int AXIS_X_INDEX = 0; // The index of the first axis
38 const int AXIS_Y_INDEX = 1; // The index of the second axis
39
40 // User Limit Configuration
41 const double MAX_POSITION_DIFFERENCE = 0.5; // the maximum position difference before the user limit triggers
42 const RSIAction USER_LIMIT_ACTION = RSIAction::RSIActionABORT; // the action to take when the user limit is triggered
43 const int USER_LIMIT_DURATION = 0; // the time delay before the action is executed after the User Limit has triggered
44
45 // Motion Parameters
46 const double RELATIVE_POSITION = 2 * MAX_POSITION_DIFFERENCE; // the relative position to move the axes
47 const double VELOCITY = 1; // the velocity to move the axes
48 const double ACCELERATION = 10; // the acceleration of the axes movement
49 const double DECELERATION = 10; // the deceleration of the axes movement
50 const double JERK_PCT = 0; // the jerk percentage of the axes movement
51
52 /* RAPIDCODE INITIALIZATION */
53 // Create the controller
55 MotionController *controller = MotionController::Create(&params);
56
57 // Variables to store initial object counts to restore later (starts at -1 to indicate it has not been set)
58 int initialUserLimitCount = -1;
59 int initialMathBlockCount = -1;
60
61 // Set the exit code to an error value.
62 int exitCode = -1;
63 try // Ensure that the controller is deleted if an error occurs.
64 {
65 // Prepare the controller as defined in SampleAppsHelper.h depending on the configuration
67 SampleAppsHelper::SetupController(controller, NUM_AXES);
68
69 // Save initial object counts to restore later
70 initialUserLimitCount = controller->UserLimitCountGet();
71 initialMathBlockCount = controller->MathBlockCountGet();
72
73 /* SAMPLE APP BODY */
74
75 /* Configure the controller object counts */
76 // Normally you would set the number of axes here, but for samples that is handled in the SampleAppsHelper::SetupController function
77 // controller->AxisCountSet(NUM_AXES);
78
79 // Each axis has a motion object associated with it, so we need to add one more motion object than axes
80 const int multiAxisIndex = controller->AxisCountGet();
81 controller->MotionCountSet(multiAxisIndex + 1);
82
83 const int userLimitIndex = initialUserLimitCount;
84 controller->UserLimitCountSet(initialUserLimitCount + 1);
85
86 const int mathBlockIndex = initialMathBlockCount;
87 controller->MathBlockCountSet(initialMathBlockCount + 1);
88
89 // Get the axes
90 Axis *axisX = controller->AxisGet(AXIS_X_INDEX);
92
93 Axis *axisY = controller->AxisGet(AXIS_Y_INDEX);
95
96 // Configure a multiaxis for the two axes
97 MultiAxis *multiAxis = controller->MultiAxisGet(multiAxisIndex);
99
100 multiAxis->AxisRemoveAll();
101 multiAxis->AxisAdd(axisX);
102 multiAxis->AxisAdd(axisY);
103
104 multiAxis->Abort(); // make sure the multiaxis is not moving
105 multiAxis->ClearFaults();
106
107 // Read the configuration of the MathBlock
108 MotionController::MathBlockConfig mathBlockConfig = controller->MathBlockConfigGet(mathBlockIndex);
109
110 // Determine which axis address type to use based on the config USE_HARDWARE flag
111 RSIAxisAddressType INPUT_AXIS_ADDRESS_TYPE = (SampleAppsConfig::USE_HARDWARE) ? (RSIAxisAddressType::RSIAxisAddressTypeACTUAL_POSITION)
112 : (RSIAxisAddressType::RSIAxisAddressTypeCOMMAND_POSITION);
113
114 // Configure the MathBlock to subtract the position of the second axis from the position of the first axis
115 mathBlockConfig.InputAddress0 = axisX->AddressGet(INPUT_AXIS_ADDRESS_TYPE);
116 mathBlockConfig.InputDataType0 = RSIDataType::RSIDataTypeDOUBLE;
117 mathBlockConfig.InputAddress1 = axisY->AddressGet(INPUT_AXIS_ADDRESS_TYPE);
118 mathBlockConfig.InputDataType1 = RSIDataType::RSIDataTypeDOUBLE;
119 mathBlockConfig.ProcessDataType = RSIDataType::RSIDataTypeDOUBLE;
120 mathBlockConfig.Operation = RSIMathBlockOperation::RSIMathBlockOperationSUBTRACT;
121
122 // Set the MathBlock configuration
123 controller->MathBlockConfigSet(mathBlockIndex, mathBlockConfig);
124
125 // Wait a sample so we know the RMP is now processing the newly configured MathBlocks
126 controller->SampleWait(1);
127 std::cout << "MathBlock configured to subtract the position of the second axis from the position of the first axis." << std::endl;
128
129 // Get the address of the MathBlock's ProcessValue to use in the UserLimit
130 uint64_t mathBlockProcessValueAddress =
131 controller->AddressGet(RSIControllerAddressType::RSIControllerAddressTypeMATHBLOCK_PROCESS_VALUE, mathBlockIndex);
132
133 // Configure the UserLimit to trigger when the absolute position difference is greater than MAX_POSITION_DIFFERENCE
134 controller->UserLimitConditionSet(
135 userLimitIndex, 0, RSIUserLimitLogic::RSIUserLimitLogicABS_GT, mathBlockProcessValueAddress, MAX_POSITION_DIFFERENCE
136 );
137
138 // Set the UserLimit action to abort motion (Note: since the axes are in a multiaxis, the other axis will also be aborted)
139 controller->UserLimitConfigSet(
140 userLimitIndex, RSIUserLimitTriggerType::RSIUserLimitTriggerTypeSINGLE_CONDITION, USER_LIMIT_ACTION, AXIS_X_INDEX,
141 USER_LIMIT_DURATION
142 );
143 std::cout << "UserLimit configured to trigger when the absolute position difference is greater than " << MAX_POSITION_DIFFERENCE
144 << " and abort motion." << std::endl;
145
146 // Command motion to trigger the UserLimit
147 std::cout << "Moving the axes to trigger the UserLimit..." << std::endl;
148 axisX->AmpEnableSet(true); // Enable the motor.
149 axisX->MoveRelative(RELATIVE_POSITION, VELOCITY, ACCELERATION, DECELERATION, JERK_PCT); // Move the axis to trigger the UserLimit.
150 axisX->MotionDoneWait();
151
152 // Disable the motor and the UserLimit
153 axisX->AmpEnableSet(false); // Disable the motor.
154 controller->UserLimitDisable(userLimitIndex);
155
156 // The motion should have been aborted and both axes should be in an error state
157 if ((axisX->StateGet() == RSIState::RSIStateERROR) && (axisY->StateGet() == RSIState::RSIStateERROR))
158 {
159 std::cout << "Both axes are in the error state after the UserLimit triggered (This is the intended behavior)." << std::endl;
160 exitCode = 0;
161 }
162 else
163 {
164 std::cout << "Error: The axes should be in an error state after the UserLimit triggers, but they are not." << std::endl;
165 std::cout << "First Axis State: " << RSIStateMap.at(axisX->StateGet()) << std::endl;
166 std::cout << "Second Axis State: " << RSIStateMap.at(axisY->StateGet()) << std::endl;
167 exitCode = -1;
168 }
169 }
170 catch (const std::exception &ex)
171 {
172 std::cerr << ex.what() << std::endl;
173 exitCode = -1;
174 }
175 // Restore the object counts to the original values
176 if (initialUserLimitCount != -1) { controller->UserLimitCountSet(initialUserLimitCount); }
177 if (initialMathBlockCount != -1) { controller->MathBlockCountSet(initialMathBlockCount); }
178 // Note: The axis and motion counts are handled by the SampleAppsHelper::Cleanup function
179
180 // Clean up the controller and any other objects as needed
181 SampleAppsHelper::Cleanup(controller);
182
183 // Delete the controller as the program exits to ensure memory is deallocated in the correct order
184 controller->Delete();
186
187 // Print a message to indicate the sample app has finished and if it was successful or not
188 SampleAppsHelper::PrintFooter(SAMPLE_APP_NAME, exitCode);
189
190 return exitCode;
191}
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:5643
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.
int32_t UserLimitCountGet()
Get the number of UserLimits processing in the firmware.
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.
int32_t MathBlockCountGet()
Get the number of MathBlocks processing in the firmware.
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.
int32_t AxisCountGet()
Get the number of axes processing.
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:796
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:10338
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.
RSIAction
Action to perform on an Axis.
Definition rsienums.h:1073
RSIAxisAddressType
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 Cleanup(MotionController *controller)
Cleanup the controller and restore the object counts to the original values.
static MotionController::CreationParameters GetCreationParameters()
Returns a MotionController::CreationParameters object with user-defined parameters.
static void SetupController(MotionController *controller, int numAxes=0)
Setup the controller with user defined axis counts and configuration.
CreationParameters for MotionController::Create.
Definition rsi.h:857
RSIDataType ProcessDataType
Data type for processing.
Definition rsi.h:3770
MathBlock configuration structure.
Definition rsi.h:3763
uint64_t InputAddress0
Host memory address for Input0. Represents the left-hand side operand in math operations.
Definition rsi.h:3764
RSIDataType InputDataType0
Data type for Input0. This is the data type of the left-hand side operand in math operations.
Definition rsi.h:3765
uint64_t InputAddress1
Host memory address for Input1. Represents the right-hand side operand in math operations.
Definition rsi.h:3766
RSIDataType InputDataType1
Data type for Input1. This is the data type of the right-hand side operand in math operations.
Definition rsi.h:3767
RSIMathBlockOperation Operation
Math operation to be performed. (+, -, *, /, etc) use RSIMathBlockOperationNONE to disable a MathBloc...
Definition rsi.h:3771
static constexpr bool USE_HARDWARE
Flag for whether to use hardware or phantom axes.