The RMP Motion Controller APIs
#include <windows.h> // this is only needed if you try to set the windows thread priority
#include "rsi.h" // Import our RapidCode Library.
#include "HelperFunctions.h" // Import our SampleApp helper functions.
using namespace RSI::RapidCode;
const int SYNC_PERIOD = (1); // interrupt every SynqNet/MotionController sample
const int AXIS_COUNT = (6); // how many axes will we process each sample
const double MS_PER_SECOND = (1000.0);
void syncInterruptMain()
Axis* axes[AXIS_COUNT];
double encoderPositions[AXIS_COUNT];
short torqueOutputs[AXIS_COUNT] = { 0, 0, 0, 0, 0, 0 };
long currentCounter = 0;
long previousCounter = 0;
long deltaSamples = 0;
long iterations = 0;
unsigned long cpuFreq = 0;
double deltaTime = 0.0;
double minTime = 1000000.0;
double maxTime = 0.0;
long i = 0;
long errorCount = 0;
// create and Initialize MotionController class. (PCI board)
// get Axis objects from MotionController
for (i = 0; i < AXIS_COUNT; i++)
axes[i] = controller->AxisGet(i);
// disable the service thread if using the controller Sync interrupt
// Get CPU frequency from Operating System performance counter
cpuFreq = controller->OS->PerformanceTimerFrequencyGet();
printf("CPU Frequency is: %u Hz\n", cpuFreq);
// See how much total time is available for Sync interrupt processing (before SynqNet buffer is DMA'd)
printf("Host will have %ld microseconds to process data.\n", controller->SyncInterruptHostProcessTimeGet());
// it will be required to set a high thread priority here for Windows... you really should have an RTOS
SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
// configure a Sync interrupt for every sample
// enable controller interrupts
// wait for someone to press a key
while (controller->OS->KeyGet((int32_t)RSIWait::RSIWaitPOLL) < 0)
// wait for the controller's Sync interrupt
// see if we exceeded our processing time during the previous interrupt
// did we take too long processing the previous interrupt?
if (controller->SyncInterruptHostProcessStatusBitGet() == true)
printf("\n\n Oops, we took too long processing the last interrupt. \n");
// clear the Host Process Status Bit
// see how long it's been since last interrupt
currentCounter = controller->OS->PerformanceTimerCountGet();
deltaSamples = currentCounter - previousCounter;
previousCounter = currentCounter;
deltaTime = (double)(deltaSamples * (double)(1 / (double)cpuFreq)) * MS_PER_SECOND;
if (iterations > 1) // ignore first time through
if (deltaTime > maxTime)
maxTime = deltaTime;
if (deltaTime < minTime)
minTime = deltaTime;
printf("IRQ %ld: %3.3lf ms Min: %3.3lf Max: %3.3lf \n", iterations, deltaTime, minTime, maxTime);
// tell the controller firmware that we are going to do some calculations
// Get Encoder Positions
for (int i = 0; i < AXIS_COUNT; i++)
encoderPositions[i] = axes[i]->EncoderPositionGet(RSIMotorFeedback::RSIMotorFeedbackPRIMARY);
// do calculations here
// Set Torque Outputs
for (int i = 0; i < AXIS_COUNT; i++)
axes[i]->FilterCoeffSet(RSIFilterGainPIDCoeff::RSIFilterGainPIDCoeffOUTPUT_OFFSET, 0, torqueOutputs[i]); // gain table 0
// tell the controller firmware that we have finished our calculations
iterations++; // used for printing info
// turn off Sync Interrupt
catch (RsiError const& err)
printf("\n%s\n", err.text);
printf("Press a key to exit.\n");
while (controller->OS->KeyGet((int32_t)RSIWait::RSIWaitPOLL) < 0)
controller->OS->Sleep(100); //ms
controller->Delete(); // Delete the controller as the program exits to ensure memory is deallocated in the correct order.
system("pause"); // Allow time to read Console.
void SyncInterruptHostProcessFlagSet(bool hostProcessFlag)
Set the Host Process flag.
RapidCodeOS * OS
Provides access to operating system (Windows) features.
Definition: rsi.h:3569
int32_t SyncInterruptHostProcessTimeGet()
Get the total number of microseconds availble for host processing.
void Sleep(int32_t milliseconds)
Put the current thread to sleep.
The RsiError object contains information about any RapidCode API object's error/exception.
Definition: rsi.h:90
void Delete(void)
Delete the MotionController and all its objects.
int32_t KeyGet(int32_t milliseconds)
Wait for a key to be pressed and return its value.
static MotionController * CreateFromSoftware()
Initialize and start the RMP EtherCAT controller.
void SyncInterruptPeriodSet(uint32_t samples)
Configure the period for the Sync Interrupt on the controller.
Axis * AxisGet(int32_t axisNumber)
AxisGet returns a pointer to an Axis object and initializes its internals.
int32_t PerformanceTimerCountGet()
Gets the current high performance counter value.
bool SyncInterruptHostProcessStatusBitGet()
See if the host was processing too int32_t on previous Sync Interrupt.
void SyncInterruptEnableSet(bool enable)
Configure Sync (periodic) interrupts for the controller.
The MotionController object represents the RMP INtime soft motion controller.
Definition: rsi.h:743
The Axis object manages a single physical axis on a motion controller.
Definition: rsi.h:5852
void ServiceThreadEnableSet(bool enable)
Enable or disable the service thread.
void SyncInterruptHostProcessStatusClear()
Clear the Host Process status bit.
static void CheckErrors(RapidCodeObject rsiObject)
Check if the RapidCode Object has any errors.
Definition: HelperFunctions.cs:64
double EncoderPositionGet(RSIMotorFeedback encoder)
Get the raw encoder position.
void FilterCoeffSet(RSIFilterGainPIDCoeff coeff, int32_t gainTable, double coeffValue)
Set a filter coefficient (ex: Kp, Ki, Kd).
int32_t PerformanceTimerFrequencyGet()
Gets the frequency of the performance counter.
int32_t SyncInterruptWait()
Suspend the current thread until an interrupt arrives from the controller.