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

ArActionStallRecover.cpp

00001 /*
00002 ActivMedia Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004,2005 ActivMedia Robotics, LLC
00004 
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 ActivMedia Robotics for information about a commercial version of ARIA at 
00022 robots@activmedia.com or 
00023 ActivMedia Robotics, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 
00025 */
00026 
00027 #include "ArExport.h"
00028 #include "ariaOSDef.h"
00029 #include <time.h>
00030 #include "ArRobot.h"
00031 #include "ArResolver.h"
00032 #include "ArActionStallRecover.h"
00033 
00042 AREXPORT
00043 ArActionStallRecover::ArActionStallRecover(const char * name,
00044                                            double obstacleDistance, 
00045                                            int cyclesToMove, 
00046                                            double speed, 
00047                                            double degreesToTurn) :
00048     ArAction(name, "Recovers the robot from a stall.")
00049 {
00050   setNextArgument(ArArg("obstacle distance", &myObstacleDistance, 
00051                 "Distance at which not to move because of obstacle. (mm)"));
00052   myObstacleDistance = obstacleDistance;
00053   setNextArgument(ArArg("cycles to move", &myCyclesToMove, 
00054                         "Number of cycles to move (# of cycles)"));
00055   myCyclesToMove = cyclesToMove;
00056   setNextArgument(ArArg("speed", &mySpeed, 
00057                         "Speed at which to back up or go forward (mm/sec)"));
00058   mySpeed = speed;
00059   setNextArgument(ArArg("degrees to turn", &myDegreesToTurn, 
00060                         "Number of Degrees to turn (deg)"));
00061   myDegreesToTurn = degreesToTurn;
00062   myState = STATE_NOTHING;
00063 
00064   myResolver = NULL;
00065   mySequenceNum = 0;
00066   addSequence(BACK | TURN);
00067   addSequence(FORWARD | TURN);
00068   addSequence(BACK);
00069   addSequence(FORWARD);
00070   addSequence(TURN_LEFT);
00071   addSequence(TURN_RIGHT);
00072   addSequence(BACK | TURN_LEFT);
00073   addSequence(BACK | TURN_RIGHT);
00074   addSequence(FORWARD | TURN_LEFT);
00075   addSequence(FORWARD | TURN_RIGHT);
00076   mySequencePos = 0;
00077   myLastFired = 0;
00078 }
00079 
00080 AREXPORT
00081 ArActionStallRecover::~ArActionStallRecover()
00082 {
00083 
00084 
00085 }
00086 
00087 void ArActionStallRecover::addSequence(int sequence)
00088 {
00089   mySequence[mySequenceNum] = sequence;
00090   ++mySequenceNum;
00091 }
00092 
00093 AREXPORT
00094 ArActionDesired *ArActionStallRecover::fire(ArActionDesired currentDesired)
00095 {
00096   if (currentDesired.getVelStrength() >= 1.0 || 
00097       currentDesired.getDeltaHeadingStrength() >= 1.0)
00098   {
00099     myState = STATE_NOTHING;
00100     myCount = -1;
00101     return NULL;
00102   }
00103 
00104   myActionDesired.reset();
00105   switch (myState)
00106   {
00107   case STATE_NOTHING:
00108     if (!myRobot->isLeftMotorStalled() && !myRobot->isRightMotorStalled())
00109       return NULL;
00110     if (time(NULL) - myLastFired <= 5)
00111     {
00112       //printf("Didn't reset... %ld time diff\n", time(NULL) - myLastFired);
00113       ++mySequencePos;
00114     }
00115     else 
00116     {
00117       //printf("Reset\n");
00118       mySequencePos = 0;
00119     }
00120     if (mySequencePos >= mySequenceNum)
00121       mySequencePos = 0;
00122     myDoing = mySequence[mySequencePos];
00123     /* 
00124     if (myDoing & FORWARD)
00125       printf("Forward ");
00126     if (myDoing & BACK)
00127       printf("Back ");
00128     if (myDoing & TURN)
00129       printf("turn ");
00130     if (myDoing & TURN_LEFT)
00131       printf("turnLeft ");
00132     if (myDoing & TURN_RIGHT)
00133       printf("turnRight ");
00134     if (myDoing == 0)
00135       printf("Not doing anything, messed up");
00136     printf("\n");
00137     */
00138     myActionDesired.setVel(0);
00139     myActionDesired.setDeltaHeading(0);
00140   case STATE_GOING:
00141     myLastFired = time(NULL);
00142     doit();
00143     break;
00144   default:
00145     break;
00146   }
00147   return &myActionDesired;
00148 }
00149 
00150 void ArActionStallRecover::doit(void)
00151 {
00152   double leftDist, rightDist;
00153   double dist;
00154   int turnDirection;
00155   bool transFired, rotFired;
00156 
00157   if (myCount == -1 || myState != STATE_GOING)
00158   {
00159     myCount = myCyclesToMove;
00160     myState = STATE_GOING;
00161     mySideStalled = 0;
00162     if (myRobot->isLeftMotorStalled())
00163       mySideStalled += 1;
00164     if (myRobot->isRightMotorStalled())
00165       mySideStalled += 2;
00166     if (myDoing & TURN) 
00167     {
00168       rightDist = myRobot->checkRangeDevicesCurrentPolar(-120, -60);
00169       leftDist = myRobot->checkRangeDevicesCurrentPolar(60, 120);
00170       if (mySideStalled == 1 || rightDist < 0)
00171         turnDirection = -1;
00172       else if (mySideStalled == 2 || leftDist < 0)
00173         turnDirection = 1;
00174       else if (rightDist < leftDist)
00175         turnDirection = 1;
00176       else
00177         turnDirection = -1;
00178       myDesiredHeading = myRobot->getTh() + turnDirection * myDegreesToTurn;
00179     }
00180     else if (myDoing & TURN_LEFT)
00181       myDesiredHeading = myRobot->getTh() + myDegreesToTurn;
00182     else if (myDoing & TURN_RIGHT)
00183       myDesiredHeading = myRobot->getTh() + -1 * myDegreesToTurn;
00184   }
00185   else
00186     --myCount;
00187 
00188   if ((myDoing & MOVEMASK))
00189   {
00190     if (myDoing & FORWARD)
00191       dist = (myRobot->checkRangeDevicesCurrentPolar(-120, 120) -
00192               myRobot->getRobotRadius());
00193     else if (myDoing & BACK)
00194       dist = (myRobot->checkRangeDevicesCurrentPolar(120, -120) -
00195               myRobot->getRobotRadius());
00196     if ((myCount <= 0 || 
00197          (dist  > 0 && dist < myObstacleDistance &&
00198           myCount <= myCyclesToMove / 2)))
00199     {
00200       //printf("Not backing ");
00201       myActionDesired.setVel(0);
00202       transFired = false;
00203     } 
00204     else
00205     {
00206       //printf("backing ");
00207       if (myDoing & BACK)
00208         myActionDesired.setVel(mySpeed * -1);
00209       if (myDoing & FORWARD)
00210         myActionDesired.setVel(mySpeed);
00211       transFired = true;
00212     }
00213   } 
00214   else
00215     transFired = false;
00216 
00217   if ((myDoing & TURNMASK) && 
00218       (myCount <= 0 || myDegreesToTurn == 0 || 
00219        ArMath::fabs(ArMath::subAngle(myRobot->getTh(),myDesiredHeading)) < 3))
00220   {
00221     //printf("Not turning \n");
00222     myActionDesired.setDeltaHeading(0);
00223     rotFired = false;
00224   }
00225   else if (myDoing & TURNMASK)
00226   {
00227     //printf("turning \n");
00228     myActionDesired.setHeading(myDesiredHeading);
00229     rotFired = true;
00230   } 
00231   else
00232     rotFired = false;
00233 
00234   if (myCount <= 0 || (!transFired && !rotFired))
00235   {
00236     myState = STATE_NOTHING;
00237     return;
00238   }
00239 }
00240 
00241 void ArActionStallRecover::addToConfig(ArConfig* config, const char* sectionName, int priority)
00242 {
00243   if (config == NULL || sectionName == NULL)
00244   {
00245     ArLog::log(ArLog::Terse, "Could not add ArActionStallRecoverToConfig because config (%p) or section (%p) are null", config, sectionName);
00246     return;
00247   }
00248   config->addParam(ArConfigArg("StallRecoverSpeed", &mySpeed, "Speed at which to back away when stalled.", priority), sectionName, ArPriority::DETAILED);
00249   config->addParam(ArConfigArg("StallRecoverDuration", &myCyclesToMove, "Cycles of operation to move when recovering from stall.", priority), sectionName, ArPriority::DETAILED);
00250   config->addParam(ArConfigArg("StallRecoverRotation", &myDegreesToTurn, "Amount of rotation when recovering (degrees).", priority), sectionName, ArPriority::DETAILED);
00251 }
00252 

Generated on Wed Oct 19 12:56:34 2005 for Aria by  doxygen 1.4.0