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