00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027 #include "ArExport.h"
00028 #include "ariaOSDef.h"
00029 #include "ArActionTriangleDriveTo.h"
00030 #include "ArRobot.h"
00031
00032 ArActionTriangleDriveTo::ArActionTriangleDriveTo(
00033 const char *name, double finalDistFromVertex,
00034 double approachDistFromVertex, double speed,
00035 double closeDist, double acquireTurnSpeed) :
00036 ArAction(name, "Finds a triangle and drives in front of it")
00037 {
00038 setNextArgument(ArArg("final dist from vertex", &myFinalDistFromVertex,
00039 "Distance from vertex we want to be at (mm)"));
00040 myFinalDistFromVertex = finalDistFromVertex;
00041
00042 setNextArgument(ArArg("approach dist from vertex", &myApproachDistFromVertex,
00043 "Distance from vertex we'll go to before going to final (0 goes straight to final) (mm)"));
00044 myApproachDistFromVertex = approachDistFromVertex;
00045
00046 setNextArgument(ArArg("speed", &mySpeed, "speed to drive at (mm/sec)"));
00047 mySpeed = speed;
00048
00049 setNextArgument(ArArg("close dist", &myCloseDist,
00050 "how close we have to get to our final point (mm)"));
00051 myCloseDist = closeDist;
00052
00053 setNextArgument(ArArg("acquire turn speed", &myAcquireTurnSpeed,
00054 "if we are aqcquiring the rot vel to turn at (deg/sec)"));
00055 myAcquireTurnSpeed = acquireTurnSpeed;
00056
00057 myLaser = NULL;
00058 myLineFinder = NULL;
00059 myOwnLineFinder = false;
00060 myState = STATE_INACTIVE;
00061 mySaveData = false;
00062 myData = NULL;
00063 myVertexSeen = false;
00064
00065 setTriangleParams();
00066 setVertexUnseenStopMSecs();
00067 setAcquire();
00068
00069 myPrinting = false;
00070 myAdjustVertex = false;
00071 myGotoVertex = false;
00072 }
00073
00074 void ArActionTriangleDriveTo::setParameters(
00075 double finalDistFromVertex,
00076 double approachDistFromVertex, double speed,
00077 double closeDist, double acquireTurnSpeed)
00078 {
00079 myFinalDistFromVertex = finalDistFromVertex;
00080 myApproachDistFromVertex = approachDistFromVertex;
00081 mySpeed = speed;
00082 myCloseDist = closeDist;
00083 myAcquireTurnSpeed = acquireTurnSpeed;
00084 }
00085
00086 ArActionTriangleDriveTo::~ArActionTriangleDriveTo()
00087 {
00088 if (myOwnLineFinder)
00089 delete myLineFinder;
00090 }
00091
00092 void ArActionTriangleDriveTo::activate(void)
00093 {
00094 if (myPrinting)
00095 ArLog::log(ArLog::Normal, "ArActionTriangleDriveTo: Activating");
00096 ArAction::activate();
00097 myVertexSeen = false;
00098 myVertexSeenLast.setToNow();
00099 if (myLineFinder != NULL)
00100 myState = STATE_ACQUIRE;
00101 else
00102 myState = STATE_FAILED;
00103 }
00104
00105 void ArActionTriangleDriveTo::deactivate(void)
00106 {
00107 ArAction::deactivate();
00108 myState = STATE_INACTIVE;
00109 }
00110
00111 void ArActionTriangleDriveTo::setRobot(ArRobot *robot)
00112 {
00113 ArAction::setRobot(robot);
00114 if (myLineFinder == NULL && myRobot != NULL)
00115 {
00116 if ((myLaser = myRobot->findRangeDevice("laser")) != NULL)
00117 {
00118 myLineFinder = new ArLineFinder(myLaser);
00119 myOwnLineFinder = true;
00120 }
00121 }
00122 }
00123
00124 void ArActionTriangleDriveTo::setLineFinder(ArLineFinder *lineFinder)
00125 {
00126 if (myLineFinder != NULL && myOwnLineFinder)
00127 delete myLineFinder;
00128
00129 myLineFinder = lineFinder;
00130 myOwnLineFinder = false;
00131 }
00132
00133 ArPose ArActionTriangleDriveTo::findPoseFromVertex(
00134 double distFromVertex)
00135 {
00136 ArPose ret;
00137 ArPose vertex;
00138 vertex = myRobot->getEncoderTransform().doTransform(myVertex);
00139
00140 ret.setX((vertex.getX() + ArMath::cos(vertex.getTh()) * distFromVertex));
00141 ret.setY((vertex.getY() + ArMath::sin(vertex.getTh()) * distFromVertex));
00142 return ret;
00143 }
00144
00153 void ArActionTriangleDriveTo::findTriangle(bool initial,
00154 bool goStraight)
00155 {
00156 if (myGotLinesCounter != myRobot->getCounter())
00157 {
00158 ArTime now;
00159 now.setToNow();
00160 myLines = myLineFinder->getLines();
00161
00162 }
00163 myGotLinesCounter = myRobot->getCounter();
00164
00165
00166 int start;
00167 int len = myLines->size();
00168 FILE *corners = NULL;
00169
00170
00171
00172
00173
00174
00175 double line1Dist;
00176
00177 double line2Dist;
00178
00179 double distLine1ToLine2;
00180
00181 double angleBetween;
00182
00183 double angleDelta;
00185 double line1Delta;
00187 double line2Delta;
00188
00189 double lineScore;
00190
00191 ArPose vertex;
00192
00193 double goodLineScore = 0.0;
00194
00195 ArPose goodVertex;
00196 ArLineSegment vertexLine;
00197 ArPose adjustedVertex;
00198
00199 ArPose lastVertex;
00200
00201 lastVertex = myRobot->getEncoderTransform().doTransform(myVertex);
00202
00203 for (start = 0; start < len; start++)
00204 {
00205 if (start + 1 < len)
00206 {
00207 line1Dist = (*myLines)[start]->getEndPoint1().findDistanceTo(
00208 (*myLines)[start]->getEndPoint2());
00209 line2Dist = (*myLines)[start+1]->getEndPoint1().findDistanceTo(
00210 (*myLines)[start+1]->getEndPoint2());
00211 distLine1ToLine2 = (*myLines)[start]->getEndPoint2().findDistanceTo(
00212 (*myLines)[start+1]->getEndPoint1());
00213 angleBetween = ArMath::subAngle(180,
00214 ArMath::subAngle((*myLines)[start]->getLineAngle(),
00215 (*myLines)[start+1]->getLineAngle()));
00216 angleDelta = ArMath::fabs(ArMath::subAngle(angleBetween, myAngleBetween));
00217 line1Delta = ArMath::fabs(line1Dist - myLine1Length);
00218 line2Delta = ArMath::fabs(line2Dist - myLine2Length);
00219 if (0)
00220 ArLog::log(ArLog::Normal, "dl1l2 %5.0f l1d %5.0f l2d %5.0f thdt %5.0f l1dt %5.0f l2dt %5.0f",
00221 distLine1ToLine2,
00222 line1Dist,
00223 line2Dist,
00224 angleDelta,
00225 line1Delta, line2Delta);
00226
00227 if (line1Delta > 125 || line2Delta > 125 ||
00228 angleDelta > 15 || distLine1ToLine2 > 100)
00229 continue;
00230
00231
00232 ArPose intersection;
00233
00234
00235 ArLine *line1Line = new ArLine(*(*myLines)[start]->getLine());
00236 ArLine *line2Line = new ArLine(*(*myLines)[start+1]->getLine());
00237 if (!line1Line->intersects(line2Line, &intersection))
00238 {
00239 ArLog::log(ArLog::Terse, "ArActionTriangeDriveTo: couldn't find intersection of lines (shouldn't happen)");
00240 return;
00241 }
00242 delete line1Line;
00243 delete line2Line;
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255 if (corners != NULL)
00256 fprintf(corners, "%.0f %.0f\n", intersection.getX(),
00257 intersection.getY());
00258
00259 vertex.setPose(intersection);
00260
00261
00262
00263
00264
00265
00266
00267 vertex.setTh(ArMath::addAngle((*myLines)[start]->getLineAngle(),
00268 angleBetween / 2));
00269
00270 vertexLine.newEndPoints(vertex.getX(), vertex.getY(),
00271 vertex.getX() + ArMath::cos(vertex.getTh()) * 10000,
00272 vertex.getY() + ArMath::sin(vertex.getTh()) * 10000);
00273
00274
00275 if (myAdjustVertex)
00276 {
00277 ArPose end1 = (*myLines)[start]->getEndPoint1();
00278 ArPose end2 = (*myLines)[start+1]->getEndPoint2();
00279 ArPose vertexLocal = vertex;
00280 end1 = myRobot->getToLocalTransform().doTransform(end1);
00281 end2 = myRobot->getToLocalTransform().doTransform(end2);
00282 vertexLocal = myRobot->getToLocalTransform().doTransform(vertexLocal);
00283
00284 ArPose closest;
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 myLaser->currentReadingBox(vertexLocal.getX() - 100, end1.getY(),
00298 ArUtil::findMax(end1.getX(), end2.getX()),
00299 end2.getY(),
00300 &closest);
00301 closest = myRobot->getToGlobalTransform().doTransform(closest);
00302
00303
00304
00305 adjustedVertex.setPose(
00306 closest.getX(), closest.getY(),
00307 ArMath::addAngle((*myLines)[start]->getLineAngle(),
00308 angleBetween / 2));
00309
00310 }
00311
00312
00313
00314
00315
00316 lineScore = 0;
00317 lineScore += 10 - 1 * (line1Delta / 25);
00318
00319 lineScore += 10 - 1 * (line2Delta / 25);
00320
00321 lineScore += 10 - 1 * (angleDelta / 2);
00322
00323
00324
00325
00326
00327 if (initial)
00328 {
00329 if (0)
00330 printf("%.0f (%.3f) %.0f\n",
00331 ArMath::subAngle(myRobot->getTh(),
00332 myRobot->getPose().findAngleTo(vertex)),
00333 90 - ArMath::fabs(myRobot->findDeltaHeadingTo(vertex)) / 90,
00334 vertexLine.getDistToLine(myRobot->getPose()));
00335
00336
00337
00338
00339
00340 lineScore *= .5 + .5 * (30 -
00341 ArMath::fabs(
00342 ArMath::subAngle(myRobot->getTh(),
00343 myRobot->getPose().findAngleTo(vertex)))) / 30;
00344
00345 lineScore *= .5 + .5 * (1500 -
00346 vertexLine.getDistToLine(myRobot->getPose())) / 1500;
00347
00348
00349
00350
00351 lineScore *= .5 + .5 * (30 - fabs(ArMath::subAngle(
00352 vertex.getTh(), vertex.findAngleTo(myRobot->getPose()))));
00353
00354
00355
00356 }
00357
00358
00359 else
00360 {
00361 double dist = lastVertex.findDistanceTo(vertex);
00362 if (dist < 100)
00363 lineScore *= 1;
00364 if (dist < 200)
00365 lineScore *= .8;
00366 else if (dist < 400)
00367 lineScore *= .5;
00368 else if (dist < 600)
00369 lineScore *= .2;
00370 else if (dist < 800)
00371 lineScore *= .1;
00372 else
00373 lineScore *= 0;
00374
00375 double angleFromLast = fabs(ArMath::subAngle(lastVertex.getTh(),
00376 vertex.getTh()));
00377
00378 if (angleFromLast < 5)
00379 lineScore *= 1;
00380 else if (angleFromLast < 10)
00381 lineScore *= .75;
00382 else if (angleFromLast < 20)
00383 lineScore *= .5;
00384 else if (angleFromLast < 30)
00385 lineScore *= .25;
00386 else
00387 lineScore *= 0;
00388
00389 if (goStraight)
00390 {
00391 double angle = fabs(myRobot->findDeltaHeadingTo(vertex));
00392 if (angle < 2)
00393 lineScore *= 1;
00394 else if (angle < 5)
00395 lineScore *= .5;
00396 else if (angle < 10)
00397 lineScore *= .1;
00398 else
00399 lineScore *= 0;
00400 }
00401 }
00402
00403
00404 if (lineScore < 5)
00405 {
00406 continue;
00407 }
00408
00409
00410 if (goodLineScore < 1 || lineScore > goodLineScore)
00411 {
00412 if (0)
00413 printf("#### %.0f %.0f %.0f at %.0f %.0f\n",
00414 vertex.getX(), vertex.getY(), vertex.getTh(),
00415 myRobot->getPose().findAngleTo(vertex),
00416 myRobot->getPose().findDistanceTo(vertex));
00417 goodLineScore = lineScore;
00418 if (myAdjustVertex)
00419 myVertex = myRobot->getEncoderTransform().doInvTransform(
00420 adjustedVertex);
00421 else
00422 myVertex = myRobot->getEncoderTransform().doInvTransform(vertex);
00423 myVertexSeen = true;
00424 myVertexSeenLast.setToNow();
00425 }
00426 continue;
00427
00428 }
00429 }
00430 if (corners != NULL)
00431 fclose(corners);
00432 myDataMutex.lock();
00433 if (mySaveData)
00434 {
00435 if (myData != NULL)
00436 myData->setLinesAndVertex(
00437 myLines, myRobot->getEncoderTransform().doTransform(myVertex));
00438 }
00439 myDataMutex.unlock();
00440 }
00441
00442 ArActionDesired *ArActionTriangleDriveTo::fire(
00443 ArActionDesired currentDesired)
00444 {
00445 myDesired.reset();
00446 double dist;
00447 double angle;
00448 double vel;
00449 ArPose approach;
00450 ArPose final;
00451 ArPose vertex;
00452
00453 myDataMutex.lock();
00454 if (myData != NULL)
00455 {
00456 delete myData;
00457 myData = NULL;
00458 }
00459 if (mySaveData)
00460 myData = new Data;
00461 myDataMutex.unlock();
00462
00463 vertex = myRobot->getEncoderTransform().doTransform(myVertex);
00464
00465 switch (myState)
00466 {
00467 case STATE_INACTIVE:
00468 return NULL;
00469 case STATE_SUCCEEDED:
00470 case STATE_FAILED:
00471 myDesired.setVel(0);
00472 myDesired.setRotVel(0);
00473 return &myDesired;
00474 case STATE_ACQUIRE:
00475 if (myPrinting)
00476 ArLog::log(ArLog::Normal, "Acquire");
00477 findTriangle(true);
00478 if (!myVertexSeen &&
00479 myVertexSeenLast.mSecSince() > myVertexUnseenStopMSecs)
00480 {
00481 if (myAcquire)
00482 {
00483 myState = STATE_SEARCHING;
00484 return fire(currentDesired);
00485 }
00486 else
00487 {
00488 if (myPrinting)
00489 ArLog::log(ArLog::Normal, "Failed");
00490 myState = STATE_FAILED;
00491 return fire(currentDesired);
00492 }
00493 }
00494 if (myVertexSeen)
00495 {
00496 approach = findPoseFromVertex(myApproachDistFromVertex);
00497 final = findPoseFromVertex(myFinalDistFromVertex);
00498 if (mySaveData)
00499 {
00500 myDataMutex.lock();
00501 if (myData != NULL)
00502 {
00503 myData->setApproach(approach);
00504 myData->setFinal(final);
00505 }
00506 myDataMutex.unlock();
00507 }
00508
00509
00510 if (myPrinting)
00511 ArLog::log(ArLog::Normal, "%.0f", ArMath::fabs(myRobot->findDeltaHeadingTo(approach)));
00512 if (myApproachDistFromVertex <= 0 ||
00513 ArMath::fabs(myRobot->findDeltaHeadingTo(approach)) > 90 ||
00514 (ArMath::fabs(myRobot->findDeltaHeadingTo(approach)) > 45 &&
00515 myRobot->findDistanceTo(final) < myRobot->findDistanceTo(approach)))
00516
00517 {
00518 if (myGotoVertex)
00519 {
00520 if (myPrinting)
00521 ArLog::log(ArLog::Normal, "Going to vertex");
00522 myState = STATE_GOTO_VERTEX;
00523 }
00524 else
00525 {
00526 if (myPrinting)
00527 ArLog::log(ArLog::Normal, "Going to final");
00528 myState = STATE_GOTO_FINAL;
00529 }
00530 return fire(currentDesired);
00531 }
00532
00533 else
00534 {
00535 myState = STATE_GOTO_APPROACH;
00536 return fire(currentDesired);
00537 }
00538 }
00539 myDesired.setVel(0);
00540 myDesired.setRotVel(0);
00541 return &myDesired;
00542 case STATE_SEARCHING:
00543 if (myPrinting)
00544 ArLog::log(ArLog::Normal, "Searching");
00545 myVertexSeen = false;
00546 findTriangle(true);
00547 if (myVertexSeen)
00548 {
00549 myState = STATE_ACQUIRE;
00550 return fire(currentDesired);
00551 }
00552 myDesired.setVel(0);
00553 myDesired.setRotVel(myAcquireTurnSpeed);
00554 return &myDesired;
00555 break;
00556 case STATE_GOTO_APPROACH:
00557 findTriangle(false);
00558 if (!myVertexSeen &&
00559 myVertexSeenLast.mSecSince() > myVertexUnseenStopMSecs)
00560 {
00561 if (myAcquire)
00562 {
00563 myState = STATE_SEARCHING;
00564 return fire(currentDesired);
00565 }
00566 else
00567 {
00568 ArLog::log(ArLog::Normal, "ArActionTriangleDriveTo: Failed");
00569 myState = STATE_FAILED;
00570 return fire(currentDesired);
00571 }
00572 }
00573 approach = findPoseFromVertex(myApproachDistFromVertex);
00574 if (mySaveData)
00575 {
00576 myDataMutex.lock();
00577 if (myData != NULL)
00578 myData->setApproach(approach);
00579 myDataMutex.unlock();
00580 }
00581 dist = myRobot->getPose().findDistanceTo(approach);
00582 angle = myRobot->getPose().findAngleTo(approach);
00583 if (dist < myCloseDist ||
00584 (dist < myCloseDist * 2 &&
00585 ArMath::fabs(myRobot->findDeltaHeadingTo(approach)) > 30))
00586 {
00587 if (myPrinting)
00588 ArLog::log(ArLog::Normal, "Goto approach there");
00589 myState = STATE_ALIGN_APPROACH;
00590 return fire(currentDesired);
00591 }
00592 myDesired.setHeading(angle);
00593 vel = sqrt(dist * 400 * 2);
00594 vel *= (180 - ArMath::fabs(myRobot->findDeltaHeadingTo(approach))) / 180;
00595 if (vel < 0)
00596 vel = 0;
00597 if (vel > mySpeed)
00598 vel = mySpeed;
00599 myDesired.setVel(vel);
00600 if (myPrinting)
00601 ArLog::log(ArLog::Normal, "Goto approach speed %.0f dist %.0f angle %.0f", vel, dist, angle);
00602 return &myDesired;
00603 case STATE_ALIGN_APPROACH:
00604 angle = myRobot->getPose().findAngleTo(vertex);
00605 if (myPrinting)
00606 ArLog::log(ArLog::Normal, "Align approach %.0f %.0f", myRobot->getTh(),
00607 angle);
00608 if (ArMath::fabs(ArMath::subAngle(myRobot->getTh(), angle)) < 2 &&
00609 ArMath::fabs(myRobot->getVel()) < 5)
00610 {
00611
00612 if (myGotoVertex)
00613 {
00614 if (myPrinting)
00615 ArLog::log(ArLog::Normal, "Going to vertex");
00616 myState = STATE_GOTO_VERTEX;
00617 }
00618 else
00619 {
00620 if (myPrinting)
00621 ArLog::log(ArLog::Normal, "Going to final");
00622 myState = STATE_GOTO_FINAL;
00623 }
00624 return fire(currentDesired);
00625 }
00626 myDesired.setHeading(angle);
00627 myDesired.setVel(0);
00628 return &myDesired;
00629 case STATE_GOTO_VERTEX:
00630
00631
00632
00633
00634
00635 findTriangle(false, true);
00636
00637 if (!myVertexSeen &&
00638 myVertexSeenLast.mSecSince() > myVertexUnseenStopMSecs)
00639 {
00640 ArLog::log(ArLog::Normal, "ActionTriangle: Failed");
00641 myState = STATE_FAILED;
00642 return fire(currentDesired);
00643 }
00644 final = findPoseFromVertex(0);
00645 if (mySaveData)
00646 {
00647 myDataMutex.lock();
00648 if (myData != NULL)
00649 myData->setFinal(final);
00650 myDataMutex.unlock();
00651 }
00652 dist = myRobot->findDistanceTo(final);
00653 dist -= myFinalDistFromVertex;
00654 angle = myRobot->findDeltaHeadingTo(final);
00655 if (ArMath::fabs(angle) > 10)
00656 {
00657 ArLog::log(ArLog::Normal, "ActionTriangle: FAILING because trying to turn %.0f degrees to something %.0f away that we saw %ld ms ago ", angle, dist, myVertexSeenLast.mSecSince());
00658 myState = STATE_FAILED;
00659 return fire(currentDesired);
00660 }
00661 else
00662 {
00663 myDesired.setDeltaHeading(angle);
00664 }
00665 if (dist > 0)
00666 vel = sqrt(dist * 100 * 2);
00667 else
00668 vel = 0;
00669 if (vel < 0)
00670 vel = 0;
00671 if (vel > mySpeed)
00672 vel = mySpeed;
00673 myDesired.setVel(vel);
00674 if (dist <= 0 && fabs(myRobot->getVel()) < 5)
00675 {
00676 ArLog::log(ArLog::Normal, "ArActionTriangleDriveTo: Succeeded (vertex) %g", dist);
00677 myState = STATE_SUCCEEDED;
00678 return fire(currentDesired);
00679 }
00680 if (myPrinting)
00681 ArLog::log(ArLog::Normal, "Goto vertex speed %.0f dist %.0f angle %.0f %ld ago",
00682 vel, dist, myRobot->findDeltaHeadingTo(final),
00683 myVertexSeenLast.mSecSince());
00684 return &myDesired;
00685
00686 case STATE_GOTO_FINAL:
00687
00688
00689
00690 final = findPoseFromVertex(myFinalDistFromVertex);
00691
00692
00693 if (myRobot->findDistanceTo(final) > 250)
00694 findTriangle(false);
00695
00696 if (!myVertexSeen &&
00697 myVertexSeenLast.mSecSince() > myVertexUnseenStopMSecs)
00698 {
00699 if (myAcquire)
00700 {
00701 myState = STATE_SEARCHING;
00702 return fire(currentDesired);
00703 }
00704 else
00705 {
00706 ArLog::log(ArLog::Normal, "ArActionTriangleDriveTo: Failed");
00707 myState = STATE_FAILED;
00708 return fire(currentDesired);
00709 }
00710 }
00711 final = findPoseFromVertex(myFinalDistFromVertex);
00712 if (mySaveData)
00713 {
00714 myDataMutex.lock();
00715 if (myData != NULL)
00716 myData->setFinal(final);
00717 myDataMutex.unlock();
00718 }
00719 dist = myRobot->getPose().findDistanceTo(final);
00720 angle = myRobot->getPose().findAngleTo(final);
00721 if (myPrinting)
00722 ArLog::log(ArLog::Normal,
00723 "final %.0f away at %.0f vertex %.0f away %ld ago",
00724 dist, myRobot->findDeltaHeadingTo(final),
00725 myRobot->findDistanceTo(vertex),
00726 myVertexSeenLast.mSecSince());
00727
00728 if ((dist < 5) ||
00729 (myRobot->getVel() > 0 && dist < myCloseDist &&
00730 ArMath::fabs(myRobot->findDeltaHeadingTo(final)) > 20) ||
00731 (myRobot->getVel() < 0 && dist < myCloseDist &&
00732 ArMath::fabs(myRobot->findDeltaHeadingTo(final)) < 160) ||
00733 (ArMath::fabs(myRobot->getVel()) < 5 && dist < myCloseDist))
00734 {
00735 if (myPrinting)
00736 ArLog::log(ArLog::Normal, "Goto final there");
00737 myState = STATE_ALIGN_FINAL;
00738 return fire(currentDesired);
00739 }
00740
00741 if (ArMath::fabs(ArMath::subAngle(myRobot->getTh(),
00742 angle)) < 90)
00743 {
00744 myDesired.setHeading(angle);
00745 vel = sqrt(dist * 100 * 2);
00746 vel *= (45 - ArMath::fabs(myRobot->findDeltaHeadingTo(final))) / 45;
00747 if (vel < 0)
00748 vel = 0;
00749 if (vel > mySpeed)
00750 vel = mySpeed;
00751 myDesired.setVel(vel);
00752 if (myPrinting)
00753 ArLog::log(ArLog::Normal, "Goto final speed %.0f dist %.0f angle %.0f", vel, dist, myRobot->findDeltaHeadingTo(final));
00754
00755 return &myDesired;
00756 }
00757 else
00758 {
00759 myDesired.setHeading(
00760 ArMath::subAngle(myRobot->getPose().findAngleTo(final), 180));
00761 vel = -1 * sqrt(dist * 100 * 2);
00762 vel *= (45 - ArMath::fabs(ArMath::subAngle(180,
00763 myRobot->findDeltaHeadingTo(final)))) / 45;
00764 if (vel > 0)
00765 vel = 0;
00766 if (vel < -mySpeed)
00767 vel = -mySpeed;
00768 myDesired.setVel(vel);
00769 if (myPrinting)
00770 ArLog::log(ArLog::Normal, "Goto final (backing) speed %.0f dist %.0f angle %.0f (turning to %.0f)", vel, dist, angle,
00771 ArMath::subAngle(180, myRobot->findDeltaHeadingTo(final)));
00772 return &myDesired;
00773 }
00774 case STATE_ALIGN_FINAL:
00775 angle = myRobot->getPose().findAngleTo(vertex);
00776 if (ArMath::fabs(ArMath::subAngle(myRobot->getTh(), angle)) < 2 &&
00777 ArMath::fabs(myRobot->getVel()) < 5)
00778 {
00779 ArLog::log(ArLog::Normal, "ArActionTriangleDriveTo: Succeeded");
00780 myState = STATE_SUCCEEDED;
00781 return fire(currentDesired);
00782 }
00783 if (myPrinting)
00784 ArLog::log(ArLog::Normal, "Align final");
00785 myDesired.setHeading(angle);
00786 myDesired.setVel(0);
00787 return &myDesired;
00788 }
00789
00790 findTriangle(true);
00791 return NULL;
00792
00793 }
00794
00795 ArActionTriangleDriveTo::Data *ArActionTriangleDriveTo::getData(void)
00796 {
00797 Data *data = NULL;
00798 myDataMutex.lock();
00799 data = myData;
00800 myData = NULL;
00801 myDataMutex.unlock();
00802 return data;
00803 }
00804
00805