#include "segmentqueue.h"
#include <stdio.h>
#include <float.h>
Include dependency graph for segmentqueue.c:
Go to the source code of this file.
|
Definition at line 113 of file segmentqueue.c. |
|
Definition at line 115 of file segmentqueue.c. |
|
Definition at line 116 of file segmentqueue.c. |
|
Definition at line 112 of file segmentqueue.c. |
|
Definition at line 110 of file segmentqueue.c. |
|
Definition at line 103 of file segmentqueue.c. |
|
Definition at line 124 of file segmentqueue.c. |
|
Definition at line 131 of file segmentqueue.c. Referenced by sqAddLine(), sqPlanSegment(), sqResume(), and sqRunCycle().
|
|
Definition at line 2217 of file segmentqueue.c. 02218 { 02219 if (1 == sq->aborting) 02220 /* we are already aborting, so let's just ignore it */ 02221 return 0; 02222 02223 if (sq==0) 02224 { 02225 diagnostics("Error in sqAbort\n"); 02226 return -1; 02227 } 02228 02229 if ( sq->paused == 1 || sq->done == 1 ) 02230 { 02231 if (-1 == sqClearQueue(sq)) 02232 { 02233 diagnostics("Error in sqAbort\n"); 02234 return -1; 02235 } 02236 } 02237 else 02238 { 02239 sq->aborting=1; 02240 sqPause(sq); 02241 } 02242 return 0; 02243 } |
|
Definition at line 1255 of file segmentqueue.c. 01257 { 01258 SEGMENT * newseg; 01259 PmCircle circle; 01260 EmcPose start; 01261 PmCartesian helix; 01262 double absHelix; 01263 01264 /* used to calculate the maximum tangential acceleration */ 01265 double rpow2,A,topIncPow2; 01266 01267 /* check if segment queue has been initialized */ 01268 if ( sq == 0 || sq->queue == 0 ) 01269 { 01270 diagnostics("Error in sqAddCircle()\n"); 01271 return -1; 01272 } 01273 01274 /* check for full */ 01275 if ( sq->numSegments == sq->size ) 01276 { 01277 diagnostics("Panic!!!!, segmentqueue overflows!!!\n"); 01278 return -1; 01279 } 01280 01281 if ( sq->numSegments==0 ) 01282 start=sq->lastPoint; 01283 else 01284 start=sq->queue[(sq->end+sq->size-1)%sq->size].end; 01285 01286 pmCircleInit(&circle, start, end, center, normal, turn); 01287 01288 if (circle.angle==0) 01289 { 01290 /* only set ID of last appended motion */ 01291 sq->lastAppMotionID=ID; 01292 return 0; 01293 } 01294 01295 /* Calculate the helix gradient in normal direction */ 01296 pmCartScalDiv( circle.rHelix, circle.angle, &helix ); 01297 pmCartMag( helix, &absHelix); 01298 01299 /* let newseg point to the first empty place in the ring buffer... */ 01300 newseg= sq->queue+sq->end; 01301 /* ...and update the ring buffer properties */ 01302 sq->end = (sq->end+1) % sq->size; 01303 sq->numSegments++; 01304 if ( sq->numSegments >= sq->size - SQ_SAFETY_MARGIN ) 01305 { 01306 sq->full=1; 01307 } 01308 01309 /* fill segment parameter fields */ 01310 newseg->ID = ID; 01311 newseg->type = SQ_CIRCULAR; 01312 newseg->circle = circle; 01313 01314 newseg->helixRadius = sqrt(circle.radius*circle.radius\ 01315 + absHelix*absHelix); 01316 newseg->length = circle.angle * newseg->helixRadius; 01317 01318 newseg->totLength = newseg->length; 01319 newseg->start = start; 01320 newseg->end = end; 01321 newseg->maxInc = min (sq->feed*sq->cycleTime, sqrt( sq->maxAcc * \ 01322 circle.radius ) * sq->cycleTime ); 01323 if ( absHelix != 0 ) 01324 newseg->maxInc = min ( newseg->maxInc, sq->feed * sq->cycleTime / absHelix ); 01325 01326 newseg->finalInc = 0; 01327 newseg->plInitInc = 0; 01328 newseg->plFinalInc = 0; 01329 newseg->cruiseInc = 0; 01330 newseg->planningDone = 0; 01331 newseg->active = 0; 01332 newseg->numLinkedSegs = 0; 01333 newseg->linkedToPrevSeg= 0; 01334 newseg->totNumPoints = 0; 01335 newseg->nextSegment = 0; 01336 01337 /* calculate the maximum tangential acceleration for this circle */ 01338 rpow2 = circle.radius*circle.radius; 01339 topIncPow2 = newseg->maxInc * newseg->maxInc; 01340 A = max (sq->maxAcc*sq->maxAcc*sq->ctPow2*sq->ctPow2*rpow2 \ 01341 - topIncPow2*topIncPow2 ,\ 01342 3.0/4.0 * topIncPow2*topIncPow2 ); 01343 01344 newseg->amaxTan = sqrt( A / ( rpow2 * (rpow2* + topIncPow2 )))/sq->ctPow2; 01345 01346 if ( absHelix != 0 ) 01347 { 01348 newseg->amaxTan= min (newseg->amaxTan, \ 01349 sq->maxAcc*newseg->helixRadius/absHelix ); 01350 } 01351 01352 if (-1 == sqPreprocessSegment(sq, newseg)) 01353 { 01354 diagnostics("Error in sqAddCircle()\n"); 01355 return -1; 01356 } 01357 01358 /* set last Appended Motion ID */ 01359 sq->lastAppMotionID=ID; 01360 01361 return 0; 01362 } |
|
Definition at line 1168 of file segmentqueue.c. 01169 { 01170 double length, maxUVec; 01171 SEGMENT *newseg; 01172 EmcPose start; 01173 01174 01175 /* check if segment queue has been initialized */ 01176 if ( sq == 0 || sq->queue == 0 ) 01177 { 01178 diagnostics("Error in sqAddLine()\n"); 01179 return -1; 01180 } 01181 01182 /* check for full */ 01183 if ( sq->numSegments == sq->size ) 01184 { 01185 diagnostics("Panic!!!!, segmentqueue overflows!!!\n"); 01186 return -1; 01187 } 01188 01189 /* check if new motion has zero length */ 01190 if ( sq->numSegments==0 ) 01191 start=sq->lastPoint; 01192 else 01193 start=sq->queue[(sq->end+sq->size-1)%sq->size].end; 01194 01195 length = sqGiveLength(start,end); 01196 01197 if (length==0) 01198 { 01199 /* only set ID of last appended motion */ 01200 sq->lastAppMotionID=ID; 01201 return 0; 01202 } 01203 01204 /* let newseg point to the first empty place in the ring buffer... */ 01205 newseg= sq->queue+sq->end; 01206 /* ...and update the ring buffer properties */ 01207 sq->end = (sq->end+1) % sq->size; 01208 sq->numSegments++; 01209 if ( sq->numSegments >= sq->size - SQ_SAFETY_MARGIN ) 01210 { 01211 sq->full=1; 01212 } 01213 01214 /* fill segment parameter fields */ 01215 newseg->ID = ID; 01216 newseg->type = SQ_LINEAR; 01217 newseg->length = length; 01218 newseg->totLength = length; 01219 newseg->start = start; 01220 newseg->end = end; 01221 newseg->maxInc = sq->feed*sq->cycleTime; 01222 newseg->finalInc = 0; 01223 newseg->plInitInc = 0; 01224 newseg->plFinalInc = 0; 01225 newseg->cruiseInc = 0; 01226 newseg->planningDone = 0; 01227 newseg->active = 0; 01228 newseg->numLinkedSegs = 0; 01229 newseg->linkedToPrevSeg= 0; 01230 newseg->totNumPoints = 0; 01231 newseg->nextSegment = 0; 01232 01233 /* initialize line */ 01234 pmLineInit( &newseg->line, newseg->start, newseg->end); 01235 01236 /* set the maximum tangential acceleration for this line */ 01237 maxUVec = max ( fabs(newseg->line.uVec.x) , fabs(newseg->line.uVec.y) ); 01238 maxUVec = max ( fabs(newseg->line.uVec.z) , maxUVec ); 01239 newseg->amaxTan = sq->maxAcc/maxUVec; 01240 01241 diagnosticsOff("Amax tan = %d\n",(int)newseg->amaxTan); 01242 01243 if (-1 == sqPreprocessSegment(sq, newseg)) 01244 { 01245 diagnostics("Error in sqAddLine()\n"); 01246 return -1; 01247 } 01248 01249 /* set last Appended Motion ID */ 01250 sq->lastAppMotionID=ID; 01251 01252 return 0; 01253 } |
|
Definition at line 772 of file segmentqueue.c. Referenced by sqPreprocessSegment().
00773 { 00774 /* function that checks whether segment s needs to be linked to its 00775 predecessor(s) based upon the finalInc. It is possible that 00776 this requires linking of a set of preceding segments to make sure that 00777 the final increment can be reached. */ 00778 00779 SEGMENT *cursor; 00780 int done, counter; 00781 int linkcrit; 00782 00783 if ( sq == 0 || s == 0 ) 00784 { 00785 diagnostics("Error in sqBackwardLinkSegment\n"); 00786 return -1; 00787 } 00788 00789 if ( s->initInc < s->finalInc ) 00790 { 00791 diagnostics("sqBackwardlinkSegment called while initInc is smaller than finalInc\n"); 00792 /* not critical, so we don't return -1, but it's not good....*/ 00793 return 0; 00794 } 00795 00796 cursor=s; 00797 done=0; 00798 counter=0; 00799 00800 while (!done) 00801 { 00802 counter++; 00803 if ( counter > sq->size ) 00804 { 00805 /* we have browsed through the whole queue and can't 00806 get out of the loop.... */ 00807 diagnostics("Can't get out of the loop in sqBackwardLinkSegment\n"); 00808 return -1; 00809 } 00810 00811 if (cursor->linkedToPrevSeg==1) 00812 /* it is already linked */ 00813 { 00814 cursor=cursor->prevSegment; 00815 if (cursor == 0 ) 00816 { 00817 diagnostics("Panic: cursor = NULL in sqBackwardLinkSegment\n"); 00818 return -1; 00819 } 00820 } 00821 else if (cursor->initInc < s->finalInc ) 00822 /* then we're done. This is always true as long as the set of 00823 segments that precede s is correctly processed, since the 00824 total length of the segments from cursor to the last segment 00825 before s is large enough to reach s's initial increment. This 00826 length is of course large enough too to reach s->finalInc 00827 because that is smaller than s->initInc (otherwise this 00828 function wouldn't have called). */ 00829 done=1; 00830 00831 else 00832 { 00833 if ( -1 == (linkcrit = sqLinkCriterion(sq,cursor,feedOverride))) 00834 { 00835 diagnostics("Error in sqBackWardLinkSegment\n"); 00836 return -1; 00837 } 00838 else if ( linkcrit == SQ_LINKING_NEEDED ) 00839 { 00840 cursor=cursor->prevSegment; 00841 if (cursor == 0 ) 00842 { 00843 diagnostics("Panic: cursor = NULL in sqBackwardLinkSegment\n"); 00844 return -1; 00845 } 00846 if (-1 == sqLinkSegments(cursor,cursor->nextSegment,SQ_HIGH_LINKING_PRIORITY)) 00847 { 00848 diagnostics("Error in sqBackwardLinkSegment\n"); 00849 return -1; 00850 } 00851 } 00852 else 00853 done=1; /* no further linking needed */ 00854 } 00855 if ( cursor == sq->queue + sq->start ) 00856 { 00857 diagnostics("Beginning of queue reached, no further linking possible\n"); 00858 done =1; 00859 } 00860 } 00861 return 0; 00862 } |
|
Definition at line 1110 of file segmentqueue.c. 01111 { 01112 if (sq==0) 01113 { 01114 diagnostics("Error in sqClearQueue(): sq == 0 \n"); 01115 return -1; 01116 } 01117 sq->numSegments=0; 01118 sq->start = sq->end = 0; 01119 sq->full = 0; 01120 sq->n=0; 01121 sq->feedOverrideFactor=1.0; 01122 sq->currentID=0; 01123 01124 sq->done=1; /* the queue is empty, so by definition we're done */ 01125 sq->paused=0; 01126 sq->stepping=0; 01127 sq->feedAdjusting=0; 01128 sq->aborting=0; 01129 01130 sq->currentVel=0; 01131 oldDist=0; 01132 oldPos = sq->lastPoint; 01133 oldVel.tran.x=0; 01134 oldVel.tran.y=0; 01135 oldVel.tran.z=0; 01136 01137 return 0; 01138 } |
|
Definition at line 665 of file segmentqueue.c. Referenced by sqPreprocessSegment(), sqResume(), and sqSetFeedOverride().
00666 { 00667 /* function that checks whether segment s needs to be linked to its 00668 successor(s) based upon its initial increment. It is possible that 00669 this requires linking of a set of succeding segments to make sure that 00670 the final increment can be reached. */ 00671 00672 SEGMENT *cursor; 00673 int done, counter; 00674 int linkcrit; 00675 00676 if ( sq == 0 || s == 0 ) 00677 { 00678 diagnostics("Error in sqForwardLinkSegment\n"); 00679 return -1; 00680 } 00681 00682 if ( s->initInc > s->finalInc ) 00683 { 00684 diagnostics("sqForwardlinkSegment called while initInc is larger than finalInc\n"); 00685 /* not critical, so we don't return -1, but it's not good....*/ 00686 return 0; 00687 } 00688 00689 cursor=s; 00690 done=0; 00691 counter=0; 00692 00693 while (!done) 00694 { 00695 counter++; 00696 if ( counter > sq->size ) 00697 { 00698 /* we have browsed through the whole queue and can't 00699 get out of the loop.... */ 00700 diagnostics("Can't get out of the loop in sqForwardLinkSegment\n"); 00701 return -1; 00702 } 00703 if (cursor->nextSegment == 0 ) 00704 { 00705 /* then this is the last segment in the queue, which always has 00706 a final velocity of zero that can always be reached. Ergo: we're 00707 done */ 00708 done = 1; 00709 } 00710 else if (cursor->nextSegment->linkedToPrevSeg==1) 00711 /* the next segment is already linked to cursor, so let's go on */ 00712 { 00713 cursor=cursor->nextSegment; 00714 if (cursor == 0 ) 00715 { 00716 /* this is VERY unlikely to happen, since we already checked 00717 that a few lines before, but just in case...... */ 00718 diagnostics("Panic: cursor = NULL in sqForwardLinkSegment\n"); 00719 return -1; 00720 } 00721 } 00722 else if (s->initInc > cursor->finalInc ) 00723 /* then we're done. This is always true as long as the set of 00724 segments that succeed s is correctly processed: if the 00725 succeeding segments are correctly processed, then 00726 cursor->finalInc can be reached from s->finalInc 00727 (= s->nextSegment->initInc) over the distance of the segments 00728 s->nextSegment to cursor. The final increment of s is larger 00729 than the initial increment (otherwise this function wouldn't 00730 have been called), so the distance of the segments s to cursor is 00731 of course large enough too to decelerate from s->initInc to 00732 cursor->finalInc */ 00733 done=1; 00734 else 00735 { 00736 if ( -1 == (linkcrit = sqLinkCriterion(sq,s,feedOverride))) 00737 { 00738 diagnostics("Error in sqForwardLinkSegment\n"); 00739 return -1; 00740 } 00741 else if ( linkcrit == SQ_LINKING_NEEDED ) 00742 { 00743 cursor=cursor->nextSegment; 00744 if (cursor == 0 ) 00745 { 00746 /* again, this is very unlikely to happen */ 00747 diagnostics("Panic: cursor = NULL in sqForwardLinkSegment\n"); 00748 return -1; 00749 } 00750 if (-1 == sqLinkSegments(cursor->prevSegment,cursor,SQ_HIGH_LINKING_PRIORITY)) 00751 { 00752 diagnostics("Error in sqForwardLinkSegment\n"); 00753 return -1; 00754 } 00755 } 00756 else 00757 /* linkcrit==SQ_NO_LINKING_NEEDED */ 00758 done=1; /* no further linking needed */ 00759 } 00760 if ( cursor == sq->queue + sq->end ) 00761 { 00762 /* sq->end points to the first free position in the ring buffer 00763 so there's no segment at that position. So if cursor points to 00764 that position, something is very wrong */ 00765 diagnostics("End of queue reached, no further linking possible\n"); 00766 done =1; 00767 } 00768 } 00769 return 0; 00770 } |
|
Definition at line 2347 of file segmentqueue.c. 02348 { 02349 if (sq==0) 02350 { 02351 diagnostics("Error in sqGetDepth\n"); 02352 return -1; 02353 } 02354 return sq->numSegments; 02355 } |
|
Definition at line 2367 of file segmentqueue.c. 02368 { 02369 if (sq==0) 02370 { 02371 diagnostics("Error in sqGetID\n"); 02372 return -1; 02373 } 02374 return sq->currentID; 02375 } |
|
Definition at line 2337 of file segmentqueue.c. 02338 { 02339 if (sq==0) 02340 { 02341 diagnostics("Error in sqGetMaxAcc\n"); 02342 return -1; 02343 } 02344 return sq->maxAcc; 02345 } |
|
Definition at line 1364 of file segmentqueue.c. 01365 { 01366 if ( (sq == 0) || (p == 0) ) 01367 { 01368 diagnostics("Error in sqGetPosition()\n"); 01369 return -1; 01370 } 01371 01372 *p = sq->lastPoint; 01373 return 0; 01374 }; |
|
Definition at line 2326 of file segmentqueue.c. 02327 { 02328 if (sq==0) 02329 { 02330 diagnostics("Error in sqGetVel\n"); 02331 return -1; 02332 } 02333 02334 return sq->currentVel; 02335 } |
|
Definition at line 152 of file segmentqueue.c. Referenced by sqPreprocessSegment().
00154 { 00155 /* s1 and s2 must have been initialized correctly and must have a nonzero 00156 lenght in order to get a valid corner */ 00157 00158 PmCartesian v1; 00159 PmCartesian v2; 00160 PmCartesian me; 00161 PmCartesian diff; 00162 PmCartesian helix; 00163 00164 double maxdiff; 00165 00166 if ( s1 == 0 || s2 == 0 ) 00167 { 00168 diagnostics("Error in sqGiveCornerVelocity()\n"); 00169 return -1; 00170 } 00171 00172 /* check if s1 or s2 has a zero length or amax or cycleTime is zero */ 00173 if ( s1->length == 0 || s2->length == 0 || amax==0 || cycleTime==0 ) 00174 { 00175 /* of course this shouldn't happen */ 00176 diagnostics("Error in sqGiveCornerVelocity()\n"); 00177 return -1; 00178 } 00179 00180 if (s1->type == SQ_LINEAR) 00181 { 00182 v1=s1->line.uVec; 00183 } 00184 else 00185 { 00186 pmCartCartSub( s1->end.tran , s1->circle.center, &me ); 00187 pmCartCartCross( s1->circle.normal, me, &v1 ); 00188 pmCartScalDiv ( s1->circle.rHelix, s1->circle.angle, &helix); 00189 pmCartCartAdd ( v1, helix, &v1); 00190 pmCartNorm ( v1, &v1 ); 00191 00192 } 00193 00194 if (s2->type == SQ_LINEAR) 00195 { 00196 v2=s2->line.uVec; 00197 } 00198 else 00199 { 00200 pmCartScalDiv ( s2->circle.rHelix, s2->circle.angle, &helix); 00201 pmCartCartAdd ( s2->circle.rPerp, helix, &v2); 00202 pmCartNorm ( v2, &v2 ); 00203 } 00204 00205 /* calculate the difference between v1 and v2 */ 00206 pmCartCartSub ( v2,v1, &diff ); 00207 00208 /* select the largest element in diff */ 00209 maxdiff = max ( fabs(diff.x), fabs(diff.y) ); 00210 maxdiff = max ( maxdiff , fabs(diff.z) ); 00211 00212 /* return cornerVelocity */ 00213 if ( maxdiff <= 0 ) 00214 return DBL_MAX; 00215 else 00216 return ( amax * cycleTime / maxdiff ); 00217 00218 }; |
|
Definition at line 140 of file segmentqueue.c. Referenced by sqAddLine(), sqRunCycle(), and sqSetFeedOverride().
|
|
Definition at line 250 of file segmentqueue.c. Referenced by sqPlanSegment().
00253 { 00254 int done=0; 00255 int minNumSteps; 00256 double startInc,finalInc; 00257 SEGMENT *cursor; 00258 double l; 00259 double maxAccTan; 00260 00261 if (sq == 0 || s == 0) 00262 { 00263 diagnostics("Error in sqGiveMaxInc()\n"); 00264 return -1; 00265 } 00266 00267 if ( s->numLinkedSegs == 0 ) 00268 return s->maxInc; 00269 00270 maxAccTan = sqGiveMinAmaxTan(s); 00271 00272 startInc=s->plInitInc; 00273 cursor=s; 00274 l=s->length; 00275 while (!done) 00276 { 00277 if ( cursor->nextSegment==0 ) 00278 { 00279 return cursor->maxInc; 00280 } 00281 if ( cursor->nextSegment!=0 && cursor->nextSegment->maxInc < \ 00282 cursor->maxInc) 00283 finalInc=min(cursor->finalInc,\ 00284 cursor->nextSegment->maxInc*sq->feedOverrideFactor); 00285 00286 else 00287 finalInc=min(cursor->finalInc,\ 00288 cursor->maxInc*sq->feedOverrideFactor); 00289 minNumSteps = ceil ( 3 *fabs(finalInc-startInc) / \ 00290 ( 2 * maxAccTan * sq->ctPow2 )); 00291 00292 if ((minNumSteps+1)* (startInc+finalInc)/2 -startInc > \ 00293 l - 5 * max(finalInc,startInc) ) 00294 { 00295 /* this segment was too short and therefore linked to the next 00296 one */ 00297 cursor=cursor->nextSegment; 00298 l+=cursor->length; 00299 } 00300 else 00301 done=1; 00302 } 00303 00304 return cursor->maxInc; 00305 } |
|
Definition at line 220 of file segmentqueue.c. Referenced by sqLinkCriterion(), sqPause(), sqPlanSegment(), and sqRunCycle().
00221 { 00222 /* give the minimum tangential acceleration for the chain of linked 00223 that starts with s. */ 00224 SEGMENT *cursor; 00225 double minAmax; 00226 00227 if (s == 0) 00228 { 00229 diagnostics("Error in sqGiveMinAmaxTan()\n"); 00230 return -1; 00231 } 00232 00233 if ( s->numLinkedSegs == 0 ) 00234 return s->amaxTan; 00235 00236 minAmax = s->amaxTan; 00237 cursor = s; 00238 00239 while (cursor->nextSegment!=0 && cursor->nextSegment->linkedToPrevSeg==1) 00240 { 00241 cursor = cursor->nextSegment; 00242 if (cursor->amaxTan < minAmax ) 00243 { 00244 minAmax = cursor->amaxTan; 00245 } 00246 } 00247 return minAmax; 00248 } |
|
Definition at line 1003 of file segmentqueue.c. 01004 { 01005 if (size <= 0 || sq == 0 || first == 0 ) 01006 { 01007 diagnostics("Error in sqInitQueue()\n"); 01008 return -1; 01009 } 01010 01011 sq->queue = first; 01012 01013 /* FIXME: third argument (size) is ignored, since the queue size for 01014 the coordinated mode queue can not be set seperately from the 01015 free mode queues */ 01016 sq->size = 2000; 01017 01018 sq->start = sq->end = 0; 01019 sq->full = 0; 01020 sq->numSegments=0; 01021 01022 sq->initXYZ.tran.x=0; 01023 sq->initXYZ.tran.y=0; 01024 sq->initXYZ.tran.z=0; 01025 sq->lastPoint=sq->initXYZ; 01026 sq->n=0; 01027 sq->maxFeedOverrideFactor = 1.0; /* this has to be set at start-up using 01028 sqSetMaxFeedOverride() */ 01029 sq->feedOverrideFactor=1.0; 01030 sq->cycleTime=0; 01031 sq->maxAcc=0; 01032 sq->maxV=0; 01033 sq->currentID=0; 01034 01035 sq->done=1; /* the queue is empty, so by definition we're done */ 01036 sq->paused=0; 01037 sq->stepping=0; 01038 sq->feedAdjusting=0; 01039 sq->aborting=0; 01040 01041 01042 /* initializing debug variables */ 01043 oldPos = sq->lastPoint; 01044 oldVel.tran.x=0; 01045 oldVel.tran.y=0; 01046 oldVel.tran.z=0; 01047 oldDist = 0; 01048 return 0; 01049 }; |
|
Definition at line 2306 of file segmentqueue.c. 02307 { 02308 if (sq==0) 02309 { 02310 diagnostics("Error in sqIsStepping\n"); 02311 return -1; 02312 } 02313 return sq->done; 02314 } |
|
Definition at line 2316 of file segmentqueue.c. 02317 { 02318 if (sq==0) 02319 { 02320 diagnostics("Error in sqIsPaused\n"); 02321 return -1; 02322 } 02323 return sq->paused; 02324 } |
|
Definition at line 2357 of file segmentqueue.c. 02358 { 02359 if (sq==0) 02360 { 02361 diagnostics("Error in sqIsQueueFull\n"); 02362 return -1; 02363 } 02364 return sq->full; 02365 } |
|
Definition at line 2296 of file segmentqueue.c. 02297 { 02298 if (sq==0) 02299 { 02300 diagnostics("Error in sqIsStepping\n"); 02301 return -1; 02302 } 02303 return sq->stepping; 02304 } |
|
Definition at line 306 of file segmentqueue.c. Referenced by sqBackwardLinkSegment(), sqForwardLinkSegment(), and sqPlanSegment().
00307 { 00308 /* this function returns SQ_LINKING_NEEDED if the chain of segments starting 00309 with s is not long enough to accelerate or decelerate from the initial 00310 increment of the first segment in the chain to the final increment of the 00311 last segment in the chain 00312 */ 00313 00314 double amaxTan; 00315 double initInc, finalInc; 00316 int minNumSteps, i; 00317 SEGMENT *lastSeg; 00318 00319 if ( sq == 0 || s == 0 ) 00320 { 00321 diagnostics("Error in sqLinkCriterion\n"); 00322 return -1; 00323 } 00324 00325 if ( s->linkedToPrevSeg == 1 ) 00326 { 00327 diagnostics("Segment s is linked to it's preceding segment in sqLinkCriterion\n"); 00328 return -1; 00329 } 00330 00331 /* find the last segment of the chain */ 00332 lastSeg = s; 00333 for ( i=0 ; i<s->numLinkedSegs; i++) 00334 { 00335 lastSeg=lastSeg->nextSegment; 00336 if (lastSeg == 0 ) 00337 { 00338 diagnostics("Panic: NULL pointer in sqLinkCriterion\n"); 00339 return -1; 00340 } 00341 } 00342 00343 /* find the minimum boundary for the acceleration in tangential 00344 direction */ 00345 /* FIXME: this can be combined with the previous for statement that 00346 looks up the last segment of the chain */ 00347 amaxTan = sqGiveMinAmaxTan(s); 00348 00349 /* find the correct value for the initial increment: when s->plInitInc is 00350 non zero, this means that the segment has been processed before, and that 00351 value should be used */ 00352 if ( 0 != s->plInitInc ) 00353 initInc = s->plInitInc; 00354 else 00355 initInc = s->initInc; 00356 00357 /* find the correct value of the final increment (with taking a feedoverride 00358 into account).*/ 00359 if ( feedOverride >= 1.0) 00360 { 00361 finalInc=lastSeg->finalInc; 00362 } 00363 else 00364 { 00365 if ( lastSeg->nextSegment!=0 && lastSeg->nextSegment->maxInc < \ 00366 lastSeg->maxInc) 00367 finalInc=min(lastSeg->finalInc,\ 00368 lastSeg->nextSegment->maxInc*feedOverride); 00369 else 00370 finalInc=min(lastSeg->finalInc,\ 00371 lastSeg->maxInc*feedOverride); 00372 } 00373 minNumSteps=ceil(3* fabs(initInc - finalInc ) / (2*amaxTan*sq->ctPow2)); 00374 if ((minNumSteps+1)*(initInc + finalInc)/2 - initInc > \ 00375 s->totLength - 2*initInc - finalInc - 5*max(initInc,finalInc) ) 00376 { 00377 return SQ_LINKING_NEEDED; 00378 } 00379 else 00380 { 00381 return SQ_LINKING_NOT_NEEDED; 00382 } 00383 } |
|
Definition at line 606 of file segmentqueue.c. Referenced by sqBackwardLinkSegment(), sqForwardLinkSegment(), sqPreprocessSegment(), and sqRunCycle().
00607 { 00608 if (s1==0) 00609 { 00610 diagnostics("Error 1a in sqLinkSegments() \n"); 00611 return -1; 00612 } 00613 if (s2==0) 00614 { 00615 diagnostics("Error 1b in sqLinkSegments() \n"); 00616 return -1; 00617 } 00618 00619 00620 /* if s2 is not the segment that immediately follows s1, then linking 00621 can not be done */ 00622 00623 if ( s1->nextSegment != s2 ) 00624 { 00625 diagnostics("Error 2 in sqLinkSegments()\n"); 00626 return -1; 00627 } 00628 00629 /* if s1 is active, linking should not be done */ 00630 if (s1->active == 1) 00631 { 00632 /* diagnostics("Error in sqLinkSegments()\n"); */ 00633 /* return -1; */ 00634 return 0; 00635 } 00636 00637 /* find the first element in the series of linked segments of which s1 is 00638 the last one */ 00639 while (s1->linkedToPrevSeg) 00640 { 00641 if (s1==0) 00642 { 00643 diagnostics("Panic: NULL pointer in sqLinkSegments\n"); 00644 return -1; 00645 } 00646 s1=s1->prevSegment; 00647 } 00648 00649 if ( s1->numLinkedSegs > SQ_MAX_NUM_LINKED_SEGS && priority==SQ_LOW_LINKING_PRIORITY) 00650 return 0; 00651 00652 s1->numLinkedSegs += s2->numLinkedSegs + 1; 00653 s1->totLength += s2->totLength; 00654 s2->linkedToPrevSeg = 1; 00655 s2->numLinkedSegs = 0; 00656 00657 /* if (priority==SQ_HIGH_LINKING_PRIORITY) */ 00658 /* { */ 00659 /* s2->amaxTan = s2->amaxTan * 0.50; */ 00660 /* } */ 00661 00662 return 0; 00663 } |
|
Definition at line 1995 of file segmentqueue.c. 01996 { 01997 SEGMENT *as; /* as = Active Segment */ 01998 double startInc; /* the incrediment at the time the pause command 01999 was given */ 02000 double startAcc; /* the derivate of the inc at that time */ 02001 int npow1,npow2,npow3; 02002 double amaxTan; 02003 02004 if (sq==0 || sq->queue==0 ) 02005 { 02006 diagnostics("Error in sqPause\n"); 02007 return -1; 02008 } 02009 02010 if (sq->paused == 1) 02011 /* don't do anything, system is already paused */ 02012 return 0; 02013 02014 /* set paused flag */ 02015 sq->paused=1; 02016 02017 if ( sq->numSegments==0) 02018 { 02019 /* the queue is empty */ 02020 sq->done = 1; /* propably redundant */ 02021 return 0; 02022 } 02023 02024 as=sq->queue+sq->start; 02025 02026 if ( as->active==0 && as->initInc==0 ) 02027 /* then this is the very first segment and we have not started yet. 02028 So let's set the done flag and return */ 02029 { 02030 sq->done=1; 02031 return 0; 02032 } 02033 02034 sq->feedAdjusting=0; /* if we were adjusting the speed, ignore that too */ 02035 02036 amaxTan= sqGiveMinAmaxTan(as); 02037 02038 if ( as->active==0 || sq->n<=3) 02039 { 02040 startInc = as->plInitInc; 02041 startAcc = 0; 02042 as->active=1; 02043 as->planningDone=1; /* the planning will be done in this function */ 02044 02045 as->q= ceil ( 3 * startInc / ( 2 * amaxTan * sq->ctPow2 ) ); 02046 as->m=0; 02047 as->p=0; 02048 as->totNumPoints = as->q + 3; 02049 sq->n=3; /* start allover, but skip the first initInc steps */ 02050 02051 } 02052 else if ( sq->n < as->m + 2 ) 02053 { 02054 /* recalculate the last two dist values */ 02055 npow1 = sq->n - 3; /* sq->n-2-1 */ 02056 npow2 = npow1 * npow1; 02057 npow3 = npow2 * npow1; 02058 startInc = as->a1 * npow3 *sq->ctPow3 \ 02059 + as->b1 * npow2 * sq->ctPow2 \ 02060 + as->c1 * npow1 * sq->cycleTime \ 02061 + as->d1; 02062 npow1 = sq->n - 4; /* sq->n-2-2 */ 02063 npow2 = npow1 * npow1; 02064 npow3 = npow2 * npow1; 02065 startAcc = startInc - (as->a1 * npow3 *sq->ctPow3 \ 02066 + as->b1 * npow2 * sq->ctPow2 \ 02067 + as->c1 * npow1 * sq->cycleTime \ 02068 + as->d1); 02069 as->q= ceil ( 2.12* startInc / ( amaxTan * sq->ctPow2 ) ); 02070 as->m=0; 02071 as->p=0; 02072 as->totNumPoints = as->q + 3; 02073 sq->n=3; /* start allover, but skip the first initInc steps */ 02074 } 02075 else if ( sq->n < as->m + as->p + 2 ) 02076 { 02077 startInc = as->cruiseInc; 02078 startAcc = 0; 02079 as->q= ceil ( 3 * startInc / ( 2 * amaxTan * sq->ctPow2 ) ); 02080 as->m=0; 02081 as->p=0; 02082 as->totNumPoints = as->q + 3; 02083 sq->n=3; /* start allover, but skip the first initInc steps */ 02084 } 02085 else 02086 { 02087 /* we are already decelerating, so it would be best to finish that 02088 first. After we're done with that, we can decelerate to zero */ 02089 02090 /* before messing the whole thing up, let's see if we are already 02091 decelerating to zero */ 02092 if (as->plFinalInc==0) 02093 { 02094 /* Then we'll reach the end of the segment with a zero velocity. 02095 This means that we don't have to do anything but waiting at the 02096 end of the segment. This is basically the same thing that 02097 happens at the end of a step-motion. This is exactly what 02098 we will tell the system: that we're stepping, so that all of 02099 the extra things needed for a pause within a segment are skipped. 02100 */ 02101 sq->paused=0; 02102 sq->stepping=1; 02103 return 0; 02104 } 02105 else 02106 { 02107 02108 /* let's do a little trick: we copy the deceleration parameters 02109 of the current motion to the acceleration phase parameter 02110 fields in the current segment and calculate a new 02111 deceleration action from finalInc to 0. We'll decrease sq->n 02112 with a number such of steps, such that it will look like 02113 nothing has happened. sqRunCycle won't notice this, and will 02114 think it's (again) in phase 1. We know better.... */ 02115 02116 as->a1=as->a3; 02117 as->b1=as->b3; 02118 as->c1=as->c3; 02119 as->d1=as->d3; 02120 02121 sq->n -= as->m + as->p; 02122 02123 as->m =as->q; 02124 as->p=1 ; /* the cruising phase now becomes the 02125 usual final step of a segment */ 02126 02127 /* find the finalInc */ 02128 startInc = as->plFinalInc; 02129 startAcc = 0; 02130 as->cruiseInc = startInc; 02131 02132 as->q= ceil ( 3 * startInc / ( 2 * amaxTan * sq->ctPow2 ) ); 02133 as->totNumPoints = as->m + as->q + as->p + 2; 02134 02135 } 02136 } 02137 as->b3 = - ( 3 * startInc + 2 * as->q* startAcc ) \ 02138 / ( as->q * as->q * sq->ctPow2 ) ; 02139 as->a3 = ( 2 * startInc + as->q* startAcc ) \ 02140 / ( as->q * as->q * as->q * sq->ctPow3 ) ; 02141 as->c3 = startAcc/sq->cycleTime; 02142 as->d3 = startInc; 02143 02144 as->plFinalInc=0; 02145 02146 return 0; 02147 } |
|
Definition at line 385 of file segmentqueue.c. Referenced by sqRunCycle().
00386 { 00387 /* variable declaration */ 00388 double length; 00389 double maxInc; 00390 double amaxTan; 00391 00392 SEGMENT *cursor; 00393 00394 int validSolutionFound; 00395 00396 if (sq==0) 00397 { 00398 diagnostics("Error in sqPlanSegment()\n"); 00399 return -1; 00400 } 00401 00402 00403 /* check is s is a valid pointer */ 00404 if (s==0) 00405 { 00406 diagnostics("Error in sqPlanSegment()\n"); 00407 return -1; 00408 } 00409 00410 00411 /* check if this segment is linked to its predecessor (which should never 00412 happen!) */ 00413 if ( s->linkedToPrevSeg == 1 ) 00414 { 00415 diagnostics("Error in sqPlanSegment()\n"); 00416 return -1; 00417 } 00418 00419 00420 length=s->length; 00421 cursor=s; 00422 00423 /* check if there are any segments linked to s, find the total length of the 00424 linked segments and find the finalInc of the last segment in the chain */ 00425 while (cursor->nextSegment!=0 && cursor->nextSegment->linkedToPrevSeg) 00426 { 00427 cursor = cursor->nextSegment; 00428 } 00429 00430 if ( SQ_LINKING_NEEDED == sqLinkCriterion(sq,s,1.0) ) 00431 { 00432 diagnostics("Error in sqPlanSegment(), chain too short\n"); 00433 if (s->initInc > cursor->finalInc ) 00434 diagnostics("InitInc > finalInc \n"); 00435 else 00436 diagnostics("InitInc < finalInc \n"); 00437 00438 diagnostics("ID = %d\n", s->ID ); 00439 diagnostics("Startpt: x=%d, y=%d, z=%d\n",(int)(1000.0*s->start.tran.x),(int)(1000.0*s->start.tran.y),(int)(1000.0*s->start.tran.z)); 00440 } 00441 00442 00443 if (-1 == (maxInc=sqGiveMaxInc(sq,s)*sq->feedOverrideFactor)) 00444 { 00445 diagnostics("Error in sqPlanSegment()\n"); 00446 return -1; 00447 } 00448 00449 /* maxInc should never exceed the the system's maximum increment 00450 (maxV*cycleTime) */ 00451 maxInc = min(maxInc, sq->maxV*sq->cycleTime); 00452 00453 /* find the minimum value for the maximum tangential acceleration for this 00454 chain of segments beginning with s*/ 00455 amaxTan = sqGiveMinAmaxTan(s); 00456 diagnosticsOff("AmaxTan in sqplansegment = %d \n",(int)(ceil(amaxTan))); 00457 /* finalInc ( = initInc of nextSegment) should never be larger than 00458 the maxInc * feedOveride of this segment and the next segment */ 00459 00460 if ( cursor->finalInc!=0) /* if true: this is not the last segment */ 00461 { 00462 if ( cursor->nextSegment->maxInc < cursor->maxInc) 00463 s->plFinalInc=min(cursor->finalInc,\ 00464 cursor->nextSegment->maxInc*sq->feedOverrideFactor); 00465 00466 else 00467 s->plFinalInc=min(cursor->finalInc,maxInc); 00468 00469 cursor->nextSegment->plInitInc=s->plFinalInc; 00470 } 00471 else 00472 s->plFinalInc=0; 00473 00474 00475 /* the first two steps and the last step are already defined */ 00476 length = s->totLength - 2* s->plInitInc - s->plFinalInc; 00477 00478 00479 /* calculate minimal number of steps for the first phase (acc) */ 00480 if (s->plInitInc == maxInc) 00481 s->m=0; 00482 else 00483 /* m should be always be two steps or more */ 00484 s->m=max(2,ceil ( 3*fabs(maxInc-s->plInitInc)/(2*amaxTan*sq->ctPow2))); 00485 00486 /* calulate minimal number of steps for the third phase (dec) */ 00487 if (s->plFinalInc == maxInc) 00488 s->q=0; 00489 else 00490 s->q=max(2,ceil(3*fabs(maxInc-s->plFinalInc)/(2*amaxTan*sq->ctPow2))); 00491 00492 /* calculate the minimal number of steps needed for the cruising phase */ 00493 if (length - ((s->m+1)*(s->plInitInc+maxInc)/2 - s->plInitInc)*(s->m!=0) \ 00494 - ((s->q+1)*(maxInc+s->plFinalInc)/2 - maxInc)*(s->q!=0) < 0 ) 00495 { 00496 /* true: there is no cruising phase */ 00497 s->p=3; 00498 validSolutionFound=0; 00499 if (s->ID==474) diagnostics("0: maxInc = %d, initInc = %d, finalInc = %d\n",(int)(100000.0*maxInc), (int)(100000.0*s->plInitInc),(int)(100000.0*s->plFinalInc)); 00500 if ( maxInc > s->plInitInc && maxInc > s->plFinalInc ) 00501 { 00502 maxInc = -s->p*amaxTan*sq->ctPow2/3 + sqrt ( 4*s->p*s->p*amaxTan*amaxTan*sq->ctPow2*sq->ctPow2 + 18*(s->plInitInc*s->plInitInc+s->plFinalInc*s->plFinalInc) + 12*amaxTan*sq->ctPow2*(s->plInitInc-s->plFinalInc+2*length))/6; 00503 diagnosticsOff("1: maxInc = %d\n",(int)(100000.0*maxInc)); 00504 if ( maxInc > s->plInitInc && maxInc > s->plFinalInc ) 00505 { 00506 validSolutionFound=1; 00507 } 00508 } 00509 00510 if ( (s->plInitInc >= maxInc && maxInc > s->plFinalInc) || !validSolutionFound ) 00511 { 00512 maxInc = 3*((s->plFinalInc*s->plFinalInc - s->plInitInc*s->plInitInc) + 2*amaxTan*sq->ctPow2*(s->plInitInc-s->plFinalInc+2*length))/(4 * s->p * amaxTan * sq->ctPow2 ); 00513 diagnosticsOff("2: maxInc = %d\n",(int)(100000.0*maxInc)); 00514 if ( s->plInitInc >= maxInc && maxInc > s->plFinalInc ) 00515 { 00516 validSolutionFound=1; 00517 } 00518 } 00519 if ( (s->plInitInc < maxInc && maxInc <= s->plFinalInc) || !validSolutionFound ) 00520 { 00521 maxInc = ( 3*( s->plInitInc*s->plInitInc - s->plFinalInc*s->plFinalInc) + 2*amaxTan*sq->ctPow2*(s->plInitInc-s->plFinalInc+2*length))/(4 * s->p * amaxTan * sq->ctPow2 ); 00522 diagnosticsOff("3: maxInc = %d\n",(int)(100000.0*maxInc)); 00523 if ( s->plInitInc < maxInc && maxInc <= s->plFinalInc ) 00524 { 00525 validSolutionFound=1; 00526 } 00527 } 00528 if ( ( maxInc <= s->plInitInc && maxInc <= s->plFinalInc) || !validSolutionFound ) 00529 { 00530 maxInc = s->p*amaxTan*sq->ctPow2/3 + sqrt ( 4*s->p*s->p*amaxTan*amaxTan*sq->ctPow2*sq->ctPow2 + 18*(s->plInitInc*s->plInitInc+s->plFinalInc*s->plFinalInc) + 12*amaxTan*sq->ctPow2*(-s->plInitInc+s->plFinalInc-2*length))/6; 00531 diagnosticsOff("4: maxInc = %d\n",(int)(100000.0*maxInc)); 00532 if ( maxInc <= s->plInitInc && maxInc <= s->plFinalInc ) 00533 { 00534 validSolutionFound=1; 00535 } 00536 } 00537 if ( !validSolutionFound ) 00538 { 00539 diagnostics("No solution found in sqPlanSegment\n"); 00540 return -1; 00541 } 00542 00543 /* recalculate m and q */ 00544 s->m=ceil(3*fabs(maxInc-s->plInitInc)/(2*amaxTan*sq->ctPow2)); 00545 s->q=ceil(3*fabs(maxInc-s->plFinalInc)/(2*amaxTan*sq->ctPow2)); 00546 s->p=ceil((length-(s->m!=0)*((s->m+1)*(s->plInitInc+maxInc)/2-\ 00547 s->plInitInc)-(s->q!=0)*((s->q+1)*(s->plFinalInc+maxInc)/2\ 00548 -maxInc))/maxInc ); 00549 } 00550 else 00551 s->p=ceil((length-(s->m!=0)*((s->m+1)*(s->plInitInc+maxInc)/2-\ 00552 s->plInitInc)-(s->q!=0)*((s->q+1)*(s->plFinalInc+maxInc)/2\ 00553 -maxInc))/maxInc ); 00554 00555 /* adjust maxInc a little */ 00556 maxInc= (2*length-(s->m!=0)*(s->m-1)*s->plInitInc\ 00557 -(s->q!=0)*(s->q+1)*s->plFinalInc) \ 00558 / ( (s->m!=0)*(s->m+1) + 2 * s->p + (s->q!=0)*(s->q-1) ); 00559 00560 /* if ((s->m<=1) && (fabs(s->plInitInc - maxInc) > 0.3*amaxTan*sq->ctPow2)) */ 00561 /* { */ 00562 /* s->m=2; */ 00563 /* maxInc = (2*length - (s->m!=0) * (s->m-1) * s->initInc */ 00564 /* - (s->q!=0) * (s->q+1) * s->plFinalInc) \ */ 00565 /* / ( (s->m!=0) * (s->m+1) + 2 * s->p + (s->q!=0)*(s->q-1) ); */ 00566 /* } */ 00567 /* if ((s->q<=1) && (fabs(s->plFinalInc-maxInc)> 0.3 * amaxTan*sq->ctPow2)) */ 00568 /* { */ 00569 /* s->q=2; */ 00570 /* maxInc= (2*length - (s->m!=0)*(s->m-1)*s->plInitInc */ 00571 /* - (s->q!=0) * (s->q+1) * s->plFinalInc) \ */ 00572 /* / ( (s->m!=0)*(s->m+1) + 2 * s->p + (s->q!=0)*(s->q-1) ); */ 00573 /* } */ 00574 s->totNumPoints= s->m + s->p + s->q + 3; 00575 s->cruiseInc=maxInc; 00576 00577 /* ok, we've found (sub)-optimal values for m, p and q. Let's go on 00578 with the actual planning */ 00579 00580 if (s->m!=0) 00581 { 00582 s->b1 = 3 * (maxInc-s->plInitInc ) / ( (s->m*s->m*sq->ctPow2) ); 00583 s->a1 = -2 * s->b1 / ( 3 * s->m * sq->cycleTime) ; 00584 s->c1 = 0; 00585 s->d1 = s->plInitInc; 00586 } 00587 00588 else s->a1 = s->b1 = s->c1 = s->d1 = 0; 00589 00590 if (s->q!=0) 00591 { 00592 s->b3 = 3 * ( s->plFinalInc - maxInc ) / ( (s->q*s->q*sq->ctPow2) ); 00593 s->a3 = -2 * s->b3 / ( 3 * s->q * sq->cycleTime) ; 00594 s->c3 = 0; 00595 s->d3 = maxInc; 00596 } 00597 else s->a3 = s->b3 = s->c3 = s->d3 = 0; 00598 00599 s->planningDone=1; 00600 00601 return 0; 00602 }; |
|
Definition at line 864 of file segmentqueue.c. Referenced by sqAddCircle(), and sqAddLine().
00865 { 00866 00867 /* this is the stuff that's needs to be done for both linear and 00868 circular motions. Only sqAddLine and sqAddCircle should call this 00869 function. 00870 */ 00871 00872 double cornerInc; 00873 00874 SEGMENT *prevseg; 00875 SEGMENT * cursor; 00876 00877 /* check if segment queue has been initialized and if newseg is valid */ 00878 if ( sq == 0 || sq->queue == 0 || newseg == 0 ) 00879 { 00880 diagnostics("Error 1 in sqPreprocessSegment()\n"); 00881 return -1; 00882 } 00883 00884 00885 /* if this is the first segment.... */ 00886 if ( sq->numSegments == 1 ) 00887 { 00888 newseg->initInc=0; 00889 newseg->start=sq->lastPoint; 00890 newseg->prevSegment=0; 00891 if (sq->paused != 1 && sq->stepping != 1 ) 00892 sq->done=0; 00893 } 00894 /* if not ... */ 00895 else 00896 { 00897 prevseg = sq->queue + ( ( sq->end+sq->size-2) % sq->size ); 00898 newseg->start = prevseg->end; 00899 prevseg->nextSegment=newseg; 00900 newseg->prevSegment=prevseg; 00901 00902 if ( prevseg->active == 1 ) 00903 /* we can't change anything of the active segment */ 00904 { 00905 newseg->initInc=prevseg->finalInc; 00906 } 00907 else 00908 { 00909 00910 /* calculate the corner velocity for the corner between prevSegment 00911 and newseg */ 00912 00913 if ( -1 == (cornerInc = sqGiveCornerVelocity( prevseg, newseg ,\ 00914 sq->maxAcc,sq->cycleTime) * sq->cycleTime )) 00915 { 00916 diagnostics("Error 2 in sqPreprocessSegment()\n"); 00917 return -1; 00918 } 00919 00920 00921 /* if the maximum speeds of the new and the previous segment 00922 are the same and the corner speed is larger than this 00923 maximum speed, the segments can be linked */ 00924 00925 if ( (prevseg->maxInc == newseg->maxInc ) && \ 00926 (cornerInc > newseg->maxInc) ) 00927 { 00928 if (-1 == sqLinkSegments(prevseg,newseg,SQ_LOW_LINKING_PRIORITY)) 00929 { 00930 diagnostics("Error 3 in sqPreprocessSegment()\n"); 00931 return -1; 00932 } 00933 cornerInc = prevseg->maxInc; 00934 newseg->initInc = cornerInc; 00935 prevseg->finalInc = cornerInc; 00936 } 00937 00938 else 00939 { 00940 /* the corner velocity shouldn't exceed the maximum 00941 speeds of both segments */ 00942 00943 if ( (cornerInc>prevseg->maxInc) || (cornerInc>newseg->maxInc) ) 00944 cornerInc = min( prevseg->maxInc, newseg->maxInc ); 00945 00946 newseg->initInc = cornerInc; 00947 prevseg->finalInc = cornerInc; 00948 00949 /* is prevseg long enough to acc/dec from initInc to finalInc 00950 (=cornerInc)? */ 00951 cursor=prevseg; 00952 /* check if prevseg is linked to its predecessor and 00953 if so, find the first segment in the linked 00954 series of segments */ 00955 00956 if (prevseg->linkedToPrevSeg == 1) 00957 { 00958 while (cursor->linkedToPrevSeg ) 00959 { 00960 cursor=cursor->prevSegment; 00961 if (cursor == 0 ) 00962 { 00963 diagnostics("Panic: cursor = NULL in sqPreprocessSegment\n"); 00964 return -1; 00965 } 00966 } 00967 } 00968 if (cursor->initInc < cornerInc) 00969 { 00970 /* check if prevseg needs to be linked to it's next 00971 segment(s), which in this case only the newseg 00972 can be. The feedoverride factor is set to the 00973 maximum feedoverride to ensure correct linking 00974 for every possible feed */ 00975 if ( -1 == sqForwardLinkSegment(sq,cursor,sq->maxFeedOverrideFactor) ) 00976 { 00977 diagnostics("Error 4 in sqPreprocessSegment()\n"); 00978 return -1; 00979 } 00980 } 00981 else /* cursor->initInc > cornerInc */ 00982 /* check if the prevseg needs to be linked to its 00983 predecessor(s). The feedoverride factor is set to 00984 the maximum feedoverride to ensure correct linking 00985 for every possible feed */ 00986 { 00987 if ( -1 == sqBackwardLinkSegment(sq,prevseg,sq->maxFeedOverrideFactor) ) 00988 { 00989 diagnostics("Error 5 in sqPreprocessSegment()\n"); 00990 return -1; 00991 } 00992 } 00993 } 00994 } 00995 } 00996 00997 return 0; 00998 } |
|
Definition at line 2150 of file segmentqueue.c. 02151 { 02152 SEGMENT *as; /* as = Active Segment */ 02153 SEGMENT *cursor; 02154 02155 if (sq==0 || sq->queue==0 ) 02156 { 02157 diagnostics("Error in sqResume\n"); 02158 return -1; 02159 } 02160 02161 if ( sq->done!=1) 02162 02163 /* we can't resume if the systems is not done yet with a step or pause 02164 action */ 02165 { 02166 diagnosticsOff("Can't resume if not done with pause or step action\n"); 02167 /* this is not a critical error, so we'll just ignore the command */ 02168 return 0; 02169 } 02170 02171 if ( sq->feedOverrideFactor == 0 ) 02172 { 02173 /* we can't resume if the feed override factor is zero. To resume 02174 the user should set a new non-zero value for this factor first. 02175 This will immediately result in a resume action. */ 02176 diagnostics("Can't resume if feed override is zero\n"); 02177 /* not a critical error, so ignore it */ 02178 return 0; 02179 } 02180 02181 if ( sq->numSegments == 0) 02182 { 02183 /* there's not much to do */ 02184 sq->paused = 0; 02185 return 0; 02186 } 02187 02188 /* let's see if the length of the segment(chain) is large enough to 02189 accelerate from zero to finalInc */ 02190 as=sq->queue+sq->start; 02191 cursor=as; 02192 /* first find the last segment in the chain */ 02193 while ( cursor->nextSegment!=0 && cursor->nextSegment->linkedToPrevSeg==1) 02194 cursor=cursor->nextSegment; 02195 02196 /* keep linking successive segments to as until the chain is long 02197 enough */ 02198 02199 if ( -1 == sqForwardLinkSegment(sq, as, sq->feedOverrideFactor )) 02200 { 02201 diagnostics("Error in sqResume \n "); 02202 return -1; 02203 } 02204 02205 if (sq->paused == 1 && sq->stepping == 1 ) 02206 sq->stepping=1; 02207 else 02208 sq->stepping=0; 02209 02210 sq->paused=0; 02211 sq->done=0; 02212 02213 return 0; 02214 } |
|
Definition at line 1376 of file segmentqueue.c. 01377 { 01378 SEGMENT *as; /* to use instead of sq->queue[sq->start], 01379 stands for Active Segment */ 01380 int i; 01381 SEGMENT *cursor; 01382 double finalInc; 01383 int done; 01384 int minNumSteps; 01385 double angleToGo; 01386 double amaxTan; 01387 int turn; 01388 PmCartesian normal, center; 01389 01390 int npow1, npow2, npow3; /* to speed up cubic calculations */ 01391 01392 if (sq==0 ) 01393 { 01394 diagnostics("Error in sqRunCycle(): Segmentqueue doesn't exist!\n"); 01395 return -1; 01396 } 01397 01398 if ( sq->full == 1 && sq->numSegments < sq->size - SQ_SAFETY_MARGIN ) 01399 diagnostics("sq->full == 1 although queue's not full!!!!\n"); 01400 01401 if ( sq->done==1 ) 01402 { 01403 /* do nothing */ 01404 return 0; 01405 } 01406 /* if buffer is empty give last point (i.e. do nothing) */ 01407 if ( sq->numSegments==0 ) 01408 { 01409 /* set the 'done' flag ..... */ 01410 sq->done=1; 01411 01412 /* check if currentID is the same as the ID of the last appended motion. 01413 The only case in which this will not be true is when the last motion 01414 has a zero length */ 01415 if (sq->currentID != sq->lastAppMotionID ) 01416 sq->currentID= sq->lastAppMotionID; 01417 return 0; 01418 } 01419 as=sq->queue+sq->start; /* much shorter ..... */ 01420 if (as == 0 ) 01421 { 01422 diagnostics("Panic: as = NULL in sqRunCycle\n"); 01423 return -1; 01424 } 01425 01426 if (as->active==0) 01427 /* we're about to start with a new segment */ 01428 { 01429 if (-1 == sqPlanSegment(sq, as)) 01430 { 01431 diagnostics("Error in sqRunCycle\n"); 01432 return -1; 01433 } 01434 /* mark the whole chain as active */ 01435 cursor=as; 01436 for (i=0;i<=as->numLinkedSegs;i++) 01437 { 01438 if (cursor == 0 ) 01439 { 01440 diagnostics("Panic: cursor = NULL in sqRunCycle\n"); 01441 return -1; 01442 } 01443 cursor->active=1; 01444 cursor=cursor->nextSegment; 01445 } 01446 oldDist=0; 01447 sq->dist=0; 01448 01449 /* reset base, cursor, offset and cumlength and n */ 01450 sq->base = as->start; 01451 sq->cursor=as; 01452 sq->offset=0; 01453 sq->cumLength=as->length; 01454 sq->n=1; 01455 sq->currentID=as->ID; 01456 01457 } 01458 /* else: planning has been done before and the parameters are correctly 01459 initialized, unless someone deliberately changed planningDone to 1. 01460 Let's trust our user and not check for that here. */ 01461 01462 /* depending of in what phase of the motion we are, determine the new 01463 distance */ 01464 if ( sq->n==1 || sq->n==2 ) 01465 { 01466 sq->dist += as->plInitInc; 01467 } 01468 else if ( sq->n <= as->m +2 ) 01469 /* acceleration phase */ 01470 { 01471 npow1 = sq->n - 2; 01472 npow2 = npow1 * npow1; 01473 npow3 = npow2 * npow1; 01474 sq->dist += as->a1 * npow3 *sq->ctPow3 \ 01475 + as->b1 * npow2 * sq->ctPow2 \ 01476 + as->c1 * npow1 * sq->cycleTime \ 01477 + as->d1; 01478 } 01479 else if ( sq->n <= as->m + as->p + 2 ) 01480 /* cruising phase */ 01481 { 01482 sq->dist += as->cruiseInc; 01483 } 01484 else if ( sq->n <= as->m + as->p + as->q +2 ) 01485 /* deceleration phase */ 01486 { 01487 npow1 = sq->n - as->m - as->p - 2; 01488 npow2 = npow1 * npow1; 01489 npow3 = npow2 * npow1; 01490 sq->dist += as->a3 * npow3 *sq->ctPow3 \ 01491 + as->b3 * npow2 * sq->ctPow2 \ 01492 + as->c3 * npow1 * sq->cycleTime \ 01493 + as->d3; 01494 01495 } 01496 else if ( sq->n == as->m + as->p + as->q + 3 ) 01497 /* last step */ 01498 { 01499 sq->dist+= as->plFinalInc; 01500 } 01501 else 01502 /* we have a problem, because this should never happen */ 01503 { 01504 diagnostics("Error in sqRunCycle\n"); 01505 return -1; 01506 } 01507 01508 /* transform the dist scalar into a XYZ triplet */ 01509 if (as->nextSegment !=0 && ( as->nextSegment->linkedToPrevSeg ==1 || 01510 sq->paused == 1)) 01511 /* the active segment is the first segment of a chain */ 01512 /* the sq->paused == 1 test is added to make sure that if a pause 01513 command is given just before the end of the segment, that the 01514 following segment is used to finish decelerating to zero */ 01515 { 01516 while ( (sq->dist > sq->cumLength) 01517 && ( sq->cursor->nextSegment!=0 ) 01518 && ( (sq->cursor->nextSegment->linkedToPrevSeg==1 ) || 01519 sq->paused==1 ) ) 01520 { 01521 sq->offset = sq->cumLength; 01522 sq->base = sq->cursor->end; 01523 sq->cursor = sq->cursor->nextSegment; 01524 sq->cumLength += sq->cursor->length; 01525 01526 } 01527 /* set currentID */ 01528 sq->currentID=sq->cursor->ID; 01529 01530 if ( sq->cursor->type == SQ_LINEAR ) 01531 pmLinePoint( &sq->cursor->line, sq->dist - sq->offset, &sq->lastPoint); 01532 else 01533 pmCirclePoint( &sq->cursor->circle, \ 01534 (sq->dist - sq->offset)/sq->cursor->helixRadius,\ 01535 &sq->lastPoint ); 01536 } 01537 01538 else 01539 /* the active segment has no other segments linked to it, which makes 01540 things much easier... */ 01541 { 01542 if ( sq->cursor->type == SQ_LINEAR ) 01543 pmLinePoint(&as->line, sq->dist, &sq->lastPoint); 01544 else 01545 pmCirclePoint(&as->circle, sq->dist/as->helixRadius, &sq->lastPoint); 01546 } 01547 01548 sq->n++; 01549 01550 if (sq->n > as->totNumPoints ) 01551 { 01552 if (sq->aborting == 1) 01553 { 01554 if (-1 == sqClearQueue(sq)) 01555 { 01556 diagnostics("Error in sqRunCycle\n"); 01557 return -1; 01558 } 01559 } 01560 01561 else if (sq->paused == 1 || sq->feedAdjusting == 1) 01562 { 01563 01564 if (sq->paused==1) 01565 { 01566 sq->done=1; 01567 finalInc=0; 01568 } 01569 else 01570 { 01571 sq->feedAdjusting=0; 01572 finalInc=as->plFinalInc; 01573 } 01574 01575 /* remove all segments preceding the current segment */ 01576 cursor=as; 01577 while ( cursor!=sq->cursor ) 01578 { 01579 cursor=cursor->nextSegment; 01580 if (cursor == 0 ) 01581 { 01582 diagnostics("Panic: cursor = NULL in sqRunCycle\n"); 01583 return -1; 01584 } 01585 sq->numSegments--; 01586 } 01587 if ( sq->numSegments < sq->size - SQ_SAFETY_MARGIN ) 01588 sq->full = 0; 01589 if ( sq->numSegments < 0 ) 01590 { 01591 diagnostics("Panic: sq->numSegments <0 in sqRunCycle\n"); 01592 return -1; 01593 } 01594 01595 cursor->prevSegment=0; 01596 cursor->linkedToPrevSeg=0; 01597 sq->start= sq->cursor - sq->queue; 01598 as=cursor; 01599 01600 as->planningDone=0; 01601 as->plInitInc=finalInc; 01602 as->start=sq->lastPoint; 01603 01604 if ( as->type == SQ_LINEAR) 01605 { 01606 as->length=sqGiveLength(as->start,as->end); 01607 as->totLength=as->length; 01608 pmLineInit(&as->line,as->start,as->end); 01609 } 01610 else 01611 { 01612 angleToGo= as->circle.angle-\ 01613 (sq->dist-sq->offset)/as->helixRadius; 01614 turn = floor(angleToGo / ( 2 * PM_PI )); 01615 normal = as->circle.normal; 01616 center = as->circle.center; 01617 pmCircleInit( &as->circle, as->start, as->end, \ 01618 center, normal, turn); 01619 as->length=as->circle.angle* as->helixRadius; 01620 as->totLength= as->length; 01621 } 01622 01623 01624 as->active=0; /* mark the first segment of the chain 01625 as not active */ 01626 01627 /* determine how many segments are linked to as */ 01628 as->numLinkedSegs=0; 01629 while (cursor->nextSegment!=0 && 01630 cursor->nextSegment->linkedToPrevSeg==1 ) 01631 { 01632 cursor=cursor->nextSegment; 01633 as->numLinkedSegs++; 01634 as->totLength+=cursor->length; 01635 } 01636 /* find the minimum of the amax's of the segments in the chain */ 01637 amaxTan=sqGiveMinAmaxTan(as); 01638 01639 done=0; 01640 /* keep linking segments until the chain is long enough */ 01641 while (!done) 01642 { 01643 if ( cursor->nextSegment!=0 && cursor->nextSegment->maxInc < \ 01644 cursor->maxInc) 01645 finalInc=min(cursor->finalInc,\ 01646 cursor->nextSegment->maxInc*sq->feedOverrideFactor); 01647 01648 else 01649 finalInc=min(cursor->finalInc,\ 01650 cursor->maxInc*sq->feedOverrideFactor); 01651 01652 amaxTan= min(amaxTan, cursor->amaxTan); 01653 minNumSteps = ceil ( 3 * fabs(finalInc-as->plInitInc) / \ 01654 ( 2 * amaxTan * sq->ctPow2 )); 01655 if ((minNumSteps+1)* (as->plInitInc+finalInc)/2-as->plInitInc >\ 01656 as->totLength - 5 * max(as->plInitInc,finalInc )) 01657 01658 { 01659 if (-1 ==sqLinkSegments(cursor,cursor->nextSegment,SQ_HIGH_LINKING_PRIORITY)) 01660 { 01661 diagnostics("Error in sqRunCycle\n"); 01662 return -1; 01663 } 01664 cursor=cursor->nextSegment; 01665 if (cursor == 0 ) 01666 { 01667 diagnostics("Panic: cursor = NULL in sqRunCycle\n"); 01668 return -1; 01669 } 01670 01671 } 01672 else 01673 done=1; 01674 } 01675 01676 } 01677 else if ( sq->stepping == 1) 01678 /* we are at the end of the segment, but shouldn't go on 01679 with the next one */ 01680 { 01681 sq->numSegments--; 01682 sq->start = (sq->start + 1 ) % sq->size; 01683 if ( sq->numSegments < sq->size - SQ_SAFETY_MARGIN ) 01684 sq->full = 0; 01685 if ( sq->numSegments < 0 ) 01686 { 01687 diagnostics("Panic: sq->numSegments < 0 in sqRunCycle\n"); 01688 return -1; 01689 } 01690 01691 as= sq->queue+sq->start; 01692 as->plInitInc=0; 01693 as->active=0; 01694 sq->done=1; 01695 } 01696 01697 else 01698 { 01699 /* end of segment reached */ 01700 sq->numSegments -= 1 + as->numLinkedSegs; 01701 sq->start = ( sq->start + as->numLinkedSegs + 1 ) % sq->size; 01702 if ( sq->numSegments < sq->size - SQ_SAFETY_MARGIN ) 01703 sq->full = 0; /* we just removed some segments ... */ 01704 if ( sq->numSegments < 0 ) 01705 { 01706 diagnostics("Panic: sq->numSegments <0 in sqRunCycle\n"); 01707 return -1; 01708 } 01709 01710 } 01711 } 01712 01713 /* for debugging */ 01714 01715 oldVel=newVel; 01716 newVel.tran.x= sq->lastPoint.tran.x - oldPos.tran.x; 01717 newVel.tran.y= sq->lastPoint.tran.y - oldPos.tran.y; 01718 newVel.tran.z= sq->lastPoint.tran.z - oldPos.tran.z; 01719 01720 oldPos=sq->lastPoint; 01721 01722 newAcc.tran.x= newVel.tran.x - oldVel.tran.x; 01723 newAcc.tran.y= newVel.tran.y - oldVel.tran.y; 01724 newAcc.tran.z= newVel.tran.z - oldVel.tran.z; 01725 01726 if (fabs(newAcc.tran.x) > sq->maxAcc*sq->ctPow2 || \ 01727 fabs(newAcc.tran.y) > sq->maxAcc*sq->ctPow2 || \ 01728 fabs(newAcc.tran.z) > sq->maxAcc*sq->ctPow2 ) 01729 { 01730 diagnosticsOff("MaxAcc limited violated on motion %d\n",sq->currentID); 01731 diagnosticsOff("ddx=%d ddy=%d ddz=%d\n",(int)(newAcc.tran.x*1000000.0),(int)(newAcc.tran.y*1000000.0),(int)(newAcc.tran.z*1000000.0 )); 01732 } 01733 01734 sq->currentVel = sq->dist - oldDist; 01735 oldDist = sq->dist; 01736 01737 return 0; 01738 } |
|
Definition at line 1073 of file segmentqueue.c. |
|
Definition at line 1153 of file segmentqueue.c. |
|
Definition at line 1741 of file segmentqueue.c. 01742 { 01743 01744 SEGMENT *as, *cursor; /* as = Active Segment */ 01745 double startInc,finalInc,startAcc=0; 01746 double prevInc; 01747 int npow1,npow2,npow3; 01748 double angleToGo; 01749 int turn; 01750 PmCartesian normal, center; 01751 01752 if ( sq==0 || sq->queue==0 ) 01753 { 01754 diagnostics("Error in sqSetFeedOverride\n"); 01755 return -1; 01756 } 01757 01758 /* if fo is out of the valid range: clamp it */ 01759 if ( fo < 0 ) 01760 fo=0; 01761 else if ( fo > sq->maxFeedOverrideFactor ) 01762 fo=sq->maxFeedOverrideFactor; 01763 01764 if ( sq->feedOverrideFactor==fo ) 01765 /* don't do anything, just return */ 01766 return 0; 01767 01768 if ( fo == 0 ) 01769 { 01770 /* then this is actually a pause action */ 01771 if ( -1 == sqPause(sq) ) 01772 { 01773 diagnostics("Error in sqSetFeedOverride\n"); 01774 return -1; 01775 } 01776 else 01777 { 01778 sq->feedOverrideFactor=0; 01779 return 0; 01780 } 01781 } 01782 01783 if ( sq->numSegments==0 ) 01784 { 01785 /* the queue is empty */ 01786 sq->feedOverrideFactor=fo; 01787 return 0; 01788 } 01789 01790 as=sq->queue+sq->start; 01791 01792 if ( sq->paused==1 ) 01793 { 01794 if ( sq->feedOverrideFactor == 0 ) 01795 { 01796 /* If the previous feed override factor equals zero, then the 01797 pause action was actually done by setting the feed 01798 override to zero */ 01799 sq->feedOverrideFactor=fo; 01800 if ( -1 == sqResume(sq) ) 01801 { 01802 diagnostics("Error in sqSetFeedOverride\n"); 01803 return -1; 01804 } 01805 else 01806 return 0; 01807 } 01808 else 01809 { 01810 /* else: don't do anything else*/ 01811 sq->feedOverrideFactor=fo; 01812 return 0; 01813 } 01814 } 01815 01816 sq->feedOverrideFactor=fo; 01817 if ( as->active==0 ) 01818 { 01819 /* the previous segment has just been finished. as still needs to 01820 be planned. So: don't do anything */ 01821 } 01822 01823 else if ( sq->n < as->m + 2 || sq->feedAdjusting==1 ) 01824 { 01825 /* we are accelerating to (macInc * 'previous fo'). We need to adjust 01826 this phase in order get to the desired cruising feed */ 01827 01828 if ( sq->feedAdjusting!=1 && as->p==0 && as->maxInc*fo > as->cruiseInc ) 01829 /* the the segment is too short to reach the current maxInc and it 01830 will be too short too to reach the new feed */ 01831 return 0; 01832 01833 if (sq->feedAdjusting==1) 01834 { 01835 /* copy the phase 3 params to the phase 1 params, since these will 01836 be used to find estimates for the current velocity and 01837 acceleration */ 01838 as->a1=as->a3; 01839 as->b1=as->b3; 01840 as->c1=as->c3; 01841 as->d1=as->d3; 01842 } 01843 01844 finalInc=as->maxInc*fo; 01845 01846 /* recalculate the last two dist values to find startInc and to use 01847 for making an estimation of startAcc */ 01848 if (sq->n==1 || sq->n==2 || sq->n==3) 01849 { 01850 startInc=as->plInitInc; 01851 startAcc=0; 01852 } 01853 else if ( sq->n==3) 01854 { 01855 npow1 = 1; 01856 npow2 = 1; 01857 npow3 = 1; 01858 startInc = as->a1 * npow3 *sq->ctPow3 \ 01859 + as->b1 * npow2 * sq->ctPow2 \ 01860 + as->c1 * npow1 * sq->cycleTime \ 01861 + as->d1; 01862 startAcc = (startInc - as->plInitInc ); 01863 } 01864 else 01865 { 01866 npow1 = sq->n - 3; /* sq->n-2-1 */ 01867 npow2 = npow1 * npow1; 01868 npow3 = npow2 * npow1; 01869 startInc = as->a1 * npow3 *sq->ctPow3 \ 01870 + as->b1 * npow2 * sq->ctPow2 \ 01871 + as->c1 * npow1 * sq->cycleTime \ 01872 + as->d1; 01873 npow1 = sq->n - 4; /* sq->n-2-2 */ 01874 npow2 = npow1 * npow1; 01875 npow3 = npow2 * npow1; 01876 prevInc = (as->a1 * npow3 *sq->ctPow3 \ 01877 + as->b1 * npow2 * sq->ctPow2 \ 01878 + as->c1 * npow1 * sq->cycleTime \ 01879 + as->d1); 01880 startAcc = startInc - prevInc; 01881 } 01882 as->q= ceil ( 1.7393877* fabs(startInc-finalInc) / \ 01883 ( sq->maxAcc * sq->ctPow2 ) + 01884 0.5967755904 * fabs(startInc-finalInc) / \ 01885 ( sq->maxAcc * sq->maxAcc * sq->ctPow2 * sq->ctPow2) *\ 01886 startAcc-(sq->maxAcc * sq->ctPow2)/2); 01887 as->m=0; 01888 as->p=0; 01889 as->totNumPoints = as->q + 1; 01890 sq->n=3; /* start all over, but skip the first initInc steps */ 01891 01892 as->b3 = - ( 3 * (startInc-finalInc) + 2 * as->q* startAcc ) \ 01893 / ( as->q * as->q * sq->ctPow2 ) ; 01894 as->a3 = ( 2 * (startInc-finalInc) + as->q* startAcc ) \ 01895 / ( as->q * as->q * as->q * sq->ctPow3 ) ; 01896 as->c3 = startAcc/sq->cycleTime; 01897 as->d3 = startInc; 01898 01899 as->plFinalInc=finalInc; 01900 /* when the desired feed is reached, some things off this segment 01901 will have to be recalculated, which is done by runCycle. By setting 01902 this flag, runCycle will know that it needs to do this 01903 */ 01904 sq->feedAdjusting=1; 01905 01906 } 01907 else if ( sq->n < as->m + as->p + 2 ) 01908 { 01909 01910 /* change the active segment such that it looks like we are starting 01911 with a new segment */ 01912 01913 startInc=as->cruiseInc; 01914 01915 /* delete all previous segments */ 01916 cursor=as; 01917 while ( cursor!=sq->cursor ) 01918 { 01919 cursor=cursor->nextSegment; 01920 if (cursor == 0 ) 01921 { 01922 diagnostics("Panic 1: cursor = NULL in sqSetFeedOverride\n"); 01923 return -1; 01924 } 01925 sq->numSegments--; 01926 } 01927 if ( sq->numSegments < sq->size - SQ_SAFETY_MARGIN ) 01928 sq->full = 0; 01929 if ( sq->numSegments < 0 ) 01930 { 01931 diagnostics("Panic: sq->numSegments <0 in sqSetFeedOverride\n"); 01932 return -1; 01933 } 01934 01935 01936 cursor->prevSegment=0; 01937 cursor->linkedToPrevSeg=0; 01938 sq->start= sq->cursor - sq->queue; 01939 as=cursor; 01940 01941 as->planningDone=0; 01942 as->plInitInc=startInc; 01943 as->start=sq->lastPoint; 01944 if ( as->type == SQ_LINEAR) 01945 { 01946 as->length=sqGiveLength(as->start,as->end); 01947 as->totLength=as->length; 01948 pmLineInit(&as->line,as->start,as->end); 01949 } 01950 else 01951 { 01952 angleToGo= as->circle.angle-(sq->dist-sq->offset)/as->helixRadius; 01953 turn = floor(angleToGo / ( 2 * PM_PI )); 01954 normal = as->circle.normal; 01955 center = as->circle.center; 01956 pmCircleInit( &as->circle, as->start, as->end, center, normal, turn); 01957 as->length=as->circle.angle* as->helixRadius; 01958 as->totLength= as->length; 01959 } 01960 01961 01962 as->active=0; /* mark the first segment of the chain 01963 as not active */ 01964 01965 /* determine how many segments are linked to as */ 01966 as->numLinkedSegs=0; 01967 while (cursor->nextSegment!=0 && 01968 cursor->nextSegment->linkedToPrevSeg==1 ) 01969 { 01970 cursor=cursor->nextSegment; 01971 as->numLinkedSegs++; 01972 as->totLength+=cursor->length; 01973 } 01974 01975 /* keep linking successive segments to as until the chain is 01976 long enough */ 01977 if ( -1 == sqForwardLinkSegment(sq,as,sq->feedOverrideFactor)) 01978 { 01979 diagnostics("Error in sqSetFeedOverride\n"); 01980 return -1; 01981 } 01982 } 01983 else 01984 { 01985 /* we are already decelerating, which is in most cases 01986 necessary. Therefore, let's not interrupt this and finish 01987 the current segment first. The new segment will be planned 01988 with the new feedOverrideFactor.*/ 01989 } 01990 01991 return 0; 01992 } |
|
Definition at line 1051 of file segmentqueue.c. 01052 { 01053 if (sq==0 || amax <=0 ) 01054 { 01055 diagnostics("Error in SetMaxAcc!!!\n"); 01056 return -1; 01057 } 01058 sq->maxAcc=amax/2; 01059 return 0; 01060 }; |
|
Definition at line 1086 of file segmentqueue.c. 01087 { 01088 if (sq==0 || mfo<=0 ) 01089 { 01090 diagnostics("Error in sqSetMaxFeedOverride()\n"); 01091 return -1; 01092 } 01093 sq->maxFeedOverrideFactor = mfo; 01094 return 0; 01095 } |
|
Definition at line 1098 of file segmentqueue.c. |
|
Definition at line 1062 of file segmentqueue.c. 01063 { 01064 if (sq==0 || vmax <= 0 ) 01065 { 01066 diagnostics("Error in SetVmax!!!\n"); 01067 return -1; 01068 } 01069 sq->maxV=vmax; 01070 return 0; 01071 }; |
|
Definition at line 2246 of file segmentqueue.c. 02247 { 02248 SEGMENT *as; /* as = Active Segment */ 02249 if (sq==0) 02250 { 02251 diagnostics("Error in sqStep\n"); 02252 return -1; 02253 } 02254 02255 if (sq->done!=1 || sq->numSegments==0 ) 02256 /* step should only be used when system is paused and waiting... */ 02257 { 02258 diagnostics("Stepping can only be done when system is paused and waiting\n"); 02259 /* not a critical error, let's ignore it */ 02260 return 0;; 02261 } 02262 02263 if ( sq->feedOverrideFactor == 0 ) 02264 { 02265 /* we can't step if the feed override factor is zero. To step 02266 the user should set a new non-zero value for this factor first. 02267 This will immediately result in a resume action. */ 02268 diagnostics("Can't resume if feed override is zero\n"); 02269 /* not a critical error, so ignore it */ 02270 return 0; 02271 } 02272 02273 02274 /* make finalInc of the current segment 0, set sq->stepping and resume. 02275 This means that after this is segment is done, it will 02276 wait for the next step or resume command */ 02277 02278 as=sq->queue+sq->start; 02279 as->finalInc=0; 02280 02281 /* if the next segment is linked to the current one, unlink it */ 02282 if (as->nextSegment!=0 && as->nextSegment->linkedToPrevSeg==1) 02283 { 02284 as->nextSegment->linkedToPrevSeg=0; 02285 as->nextSegment->numLinkedSegs=as->numLinkedSegs-1; 02286 as->nextSegment->totLength=as->totLength - as->length; 02287 as->numLinkedSegs=0; 02288 as->totLength=as->length; 02289 } 02290 sq->done=0; 02291 sq->stepping=1; 02292 sq->paused=0; 02293 return 0; 02294 } |
|
Definition at line 1140 of file segmentqueue.c. 01141 { 01142 if ( sq == 0 || sq->queue == 0 ) 01143 { 01144 diagnostics("Error in sqTrashQueue()\n"); 01145 return -1; 01146 } 01147 sqClearQueue(sq); 01148 sq->queue=0; 01149 return 0; 01150 }; |
|
Definition at line 134 of file segmentqueue.c. |
|
Definition at line 134 of file segmentqueue.c. |
|
Definition at line 135 of file segmentqueue.c. |
|
Definition at line 134 of file segmentqueue.c. |
|
Definition at line 134 of file segmentqueue.c. |