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 "ArActionRatioInput.h"
00030 #include "ArRobot.h"
00034 ArActionRatioInput::ArActionRatioInput(const char *name) :
00035 ArAction(name, "RatioInputs vel and heading")
00036 {
00037 myTransRatio = 0;
00038 myRotRatio = 0;
00039 myThrottleRatio = 0;
00040 myFullThrottleForwards = 0;
00041 myFullThrottleBackwards = 0;
00042 myRotAtFullForwards = 0;
00043 myRotAtFullBackwards = 0;
00044 myRotAtStopped = 0;
00045
00046 myFullThrottleForwards = 0;
00047 myFullThrottleBackwards = 0;
00048 myRotAtFullForwards = 0;
00049 myRotAtFullBackwards = 0;
00050 myRotAtStopped = 0;
00051 myPrinting = false;
00052
00053 myTransDeadZone = 10;
00054 myRotDeadZone = 5;
00055 }
00056
00057 ArActionRatioInput::~ArActionRatioInput()
00058 {
00059 }
00060
00061 void ArActionRatioInput::addToConfig(ArConfig *config,
00062 const char *section)
00063 {
00064 config->addParam(
00065 ArConfigArg("FullThrottleForwards", &myFullThrottleForwards,
00066 "The maximum forwards speed (0 means robot's TransVelMax) (mm/sec)", 0),
00067 section, ArPriority::NORMAL);
00068
00069 config->addParam(
00070 ArConfigArg("FullThrottleBackwards", &myFullThrottleBackwards,
00071 "The maximum backwards speed (0 means 1/4 robot's TransVelMax) (mm/sec)", 0),
00072 section, ArPriority::NORMAL);
00073
00074 config->addParam(
00075 ArConfigArg("RotAtFullForwards", &myRotAtFullForwards,
00076 "The maximum speed we turn at when going full forwards (0 means 1/2 robots RotVelMax) (deg/sec)", 0),
00077 section, ArPriority::NORMAL);
00078
00079 config->addParam(
00080 ArConfigArg("RotAtFullBackwards", &myRotAtFullBackwards,
00081 "The maximum speed we turn at when going full backwards (0 means 1/2 robots RotVelMax) (deg/sec)", 0),
00082 section, ArPriority::NORMAL);
00083
00084 config->addParam(
00085 ArConfigArg("RotAtStopped", &myRotAtStopped,
00086 "The maximum speed we turn at when stopped (0 means robot's RotVelMax) (deg/sec)", 0),
00087 section, ArPriority::NORMAL);
00088
00089 }
00090
00094 void ArActionRatioInput::setRatios(double transRatio,
00095 double rotRatio,
00096 double throttleRatio)
00097 {
00098 setTransRatio(transRatio);
00099 setRotRatio(rotRatio);
00100 setThrottleRatio(throttleRatio);
00101 }
00102
00107 void ArActionRatioInput::setTransRatio(double transRatio)
00108 {
00109 if (transRatio > 100)
00110 myTransRatio = 100;
00111 else if (transRatio < -100)
00112 myTransRatio = -100;
00113 else
00114 myTransRatio = transRatio;
00115 }
00116
00121 void ArActionRatioInput::setRotRatio(double rotRatio)
00122 {
00123 if (rotRatio > 100)
00124 myRotRatio = 100;
00125 else if (rotRatio < -100)
00126 myRotRatio = -100;
00127 else
00128 myRotRatio = rotRatio;
00129 }
00130
00135 void ArActionRatioInput::setThrottleRatio(double throttleRatio)
00136 {
00137 if (throttleRatio > 100)
00138 myThrottleRatio = 100;
00139 else if (throttleRatio < 0)
00140 myThrottleRatio = 0;
00141 else
00142 myThrottleRatio = throttleRatio;
00143 }
00144
00158 void ArActionRatioInput::setParameters(double fullThrottleForwards,
00159 double fullThrottleBackwards,
00160 double rotAtFullForwards,
00161 double rotAtFullBackwards,
00162 double rotAtStopped)
00163 {
00164 myFullThrottleForwards = fullThrottleForwards;
00165 myFullThrottleBackwards = fullThrottleBackwards;
00166 myRotAtFullForwards = rotAtFullForwards;
00167 myRotAtFullBackwards = rotAtFullBackwards;
00168 myRotAtStopped = rotAtStopped;
00169 }
00170
00176 void ArActionRatioInput::addFireCallback(int priority,
00177 ArFunctor *functor)
00178 {
00179 myFireCallbacks.insert(std::pair<int, ArFunctor *>(priority, functor));
00180 }
00181
00182 void ArActionRatioInput::remFireCallback(ArFunctor *functor)
00183 {
00184 std::multimap<int, ArFunctor *>::iterator it;
00185 for (it = myFireCallbacks.begin(); it != myFireCallbacks.end(); it++)
00186 {
00187 if ((*it).second == functor)
00188 break;
00189
00190 }
00191 if (it != myFireCallbacks.end())
00192 {
00193 myFireCallbacks.erase(it);
00194 }
00195 else
00196 ArLog::log(ArLog::Normal, "ArActionRatioInput::RemFireCallback: could not remove callback");
00197 }
00198
00199 void ArActionRatioInput::addActivateCallback(ArFunctor *functor,
00200 ArListPos::Pos position)
00201 {
00202 if (position == ArListPos::FIRST)
00203 myActivateCallbacks.push_front(functor);
00204 else if (position == ArListPos::LAST)
00205 myActivateCallbacks.push_back(functor);
00206 else
00207 ArLog::log(ArLog::Terse,
00208 "ArActionRatioInput::addActivateCallback: Invalid position.");
00209 }
00210
00211 void ArActionRatioInput::remActivateCallback(ArFunctor *functor)
00212 {
00213 myActivateCallbacks.remove(functor);
00214 }
00215
00216 void ArActionRatioInput::addDeactivateCallback(ArFunctor *functor,
00217 ArListPos::Pos position)
00218 {
00219 if (position == ArListPos::FIRST)
00220 myDeactivateCallbacks.push_front(functor);
00221 else if (position == ArListPos::LAST)
00222 myDeactivateCallbacks.push_back(functor);
00223 else
00224 ArLog::log(ArLog::Terse,
00225 "ArActionRatioInput::addDeactivateCallback: Invalid position.");
00226 }
00227
00228 void ArActionRatioInput::remDeactivateCallback(ArFunctor *functor)
00229 {
00230 myDeactivateCallbacks.remove(functor);
00231 }
00232
00233 void ArActionRatioInput::activate(void)
00234 {
00235 std::list<ArFunctor *>::iterator it;
00236
00237 if (!isActive())
00238 {
00239 myTransRatio = 0;
00240 myRotRatio = 0;
00241 myThrottleRatio = 0;
00242 for (it = myActivateCallbacks.begin();
00243 it != myActivateCallbacks.end();
00244 it++)
00245 (*it)->invoke();
00246 }
00247 ArAction::activate();
00248 }
00249
00250 void ArActionRatioInput::deactivate(void)
00251 {
00252 std::list<ArFunctor *>::iterator it;
00253
00254 if (!isActive())
00255 {
00256 myTransRatio = 0;
00257 myRotRatio = 0;
00258 myThrottleRatio = 0;
00259 for (it = myDeactivateCallbacks.begin();
00260 it != myDeactivateCallbacks.end();
00261 it++)
00262 (*it)->invoke();
00263 }
00264 ArAction::deactivate();
00265 }
00266
00267 ArActionDesired *ArActionRatioInput::fire(
00268 ArActionDesired currentDesired)
00269 {
00270 std::multimap<int, ArFunctor *>::iterator it;
00271
00272
00273 for (it = myFireCallbacks.begin(); it != myFireCallbacks.end(); it++)
00274 {
00275 (*it).second->invoke();
00276
00277
00278
00279
00280 }
00281
00282 myDesired.reset();
00283
00284 if (myPrinting)
00285 printf("trans %.0f rot %.0f\n", myTransRatio, myRotRatio);
00286
00287 double fullThrottleForwards, fullThrottleBackwards;
00288 double rotAtFullForwards, rotAtFullBackwards, rotAtStopped;
00289
00290 if (myFullThrottleForwards < 1)
00291 fullThrottleForwards = myRobot->getTransVelMax();
00292 else
00293 fullThrottleForwards = myFullThrottleForwards;
00294
00295 if (myFullThrottleBackwards < 1)
00296 fullThrottleBackwards = myRobot->getTransVelMax() / 4;
00297 else
00298 fullThrottleBackwards = myFullThrottleBackwards;
00299
00300 if (myRotAtFullForwards < 1)
00301 rotAtFullForwards = myRobot->getRotVelMax() / 2;
00302 else
00303 rotAtFullForwards = myRotAtFullForwards;
00304
00305 if (myRotAtFullBackwards < 1)
00306 rotAtFullBackwards = myRobot->getRotVelMax() / 2;
00307 else
00308 rotAtFullBackwards = myRotAtFullBackwards;
00309
00310 if (myRotAtStopped < 1)
00311 rotAtStopped = myRobot->getRotVelMax();
00312 else
00313 rotAtStopped = myRotAtStopped;
00314
00315
00316
00317 if (myTransRatio > myTransDeadZone)
00318 {
00319 myDesired.setVel(myTransRatio/100.0 *
00320 fullThrottleForwards * myThrottleRatio/100.0);
00321
00322
00323 double speedRatio = fabs(myRobot->getVel() / fullThrottleForwards);
00324 if (ArMath::fabs(myRotRatio) < myRotDeadZone)
00325 myDesired.setRotVel(0);
00326 else
00327 myDesired.setRotVel(
00328 myRotRatio/100.0 * ((rotAtFullForwards - rotAtStopped) *
00329 speedRatio + rotAtStopped));
00330 if (myPrinting)
00331 printf("forwards %.0f %.0f %.0f %.0f\n", myRotRatio/100.0, rotAtFullForwards - rotAtStopped, speedRatio, rotAtStopped);
00332
00333 }
00334
00335 else if (myTransRatio < -myTransDeadZone)
00336 {
00337 myDesired.setVel(myTransRatio/100.0 *
00338 fullThrottleBackwards * myThrottleRatio/100.0);
00339
00340
00341 double speedRatio = fabs(myRobot->getVel() / fullThrottleForwards);
00342 if (ArMath::fabs(myRotRatio) < myRotDeadZone)
00343 myDesired.setRotVel(0);
00344 else
00345 myDesired.setRotVel(
00346 myRotRatio/100.0 * ((rotAtFullBackwards - rotAtStopped) *
00347 speedRatio + rotAtStopped));
00348 if (myPrinting)
00349 printf("backwards %.0f %.0f %.0f %.0f\n", myRotRatio/100.0, rotAtFullForwards - rotAtStopped, speedRatio, rotAtStopped);
00350 }
00351 else
00352 {
00353 myDesired.setVel(0);
00354 if (ArMath::fabs(myRotRatio) < myRotDeadZone)
00355 myDesired.setRotVel(0);
00356 else
00357 myDesired.setRotVel(myRotRatio/100.0 * rotAtStopped);
00358 }
00359
00360 if (myPrinting)
00361 printf("ratioInput %.0f %.0f\n", myDesired.getVel(), myDesired.getRotVel());
00362
00363
00364
00365 if ((myRobot->getVel() > 0 && myTransRatio < -50) ||
00366 (myRobot->getVel() < 0 && myTransRatio > 50))
00367 {
00368 if (myPrinting)
00369 printf("Decelerating trans more\n");
00370 myDesired.setTransDecel(myRobot->getTransDecel() * 3,
00371 ArActionDesired::MIN_STRENGTH);
00372 }
00373
00374
00375
00376 if ((myRobot->getRotVel() > 0 && myRotRatio < -50) ||
00377 (myRobot->getRotVel() < 0 && myRotRatio > 50))
00378 {
00379 if (myPrinting)
00380 printf("Decelerating rot more\n");
00381 myDesired.setRotDecel(myRobot->getRotDecel() * 3,
00382 ArActionDesired::MIN_STRENGTH);
00383 }
00384
00385 return &myDesired;
00386 }