APIs, concepts, guides, and more
Phantom Axes

Utilize phantom axes to test or simulate more axes than physically available, configurable via RapidCode or RapidSetup.

๐Ÿ”น What are Phantom Axes?

Phantom axes are virtual axes, they allow you to test your code while the network is unavailable or if your application uses more axes than you have available.

๐Ÿ”น Why use Phantom Axes?

Phantom axes allow you to test applications offline or use more axes than are actually available on your network. You can add an arbitrary number of phantom axes to your network. Phantom axes can be added through RapidCode (as demonstrated in the sample app below) or through RapidSetup (shown directly below).

Image

Increasing the number in the โ€œAxis Countโ€ box will create phantom axes. Add the number of phantom axes you want to the number of axes already on the network (e.g., if there were two axes on the network and you wanted one phantom axis, you would put 3 in the Axis Count box) and type that number in the box. Hit enter and RapidSetup will restart with the appropriate number of phantom axes.

Note
The ActualPosition of a phantom axis will remain at 0 given a command. Use CommandPositionGet and CommandVelocityGet instead.

Motion commanded on an Phantom Axis will emulate the settling behavior of a real axis. Here is a Motion Scope Plot of a Phantom axis

Red = Command, Green = Actual, Yellow = Velocity, White = Acceleration

Warning
Be careful when transitioning between real axes and phantom axes. Some settings may need to be adjusted for your application to function properly when moving from one to the other.

๐Ÿ”น PhantomAxis.xml

If you are using rsiconfig Axis XML files, here's an XML file you can use to configure a phantom axis without writing any code.

<SerializableAxis xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<AxisNumber>0</AxisNumber>
<Properties>
<string>ErrorLimitAction=RSIActionNONE</string>
<string>HardwareNegLimitAction=RSIActionNONE</string>
<string>HardwarePosLimitAction=RSIActionNONE</string>
<string>SoftwareNegLimitAction=RSIActionNONE</string>
<string>SoftwarePosLimitAction=RSIActionNONE</string>
<string>EncoderFaultAction=RSIActionNONE</string>
<string>NodeFailureAction=RSIActionNONE</string>
<!-- for the position tolerances, use *almost* Double.MaxValue -->
<string>PositionToleranceFine=1e+307</string>
<string>PositionToleranceCoarse=1e+307</string>
</Properties>
</SerializableAxis>

๐Ÿ“œ Sample Code

  • C#

    controller.AxisCountSet(controller.AxisCountGet() + 1); // Configure one additional axis to be used for the phantom axis
    int axisNumber = controller.AxisCountGet() - 1; // Set the axis number to the last axis on the network (subtract one because the axes are zero indexed)
    axis = controller.AxisGet(axisNumber); // Initialize Axis class
    HelperFunctions.CheckErrors(axis); // [Helper Function] Check that the axis has been initialized correctly
    // These limits are not meaningful for a Phantom Axis (e.g., a phantom axis has no actual position so a position error trigger is not necessary)
    // Therefore, you must set all of their actions to "NONE".
    axis.ErrorLimitActionSet(RSIAction.RSIActionNONE); // Set Error Limit Action.
    axis.HardwareNegLimitActionSet(RSIAction.RSIActionNONE); // Set Hardware Negative Limit Action.
    axis.HardwarePosLimitActionSet(RSIAction.RSIActionNONE); // Set Hardware Positive Limit Action.
    axis.HomeActionSet(RSIAction.RSIActionNONE); // Set Home Action.
    axis.SoftwareNegLimitActionSet(RSIAction.RSIActionNONE); // Set Software Negative Limit Action.
    axis.SoftwarePosLimitActionSet(RSIAction.RSIActionNONE); // Set Software Positive Limit Action.
    const double positionToleranceMax = Double.MaxValue / 10.0; // Reduce from max slightly, so XML to string serialization and deserialization works without throwing System.OverflowException
    axis.PositionToleranceCoarseSet(positionToleranceMax); // Set Settling Coarse Position Tolerance to max value
    axis.PositionToleranceFineSet(positionToleranceMax); // Set Settling Fine Position Tolerance to max value (so Phantom axis will get immediate MotionDone when target is reached)
    axis.MotorTypeSet(RSIMotorType.RSIMotorTypePHANTOM); // Set the MotorType to phantom

  • C++

    // Get the axis
    Axis *axis = controller->AxisGet(AXIS_INDEX);
    // Configure the axis as a phantom axis
    // These limits are not meaningful for a Phantom Axis (e.g., a phantom axis has no actual position so a position error trigger is not necessary)
    // Therefore, you must set all of their actions to "NONE".
    axis->PositionSet(0); // Set the position to 0
    axis->ErrorLimitActionSet(RSIAction::RSIActionNONE); // Set Error Limit Action.
    axis->AmpFaultActionSet(RSIAction::RSIActionNONE); // Set Amp Fault Action.
    axis->AmpFaultTriggerStateSet(1); // Set Amp Fault Trigger State.
    axis->HardwareNegLimitActionSet(RSIAction::RSIActionNONE); // Set Hardware Negative Limit Action.
    axis->HardwarePosLimitActionSet(RSIAction::RSIActionNONE); // Set Hardware Positive Limit Action.
    axis->SoftwareNegLimitActionSet(RSIAction::RSIActionNONE); // Set Software Negative Limit Action.
    axis->SoftwarePosLimitActionSet(RSIAction::RSIActionNONE); // Set Software Positive Limit Action.
    axis->HomeActionSet(RSIAction::RSIActionNONE); // Set Home Action.
    // Reduce from max slightly, so XML to string serialization and deserialization works without throwing System.OverflowException
    const double positionToleranceMax = std::numeric_limits<double>::max() / 10.0;
    axis->PositionToleranceCoarseSet(positionToleranceMax); // Set Settling Coarse Position Tolerance to max value
    // Set Settling Fine Position Tolerance to max value (so Phantom axis will get immediate MotionDone when target is reached)
    axis->PositionToleranceFineSet(positionToleranceMax);
    axis->MotorTypeSet(RSIMotorType::RSIMotorTypePHANTOM); // Set the MotorType to phantom