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 #include "ariaOSDef.h"
00029 #include "ArActionDeceleratingLimiter.h"
00030 #include "ArRobot.h"
00031 #include "ArCommands.h"
00032 #include "ariaInternal.h"
00033 #include "ArRobotConfigPacketReader.h"
00034
00039 ArActionDeceleratingLimiter::ArActionDeceleratingLimiter(
00040 const char *name,
00041 bool forwards) :
00042 ArAction(name,
00043 "Slows the robot down and cranks up deceleration so as not to hit anything in front of it.")
00044 {
00045 myForwards = forwards;
00046 setParameters();
00047
00048 myLastStopped = false;
00049 }
00050
00051 ArActionDeceleratingLimiter::~ArActionDeceleratingLimiter()
00052 {
00053
00054 }
00055
00068 void ArActionDeceleratingLimiter::setParameters(
00069 double clearance,
00070 double sideClearanceAtSlowSpeed,
00071 double paddingAtSlowSpeed,
00072 double slowSpeed,
00073 double sideClearanceAtFastSpeed,
00074 double paddingAtFastSpeed,
00075 double fastSpeed,
00076 double preferredDecel,
00077 bool useEStop,
00078 double maxEmergencyDecel)
00079 {
00080 myClearance = clearance;
00081 mySideClearanceAtSlowSpeed = sideClearanceAtSlowSpeed;
00082 myPaddingAtSlowSpeed = paddingAtSlowSpeed;
00083 mySlowSpeed = slowSpeed;
00084 mySideClearanceAtFastSpeed = sideClearanceAtFastSpeed;
00085 myPaddingAtFastSpeed = paddingAtFastSpeed;
00086 myFastSpeed = fastSpeed;
00087 myPreferredDecel = preferredDecel;
00088 myUseEStop = useEStop;
00089 myMaxEmergencyDecel = maxEmergencyDecel;
00090 }
00091
00092 void ArActionDeceleratingLimiter::addToConfig(ArConfig *config,
00093 const char *section,
00094 const char *prefix)
00095 {
00096 std::string strPrefix;
00097 std::string name;
00098 if (prefix == NULL || prefix[0] == '\0')
00099 strPrefix = "";
00100 else
00101 strPrefix = prefix;
00102
00103
00104 name = strPrefix;
00105 name += "Clearance";
00106 config->addParam(
00107 ArConfigArg(name.c_str(), &myClearance,
00108 "Don't get closer than this to something in front or back. (mm)"),
00109 section, ArPriority::NORMAL);
00110
00111 name = strPrefix;
00112 name += "SlowSpeed";
00113 config->addParam(
00114 ArConfigArg(name.c_str(),
00115 &mySlowSpeed,
00116 "Consider this speed slow (mm/sec)"),
00117 section, ArPriority::NORMAL);
00118
00119 name = strPrefix;
00120 name += "SideClearanceAtSlowSpeed";
00121 config->addParam(
00122 ArConfigArg(name.c_str(),
00123 &mySideClearanceAtSlowSpeed,
00124 "Don't get closer than this to something on the side if we're going at slow speed or below. (mm)"),
00125 section, ArPriority::NORMAL);
00126
00127 name = strPrefix;
00128 name += "PaddingAtSlowSpeed";
00129 config->addParam(
00130 ArConfigArg(name.c_str(), &myPaddingAtSlowSpeed,
00131 "Try to stop this far away from clearance at slow speed or below. (mm)"),
00132 section, ArPriority::NORMAL);
00133
00134 name = strPrefix;
00135 name += "FastSpeed";
00136 config->addParam(
00137 ArConfigArg(name.c_str(),
00138 &myFastSpeed,
00139 "Consider this speed fast (mm/sec)"),
00140 section, ArPriority::NORMAL);
00141
00142 name = strPrefix;
00143 name += "SideClearanceAtFastSpeed";
00144 config->addParam(
00145 ArConfigArg(name.c_str(),
00146 &mySideClearanceAtFastSpeed,
00147 "Don't get closer than this to something on the side if we're going at fast speed or above. (mm)"),
00148 section, ArPriority::NORMAL);
00149
00150 name = strPrefix;
00151 name += "PaddingAtFastSpeed";
00152 config->addParam(
00153 ArConfigArg(name.c_str(), &myPaddingAtFastSpeed,
00154 "Try to stop this far away from clearance at fast speed or below. (mm)"),
00155 section, ArPriority::NORMAL);
00156
00157 name = strPrefix;
00158 name += "PreferredDecel";
00159 config->addParam(
00160 ArConfigArg(name.c_str(),
00161 &myPreferredDecel,
00162 "The maximum decel we'll use until something might infringe on clearance and sideClearanceAtSlowSpeed (mm/sec/sec"),
00163 section, ArPriority::NORMAL);
00164
00165 name = strPrefix;
00166 name += "MaxEmergencyDecel";
00167 config->addParam(
00168 ArConfigArg(name.c_str(),
00169 &myMaxEmergencyDecel,
00170 "The maximum decel we'll ever use, 0 means use the robot's maximum (mm/sec/sec"),
00171 section, ArPriority::NORMAL);
00172
00173 name = strPrefix;
00174 name += "UseEStop";
00175 config->addParam(
00176 ArConfigArg(name.c_str(),
00177 &myUseEStop,
00178 "Whether to use an EStop to stop if something will intrude on our clearance"),
00179 section, ArPriority::NORMAL);
00180 }
00181
00182 ArActionDesired *
00183 ArActionDeceleratingLimiter::fire(ArActionDesired currentDesired)
00184 {
00185 double dist;
00186 double distInner;
00187 bool printing = false;
00188 double absVel;
00189
00190 myDesired.reset();
00191
00192 if (myRobot->getVel() < -100 && myForwards)
00193 return NULL;
00194 else if (myRobot->getVel() > 100 && !myForwards)
00195 return NULL;
00196 absVel = ArMath::fabs(myRobot->getVel());
00197
00198 double sideClearance;
00199 double padding;
00200
00201
00202 if (ArMath::fabs(myRobot->getVel()) <= mySlowSpeed)
00203 {
00204 sideClearance = mySideClearanceAtSlowSpeed;
00205 padding = myPaddingAtSlowSpeed;
00206 }
00207
00208 else if (ArMath::fabs(myRobot->getVel()) >= myFastSpeed)
00209 {
00210 sideClearance = mySideClearanceAtFastSpeed;
00211 padding = myPaddingAtFastSpeed;
00212 }
00213
00214 else
00215 {
00216 sideClearance = (((mySideClearanceAtFastSpeed -
00217 mySideClearanceAtSlowSpeed) *
00218 ((ArMath::fabs(myRobot->getVel()) - mySlowSpeed) /
00219 (myFastSpeed - mySlowSpeed))) +
00220 mySideClearanceAtSlowSpeed);
00221 padding = (((myPaddingAtFastSpeed -
00222 myPaddingAtSlowSpeed) *
00223 ((ArMath::fabs(myRobot->getVel()) - mySlowSpeed) /
00224 (myFastSpeed - mySlowSpeed))) +
00225 myPaddingAtSlowSpeed);
00226 }
00227
00228
00229 if (printing)
00230 printf("%d side %.0f padding %.0f\n", myForwards, sideClearance, padding);
00231
00232 if (myForwards)
00233 dist = myRobot->checkRangeDevicesCurrentBox(
00234 0,
00235 -(myRobot->getRobotWidth()/2.0 + sideClearance),
00236 myRobot->getRobotLength()/2.0 + myClearance + padding + 8000,
00237 (myRobot->getRobotWidth()/2.0 + sideClearance));
00238 else
00239 dist = myRobot->checkRangeDevicesCurrentBox(
00240 0,
00241 -(myRobot->getRobotWidth()/2.0 + sideClearance),
00242 -(myRobot->getRobotLength()/2.0 + myClearance + padding + 8000),
00243 (myRobot->getRobotWidth()/2.0 + sideClearance));
00244
00245 if (myForwards)
00246 distInner = myRobot->checkRangeDevicesCurrentBox(
00247 0,
00248 -(myRobot->getRobotWidth()/2.0 + mySideClearanceAtSlowSpeed),
00249 myRobot->getRobotLength()/2.0 + myClearance + 8000,
00250 (myRobot->getRobotWidth()/2.0 + mySideClearanceAtSlowSpeed));
00251 else
00252 distInner = myRobot->checkRangeDevicesCurrentBox(
00253 0,
00254 -(myRobot->getRobotWidth()/2.0 + mySideClearanceAtSlowSpeed),
00255 -(myRobot->getRobotLength()/2.0 + myClearance + 8000),
00256 (myRobot->getRobotWidth()/2.0 + mySideClearanceAtSlowSpeed));
00257
00258
00259 dist -= myRobot->getRobotLength() / 2.0;
00260 dist -= myClearance;
00261 dist -= padding;
00262
00263
00264 distInner -= myRobot->getRobotLength() / 2.0;
00265 distInner -= myClearance;
00266
00267 if (printing)
00268 printf("%d dist %.0f\n", myForwards, dist);
00269
00270 if (distInner < 1 && ((myRobot->getVel() > 5 && myForwards) ||
00271 (myRobot->getVel() < -5 && !myForwards)))
00272 {
00273 if (printing && !myLastStopped)
00274 printf("%d Stopping\n", myForwards);
00275 if (ArMath::fabs(myRobot->getVel()) > 100)
00276 {
00277 if (myUseEStop)
00278 {
00279 ArLog::log(ArLog::Normal, "ArActionDeceleratingLimiter: estopping");
00280 myRobot->comInt(ArCommands::ESTOP, 1);
00281 }
00282 else
00283 {
00284 ArLog::log(ArLog::Verbose, "ArActionDeceleratingLimiter: maximum deceleration");
00285 }
00286
00287 if (fabs(myMaxEmergencyDecel) > 1)
00288 {
00289 if (printing)
00290 printf("Max emergency decel %.0f\n",
00291 myMaxEmergencyDecel);
00292 myDesired.setTransDecel(myMaxEmergencyDecel);
00293 }
00294
00295 else if (myRobot->getOrigRobotConfig() != NULL &&
00296 myRobot->getOrigRobotConfig()->hasPacketArrived())
00297 {
00298 if (printing)
00299 printf("Robots max decel %d\n",
00300 myRobot->getOrigRobotConfig()->getTransAccelTop());
00301 myDesired.setTransDecel(
00302 myRobot->getOrigRobotConfig()->getTransAccelTop());
00303 }
00304
00305 else
00306 {
00307 if (printing)
00308 printf("Prefered decel %g\n", myPreferredDecel);
00309 myDesired.setTransDecel(myPreferredDecel);
00310 }
00311 }
00312 myLastStopped = true;
00313 if (myForwards)
00314 myDesired.setMaxVel(0);
00315 else
00316 myDesired.setMaxNegVel(0);
00317 myDesired.setVel(0);
00318 return &myDesired;
00319 }
00320
00321
00322 if (dist > absVel * absVel / 2.0 / myRobot->getTransDecel())
00323 {
00324 if (printing)
00325 printf("%d Nothing\n", myForwards);
00326 return NULL;
00327 }
00328
00329 if (printing && myLastStopped)
00330 printf("%d moving\n", myForwards);
00331 myLastStopped = false;
00332
00333
00334 double deceleration = - absVel * absVel / dist / 2.0;
00335 double decelerationInner = - absVel * absVel / distInner / 2.0;
00336
00337
00338
00339
00340 if (fabs(deceleration) > fabs(myRobot->getTransDecel()) &&
00341 (currentDesired.getTransDecelStrength() < ArActionDesired::MIN_STRENGTH
00342 || fabs(deceleration) > fabs(currentDesired.getTransDecel())))
00343 {
00344
00345
00346 if (fabs(myMaxEmergencyDecel) > 1 &&
00347 fabs(decelerationInner) > myMaxEmergencyDecel)
00348 myDesired.setTransDecel(myMaxEmergencyDecel);
00349 else if (fabs(decelerationInner) > myPreferredDecel)
00350 myDesired.setTransDecel(fabs(decelerationInner));
00351 else if (fabs(myMaxEmergencyDecel) > 1 &&
00352 fabs(deceleration) > myMaxEmergencyDecel)
00353 myDesired.setTransDecel(myMaxEmergencyDecel);
00354 else if (fabs(deceleration) > myPreferredDecel)
00355 myDesired.setTransDecel(myPreferredDecel);
00356 else
00357 myDesired.setTransDecel(fabs(deceleration));
00358 if (printing)
00359 printf("Set deceleration to %g\n", myDesired.getTransDecel());
00360 }
00361 else
00362 deceleration = myRobot->getTransDecel();
00363
00364
00365
00366 if (printing)
00367 printf("%d accel %.0f\n", myForwards, deceleration);
00368
00369
00370 if (myForwards)
00371 myDesired.setMaxVel(0);
00372 else
00373 myDesired.setMaxNegVel(0);
00374 return &myDesired;
00375 }
00376
00377
00378