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