The RMP Motion Controller APIs
SyncInterrupt.cpp
#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;
//configurable
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)
try
{
// 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
controller->ServiceThreadEnableSet(false);
// 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
controller->SyncInterruptPeriodSet(SYNC_PERIOD);
// enable controller interrupts
controller->SyncInterruptEnableSet(true);
// wait for someone to press a key
while (controller->OS->KeyGet((int32_t)RSIWait::RSIWaitPOLL) < 0)
{
// wait for the controller's Sync interrupt
controller->SyncInterruptWait();
// 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
controller->SyncInterruptHostProcessFlagSet(false);
iterations++; // used for printing info
}
// turn off Sync Interrupt
controller->SyncInterruptEnableSet(false);
}
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.
}
RSI::RapidCode::MotionController::SyncInterruptHostProcessFlagSet
void SyncInterruptHostProcessFlagSet(bool hostProcessFlag)
Set the Host Process flag.
RSI::RapidCode::MotionController::OS
RapidCodeOS * OS
Provides access to operating system (Windows) features.
Definition: rsi.h:3569
RSI::RapidCode::MotionController::SyncInterruptHostProcessTimeGet
int32_t SyncInterruptHostProcessTimeGet()
Get the total number of microseconds availble for host processing.
RSI::RapidCode::RapidCodeOS::Sleep
void Sleep(int32_t milliseconds)
Put the current thread to sleep.
RSI::RapidCode::RsiError
The RsiError object contains information about any RapidCode API object's error/exception.
Definition: rsi.h:90
RSI::RapidCode::MotionController::Delete
void Delete(void)
Delete the MotionController and all its objects.
RSI::RapidCode::RapidCodeOS::KeyGet
int32_t KeyGet(int32_t milliseconds)
Wait for a key to be pressed and return its value.
RSI::RapidCode::MotionController::CreateFromSoftware
static MotionController * CreateFromSoftware()
Initialize and start the RMP EtherCAT controller.
RSI::RapidCode
RSI::RapidCode::MotionController::SyncInterruptPeriodSet
void SyncInterruptPeriodSet(uint32_t samples)
Configure the period for the Sync Interrupt on the controller.
RSI::RapidCode::MotionController::AxisGet
Axis * AxisGet(int32_t axisNumber)
AxisGet returns a pointer to an Axis object and initializes its internals.
RSI::RapidCode::RapidCodeOS::PerformanceTimerCountGet
int32_t PerformanceTimerCountGet()
Gets the current high performance counter value.
RSI::RapidCode::MotionController::SyncInterruptHostProcessStatusBitGet
bool SyncInterruptHostProcessStatusBitGet()
See if the host was processing too int32_t on previous Sync Interrupt.
RSI::RapidCode::MotionController::SyncInterruptEnableSet
void SyncInterruptEnableSet(bool enable)
Configure Sync (periodic) interrupts for the controller.
RSI::RapidCode::MotionController
The MotionController object represents the RMP INtime soft motion controller.
Definition: rsi.h:743
RSI::RapidCode::Axis
The Axis object manages a single physical axis on a motion controller.
Definition: rsi.h:5852
RSI::RapidCode::MotionController::ServiceThreadEnableSet
void ServiceThreadEnableSet(bool enable)
Enable or disable the service thread.
RSI::RapidCode::MotionController::SyncInterruptHostProcessStatusClear
void SyncInterruptHostProcessStatusClear()
Clear the Host Process status bit.
HelperFunctions.CheckErrors
static void CheckErrors(RapidCodeObject rsiObject)
Check if the RapidCode Object has any errors.
Definition: HelperFunctions.cs:64
RSI::RapidCode::Axis::EncoderPositionGet
double EncoderPositionGet(RSIMotorFeedback encoder)
Get the raw encoder position.
RSI::RapidCode::Axis::FilterCoeffSet
void FilterCoeffSet(RSIFilterGainPIDCoeff coeff, int32_t gainTable, double coeffValue)
Set a filter coefficient (ex: Kp, Ki, Kd).
RSI::RapidCode::RapidCodeOS::PerformanceTimerFrequencyGet
int32_t PerformanceTimerFrequencyGet()
Gets the frequency of the performance counter.
RSI::RapidCode::MotionController::SyncInterruptWait
int32_t SyncInterruptWait()
Suspend the current thread until an interrupt arrives from the controller.