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
00028 #include "ariaOSDef.h"
00029 #include "ArActionAvoidFront.h"
00030 #include "ArResolver.h"
00031 #include "ArRobot.h"
00032 #include "ArLog.h"
00033
00044 AREXPORT ArActionAvoidFront::ArActionAvoidFront(const char *name,
00045 double obstacleDistance,
00046 double avoidVelocity,
00047 double turnAmount,
00048 bool useTableIRIfAvail) :
00049 ArAction(name, "Slows down and avoids obstacles in front of the robot.")
00050 {
00051 setNextArgument(ArArg("obstacle distance", &myObsDist,
00052 "Distance at which to turn. (mm)"));
00053 myObsDist = obstacleDistance;
00054
00055 setNextArgument(ArArg("avoid speed", &myAvoidVel,
00056 "Speed at which to go while avoiding an obstacle. (mm/sec)"));
00057 myAvoidVel = avoidVelocity;
00058
00059 setNextArgument(ArArg("turn ammount", &myTurnAmountParam,
00060 "Degrees to turn relative to current heading while avoiding obstacle (deg)"));
00061 myTurnAmountParam = turnAmount;
00062
00063 setNextArgument(ArArg("use table IR", &myUseTableIRIfAvail,
00064 "true to use table sensing IR for avoidance if the robot has them, false otherwise"));
00065 myUseTableIRIfAvail = useTableIRIfAvail;
00066
00067 myTurning = 0;
00068 }
00069
00070 AREXPORT ArActionAvoidFront::~ArActionAvoidFront()
00071 {
00072
00073 }
00074
00075 AREXPORT ArActionDesired *ArActionAvoidFront::fire(ArActionDesired currentDesired)
00076 {
00077 double dist, angle;
00078
00079 if (currentDesired.getDeltaHeadingStrength() >= 1.0)
00080 myTurning = 0;
00081
00082 myDesired.reset();
00083
00084 dist = (myRobot->checkRangeDevicesCurrentPolar(-70, 70, &angle)
00085 - myRobot->getRobotRadius());
00086
00087
00088
00089 if (dist > myObsDist &&
00090 (!myUseTableIRIfAvail ||
00091 (myUseTableIRIfAvail && !myRobot->hasTableSensingIR()) ||
00092 (myUseTableIRIfAvail && myRobot->hasTableSensingIR() &&
00093 !myRobot->isLeftTableSensingIRTriggered() &&
00094 !myRobot->isRightTableSensingIRTriggered())))
00095 {
00096 if (myTurning != 0)
00097 {
00098 myDesired.setDeltaHeading(0);
00099 myTurning = 0;
00100 return &myDesired;
00101 }
00102 else
00103 {
00104
00105 myTurning = 0;
00106 return NULL;
00107 }
00108 }
00109
00110
00111
00112 if (myTurning == 0)
00113 {
00114 if (myUseTableIRIfAvail && myRobot->hasTableSensingIR() &&
00115 myRobot->isLeftTableSensingIRTriggered())
00116 myTurning = 1;
00117 else if (myUseTableIRIfAvail && myRobot->hasTableSensingIR() &&
00118 myRobot->isRightTableSensingIRTriggered())
00119 myTurning = -1;
00120 else if (angle < 0)
00121 myTurning = 1;
00122 else
00123 myTurning = -1;
00124 myTurnAmount = myTurnAmountParam;
00125 myQuadrants.clear();
00126 }
00127
00128 myQuadrants.update(myRobot->getTh());
00129 if (myTurning && myQuadrants.didAll())
00130 {
00131 myQuadrants.clear();
00132 myTurnAmount /= 2;
00133 if (myTurnAmount == 0)
00134 myTurnAmount = myTurnAmountParam;
00135 }
00136
00137 myDesired.setDeltaHeading(myTurning * myTurnAmount);
00138
00139 if (dist > myObsDist/2 &&
00140 (!myUseTableIRIfAvail ||
00141 (myUseTableIRIfAvail && !myRobot->hasTableSensingIR()) ||
00142 (myUseTableIRIfAvail && myRobot->hasTableSensingIR() &&
00143 !myRobot->isLeftTableSensingIRTriggered() &&
00144 !myRobot->isRightTableSensingIRTriggered())))
00145 {
00146
00147
00148 myDesired.setVel(myAvoidVel * dist / myObsDist);
00149 }
00150 else
00151 {
00152
00153 myDesired.setVel(0);
00154 }
00155
00156
00157 return &myDesired;
00158 }