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 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include "ArActionGotoStraight.h"
00029 #include "ArRobot.h"
00030
00031 AREXPORT ArActionGotoStraight::ArActionGotoStraight(const char *name,
00032 double speed) :
00033 ArAction(name, "Goes to the given goal.")
00034 {
00035 myPrinting = false;
00036
00037 setNextArgument(ArArg("speed", &mySpeed,
00038 "Speed to travel to goal at. (mm/sec)"));
00039 mySpeed = speed;
00040 myState = STATE_NO_GOAL;
00041
00042 myUseEncoderGoal = false;
00043 myBacking = false;
00044 setCloseDist();
00045 }
00046
00047 AREXPORT ArActionGotoStraight::~ArActionGotoStraight()
00048 {
00049
00050 }
00051
00052 AREXPORT bool ArActionGotoStraight::haveAchievedGoal(void)
00053 {
00054 if (myState == STATE_ACHIEVED_GOAL)
00055 return true;
00056 else
00057 return false;
00058 }
00059
00060 AREXPORT void ArActionGotoStraight::cancelGoal(void)
00061 {
00062 myState = STATE_NO_GOAL;
00063 }
00064
00065 AREXPORT void ArActionGotoStraight::setGoal(ArPose goal, bool backToGoal,
00066 bool justDistance)
00067 {
00068 myState = STATE_GOING_TO_GOAL;
00069 myGoal = goal;
00070 myUseEncoderGoal = false;
00071 myBacking = backToGoal;
00072 myLastPose = myRobot->getPose();
00073 myDist = myRobot->getPose().findDistanceTo(goal);
00074 myJustDist = true;
00075 myDistTravelled = 0;
00076 }
00077
00078 AREXPORT void ArActionGotoStraight::setGoalRel(double dist,
00079 double deltaHeading,
00080 bool backToGoal,
00081 bool justDistance)
00082 {
00083 ArPose goal;
00084 goal.setX(dist * ArMath::cos(deltaHeading));
00085 goal.setY(dist * ArMath::sin(deltaHeading));
00086 goal = myRobot->getToGlobalTransform().doTransform(goal);
00087 setGoal(goal, backToGoal, justDistance);
00088 }
00089
00090 AREXPORT void ArActionGotoStraight::setEncoderGoal(ArPose encoderGoal,
00091 bool backToGoal,
00092 bool justDistance)
00093 {
00094 myState = STATE_GOING_TO_GOAL;
00095 myEncoderGoal = encoderGoal;
00096 myUseEncoderGoal = true;
00097 myBacking = backToGoal;
00098 myDist = myRobot->getEncoderPose().findDistanceTo(encoderGoal);
00099 myJustDist = justDistance;
00100 myDistTravelled = 0;
00101 myLastPose = myRobot->getEncoderPose();
00102 }
00103
00104 AREXPORT void ArActionGotoStraight::setEncoderGoalRel(double dist,
00105 double deltaHeading,
00106 bool backToGoal,
00107 bool justDistance)
00108 {
00109 ArPose goal;
00110 goal.setX(dist * ArMath::cos(deltaHeading));
00111 goal.setY(dist * ArMath::sin(deltaHeading));
00112 goal = myRobot->getToGlobalTransform().doTransform(goal);
00113 goal = myRobot->getEncoderTransform().doInvTransform(goal);
00114 setEncoderGoal(goal, backToGoal, justDistance);
00115 }
00116
00117 AREXPORT ArActionDesired *ArActionGotoStraight::fire(ArActionDesired currentDesired)
00118 {
00119 double angle;
00120 double dist;
00121 double distToGo;
00122 double vel;
00123
00124
00125 if (myState == STATE_ACHIEVED_GOAL || myState == STATE_NO_GOAL)
00126 return NULL;
00127
00128
00129 ArPose goal;
00130 if (!myUseEncoderGoal)
00131 {
00132 goal = myGoal;
00133 myDistTravelled += myRobot->getPose().findDistanceTo(myLastPose);
00134 myLastPose = myRobot->getPose();
00135 }
00136 else
00137 {
00138 goal = myRobot->getEncoderTransform().doTransform(myEncoderGoal);
00139 myDistTravelled += myRobot->getEncoderPose().findDistanceTo(myLastPose);
00140 myLastPose = myRobot->getEncoderPose();
00141 }
00142
00143 if (myJustDist)
00144 {
00145 distToGo = myDist - myDistTravelled;
00146 dist = fabs(distToGo);
00147 }
00148 else
00149 {
00150 dist = myRobot->getPose().findDistanceTo(goal);
00151 }
00152
00153 if (((myJustDist && distToGo <= 0) ||
00154 (!myJustDist && dist < myCloseDist))
00155 && ArMath::fabs(myRobot->getVel() < 5))
00156 {
00157 if (myPrinting)
00158 ArLog::log(ArLog::Normal, "Achieved goal");
00159 myState = STATE_ACHIEVED_GOAL;
00160 myDesired.setVel(0);
00161 myDesired.setDeltaHeading(0);
00162 return &myDesired;
00163 }
00164
00165
00166 angle = myRobot->getPose().findAngleTo(goal);
00167 if (myBacking)
00168 angle = ArMath::subAngle(angle, 180);
00169 myDesired.setHeading(angle);
00170
00171 if ((myJustDist && distToGo <= 0) ||
00172 (!myJustDist && dist < myCloseDist))
00173 {
00174 myDesired.setVel(0);
00175 vel = 0;
00176 }
00177 else
00178 {
00179 vel = sqrt(dist * 200 * 2);
00180 if (vel > mySpeed)
00181 vel = mySpeed;
00182 if (myBacking)
00183 vel *= -1;
00184 myDesired.setVel(vel);
00185 }
00186 if (myPrinting)
00187 ArLog::log(ArLog::Normal, "dist %.0f angle %.0f vel %.0f",
00188 dist, angle, vel);
00189 return &myDesired;
00190 }
00191