MotionHold.cs
using RSI.RapidCode.dotNET; // Import our RapidCode Library.
using NUnit.Framework;
using System;
namespace SampleAppsCS
{
[TestFixture]
[Category("SoftwareSample")]
public class MotionHold : SampleAppTestBase
{
public void MotionHoldByDigitalInput()
{
//@[MotionHoldByDigitalInput]
// Constants
const int DIGITAL_INPUTS_PDO_INDEX = 3; // Specify the pdo inputs index that represent digital inputs.
// SET MOTION HOLD
ulong inputAddress = controller.NetworkInputAddressGet(DIGITAL_INPUTS_PDO_INDEX); // Get host address using the PDO Input Index of Digital Inputs.
axis.MotionHoldTypeSet(RSIMotionHoldType.RSIMotionHoldTypeCUSTOM); // Use TypeCUSTOM to hold execution based on a particular bit turning ON or OFF.
axis.MotionHoldUserAddressSet(inputAddress); // Specify the digital inputs host address. This address' value will be used to evaluate the motion hold condition.
axis.MotionHoldUserMaskSet(0x20000); // Specify the bit you want to mask/watch from the MotionHoldUserAddressSet' address value (this evaluates using a logic AND)
axis.MotionHoldUserPatternSet(0x20000); // Specify the bit value that will release the motion hold. (When this value is met, motion hold will be released)
axis.MotionAttributeMaskOnSet(RSIMotionAttrMask.RSIMotionAttrMaskHOLD); // Set the HOLD motion attribute mask ON. (This initializes the HOLD on a particular motion)
axis.MoveRelative(10); // Command simple relative motion. (This motion will be HOLD by the condition above)
axis.MotionDoneWait(); // Wait for Motion to be completed.
axis.MoveRelative(10); // If motion attribute mask off has not been set, this motion will have same HOLD condition as previous move.
axis.MotionDoneWait(); // Wait for Motion to be completed.
axis.MotionAttributeMaskOffSet(RSIMotionAttrMask.RSIMotionAttrMaskHOLD);// Set the HOLD motion attribute mask OFF. (This will clear any motion HOLDS that were set on this Axis)
axis.MoveRelative(10); // This motion will have no HOLD since the previous line has set the motion attribute mask OFF.
axis.MotionDoneWait(); // Wait for Motion to be completed.
// Abort and Clear Faults
axis.Abort();
axis.ClearFaults();
//@[MotionHoldByDigitalInput]
}
[Test]
public void MotionHoldByPosition()
{
//@[MotionHoldByPosition]
// Constants
const double TRIGGER_POS = 1; // Specify the position that will be evaluted on triggering/releasing motion
const int MOVING_AXIS_TARGET = 10;
const int HOLDINGAXIS_TARGET = 2;
// Initialize RapidCode Objects
// Initiazlize Axes: holdingAxis and movingAxis
Axis holdingAxis = controller.AxisGet(Constants.HOLDING_AXIS_INDEX); // Initialize Axis Class. (Use RapidSetup Tool to see what is your axis number)
SampleAppsCS.HelperFunctions.CheckErrors(holdingAxis); // [Helper Function] Check that the axis has been initialize correctly.
Axis movingAxis = controller.AxisGet(Constants.MOVING_AXIS_INDEX); // Initialize HoldAxis Class. (Use RapidSetup Tool to see what is your axis number)
SampleAppsCS.HelperFunctions.CheckErrors(movingAxis); // [Helper Function] Check that the axis has been initialize correctly.
// SET UP MOTION HOLD // Condition/Configuration to the Axis(movingAxis) that will hold Motion and its Position that will trigger/release motion
holdingAxis.MotionHoldTypeSet(RSIMotionHoldType.RSIMotionHoldTypeAXIS_COMMAND_POSITION); // Use RSIMotionHoldTypeAXIS_ACTUAL_POSITION if it is not Phantom Axis.
holdingAxis.MotionHoldAxisNumberSet(movingAxis.NumberGet()); // Specify motion hold to the Axis(movingAxis) whose position will hold the motion of holdingAxis.
holdingAxis.MotionHoldAxisPositionSet(TRIGGER_POS); // Specify motion hold position which is the movingAxis's position(need to multiply with USER_UNITS to get correct position value) to trigger/release the motion of holdingAxis.
holdingAxis.MotionHoldAxisLogicSet(RSIUserLimitLogic.RSIUserLimitLogicGE); // Specify the logic condition that will be evaluated to trigger/release motion based on the SET POSITION(USER_UNITS * TRIGGER_POS).In this case, GT(Greater than or Equal to) motion hold position limit to release
// SET MOTION HOLD ON
holdingAxis.MotionAttributeMaskOnSet(RSIMotionAttrMask.RSIMotionAttrMaskHOLD); // Set the HOLD motion attribute mask ON. (This initializes the HOLD on a particular motion)
holdingAxis.MoveRelative(HOLDINGAXIS_TARGET); // Command simple relative motion(This motion will be hold by condition above until movingAxis's Position passes motion hold position limit)
//---ASSERT---
Assert.AreEqual(0, holdingAxis.CommandPositionGet());
// Release MOTION HOLD
movingAxis.MoveRelative(MOVING_AXIS_TARGET); // Move movingAxis.MovingAxis's position reaches its MotionHold Position limit(in this case, limit is 5). It will trigger/release motion on holdingAxis (holidingAxis will move relatively 10).
movingAxis.MotionDoneWait();
holdingAxis.MotionDoneWait();
//---ASSERT---
Assert.AreEqual(HOLDINGAXIS_TARGET, holdingAxis.CommandPositionGet());
//@[MotionHoldByPosition]
}
[Test]
public void MotionHoldBySoftwareAddress()
{
//@[MotionHoldBySoftwareAddress]
// Constants
uint SOFTWARE_ADDRESS = (uint)controller.AddressGet(RSIControllerAddressType.RSIControllerAddressTypeUSER_BUFFER, 1);
int WAIT_TIME = 10;
int MOVE_DIST = 2;
// SET MOTION HOLD ON AVAILABLE SOFTWARE ADDRESS
axis.MotionHoldTypeSet(RSIMotionHoldType.RSIMotionHoldTypeCUSTOM); // Use TypeCUSTOM to hold execution based on a particular bit turning ON or OFF.
axis.MotionHoldUserAddressSet(SOFTWARE_ADDRESS); // Specify the available hostAddress . This address' value will be used to evaluate the motion hold condition.
axis.MotionHoldUserMaskSet(0x1); // Specify the bit you want to mask/watch from the MotionHoldUserAddressSet' address value (this evaluates using a logic AND)
axis.MotionHoldUserPatternSet(0x1); // Specify the bit value that will release the motion hold. (When this value is met, motion hold will be released)
// Check the condition to be false at first
if (controller.MemoryGet(SOFTWARE_ADDRESS) != 0x0) // Check Available host address value is mask to be false (in this case 0x0)
{
controller.MemorySet(SOFTWARE_ADDRESS, 0x0); // if not, mask it to false value/condition (in this case 0x0)
}
// SET MOTION HOLD
axis.MotionAttributeMaskOnSet(RSIMotionAttrMask.RSIMotionAttrMaskHOLD); // Set the HOLD motion attribute mask ON. (This initializes the HOLD on a particular motion)
axis.MoveRelative(MOVE_DIST); // Command simple relative motion. (This motion will be HOLD by the condition above)
System.Threading.Thread.Sleep(WAIT_TIME); // Sleep for (x) miliseconds before releasing motion hold.
//---ASSERT---
Assert.AreEqual(0, axis.CommandPositionGet());
// RELEASE MOTION HOLD
controller.MemorySet(SOFTWARE_ADDRESS, 0x1); // Release Motion Hold by specifying the host address value to SET Condition (in this case 0x10000)
axis.MotionDoneWait(); // Wait for motion to be done
controller.MemorySet(SOFTWARE_ADDRESS, 0x0); // Specify host address value back to false value/condition (in this case 0x0)
//---ASSERT---
Assert.AreEqual(MOVE_DIST, axis.CommandPositionGet());
// COMMAND MOTION AGAIN
axis.MoveRelative(MOVE_DIST); // Command simple relative motion again. (This motion will be HOLD by the condition above)
System.Threading.Thread.Sleep(WAIT_TIME); // Sleep for (x) miliseconds before releasing motion hold.
// RELEASE MOTION HOLD
controller.MemorySet(SOFTWARE_ADDRESS, 0x1); // Release Motion Hold by specifying the host address value to SET Condition (in this case 0x1)
axis.MotionDoneWait(); // Wait for motion to be done
controller.MemorySet(SOFTWARE_ADDRESS, 0x0); // Specify host address value back to false value/condition (in this case 0x0)
// CLEAR MOTION HOLD
axis.MotionAttributeMaskOffSet(RSIMotionAttrMask.RSIMotionAttrMaskHOLD); // Set the HOLD motion attribute mask OFF. (This will clear any motion HOLDS that were set on this Axis)
axis.MoveRelative(MOVE_DIST); // This motion will have no HOLD since the previous line has set the motion attribute mask OFF.
axis.MotionDoneWait(); // Wait for Motion to be completed.
//@[MotionHoldBySoftwareAddress]
}
}
}