The RMP Motion Controller APIs
StreamingMotionBufferManagement.cpp
1
22#if !defined(__INTIME__)
23
24#include "rsi.h" // Import our RapidCode Library.
25
26#include <process.h>
27
28using namespace RSI::RapidCode;
29
30const int AXIS_COUNT = 2;
31const int DESIRED_POINTS = 50; // We'd like to keep a buffer of 50 points.
32const int SYNC_PERIOD = 10; // Every 10 samples.
33
34int32_t lastSample = 0;
35
36#pragma region Fixed Size Implementation
37//Some applications might like to send block of say 10 points.
38//This means they might end up with anywhere from DESIRED_POINTS to DESIRED_POINTS + (POINT_BLOCK_COUNT - 1) in points at the time of Motion Call.
39//We want to adjust desired points and keep track of the extra for future calculations.
40//You don't need to do it this way unless you've a reason to.
41//If you are using fixed size blocks, you might just want to just use MotionIdGet() and ExecutingMotionIdGet() to determine the number of blocks to send.
42const int POINT_BLOCK_COUNT = 10;
43int32_t extraPointsSentToEvenOutBlock = 0;
44
46int32_t AdjustPointsNeededToBlockCount(int32_t initialCount)
47{
48 int32_t calculatedCount = 0;
49 int32_t adjustedInitialCount = initialCount - extraPointsSentToEvenOutBlock;
50
51 while ((adjustedInitialCount > 0) && (adjustedInitialCount > calculatedCount))
52 {
53 calculatedCount += POINT_BLOCK_COUNT;
54 }
55
56 //Adjust ExtraPointsSent so it can be used in future cycles.
57 extraPointsSentToEvenOutBlock += calculatedCount - initialCount;
58
59 return calculatedCount;
60}
61#pragma endregion
62
63volatile int _continueMonitoring = true;
64// In this example the expected passed Object is a Controller Object.
65
67void monitoringThread(void* tmp)
68{
69 MotionController* controller = (MotionController*)tmp;
70
71 //Configure Sync Interrupts here.
72 controller->SyncInterruptPeriodSet(SYNC_PERIOD);
73 controller->SyncInterruptEnableSet(true);
74
75 while (_continueMonitoring)
76 {
77 //SyncInterruptWait will wait until the next Interrupt generated by the controller.
78 //This is the best way to periodically trigger your application while getting useful information about jitter.
79 int32_t sampleRecieved = controller->SyncInterruptWait();
80 int32_t pointsNeeded = sampleRecieved - lastSample;
81
82 //Some applications may want to see specific block counts. You likely don't need to do this. See region (Fixed Size Implementation) Notes above.
83 pointsNeeded = AdjustPointsNeededToBlockCount(pointsNeeded);
84
85 //Note this application doesn't do the following as it is intended to help organization rather than preform motion. Please see other examples for that.
86 //Generate pointsNeeded Points.
87 //Potentially Command Move with generated Points -or- signal thread to do so -or- any number of things.
88
89 //Save sample for next calculation.
90 lastSample = sampleRecieved;
91
92 //One possible point lookup method might be to keep a rotating buffer of points which you use SampleRate Modulus BufferSize for setting/lookup.
93 //SampleRateGet() Modulus BufferSize would be your key for current point.
94 }
95}
96
97// Print out any errors on the associated Object.
99void checkErrors(RapidCodeObject *object)
100{
101 while (object->ErrorLogCountGet() > 0)
102 {
103 printf("Error Found: %s\n", object->ErrorLogGet()->text);
104 }
105}
106
108void streamingMotionBufferManagementMain()
109{
110 // Initialize MotionController. An example path to RapidCode diretory provided.
111 // NOTE: Use CreateFromBoard(#) and skip NetworkStart() for SynqNet.
112 MotionController *controller = MotionController::CreateFromSoftware(/*rmpPath*/);;// .XX\\");
113 checkErrors(controller);
114
115 try
116 {
117
118
119 // Initialize the Network.
120 controller->NetworkStart();
121 checkErrors(controller);
122
123 //Create Monitoring Thread.
124 _beginthread(monitoringThread, 0, controller);
125
126 //Wait for some exit condition
127 bool exitCondition = false;
128 while (!exitCondition)
129 {
130 //In theory, you application will be doing a lot in here. Note this application has no way to trigger exitCondition and will run forever.
131 }
132 }
133 catch (RsiError const& err)
134 {
135 printf("\n%s\n", err.text);
136 }
137 controller->Delete(); // Delete the controller as the program exits to ensure memory is deallocated in the correct order.
138
139 //Exit Gracefully
140 _continueMonitoring = false;
141 //Wait an appropriate time to get from the top of the Monitoring Loop to the bottom of it.
142}
143#endif
void SyncInterruptEnableSet(bool enable)
Configure Sync (periodic) interrupts for the controller.
void SyncInterruptPeriodSet(uint32_t samples)
Configure the period for the Sync Interrupt on the controller.
static MotionController * CreateFromSoftware()
Initialize and start the RMP EtherCAT controller.
void Delete(void)
Delete the MotionController and all its objects.
int32_t SyncInterruptWait()
Suspend the current thread until an interrupt arrives from the controller.
Represents the RMP soft motion controller. This class provides an interface to general controller con...
Definition rsi.h:762
void NetworkStart()
Start the network with RSINetworkStartupMethodNORMAL.
const RsiError *const ErrorLogGet()
Get the next RsiError in the log.
int32_t ErrorLogCountGet()
Get the number of software errors in the error log.
The RapidCode base class. All non-error objects are derived from this class.
Definition rsi.h:178
Represents the error details thrown as an exception by all RapidCode classes. This class contains an ...
Definition rsi.h:105