00001 /* 00002 segmentqueue.h 00003 00004 Headerfile for segmentqueue.c 00005 00006 A segment is basically defined as a straight trajectory in space, 00007 characterized by a start point and an end point. Additional to this, 00008 a segment can be interpreted as a number of consequetive segments 00009 with similar properties (orientation and feed). These segments are 00010 said to be linked. 00011 00012 The segment queue contains consequetive segments, which are stored 00013 in a double linked list. 00014 00015 Using this datastructure the trajectory planning is performed. The basic 00016 principles for the planning are these: 00017 * The motion along each segment consists of 3 phases: 00018 1) adjusting velocity (in most cases acceleration) 00019 2) cruising 00020 3) adjusting velocity (in most cases deceleration) 00021 * When the velocity is adjusted, it is a 3rd order function of time. 00022 * The cruising speed is calculated such that the last calculated position 00023 on a segment is exactly the specified end point and that it is never larger 00024 than the specified feed value. 00025 00026 The planning of a segment is done whenever needed, so that 00027 runCycle/getPosition always return a valid new position. 00028 00029 00030 Modification history: 00031 8-Jun-1999 RSB added sqSetMaxFeedOverride() 00032 8-Jun-1999 RSB changed arguments of sqInitQueue, now also the start point 00033 of the queue has to be passed. Also took out the line for a statically 00034 linked in memory pool for the segmentqueue 00035 7-Jun-1999 RSB added currentVel 00036 18-May-1999 RSB added helixRadius and amaxTan to SEGMENT 00037 11-Mar-1999 RSB remove sqAppendMotion, added sqAddLine and sqAddCircle 00038 9-Mar-1999 RSB changed to PmPose 00039 5-Mar-1999 RSB removed switch for malloc/kmalloc, now taken care of in 00040 rtmalloc.h, that's included in segmentqueue.c 00041 3-Mar-1999 RSB added a flag in segmentqueue named aborting 00042 18-Feb-1999 FMP changed flag for malloc definition from __KERNEL__ 00043 to rtlinux 00044 07-Dec-1998 RSB created 00045 */ 00046 00047 #ifndef SEGMENTQUEUE_H 00048 #define SEGMENTQUEUE_H 00049 00050 #include <math.h> 00051 /* #include <stdio.h> */ 00052 00053 #include "posemath.h" 00054 /* #include <linux/cons.h> */ 00055 00056 #define max(A,B) ( (A) > (B) ? (A) : (B)) 00057 #define min(A,B) ( (A) < (B) ? (A) : (B)) 00058 00059 #ifndef PI 00060 #define PI 3.141592654 00061 #endif 00062 00063 #define SQ_LINEAR 1 00064 #define SQ_CIRCULAR 2 00065 00066 00067 /* Structure that contains all the information about a segment */ 00068 typedef struct _seg 00069 { 00070 int ID; /* identification number */ 00071 int type; /* SQ_LINEAR or SQ_CIRCULAR */ 00072 00073 EmcPose start; 00074 EmcPose end; 00075 00076 PmLine line; 00077 PmCircle circle; 00078 00079 double helixRadius; /* radius of circle with correction for displacement 00080 in normal direction */ 00081 double length; 00082 double totLength; /* differs from length when segment consists of 00083 multiple linked segments */ 00084 double initInc; 00085 double maxInc; 00086 double finalInc; 00087 00088 double amaxTan; /* maximum tangential acceleration for this segment 00089 the value of this can differ from the general 00090 maximum acceleration for non-linear segments */ 00091 00092 /* the next coefficients are for internal use and are calculated at planning 00093 time */ 00094 int m,p,q; /* number steps needed for acceleration, cruising 00095 and decelerating. */ 00096 int totNumPoints; /* total number of points on segment (=m+p+q+3) */ 00097 00098 double a1,b1,c1,d1; /* coefficients for the 3rd polynomial for 00099 the speed adjusting in phase 1 */ 00100 double plInitInc; /* planned init inc */ 00101 double cruiseInc; /* incrediment for phase 2 */ 00102 double plFinalInc; /* planned final inc */ 00103 00104 double a3,b3,c3,d3; /* like the coefficients for phase 1, but then for 00105 phase 3 */ 00106 00107 /* pointers to previous and next segments. These are in a sense redundant 00108 for a ring buffer structure, but it make search actions a litte easier 00109 to implement (and understand) */ 00110 struct _seg *prevSegment; 00111 struct _seg *nextSegment; 00112 00113 /* some flags */ 00114 int planningDone; 00115 int active; /* indicates if the last calculated point comes 00116 from this segment */ 00117 int linkedToPrevSeg; /* indicates if this segment is linked to the 00118 previous one */ 00119 00120 int numLinkedSegs; /* this is the number of (next) segments that are 00121 linked to this segment. When linkedToPrevSeg 00122 equals 1, this variable is always zero */ 00123 00124 00125 } SEGMENT ; 00126 00127 00128 /* declaration of the segment queue */ 00129 typedef struct 00130 { 00131 00132 /* Definition of the ring buffer of SEGMENTs */ 00133 SEGMENT *queue; 00134 int size; /* the total size of the queue */ 00135 int numSegments; /* the number of SEGMENTs currently in the queue */ 00136 int start, end; /* indices to the start (next to get) and the end 00137 (last added) of the queue */ 00138 int full; /* indicates if the queue is full */ 00139 00140 int n; /* the current discrete time moment */ 00141 00142 /* some parameters */ 00143 double cycleTime; 00144 double ctPow2, ctPow3; /* cycleTime to the second and third order, to speed 00145 up calculations */ 00146 double maxAcc; /* maximum acceleration (both tang and normal) */ 00147 double maxV; /* the absolute maximum velocity */ 00148 double maxFeedOverrideFactor; /* the maximum value for the feed 00149 override factor */ 00150 00151 /* feed rate of the next motion(s) to append */ 00152 double feed; 00153 00154 /* initial position */ 00155 EmcPose initXYZ; 00156 00157 /* the so far travelled distance along the segment */ 00158 double dist; 00159 00160 /* last calculated point */ 00161 EmcPose lastPoint; 00162 00163 /* feed overide factor, 1 is default */ 00164 double feedOverrideFactor; 00165 00166 /* some flags */ 00167 int done; /* set (=1) when segmentqueue is empty or when done 00168 with pause/abort action */ 00169 int paused; /* set when a paused command has been given */ 00170 int stepping; /* set when a sqStep command has been given */ 00171 int feedAdjusting; 00172 int aborting; 00173 00174 /* for internal use .... */ 00175 EmcPose base; 00176 double offset; 00177 double cumLength; 00178 SEGMENT *cursor; 00179 00180 /* ID of the segment on which the last calculated point lays */ 00181 int currentID; 00182 00183 /* ID of the last appended motion */ 00184 int lastAppMotionID; 00185 00186 double currentVel; /* the current increment */ 00187 00188 00189 } SEGMENTQUEUE; 00190 00191 00192 /* Interface functions */ 00193 00194 00195 /* function to initialize the segment queue. Needs to be called after 00196 creating an instantiation of the segmentqueue before it can be used */ 00197 extern int sqInitQueue(SEGMENTQUEUE *sq, SEGMENT *first, int size); 00198 00199 /* functions to set some parameters */ 00200 extern int sqSetMaxAcc(SEGMENTQUEUE *sq, double amax); 00201 extern int sqSetVmax(SEGMENTQUEUE *sq, double vmax); 00202 extern int sqSetCycleTime(SEGMENTQUEUE *sq, double secs); 00203 extern int sqSetMaxFeedOverride(SEGMENTQUEUE *sq, double mfo); 00204 00205 /* function to specify what the initial/current position is */ 00206 extern int sqSetPos(SEGMENTQUEUE *sq, EmcPose pos); 00207 00208 /* function to remove a whole segmentqueue from memory */ 00209 extern int sqTrashQueue(SEGMENTQUEUE *sq); 00210 00211 /* function to empty the segmentqueue */ 00212 extern int sqClearQueue(SEGMENTQUEUE *sq); 00213 00214 00215 /* Implemented commands */ 00216 /* -------------------- */ 00217 00218 /* functiosn to add a motion to the queue */ 00219 extern int sqAddLine(SEGMENTQUEUE *sq, EmcPose end, int ID); 00220 extern int sqAddCircle(SEGMENTQUEUE *sq, EmcPose end, 00221 PmCartesian center, PmCartesian normal, 00222 int turn, int ID); 00223 00224 /* function to set the feed rate for the motions appended after this command */ 00225 extern int sqSetFeed(SEGMENTQUEUE *sq, double feed); 00226 00227 /* function to change the feed override factor */ 00228 extern int sqSetFeedOverride(SEGMENTQUEUE *sq, double factor); 00229 00230 /* function to run a new cycle */ 00231 extern int sqRunCycle(SEGMENTQUEUE *sq); 00232 00233 /* function to get a new position */ 00234 extern int sqGetPosition(SEGMENTQUEUE *sq, EmcPose *p); 00235 00236 /* function to pause the system (decelerate to zero velocity) */ 00237 extern int sqPause(SEGMENTQUEUE *sq); 00238 00239 /* function to resume with a paused segmentqueue */ 00240 extern int sqResume(SEGMENTQUEUE *sq); 00241 00242 /* function to abort */ 00243 extern int sqAbort(SEGMENTQUEUE *sq); 00244 00245 /* function to do execute one motion from a stop and stop again */ 00246 extern int sqStep(SEGMENTQUEUE *sq); 00247 00248 00249 /* functions to get some status information */ 00250 /* ---------------------------------------- */ 00251 00252 extern int sqIsDone(SEGMENTQUEUE *sq); /* after pause/abort to see if we're done*/ 00253 extern int sqIsPaused(SEGMENTQUEUE *sq); 00254 extern int sqIsStepping(SEGMENTQUEUE *sq); 00255 extern double sqGetVel(SEGMENTQUEUE *sq); 00256 extern double sqGetMaxAcc(SEGMENTQUEUE *sq); 00257 extern int sqGetDepth(SEGMENTQUEUE *sq); 00258 extern int sqIsQueueFull(SEGMENTQUEUE *sq); 00259 extern int sqGetID(SEGMENTQUEUE *sq); /* function the get the ID of the 00260 active (sub)segment */ 00261 00262 00263 #endif