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 "ArActionBumpers.h"
00030 #include "ArRobot.h"
00031
00038 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 myStopTime = 1000;
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 ArActionBumpers::~ArActionBumpers()
00071 {
00072
00073 }
00074
00075 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 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 myDesired.reset();
00127 if (myFiring)
00128 {
00129
00130 if (myStartBack.mSecSince() < myBackOffTime)
00131 {
00132 if ((mySpeed < 0 && rearBump != 0) ||
00133 (mySpeed > 0 && frontBump != 0))
00134 {
00135
00136 myDesired.setVel(0);
00137 }
00138 else
00139 {
00140
00141 myDesired.setVel(mySpeed);
00142 }
00143
00144 myDesired.setDeltaHeading(0);
00145 return &myDesired;
00146 }
00147 else if (myStartBack.mSecSince() < myBackOffTime + myTurnTime &&
00148 ArMath::fabs(ArMath::subAngle(myRobot->getTh(), myHeading)) > 3)
00149 {
00150
00151 myDesired.setVel(0);
00152 myDesired.setHeading(myHeading);
00153 return &myDesired;
00154 }
00155 else if(stoppedSince.mSecSince() < myStopTime)
00156 {
00157 myDesired.setVel(0);
00158 myDesired.setDeltaHeading(0);
00159 return &myDesired;
00160 }
00161
00162 myFiring = false;
00163 }
00164
00165 if (myRobot->getVel() > 1)
00166 {
00167 if (frontBump == 0)
00168 return NULL;
00169 whichBumper = 1;
00170 printf("Bumped a forward bumper while going forward, turning %.0f \n",
00171 findDegreesToTurn(frontBump, whichBumper));
00172 myHeading = ArMath::addAngle(myRobot->getTh(),
00173 findDegreesToTurn(frontBump, whichBumper));
00174 mySpeed = -myBackOffSpeed;
00175 myStartBack.setToNow();
00176 }
00177 else if (myRobot->getVel() < -1)
00178 {
00179 if (rearBump == 0)
00180 return NULL;
00181 whichBumper = 2;
00182 printf("Bumped a rear bumper while going backwards, turning %.0f \n",
00183 findDegreesToTurn(rearBump, whichBumper));
00184 myHeading = ArMath::subAngle(myRobot->getTh(),
00185 findDegreesToTurn(rearBump, whichBumper));
00186 mySpeed = myBackOffSpeed;
00187 myStartBack.setToNow();
00188 }
00189 else if(myRobot->getVel() > -1 && myRobot->getVel() < 1)
00190 {
00191 if(frontBump == 0 && rearBump == 0) return NULL;
00192
00193 stoppedSince.setToNow();
00194 }
00195 else
00196 return NULL;
00197
00198
00199 myFiring = true;
00200 myDesired.setVel(mySpeed);
00201 myDesired.setHeading(myHeading);
00202
00203 if (mySetMaximums)
00204 {
00205 if (mySpeed > 0)
00206 myDesired.setMaxVel(mySpeed);
00207 else
00208 myDesired.setMaxNegVel(mySpeed);
00209 }
00210 return &myDesired;
00211 }