Learn how to use motion hold in C#.
- 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.
In this page:
📜 Motion Hold: via Position
Learn how to use Motion Hold 📖 based on another axis reaching a specified position. One axis controls when another axis's motion is released, useful for synchronized operations.
Console.WriteLine("📜 Motion Hold: via Position");
int exitCode = 0;
const double TRIGGER_POSITION = 1;
const int MOVING_AXIS_TARGET = 10;
const int HOLDING_AXIS_TARGET = 2;
try
{
Helpers.VerifyHardwareUsage(controller);
Helpers.VerifyAxisCount(controller, minRequiredSampleAxisCount: 2);
Helpers.PhantomAxisReset(holdingAxis);
Helpers.PhantomAxisReset(movingAxis);
Console.WriteLine($"\tHolding axis commanded to move to {HOLDING_AXIS_TARGET}, but motion is held");
Console.WriteLine($"\tMoving axis to {MOVING_AXIS_TARGET} to release hold...");
Console.WriteLine($"\tHolding axis final position: {holdingAxis.CommandPositionGet()} (expected: {HOLDING_AXIS_TARGET})");
Console.WriteLine($"\tMoving axis final position: {movingAxis.CommandPositionGet()} (expected: {MOVING_AXIS_TARGET})");
Helpers.AbortMotionObject(holdingAxis);
Helpers.AbortMotionObject(movingAxis);
}
catch (Exception e)
{
Console.WriteLine($"❌ Error: {e.Message}");
}
finally
{
controller.Delete();
}
return exitCode;
Constants used in the C# sample apps.
const int EXIT_FAILURE
Exit code for failed execution.
const int AXIS_0_INDEX
Default: 0.
const int AMP_ENABLE_MS
Default: 750.
const int EXIT_SUCCESS
Exit code for successful execution.
const int AXIS_1_INDEX
Default: 1.
RSIMotorType MotorTypeGet()
Get the motor type.
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,...
static MotionController * Get()
Get an already running RMP EtherCAT controller.
Represents the RMP soft motion controller. This class provides an interface to general controller con...
void MotionHoldAxisPositionSet(double position)
Sets the Axis position.
void MotionHoldTypeSet(RSIMotionHoldType type)
Set the motion hold type.
void MotionHoldAxisNumberSet(int32_t number)
Sets the Axis number for Motion Hold.
int32_t MotionDoneWait(int32_t waitTimeoutMilliseconds=WaitForever)
Waits for a move to complete.
int32_t AmpEnableSet(bool enable, int32_t ampActiveTimeoutMilliseconds=AmpEnableTimeoutMillisecondsDefault, bool overrideRestrictedState=false)
Enable all amplifiers.
int32_t NumberGet()
Get the axis number.
void MotionAttributeMaskOnSet(RSIMotionAttrMask maskOn)
Turn on a particular motion attribute mask.
void MotionHoldAxisLogicSet(RSIUserLimitLogic logic)
Set the logic when holding for Axis ActualPosition.
RSIUserLimitLogic
Logic options for User Limits.
RSIMotionAttrMask
Attribute masks for motion. You cannot mix RSIMotionAttrMaskDELAY and RSIMotionAttrMaskAPPEND.
RSIMotionHoldType
Types for MotionHold attribute.
@ RSIMotionHoldTypeAXIS_ACTUAL_POSITION
Helpers namespace provides utility functions for common tasks in RMP applications.
📜 Motion Hold: via Digital Input
Learn how to use Motion Hold 📖 triggered by a digital input signal. Motion is held until the specified digital input pattern is detected.
Console.WriteLine("📜 Motion Hold: via Digital Input");
int exitCode = 0;
const int DIGITAL_INPUTS_PDO_INDEX = 3;
try
{
Helpers.VerifyHardwareUsage(controller);
Helpers.VerifyAxisCount(controller);
{
Console.WriteLine("Phantom axes do not have digital inputs. Please enable USE_HARDWARE to run this sample.");
}
if (controller.NetworkStateGet() !=
RSINetworkState.RSINetworkStateOPERATIONAL)
{
Console.WriteLine("Network not started. Please start it before running this app.");
}
ulong inputAddress = controller.NetworkInputAddressGet(DIGITAL_INPUTS_PDO_INDEX);
Console.WriteLine("\tFirst motion commanded (held until digital input triggers)");
Console.WriteLine("\tSecond motion commanded (held until digital input triggers)");
Console.WriteLine("\tThird motion commanded (no hold, executes immediately)");
Console.WriteLine($"\tFinal position: {axis.CommandPositionGet()}");
}
catch (Exception e)
{
Console.WriteLine($"❌ Error: {e.Message}");
}
finally
{
controller.Delete();
}
return exitCode;
const bool USE_HARDWARE
Default: false.
void MotionHoldUserMaskSet(int32_t holdMask)
Sets the Motion Hold User bit mask.
void MotionHoldUserPatternSet(int32_t pattern)
Sets the Motion Hold User pattern bit mask.
void MotionAttributeMaskOffSet(RSIMotionAttrMask maskOff)
Turn off a particular motion attribute mask.
void MotionHoldUserAddressSet(uint64_t address)
Sets the Motion Hold User Address.
RSINetworkState
State of network.
📜 Motion Hold: via Address
Learn how to use Motion Hold 📖 controlled by a software address. Motion is held until a specific bit pattern is written to a memory location.
using System.Threading;
Console.WriteLine("📜 Motion Hold: via Address");
int exitCode = 0;
const int MOVE_DISTANCE = 2;
try
{
Helpers.VerifyHardwareUsage(controller);
Helpers.VerifyAxisCount(controller);
if (controller.MemoryGet(softwareAddress) != 0x0)
controller.MemorySet(softwareAddress, 0x0);
Console.WriteLine($"\tFirst motion commanded to move {MOVE_DISTANCE} (held)");
Thread.Sleep(100);
Console.WriteLine($"\tPosition while held: {positionWhileHeld} (should be 0)");
controller.MemorySet(softwareAddress, 0x1);
Console.WriteLine("\tReleasing hold via address...");
controller.MemorySet(softwareAddress, 0x0);
Console.WriteLine($"\tPosition after release: {axis.CommandPositionGet()} (expected: {MOVE_DISTANCE})");
Console.WriteLine($"\tSecond motion commanded to move {MOVE_DISTANCE} (held)");
Thread.Sleep(100);
controller.MemorySet(softwareAddress, 0x1);
Console.WriteLine("\tReleasing hold via address...");
controller.MemorySet(softwareAddress, 0x0);
Console.WriteLine($"\tThird motion commanded to move {MOVE_DISTANCE} (no hold)");
Console.WriteLine($"\tFinal position: {axis.CommandPositionGet()} (expected: {MOVE_DISTANCE * 3})");
}
catch (Exception e)
{
Console.WriteLine($"❌ Error: {e.Message}");
}
finally
{
controller.Delete();
}
return exitCode;
const double AXIS_0_USER_UNITS
Default: 1.
double CommandPositionGet()
Get the current command position.
void UserUnitsSet(double countsPerUserUnit)
Sets the number of counts per User Unit.
void PositionSet(double position)
Set the Command and Actual positions.
RSIControllerAddressType
Used to get firmware address used in User Limits, Recorders, etc.