Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages | Examples

ArActionBumpers.cpp

00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
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   //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 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     //printf("0 norot\n");
00141     myDesired.setVel(0);
00142       }
00143       else
00144       {
00145     //printf("%.0f norot\n", mySpeed);
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       //printf("0 %.0f\n", myHeading);
00156       myDesired.setVel(0);
00157       myDesired.setHeading(myHeading);
00158       return &myDesired;
00159     }
00160     /*
00161       else if (myStoppedSince.mSecSince() < myStopTime)
00162       {
00163       myDesired.setVel(0);
00164       myDesired.setDeltaHeading(0);
00165       return &myDesired;
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     else if (myRobot->getVel() >= -5 && myRobot->getVel() <= 5)
00200     {
00201     if (frontBump == 0 && rearBump == 0) 
00202     return NULL;
00203     myStoppedSince.setToNow();
00204     }
00205   */
00206   else
00207   {
00208     return NULL;
00209   }
00210   
00211   //myStartBack.setToNow();
00212   myFiring = true;
00213   myDesired.setVel(mySpeed);
00214   myDesired.setHeading(myHeading);
00215   // Set the maximums if that feature is desired
00216   if (mySetMaximums)
00217   {
00218     if (mySpeed > 0)
00219       myDesired.setMaxVel(mySpeed);
00220     else
00221       myDesired.setMaxNegVel(mySpeed);
00222   }
00223   return &myDesired;
00224 }  

Generated on Tue Feb 20 10:51:38 2007 for Aria by  doxygen 1.4.0