APIs, concepts, guides, and more
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; // Import the RapidCode namespace
29const int AXIS_COUNT = 2;
30const int DESIRED_POINTS = 50; // We'd like to keep a buffer of 50 points.
31const int SYNC_PERIOD = 10; // Every 10 samples.
32
33int32_t lastSample = 0;
34
35#pragma region Fixed Size Implementation
36//Some applications might like to send block of say 10 points.
37//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.
38//We want to adjust desired points and keep track of the extra for future calculations.
39//You don't need to do it this way unless you've a reason to.
40//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.
41const int POINT_BLOCK_COUNT = 10;
42int32_t extraPointsSentToEvenOutBlock = 0;
43
45int32_t AdjustPointsNeededToBlockCount(int32_t initialCount)
46{
47 int32_t calculatedCount = 0;
48 int32_t adjustedInitialCount = initialCount - extraPointsSentToEvenOutBlock;
49
50 while ((adjustedInitialCount > 0) && (adjustedInitialCount > calculatedCount))
51 {
52 calculatedCount += POINT_BLOCK_COUNT;
53 }
54
55 //Adjust ExtraPointsSent so it can be used in future cycles.
56 extraPointsSentToEvenOutBlock += calculatedCount - initialCount;
57
58 return calculatedCount;
59}
60#pragma endregion
61
62volatile int _continueMonitoring = true;
63// In this example the expected passed Object is a Controller Object.
64
66void monitoringThread(void* tmp)
67{
68 MotionController* controller = (MotionController*)tmp;
69
70 //Configure Sync Interrupts here.
71 controller->SyncInterruptPeriodSet(SYNC_PERIOD);
72 controller->SyncInterruptEnableSet(true);
73
74 while (_continueMonitoring)
75 {
76 //SyncInterruptWait will wait until the next Interrupt generated by the controller.
77 //This is the best way to periodically trigger your application while getting useful information about jitter.
78 int32_t sampleRecieved = controller->SyncInterruptWait();
79 int32_t pointsNeeded = sampleRecieved - lastSample;
80
81 //Some applications may want to see specific block counts. You likely don't need to do this. See region (Fixed Size Implementation) Notes above.
82 pointsNeeded = AdjustPointsNeededToBlockCount(pointsNeeded);
83
84 //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.
85 //Generate pointsNeeded Points.
86 //Potentially Command Move with generated Points -or- signal thread to do so -or- any number of things.
87
88 //Save sample for next calculation.
89 lastSample = sampleRecieved;
90
91 //One possible point lookup method might be to keep a rotating buffer of points which you use SampleRate Modulus BufferSize for setting/lookup.
92 //SampleRateGet() Modulus BufferSize would be your key for current point.
93 }
94}
95
96// Print out any errors on the associated Object.
98void checkErrors(RapidCodeObject *object)
99{
100 while (object->ErrorLogCountGet() > 0)
101 {
102 printf("Error Found: %s\n", object->ErrorLogGet()->text);
103 }
104}
105
107void streamingMotionBufferManagementMain()
108{
109 // Initialize MotionController. An example path to RapidCode diretory provided.
110 // NOTE: Use CreateFromBoard(#) and skip NetworkStart() for SynqNet.
111 MotionController *controller = MotionController::CreateFromSoftware(/*rmpPath*/);;// .XX\\");
112 checkErrors(controller);
113
114 try
115 {
116
117
118 // Initialize the Network.
119 controller->NetworkStart();
120 checkErrors(controller);
121
122 //Create Monitoring Thread.
123 _beginthread(monitoringThread, 0, controller);
124
125 //Wait for some exit condition
126 bool exitCondition = false;
127 while (!exitCondition)
128 {
129 //In theory, you application will be doing a lot in here. Note this application has no way to trigger exitCondition and will run forever.
130 }
131 }
132 catch (RsiError const& err)
133 {
134 printf("\n%s\n", err.text);
135 }
136 controller->Delete(); // Delete the controller as the program exits to ensure memory is deallocated in the correct order.
137
138 //Exit Gracefully
139 _continueMonitoring = false;
140 //Wait an appropriate time to get from the top of the Monitoring Loop to the bottom of it.
141}
142#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:795
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:179
Represents the error details thrown as an exception by all RapidCode classes. This class contains an ...
Definition rsi.h:106