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 #include "ariaOSDef.h"
00028 #include "ArActionIRs.h"
00029 #include "ArRobot.h"
00030 #include "ArCommands.h"
00031
00039 AREXPORT ArActionIRs::ArActionIRs(const char *name,
00040 double backOffSpeed,
00041 int backOffTime, int turnTime,
00042 bool setMaximums) :
00043 ArAction(name, "Reacts to the IRs triggering")
00044 {
00045 setNextArgument(ArArg("back off speed", &myBackOffSpeed,
00046 "Speed at which to back away (mm/sec)"));
00047 myBackOffSpeed = backOffSpeed;
00048
00049 setNextArgument(ArArg("back off time", &myBackOffTime,
00050 "Number of msec to back up for (msec)"));
00051 myBackOffTime = backOffTime;
00052
00053 myStopTime = 1000;
00054
00055 setNextArgument(ArArg("turn time", &myTurnTime,
00056 "Number of msec to allow for turn (msec)"));
00057 myTurnTime = turnTime;
00058
00059 setNextArgument(ArArg("set maximums", &mySetMaximums,
00060 "Whether to set maximum vels or not (bool)"));
00061 mySetMaximums = setMaximums;
00062
00063 myFiring = false;
00064 mySpeed = 0.0;
00065 myHeading = 0.0;
00066 }
00067
00068 AREXPORT ArActionIRs::~ArActionIRs()
00069 {
00070
00071 }
00072
00073 AREXPORT void ArActionIRs::setRobot(ArRobot *robot)
00074 {
00075 myRobot = robot;
00076 const ArRobotParams *params;
00077 params = myRobot->getRobotParams();
00078 myParams = *params;
00079
00080 for(int i = 0; i < myParams.getNumIR(); i++)
00081 cycleCounters.push_back(1);
00082 }
00083
00084 AREXPORT ArActionDesired *ArActionIRs::fire(ArActionDesired currentDesired)
00085 {
00086 myDesired.reset();
00087
00088 double angle = 0;
00089 int counter = 0;
00090 double turnRange = 135;
00091
00092 ArUtil::BITS bit;
00093
00094 if(myFiring)
00095 {
00096 if (myStartBack.mSecSince() < myBackOffTime)
00097 {
00098 myDesired.setVel(mySpeed);
00099 myDesired.setDeltaHeading(0);
00100 return &myDesired;
00101 }
00102 else if (myStartBack.mSecSince() < myBackOffTime + myTurnTime &&
00103 ArMath::fabs(ArMath::subAngle(myRobot->getTh(), myHeading)) > 3)
00104 {
00105 myDesired.setVel(0);
00106 myDesired.setHeading(myHeading);
00107 return &myDesired;
00108 }
00109 else if(stoppedSince.mSecSince() < myStopTime)
00110 {
00111 myDesired.setVel(0);
00112 myDesired.setDeltaHeading(0);
00113 return &myDesired;
00114 }
00115
00116 myFiring = false;
00117 }
00118
00119
00120 if(myParams.haveTableSensingIR())
00121 {
00122 for (int i = 0; i < myParams.getNumIR(); ++i)
00123 {
00124 switch(i)
00125 {
00126 case 0:
00127 bit = ArUtil::BIT0;
00128 break;
00129 case 1:
00130 bit = ArUtil::BIT1;
00131 break;
00132 case 2:
00133 bit = ArUtil::BIT2;
00134 break;
00135 case 3:
00136 bit = ArUtil::BIT3;
00137 break;
00138 case 4:
00139 bit = ArUtil::BIT4;
00140 break;
00141 case 5:
00142 bit = ArUtil::BIT5;
00143 break;
00144 case 6:
00145 bit = ArUtil::BIT6;
00146 break;
00147 case 7:
00148 bit = ArUtil::BIT7;
00149 break;
00150 }
00151 if(myParams.haveNewTableSensingIR() && myRobot->getIODigInSize() > 3)
00152 {
00153 if((myParams.getIRType(i) && !(myRobot->getIODigIn(3) & bit)) ||
00154 (!myParams.getIRType(i) && (myRobot->getIODigIn(3) & bit)))
00155 {
00156 if(cycleCounters[i] < myParams.getIRCycles(i))
00157 {
00158 cycleCounters[i] = cycleCounters[i] + 1;
00159 }
00160 else
00161 {
00162 cycleCounters[i] = 1;
00163
00164 ArPose pose;
00165 pose.setX(myParams.getIRX(i));
00166 pose.setY(myParams.getIRY(i));
00167 if(pose.getX() > 0)
00168 {
00169 ArPose center(0,0,0);
00170 angle += center.findAngleTo(pose);
00171 counter++;
00172 }
00173 }
00174 }
00175 else
00176 {
00177 cycleCounters[i] = 1;
00178 }
00179 }
00180 else
00181 {
00182 if(!(myRobot->getDigIn() & bit))
00183 {
00184 if(cycleCounters[i] < myParams.getIRCycles(i))
00185 {
00186 cycleCounters[i] = cycleCounters[i] + 1;
00187 }
00188 else
00189 {
00190 cycleCounters[i] = 1;
00191
00192 ArPose pose;
00193 pose.setX(myParams.getIRX(i));
00194 pose.setY(myParams.getIRY(i));
00195 if(pose.getX() > 0)
00196 {
00197 ArPose center(0,0,0);
00198 angle += center.findAngleTo(pose);
00199 counter++;
00200 }
00201 }
00202 }
00203 else
00204 {
00205 cycleCounters[i] = 1;
00206 }
00207
00208 }
00209 }
00210
00211 if(counter > 0 && myRobot->getVel() > 50)
00212 {
00213 angle = angle / (double) counter;
00214 if(angle > (turnRange / 2))
00215 angle = turnRange / 2;
00216 else if(angle < -(turnRange / 2))
00217 angle = -(turnRange / 2);
00218
00219 if(angle < 0) angle = ((turnRange / 2) + angle) * -1;
00220 else angle = ((turnRange / 2) - angle);
00221
00222 myHeading = ArMath::addAngle(myRobot->getTh(), angle);
00223 mySpeed = -myBackOffSpeed;
00224 myStartBack.setToNow();
00225 ArLog::log(ArLog::Normal, "ArActionIRS: estopping");
00226 myRobot->comInt(ArCommands::ESTOP, 0);
00227 myFiring = true;
00228
00229 myDesired.setVel(mySpeed);
00230 myDesired.setHeading(myHeading);
00231
00232 }
00233 else if(counter > 0 && (myRobot->getVel() > -50 && myRobot->getVel() < 50))
00234 {
00235 stoppedSince.setToNow();
00236 }
00237 else return NULL;
00238 }
00239 else return NULL;
00240
00241
00242 return &myDesired;
00243 }