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 "ArActionBumpers.h"
00029 #include "ArRobot.h"
00030
00038 AREXPORT ArActionBumpers::ArActionBumpers(const char *name,
00039 double backOffSpeed,
00040 int backOffTime, int turnTime,
00041 bool setMaximums) :
00042 ArAction(name, "Reacts to the bumpers triggering")
00043 {
00044 setNextArgument(ArArg("back off speed", &myBackOffSpeed,
00045 "Speed at which to back away (mm/sec)"));
00046 myBackOffSpeed = backOffSpeed;
00047
00048 setNextArgument(ArArg("back off time", &myBackOffTime,
00049 "Number of msec to back up for (msec)"));
00050 myBackOffTime = backOffTime;
00051
00052
00053
00054 setNextArgument(ArArg("turn time", &myTurnTime,
00055 "Number of msec to allow for turn (msec)"));
00056 myTurnTime = turnTime;
00057
00058 setNextArgument(ArArg("set maximums", &mySetMaximums,
00059 "Whether to set maximum vels or not (bool)"));
00060 mySetMaximums = setMaximums;
00061
00062 myFiring = false;
00063 mySpeed = 0.0;
00064 myHeading = 0.0;
00065
00066 myBumpMask = (ArUtil::BIT1 | ArUtil::BIT2 | ArUtil::BIT3 | ArUtil::BIT4 |
00067 ArUtil::BIT5 | ArUtil::BIT6 | ArUtil::BIT7 | ArUtil::BIT8);
00068 }
00069
00070 AREXPORT ArActionBumpers::~ArActionBumpers()
00071 {
00072
00073 }
00074
00075 AREXPORT double ArActionBumpers::findDegreesToTurn(int bumpValue, int whichBumper)
00076 {
00077 double totalTurn = 0;
00078 int numTurn = 0;
00079 int numBumpers;
00080
00081 double turnRange = 135;
00082
00083 if(whichBumper == 1) numBumpers = myRobot->getNumFrontBumpers();
00084 else numBumpers = myRobot->getNumRearBumpers();
00085
00086 for (int i = 0; i < numBumpers; i++)
00087 {
00088 if((i == 0 && (bumpValue & ArUtil::BIT1)) ||
00089 (i == 1 && (bumpValue & ArUtil::BIT2)) ||
00090 (i == 2 && (bumpValue & ArUtil::BIT3)) ||
00091 (i == 3 && (bumpValue & ArUtil::BIT4)) ||
00092 (i == 4 && (bumpValue & ArUtil::BIT5)) ||
00093 (i == 5 && (bumpValue & ArUtil::BIT6)) ||
00094 (i == 6 && (bumpValue & ArUtil::BIT7)) ||
00095 (i == 7 && (bumpValue & ArUtil::BIT8)))
00096 {
00097 totalTurn = totalTurn + (i * (turnRange / (double)numBumpers) +
00098 ((turnRange / (double)numBumpers) / 2) - (turnRange / 2));
00099 ++numTurn;
00100 }
00101 }
00102
00103 totalTurn = totalTurn / (double)numTurn;
00104
00105 if(totalTurn < 0) totalTurn = ((turnRange / 2) + totalTurn) * -1;
00106 else totalTurn = ((turnRange / 2) - totalTurn);
00107
00108 return totalTurn;
00109 }
00110
00111 AREXPORT ArActionDesired *ArActionBumpers::fire(ArActionDesired currentDesired)
00112 {
00113 int frontBump;
00114 int rearBump;
00115 int whichBumper;
00116
00117 if (myRobot->hasFrontBumpers())
00118 frontBump = ((myRobot->getStallValue() & 0xff00) >> 8) & myBumpMask;
00119 else
00120 frontBump = 0;
00121 if (myRobot->hasRearBumpers())
00122 rearBump = (myRobot->getStallValue() & 0xff) & myBumpMask;
00123 else
00124 rearBump = 0;
00125
00126 if (frontBump != 0)
00127 ArLog::log(ArLog::Verbose, "########## Front bump %x\n", frontBump);
00128 if (rearBump != 0)
00129 ArLog::log(ArLog::Verbose, "########## Rear bump %x\n", rearBump);
00130
00131
00132 myDesired.reset();
00133 if (myFiring)
00134 {
00135 if (myStartBack.mSecSince() < myBackOffTime)
00136 {
00137 if ((mySpeed < 0 && rearBump != 0) ||
00138 (mySpeed > 0 && frontBump != 0))
00139 {
00140
00141 myDesired.setVel(0);
00142 }
00143 else
00144 {
00145
00146 myDesired.setVel(mySpeed);
00147 }
00148
00149 myDesired.setDeltaHeading(0);
00150 return &myDesired;
00151 }
00152 else if (myStartBack.mSecSince() < myBackOffTime + myTurnTime &&
00153 ArMath::fabs(ArMath::subAngle(myRobot->getTh(), myHeading)) > 3)
00154 {
00155
00156 myDesired.setVel(0);
00157 myDesired.setHeading(myHeading);
00158 return &myDesired;
00159 }
00160
00161
00162
00163
00164
00165
00166
00167
00168 myFiring = false;
00169 ArLog::log(ArLog::Normal, "Bumpers: done");
00170 }
00171
00172 if (myRobot->getVel() > 5)
00173 {
00174 if (frontBump == 0)
00175 return NULL;
00176 whichBumper = 1;
00177 ArLog::log(ArLog::Normal,
00178 "Bumpers: Bumped a forward bumper while going forward, turning %.0f",
00179 findDegreesToTurn(frontBump, whichBumper));
00180 myHeading = ArMath::addAngle(myRobot->getTh(),
00181 findDegreesToTurn(frontBump, whichBumper));
00182 mySpeed = -myBackOffSpeed;
00183 myStartBack.setToNow();
00184 }
00185 else if (myRobot->getVel() < -5)
00186 {
00187 if (rearBump == 0)
00188 return NULL;
00189 whichBumper = 2;
00190 ArLog::log(ArLog::Normal,
00191 "Bumpers: Bumped a rear bumper while going backwards, turning %.0f \n",
00192 findDegreesToTurn(rearBump, whichBumper));
00193 myHeading = ArMath::subAngle(myRobot->getTh(),
00194 findDegreesToTurn(rearBump, whichBumper));
00195 mySpeed = myBackOffSpeed;
00196 myStartBack.setToNow();
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206 else
00207 {
00208 return NULL;
00209 }
00210
00211
00212 myFiring = true;
00213 myDesired.setVel(mySpeed);
00214 myDesired.setHeading(myHeading);
00215
00216 if (mySetMaximums)
00217 {
00218 if (mySpeed > 0)
00219 myDesired.setMaxVel(mySpeed);
00220 else
00221 myDesired.setMaxNegVel(mySpeed);
00222 }
00223 return &myDesired;
00224 }