00001
00011 #include <exception>
00012 #include <typeinfo>
00013 #include <iterator>
00014 #include "trgen.h"
00015
00016
00017
00018 #ifdef DEBUG
00019 #ifdef MATLAB_MEX_FILE
00020 #define dbgPrintf(format, ...) ssPrintf(format, ##__VA_ARGS__)
00021 #else
00022 #define dbgPrintf(format, ...) printf(format, ##__VA_ARGS__)
00023 #endif
00024 #else
00025 #define dbgPrintf(format, ...)
00026 #endif
00027
00028 #ifdef MATLAB_MEX_FILE
00029 #define S_FUNCTION_LEVEL 2
00030 #define S_FUNCTION_NAME sf_trgen
00031 #include "simstruc.h"
00032 #endif
00033
00034 namespace Segment {
00035
00039 class Line : public TrajectorySegment
00040 {
00041 Point *p1, *p2;
00042 double angle;
00043 double length;
00044 double cosphi, sinphi;
00045 public:
00046 Line(Point *_p1, Point *_p2) : p1(_p1), p2(_p2) {
00047 length = p1->distanceTo(*p2);
00048 angle = p1->angleTo(*p2);
00049 sinphi = (p2->y-p1->y)/length;
00050 cosphi = (p2->x-p1->x)/length;
00051 }
00052 virtual ~Line() {};
00053
00054 virtual void setMaxV(const TrajectoryConstraints &constr) {
00055 maxv = constr.maxv;
00056 }
00057
00058 virtual double getLength() const {return length;}
00059 double getAngle() {return angle;}
00060
00061 virtual void getPointAt(double distance, Point *p) {
00062 double ratio;
00063 if (distance > 0) {
00064 ratio = distance/length;
00065 } else {
00066 ratio = (length+distance)/length;
00067 }
00068 p->x = p1->x + ratio*(p2->x - p1->x);
00069 p->y = p1->y + ratio*(p2->y - p1->y);
00070 }
00071
00072 virtual void shortenBy(double distance, Point *newEnd) {
00073 getPointAt(-distance, newEnd);
00074 if (distance > 0) {
00075 p2 = newEnd;
00076 } else {
00077 distance = -distance;
00078 p1 = newEnd;
00079 }
00080 length -= distance;
00081 }
00082
00083 virtual TrajectorySegment* splitAt(double distance, Point *newEnd) {
00084 if (distance <= 0 || distance >= length) {
00085 dbgPrintf("splitAt: distance=%g length=%g\n", distance, length);
00086 return NULL;
00087 }
00088
00089 getPointAt(distance, newEnd);
00090 Line *ns = new Line(*this);
00091 p2 = newEnd;
00092 length = distance;
00093 ns->length -= distance;
00094 ns->p1 = newEnd;
00095 return ns;
00096 }
00097
00098 virtual void getRefPos(double time, Pos &rp) {
00099 double t = time-t1;
00100 double fraction = t/(t2-t1);
00101 double distance = (v1 + 0.5*acc*t) * t;
00102 rp.x = p1->x + distance*cosphi;
00103 rp.y = p1->y + distance*sinphi;
00104 rp.phi = angle;
00105
00106 rp.v = v1+fraction*(v2-v1);
00107 rp.omega = 0;
00108
00109 }
00110 #ifdef MATLAB_MEX_FILE
00111 virtual void plot(const char *style) {
00112 char cmd[300];
00113 sprintf(cmd, "plot([%g %g], [%g %g], '%so')",
00114 p1->x, p2->x, p1->y, p2->y, style);
00115 mexEvalString(cmd);
00116 };
00117 #endif
00118 };
00119
00124 class Arc : public TrajectorySegment
00125 {
00126 Point *p1, *p2;
00127 double angle;
00128 double startAngle;
00129 double radius;
00130 double length;
00131 Point center;
00132 public:
00133 Arc(Point *_p1, Point *_p2, double _radius) :
00134 p1(_p1), p2(_p2), radius(fabs(_radius)) {
00135
00136
00137 double angp1p2 = p1->angleTo(*p2);
00138 double m = p1->distanceTo(*p2)/2.0;
00139 if (radius < m) {
00140 radius = m;
00141 dbgPrintf("EEEERRRRRRRRROOOOOOOOORRRRRRRRR!!!!!!!!!!\n");
00142 }
00143 double angcen = acos(m/radius);
00144 if (_radius < 0) angcen = -angcen;
00145 center = Point(p1->x + radius * cos(angp1p2+angcen),
00146 p1->y + radius * sin(angp1p2+angcen));
00147
00148 startAngle = center.angleTo(*p1);
00149 angle = center.angleTo(*p2) - startAngle;
00150 if (angle < -M_PI) angle += 2.0*M_PI;
00151 if (angle > +M_PI) angle -= 2.0*M_PI;
00152
00153 length = fabs(angle*radius);
00154 }
00155 virtual ~Arc() {};
00156
00157
00158 virtual void setMaxV(const TrajectoryConstraints &constr) {
00159 double r = radius;
00160 maxv = fmin(constr.maxv, constr.maxomega * r);
00161 maxv = fmin(maxv, sqrt(constr.maxcenacc * r));
00162 }
00163
00164 virtual double getLength() const {return length;}
00165
00166 virtual void getPointAt(double distance, Point *p) {
00167 double ratio, a;
00168 if (distance > 0) {
00169 ratio = distance/length;
00170 } else {
00171 distance = -distance;
00172 ratio = (length-distance)/length;
00173 }
00174 a = startAngle + ratio*angle;
00175 p->x = center.x + radius*cos(a);
00176 p->y = center.y + radius*sin(a);
00177 }
00178 virtual void shortenBy(double distance, Point *newEnd) {
00179 getPointAt(-distance, newEnd);
00180 if (distance > 0) {
00181 angle *= (length-distance)/length;
00182 p2 = newEnd;
00183 } else {
00184 distance = -distance;
00185 startAngle = startAngle + distance/length*angle;
00186 angle *= (length-distance)/length;
00187 p1 = newEnd;
00188 }
00189 length -= distance;
00190 }
00191
00192 virtual TrajectorySegment* splitAt(double distance, Point *newEnd) {
00193 if (distance <= 0 || distance >= length)
00194 return NULL;
00195
00196 getPointAt(distance, newEnd);
00197 Arc *ns = new Arc(*this);
00198
00199 double a = distance/length*angle;
00200 angle = a;
00201 length = distance;
00202 p2 = newEnd;
00203
00204 ns->startAngle += a;
00205 ns->angle -= a;
00206 ns->length -= distance;
00207 ns->p1 = newEnd;
00208 return ns;
00209 }
00210
00211 virtual void getRefPos(double time, Pos &rp) {
00212 double t = time-t1;
00213 double fraction = t/(t2-t1);
00214 double distance = (v1 + 0.5*acc*t) * t;
00215 double a = startAngle + distance/length*angle;
00216 rp.x = center.x + radius*cos(a);
00217 rp.y = center.y + radius*sin(a);
00218 if (angle > 0)
00219 rp.phi = a + M_PI/2.0;
00220 else
00221 rp.phi = a - M_PI/2.0;
00222
00223 rp.v = v1+fraction*(v2-v1);
00224 rp.omega =rp.v/radius;
00225 if (angle < 0) rp.omega = -rp.omega;
00226
00227 }
00228 #ifdef MATLAB_MEX_FILE
00229 virtual void plot(const char *style) {
00230 char cmd[300];
00231 const int len = 10;
00232 int i;
00233 Pos rp;
00234 mxArray *x = mxCreateDoubleMatrix(1, len, mxREAL);
00235 mxArray *y = mxCreateDoubleMatrix(1, len, mxREAL);
00236 mxArray *s = mxCreateCharMatrixFromStrings(1, &style);
00237 mxArray *rhs[] = {x,y,s};
00238
00239 for (i=0; i < len; i++) {
00240 getRefPos(t1+(t2-t1)*i/(len-1), rp);
00241 mxGetPr(x)[i] = rp.x;
00242 mxGetPr(y)[i] = rp.y;
00243 }
00244 mexCallMATLAB(0, NULL, 3, rhs, "plot");
00245 sprintf(cmd, "plot([%g %g], [%g %g], 'mo')",
00246 p1->x, p2->x, p1->y, p2->y);
00247 mexEvalString(cmd);
00248 mxDestroyArray(x);
00249 mxDestroyArray(y);
00250 mxDestroyArray(s);
00251 };
00252 #endif
00253 };
00254
00262 class Turn : public TrajectorySegment
00263 {
00264 Point *center;
00265 double turnBy;
00266 double startHeading;
00267 public:
00268 Turn(Point *_center, double _startHeading, double _turnBy) :
00269 center(_center), turnBy(_turnBy), startHeading(_startHeading) {}
00270 virtual ~Turn() {};
00271
00272
00273 virtual void setMaxV(const TrajectoryConstraints &constr) {
00274 maxv = constr.maxomega;
00275 }
00276
00277 virtual double getMaxAcc(const TrajectoryConstraints &constr) const {
00278 return constr.maxangacc;
00279 }
00280
00281 virtual bool isTurn() const { return true; };
00282
00283 virtual double getLength() const {return 0;}
00284 virtual double getUnifiedLength() const {
00285 return fabs(turnBy);
00286 }
00287
00288 virtual void getPointAt(double distance, Point *p) {
00289 *p = *center;
00290 }
00291 virtual void shortenBy(double distance, Point *newEnd) {}
00292
00293 virtual TrajectorySegment* splitAt(double distance, Point *newEnd) {
00294 if (distance <= 0 || distance >= fabs(turnBy)) {
00295 dbgPrintf("splitAt: distance=%g turnBy=%g\n", distance, turnBy);
00296 return NULL;
00297 }
00298
00299 Turn *ns = new Turn(*this);
00300 if (turnBy < 0)
00301 distance = -distance;
00302 turnBy = distance;
00303 ns->startHeading+=distance;
00304 ns->turnBy -= distance;
00305 return ns;
00306 }
00307
00308 virtual void getRefPos(double time, Pos &rp) {
00309 double t = time-t1;
00310 double fraction = t/(t2-t1);
00311 double distance = (v1 + 0.5*acc*t) * t;
00312 rp.x = center->x;
00313 rp.y = center->y;
00314 if (turnBy > 0)
00315 rp.phi = startHeading + distance;
00316 else
00317 rp.phi = startHeading - distance;
00318 rp.v=0;
00319 if (time < t2)
00320 rp.omega = v1+fraction*(v2-v1);
00321 else
00322 rp.omega = 0;
00323 }
00324
00325 #ifdef MATLAB_MEX_FILE
00326 virtual void plot(const char *style) {};
00327 #endif
00328 };
00329
00330 }
00331
00332
00333 using namespace Segment;
00334
00344 bool
00345 Trajectory::splitSegment(iterator &seg, double distance)
00346 {
00347 TrajectorySegment *ns;
00348 Point *np = NULL;
00349 if (typeid(**seg) != typeid(Turn))
00350 np = new Point;
00351
00352 ns = (*seg)->splitAt(distance, np);
00353 if (ns == NULL) {
00354 dbgPrintf("ERROR\n");
00355 delete(np);
00356 return false;
00357 }
00358 if (np)
00359 wayPoints.push_back(np);
00360 seg = insert(++seg, ns);
00361 return true;
00362 }
00363
00364
00365
00366
00367
00371 bool
00372 Trajectory::points2segments()
00373 {
00374 TrajectoryPoints::iterator p1, p2;
00375 Point ip(initPos.x, initPos.y);
00376
00377 if (*wayPoints.front() != ip) {
00378 initialPoint = new Point(ip);
00379 wayPoints.push_front(initialPoint);
00380 } else
00381 initialPoint = wayPoints.front();
00382
00383
00384 deleteSegments();
00385
00386 if (wayPoints.size() < 2) {
00387 return false;
00388 }
00389 for (p1 = wayPoints.begin(), p2 = ++wayPoints.begin();
00390 p2 != wayPoints.end();
00391 p1++, p2++) {
00392 push_back(new Line(*p1, *p2));
00393 }
00394 return true;
00395 }
00396
00397
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 void
00417 Trajectory::corners2arcs()
00418 {
00419 iterator seg, segNext, segPrev;
00420
00421 if (size() < 2) return;
00422
00423
00424 for (segPrev = begin(), segNext = ++begin();
00425 segNext != end();
00426 segPrev++, segNext++) {
00427
00428 double alpha;
00429 double r;
00430 double s;
00431 try {
00432 alpha = dynamic_cast<Line*>(*segNext)->getAngle() -
00433 dynamic_cast<Line*>(*segPrev)->getAngle();
00434 if (alpha > +M_PI) alpha -= 2.0*M_PI;
00435 if (alpha < -M_PI) alpha += 2.0*M_PI;
00436
00437 if (fabs(alpha) < M_PI/180.0) continue;
00438
00439 r = constr.maxe / (1/cos(alpha/2.0) - 1);
00440 if (alpha < 0) r = -r;
00441 s = r*tan(alpha/2.0);
00442 if (s > (*segPrev)->getLength()) {
00443 s = (*segPrev)->getLength();
00444 r = s/tan(alpha/2.0);
00445 }
00446 if (s > (*segNext)->getLength()) {
00447 s = (*segNext)->getLength();
00448 r = s/tan(alpha/2.0);
00449 }
00450 (*segPrev)->r = r;
00451 (*segPrev)->s = s;
00452 (*segPrev)->alphahalf = alpha/2.0;
00453 }
00454 catch (std::exception& e) {}
00455 }
00456
00457 if (size() >= 3) {
00458
00459 double s1, s2, r1, r2, l, alphahalf1, alphahalf2;
00460 bool wantSameR;
00461 for (segPrev = begin(), segNext = ++begin();
00462 segNext != --end();
00463 segPrev++, segNext++) {
00464 l = (*segNext)->getLength();
00465 s1 = (*segPrev)->s;
00466 s2 = (*segNext)->s;
00467 r1 = (*segPrev)->r;
00468 r2 = (*segNext)->r;
00469 alphahalf1 = (*segPrev)->alphahalf;
00470 alphahalf2 = (*segNext)->alphahalf;
00471 if (s1 + s2 > l) {
00472 if (fabs(r1) > fabs(r2)) {
00473 s1 = l - s2;
00474 r1 = s1/tan(alphahalf1);
00475 wantSameR = (fabs(r1) < fabs(r2));
00476 } else {
00477 s2 = l - s1;
00478 r2 = s2/tan(alphahalf2);
00479 wantSameR = (fabs(r1) > fabs(r2));
00480 }
00481 if (wantSameR) {
00482 if (alphahalf1 < 0 ^ alphahalf2 < 0)
00483 s1 = l*tan(alphahalf1)/(tan(alphahalf1)-tan(alphahalf2));
00484 else
00485 s1 = l*tan(alphahalf1)/(tan(alphahalf1)+tan(alphahalf2));
00486 s2 = l - s1;
00487 r1 = s1/tan(alphahalf1);
00488 r2 = s2/tan(alphahalf2);
00489 }
00490 (*segPrev)->s = s1;
00491 (*segNext)->s = s2;
00492 (*segPrev)->r = r1;
00493 (*segNext)->r = r2;
00494 }
00495 }
00496 }
00497
00498
00499 for (segPrev = begin(), segNext = ++begin();
00500 segNext != end();
00501 ++segPrev, ++segNext) {
00502 if (fabs((*segPrev)->r) > 0) {
00503 Point *newEnd1, *newEnd2;
00504 double s = (*segPrev)->s;
00505 newEnd1 = new Point();
00506 newEnd2 = new Point();
00507 (*segPrev)->shortenBy(+s, newEnd1);
00508 (*segNext)->shortenBy(-s, newEnd2);
00509 wayPoints.push_back(newEnd1);
00510 wayPoints.push_back(newEnd2);
00511 segPrev = insert(segNext, new Arc(newEnd1, newEnd2,
00512 (*segPrev)->r));
00513 }
00514 }
00515
00516
00517 seg = begin();
00518 while (seg != end()) {
00519 if ((*seg)->getLength() <= 1e-9) {
00520 delete(*seg);
00521 seg = erase(seg);
00522 } else
00523 seg++;
00524 }
00525 }
00526
00527
00562 void
00563 Trajectory::calcSpeeds()
00564 {
00565 if (size() == 0) return;
00566
00567
00568 for (iterator seg = begin(); seg != end(); seg++) {
00569 (*seg)->setMaxV(constr);
00570 (*seg)->v1 = (*seg)->maxv;
00571 (*seg)->v2 = (*seg)->maxv;
00572 }
00573 #ifdef MATLAB_MEX_FILE
00574 plotSpeed("r-o");
00575 #endif
00576
00577 double lastv;
00578 bool turning = false;
00579
00580
00581 lastv = initPos.v;
00582 for (iterator seg = begin(); seg != end(); seg++) {
00583 if (turning != (*seg)->isTurn()) {
00584 turning = (*seg)->isTurn();
00585 lastv = 0;
00586 }
00587 double v1 = (*seg)->v1;
00588 double v2 = (*seg)->v2;
00589 double maxv = (*seg)->maxv;
00590
00591 if (v1 > lastv) {
00592 v1 = lastv;
00593 double l = (*seg)->getUnifiedLength();
00594 double a = (*seg)->getMaxAcc(constr);
00595 double t;
00596
00597 t = (-v1+sqrt(v1*v1 + 2.0*a*l))/a;
00598 v2 = v1+a*t;
00599
00600
00601 if (v2 > maxv) {
00602 v2 = maxv;
00603 t = (v2 - v1)/a;
00604 l = v1*t+0.5*a*t*t;
00605
00606 iterator ns = seg;
00607 if (splitSegment(ns, l)) {
00608 (*ns)->v1 = v2;
00609 }
00610 }
00611
00612 (*seg)->v1 = v1;
00613 (*seg)->v2 = v2;
00614 }
00615 lastv = (*seg)->v2;
00616 }
00617 #ifdef MATLAB_MEX_FILE
00618 plotSpeed("g-o");
00619 #endif
00620
00621
00622 turning = false;
00623 lastv = 0;
00624 for (reverse_iterator seg = rbegin(); seg != rend(); seg++) {
00625 if (turning != (*seg)->isTurn()) {
00626 turning = (*seg)->isTurn();
00627 lastv = 0;
00628 }
00629 double v1 = (*seg)->v1;
00630 double v2 = (*seg)->v2;
00631 double maxv = (*seg)->maxv;
00632 dbgPrintf("processing: %p v2=%g\n", *seg, v2);
00633 if (v2 > lastv) {
00634 v2 = lastv;
00635 double l = (*seg)->getUnifiedLength();
00636 double a = (*seg)->getMaxAcc(constr);
00637 double t;
00638
00639 t = (-v2+sqrt(v2*v2 + 2.0*a*l))/a;
00640 v1 = v2+a*t;
00641
00642
00643 if (v1 > maxv && (*seg)->v1 == maxv) {
00644 v1 = maxv;
00645 t = (v1 - v2)/a;
00646 double l2 = v2*t+0.5*a*t*t;
00647
00648 iterator ns = --(seg.base());
00649
00650 if (splitSegment(ns, l-l2)) {
00651
00652 (*ns)->v2 = v1;
00653 (*seg)->v1 = v1;
00654 }
00655 } else if (v1 > (*seg)->v1) {
00656
00657
00658 v1 = (*seg)->v1;
00659 double s1 = l/2.0 + (v2*v2 - v1*v1)/4.0*a;
00660
00661 if (s1 > l/1000 && s1 < l - l/1000) {
00662
00663 iterator ns = --(seg.base());
00664
00665 if (splitSegment(ns, s1)) {
00666 ++seg;
00667
00668 v1 = sqrt(v1*v1 + 2.0*a*s1);
00669 (*ns)->v1 = v1;
00670 (*ns)->v2 = v2;
00671 v2 = v1;
00672 v1 = (*seg)->v1;
00673 }
00674 }
00675 } else {
00676 (*seg)->v1 = v1;
00677 }
00678 (*seg)->v2 = v2;
00679 }
00680 lastv = (*seg)->v1;
00681 }
00682 #ifdef MATLAB_MEX_FILE
00683 plotSpeed("b-o");
00684 #endif
00685 for (iterator seg = begin(); seg != end(); ++seg) {
00686 dbgPrintf("final: %-16s %p v1=%-8.2g v2=%-8.2g l=%-8.2g\n",
00687 typeid(**seg).name(),
00688 *seg, (*seg)->v1, (*seg)->v2, (*seg)->getLength());
00689 }
00690 }
00691
00692
00693 double
00694 Trajectory::calcLength()
00695 {
00696 double totLen = 0;
00697 for (iterator seg = begin(); seg != end(); ++seg) {
00698 totLen += (*seg)->getLength();
00699 }
00700 return totLen;
00701 }
00702
00703 static double minimizeAngle(double rad)
00704 {
00705 rad = fmod(rad, 2.0*M_PI);
00706 if (rad > +M_PI/2.0) rad -= 2.0*M_PI;
00707 if (rad < -M_PI/2.0) rad += 2.0*M_PI;
00708 return rad;
00709 }
00710
00711 void Trajectory::addTurns()
00712 {
00713 Pos p;
00714 TrajectorySegment *seg;
00715 double initialHeading = initPos.phi;
00716 double turnBy;
00717 if (backward)
00718 initialHeading -= M_PI;
00719
00720 if (size() == 0) {
00721
00722 dbgPrintf("*** Adding only the turn - start: %5.2f, end %5.2f\n", initialHeading/M_PI*180, finalHeading/M_PI*180);
00723 turnBy = minimizeAngle(finalHeading - initialHeading);
00724 if (fabs(turnBy) > 1e-3) {
00725 push_front(new Turn(initialPoint, initialHeading,
00726 finalHeading - initialHeading));
00727 }
00728 } else {
00729
00730 seg = *begin();
00731 seg->v1 = 1;
00732 seg->v2 = 1;
00733 seg->startAt(0);
00734
00735 seg->getRefPos(0, p);
00736 dbgPrintf("*** Adding initial turn - start: %5.2f, end %5.2f\n", initialHeading/M_PI*180, p.phi/M_PI*180);
00737 turnBy = minimizeAngle(p.phi - initialHeading);
00738 if (fabs(turnBy) > 1e-3) {
00739 push_front(new Turn(initialPoint, initialHeading, turnBy));
00740 }
00741
00742
00743 seg = *(--end());
00744 seg->v1 = 1;
00745 seg->v2 = 1;
00746 seg->startAt(0);
00747 seg->getRefPos(seg->getT2(), p);
00748 turnBy = minimizeAngle(p.phi - finalHeading);
00749 if (fabs(turnBy) > 1e-3) {
00750 dbgPrintf("*** Adding final turn - start: %5.2f, end %5.2f\n", p.phi/M_PI*180, finalHeading/M_PI*180);
00751 push_back(new Turn(finalPoint, p.phi, turnBy));
00752 }
00753 }
00754 }
00755
00770 bool
00771 Trajectory::prepare(Pos _initPos)
00772 {
00773 if (constr.maxv <= 0 || constr.maxv > 10 ||
00774 constr.maxomega <= 0 || constr.maxomega > 10 ||
00775 constr.maxangacc <= 0 || constr.maxangacc > 10 ||
00776 constr.maxacc <= 0 || constr.maxacc > 10 ||
00777 constr.maxcenacc <= 0 || constr.maxcenacc > 10 ||
00778 constr.maxe <= 0 || constr.maxe > 10) {
00779 dbgPrintf("wrong constraints!!!!\n");
00780 }
00781
00782 if (wayPoints.size() == 0) {
00783 dbgPrintf("No point in trajectory!\n");
00784 return false;
00785 }
00786
00787 initPos = _initPos;
00788 if (points2segments() == false) {
00789 dbgPrintf("points2segments error!\n");
00790 return false;
00791 }
00792 corners2arcs();
00793 addTurns();
00794 if (size() == 0)
00795 return false;
00796 calcSpeeds();
00797
00798
00799 double t=0;
00800 for (iterator seg = begin(); seg != end(); ++seg) {
00801 t = (*seg)->startAt(t);
00802 }
00803 currentSeg = begin();
00804 prepared = true;
00805 return true;
00806 }
00807
00816 bool
00817 Trajectory::getRefPos(double time, Pos &rp)
00818 {
00819 int d;
00820 bool ret = false;
00821 TrajectorySegment *seg;
00822
00823 if (!prepared) {
00824 ret = true;
00825 } else {
00826 do {
00827 d=(*currentSeg)->containsTime(time);
00828 if (d==0) break;
00829 if (currentSeg == --end() && d > 0) break;
00830 if (currentSeg == begin() && d < 0) break;
00831 if (d>0) ++currentSeg;
00832 else if (d<0) --currentSeg;
00833 } while (1);
00834
00835 seg = *currentSeg;
00836 if (d==0)
00837 getSegRefPos(seg, time, rp);
00838 else if (d<0)
00839 getSegRefPos(seg, seg->getT1(), rp);
00840 else {
00841 getSegRefPos(seg, seg->getT2(), rp);
00842 ret = true;
00843 }
00844 }
00845
00846 return ret;
00847 }
00848
00857 void
00858 Trajectory::getSegRefPos(TrajectorySegment *seg, double time, Pos &rp)
00859 {
00860 seg->getRefPos(time, rp);
00861
00862 if (backward) {
00863 rp.phi += M_PI;
00864 rp.v = -rp.v;
00865 }
00866 }
00867
00868 #ifdef MATLAB_MEX_FILE
00869 void
00870 Trajectory::plot(const char *style)
00871 {
00872 for (iterator seg = begin(); seg != end(); ++seg) {
00873 (*seg)->plot(style);
00874 }
00875 };
00876 void
00877 Trajectory::plotSpeed(const char *style)
00878 {
00879 char *f2 = "figure(2);";
00880 char *f1 = "hold on; figure(1)";
00881 double t = 0;
00882 mexEvalString(f2);
00883 for (iterator seg = begin(); seg != end(); ++seg) {
00884 t = (*seg)->startAt(t);
00885 (*seg)->plotSpeed(style);
00886 }
00887 mexEvalString(f1);
00888 };
00889 #endif
00890