#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. |
1.2.11.1 written by Dimitri van Heesch,
© 1997-2001