Learn how to use Math Blocks to perform real-time mathematical operations on data in the RMP firmware every sample.
What are Math Blocks?
Math Blocks are a powerful feature within the RMP firmware, designed to facilitate real-time mathematical operations on data. These blocks are integral for developing sophisticated control systems, enabling calculations with the assurance of real-time execution, which is crucial for time-sensitive applications.
Every sampling interval, the RMP firmware evaluates each Math Block, allowing for a series of bitwise and mathematical operations on data inputs.
Supported Operations
Math Blocks support a variety of operations, categorized as follows:
- Mathematical Operations:
- Addition
- Subtraction
- Multiplication
- Division
- Square Root
- Square Root of Sum of Squares
- Bitwise Operations:
Why Use Math Blocks?
Math Blocks are invaluable for data manipulation in real-time scenarios. For instance, calculating an axis's acceleration from velocity data, or determining the ratio between the encoder positions of two axes, are tasks where Math Blocks excel.
Math Blocks can be especially useful when integrated with User Limits to enhance system safety and efficiency. For example, a Math Block could compute the real-time positional difference between two axes. Coupled with a User Limit, the system could automatically halt operations if this difference exceeds a predefined threshold, preventing potential damage or inaccuracies.
The Structure of a Math Block:
Sample Code
- 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.
📜 MathBlock - User Limit on Difference of Position Between Two Axes
MathBlock
Operation SUBTRACT: First Axis Position - Second Axis Position
Output: none
This sample code demonstrates how to use a MathBlock to calculate the difference of in position between two axes and trigger a UserLimit when the difference exceeds a certain value.
const int MATHBLOCK_COUNT = 1;
const int AXIS_COUNT = 2;
const int USER_LIMIT_COUNT = 1;
const int FIRST_AXIS_INDEX = 0;
const int SECOND_AXIS_INDEX = 1;
const double USER_UNITS = 1048576;
const int MATHBLOCK_INDEX = 0;
const int USER_LIMIT_INDEX = 0;
const double MAX_POSITION_DIFFERENCE = 0.5 * USER_UNITS;
const int USER_LIMIT_DURATION = 0;
const double RELATIVE_POSITION = 2 * MAX_POSITION_DIFFERENCE;
const double VELOCITY = 1;
const double ACCELERATION = 10;
const double DECELERATION = 10;
const double JERK_PCT = 0;
USE_HARDWARE = false;
try
{
HelperFunctionsCS.CheckErrors(controller);
if (USE_HARDWARE)
{
HelperFunctionsCS.SetupControllerForHardware(controller);
}
else
{
HelperFunctionsCS.SetupControllerForPhantoms(controller, AXIS_COUNT, new int[] { FIRST_AXIS_INDEX, SECOND_AXIS_INDEX });
}
HelperFunctionsCS.CheckErrors(axis0);
HelperFunctionsCS.CheckErrors(axis1);
HelperFunctionsCS.CheckErrors(multiAxis);
mathBlockConfig.InputAddress0 = axis0.
AddressGet(INPUT_AXIS_ADDRESS_TYPE);
mathBlockConfig.InputDataType0 =
RSIDataType.RSIDataTypeDOUBLE;
mathBlockConfig.InputAddress1 = axis1.
AddressGet(INPUT_AXIS_ADDRESS_TYPE);
mathBlockConfig.InputDataType1 =
RSIDataType.RSIDataTypeDOUBLE;
mathBlockConfig.ProcessDataType =
RSIDataType.RSIDataTypeDOUBLE;
Console.WriteLine("MathBlock configured to subtract the position of the second axis from the position of the first axis.");
Console.WriteLine("UserLimit configured to trigger when the absolute position difference is greater than " + MAX_POSITION_DIFFERENCE + " and abort motion.");
Console.WriteLine("Moving the axes to trigger the UserLimit...");
axis0.
MoveRelative(RELATIVE_POSITION, VELOCITY, ACCELERATION, DECELERATION, JERK_PCT);
{
Console.WriteLine("Both axes are in the error state after the UserLimit triggered (This is the intended behavior).");
return 0;
}
else
{
Console.WriteLine("Error: The axes should be in an error state after the UserLimit triggers, but they are not.");
Console.WriteLine(
"First Axis State: " + axis0.
StateGet());
Console.WriteLine(
"Second Axis State: " + axis1.
StateGet());
return -1;
}
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
return -1;
}
finally
{
}
Learn more in topic page.
📜 MathBlock - Calculate Acceleration From Velocity
MathBlock 0
Operation SUBTRACT: Previous command velocity - current command velocity
Output: none
MathBlock 1
Operation MULTIPLY: Current command velocity * 1.0
Output: write to UserBuffer
const int MATHBLOCK_COUNT = 2;
const int AXIS_COUNT = 1;
const int AXIS_INDEX = 0;
const double USER_UNITS = 1048576;
const int SUBTRACTION_MATHBLOCK_INDEX = 0;
const int PREVIOUS_VELOCITY_MATHBLOCK_INDEX = 1;
const double ONE = 1.0;
const int USERBUFFER_INDEX = 0;
const double VELOCITY = 1.0;
const double ACCELERATION = 0.123;
USE_HARDWARE = false;
try
{
HelperFunctionsCS.CheckErrors(controller);
if (USE_HARDWARE)
{
HelperFunctionsCS.SetupControllerForHardware(controller);
}
else
{
HelperFunctionsCS.SetupControllerForPhantoms(controller, AXIS_COUNT, new int[] { AXIS_INDEX });
}
HelperFunctionsCS.CheckErrors(axis);
subtractionConfig.InputAddress0 = axis.
AddressGet(INPUT_AXIS_ADDRESS_TYPE);
subtractionConfig.InputDataType0 =
RSIDataType.RSIDataTypeDOUBLE;
subtractionConfig.InputDataType1 =
RSIDataType.RSIDataTypeDOUBLE;
subtractionConfig.ProcessDataType =
RSIDataType.RSIDataTypeDOUBLE;
previousVelocityConfig.InputAddress0 = axis.
AddressGet(INPUT_AXIS_ADDRESS_TYPE);
previousVelocityConfig.InputDataType0 =
RSIDataType.RSIDataTypeDOUBLE;
previousVelocityConfig.InputDataType1 =
RSIDataType.RSIDataTypeDOUBLE;
previousVelocityConfig.ProcessDataType =
RSIDataType.RSIDataTypeDOUBLE;
Console.WriteLine($"Calculated acceleration from MathBlock: {calculatedAcceleration}");
if (Math.Abs(calculatedAcceleration - ACCELERATION) <= 0.000001)
{
Console.WriteLine("The MathBlock is calculating the Axis' acceleration by subtracting previous velocity from current velocity.");
return 0;
}
else
{
Console.WriteLine("Error: The MathBlock is not calculating the Axis' acceleration as expected.");
return -1;
}
}
catch (Exception e)
{
Console.WriteLine("Error: " + e.Message);
return -1;
}
finally
{
}
Learn more in topic page.