Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages | Examples

ArActionRatioInput.cpp

00001 /*
00002 MobileRobots Advanced Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004, 2005 ActivMedia Robotics LLC
00004 Copyright (C) 2006, 2007 MobileRobots Inc.
00005 
00006      This program is free software; you can redistribute it and/or modify
00007      it under the terms of the GNU General Public License as published by
00008      the Free Software Foundation; either version 2 of the License, or
00009      (at your option) any later version.
00010 
00011      This program is distributed in the hope that it will be useful,
00012      but WITHOUT ANY WARRANTY; without even the implied warranty of
00013      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014      GNU General Public License for more details.
00015 
00016      You should have received a copy of the GNU General Public License
00017      along with this program; if not, write to the Free Software
00018      Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019 
00020 If you wish to redistribute ARIA under different terms, contact 
00021 MobileRobots for information about a commercial version of ARIA at 
00022 robots@mobilerobots.com or 
00023 MobileRobots Inc, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
00024 */
00025 
00026 #include "ArExport.h"
00027 #include "ariaOSDef.h"
00028 #include "ArActionRatioInput.h"
00029 #include "ArRobot.h"
00033 AREXPORT ArActionRatioInput::ArActionRatioInput(const char *name) :
00034     ArAction(name, "RatioInputs vel and heading")
00035 {
00036   myTransRatio = 0;
00037   myRotRatio = 0;
00038   myThrottleRatio = 0;
00039   myFullThrottleForwards = 0;
00040   myFullThrottleBackwards = 0;
00041   myRotAtFullForwards = 25;
00042   myRotAtFullBackwards = 25;
00043   myRotAtStopped = 50;
00044 
00045   myFullThrottleForwards = 0;
00046   myFullThrottleBackwards = 0;
00047   myRotAtFullForwards = 0;
00048   myRotAtFullBackwards = 0;
00049   myRotAtStopped = 0;
00050   myPrinting = false;
00051 
00052   myTransDeadZone = 10;
00053   myRotDeadZone = 5;
00054 }
00055 
00056 AREXPORT ArActionRatioInput::~ArActionRatioInput()
00057 {
00058 }
00059 
00060 AREXPORT void ArActionRatioInput::addToConfig(ArConfig *config, 
00061                           const char *section)
00062 {
00063   config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), section, ArPriority::NORMAL);
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   config->addParam(ArConfigArg(ArConfigArg::SEPARATOR), section, ArPriority::NORMAL);
00090 }
00091 
00095 AREXPORT void ArActionRatioInput::setRatios(double transRatio, 
00096                         double rotRatio, 
00097                         double throttleRatio)
00098 {
00099   setTransRatio(transRatio);
00100   setRotRatio(rotRatio);
00101   setThrottleRatio(throttleRatio);
00102 }
00103 
00108 AREXPORT void ArActionRatioInput::setTransRatio(double transRatio)
00109 {
00110   if (transRatio > 100)
00111     myTransRatio = 100;
00112   else if (transRatio < -100)
00113     myTransRatio = -100;
00114   else
00115     myTransRatio = transRatio;
00116 }
00117 
00122 AREXPORT void ArActionRatioInput::setRotRatio(double rotRatio)
00123 {
00124   if (rotRatio > 100)
00125     myRotRatio = 100;
00126   else if (rotRatio < -100)
00127     myRotRatio = -100;
00128   else
00129     myRotRatio = rotRatio;
00130 }
00131 
00136 AREXPORT void ArActionRatioInput::setThrottleRatio(double throttleRatio)
00137 {
00138   if (throttleRatio > 100)
00139     myThrottleRatio = 100;
00140   else if (throttleRatio < 0)
00141     myThrottleRatio = 0;
00142   else
00143     myThrottleRatio = throttleRatio;
00144 }
00145 
00159 AREXPORT void ArActionRatioInput::setParameters(double fullThrottleForwards, 
00160                         double fullThrottleBackwards, 
00161                         double rotAtFullForwards,
00162                         double rotAtFullBackwards,
00163                         double rotAtStopped)
00164 {
00165   myFullThrottleForwards = fullThrottleForwards;
00166   myFullThrottleBackwards = fullThrottleBackwards;
00167   myRotAtFullForwards = rotAtFullForwards;
00168   myRotAtFullBackwards = rotAtFullBackwards;
00169   myRotAtStopped = rotAtStopped;
00170 }
00171 
00177 AREXPORT void ArActionRatioInput::addFireCallback(int priority, 
00178                           ArFunctor *functor)
00179 {
00180   myFireCallbacks.insert(std::pair<int, ArFunctor *>(priority, functor));
00181 }
00182 
00183 AREXPORT void ArActionRatioInput::remFireCallback(ArFunctor *functor)
00184 {
00185   std::multimap<int, ArFunctor *>::iterator it;
00186   for (it = myFireCallbacks.begin(); it != myFireCallbacks.end(); it++)
00187   {
00188     if ((*it).second == functor)
00189       break;
00190 
00191   }
00192   if (it != myFireCallbacks.end())
00193   {
00194     myFireCallbacks.erase(it);
00195   }
00196   else 
00197     ArLog::log(ArLog::Normal, "ArActionRatioInput::RemFireCallback: could not remove callback");
00198 }
00199 
00200 AREXPORT void ArActionRatioInput::addActivateCallback(ArFunctor *functor, 
00201                         ArListPos::Pos position)
00202 {
00203   if (position == ArListPos::FIRST)
00204     myActivateCallbacks.push_front(functor);
00205   else if (position == ArListPos::LAST)
00206     myActivateCallbacks.push_back(functor);
00207   else
00208     ArLog::log(ArLog::Terse, 
00209            "ArActionRatioInput::addActivateCallback: Invalid position.");
00210 }
00211 
00212 AREXPORT void ArActionRatioInput::remActivateCallback(ArFunctor *functor)
00213 {
00214   myActivateCallbacks.remove(functor);
00215 }
00216 
00217 AREXPORT void ArActionRatioInput::addDeactivateCallback(ArFunctor *functor, 
00218                         ArListPos::Pos position)
00219 {
00220   if (position == ArListPos::FIRST)
00221     myDeactivateCallbacks.push_front(functor);
00222   else if (position == ArListPos::LAST)
00223     myDeactivateCallbacks.push_back(functor);
00224   else
00225     ArLog::log(ArLog::Terse, 
00226            "ArActionRatioInput::addDeactivateCallback: Invalid position.");
00227 }
00228 
00229 AREXPORT void ArActionRatioInput::remDeactivateCallback(ArFunctor *functor)
00230 {
00231   myDeactivateCallbacks.remove(functor);
00232 }
00233 
00234 AREXPORT void ArActionRatioInput::activate(void)
00235 {
00236   std::list<ArFunctor *>::iterator it;
00237 
00238   if (!isActive())
00239   {
00240     myTransRatio = 0;
00241     myRotRatio = 0;
00242     myThrottleRatio = 0;
00243     for (it = myActivateCallbacks.begin(); 
00244      it != myActivateCallbacks.end(); 
00245      it++)
00246       (*it)->invoke();
00247   }
00248   ArAction::activate();
00249 }
00250 
00251 AREXPORT void ArActionRatioInput::deactivate(void)
00252 {
00253   std::list<ArFunctor *>::iterator it;
00254 
00255   if (!isActive())
00256   {
00257     myTransRatio = 0;
00258     myRotRatio = 0;
00259     myThrottleRatio = 0;
00260     for (it = myDeactivateCallbacks.begin(); 
00261      it != myDeactivateCallbacks.end(); 
00262      it++)
00263       (*it)->invoke();
00264   }
00265   ArAction::deactivate();
00266 }
00267 
00268 AREXPORT ArActionDesired *ArActionRatioInput::fire(
00269     ArActionDesired currentDesired)
00270 {
00271   std::multimap<int, ArFunctor *>::iterator it;
00272   //ArLog::log(ArLog::Normal, "Calling");
00273   // call the callbacks that'll set our ratios
00274   for (it = myFireCallbacks.begin(); it != myFireCallbacks.end(); it++)
00275   {
00276     (*it).second->invoke();
00277     /*ArLog::log(ArLog::Normal, "Called %s now %g %g %g\n", 
00278            (*it).second->getName(), 
00279            myTransRatio, myRotRatio, myThrottleRatio);
00280     */
00281   }
00282   
00283   myDesired.reset();
00284 
00285   if (myPrinting)
00286     printf("trans %.0f rot %.0f\n", myTransRatio, myRotRatio);
00287 
00288   double fullThrottleForwards, fullThrottleBackwards;
00289   double rotAtFullForwards, rotAtFullBackwards, rotAtStopped;
00290 
00291   if (myFullThrottleForwards < 1)
00292     fullThrottleForwards = myRobot->getTransVelMax();
00293   else
00294     fullThrottleForwards = myFullThrottleForwards;
00295 
00296   if (myFullThrottleBackwards < 1)
00297     fullThrottleBackwards = myRobot->getTransVelMax() / 4;
00298   else
00299     fullThrottleBackwards = myFullThrottleBackwards;
00300 
00301   if (myRotAtFullForwards < 1)
00302     rotAtFullForwards = myRobot->getRotVelMax() / 2;
00303   else
00304     rotAtFullForwards = myRotAtFullForwards;
00305 
00306   if (myRotAtFullBackwards < 1)
00307     rotAtFullBackwards = myRobot->getRotVelMax() / 2;
00308   else
00309     rotAtFullBackwards = myRotAtFullBackwards;
00310 
00311   if (myRotAtStopped < 1)
00312     rotAtStopped = myRobot->getRotVelMax();
00313   else
00314     rotAtStopped = myRotAtStopped;
00315 
00316   //printf("%g %g %g %g %g\n", fullThrottleForwards, fullThrottleBackwards, rotAtFullForwards, rotAtFullBackwards, rotAtStopped);
00317   // forwards
00318   if (myTransRatio > myTransDeadZone)
00319   {
00320     myDesired.setVel(myTransRatio/100.0 * 
00321              fullThrottleForwards * myThrottleRatio/100.0);
00322     //double totalThrottle = ArMath::fabs(myTransRatio/100.0 * 
00323     //myThrottleRatio/100.0);
00324     double speedRatio = fabs(myRobot->getVel() / fullThrottleForwards);
00325     if (ArMath::fabs(myRotRatio) < myRotDeadZone)
00326       myDesired.setRotVel(0);
00327     else
00328       myDesired.setRotVel(
00329           myRotRatio/100.0 * ((rotAtFullForwards - rotAtStopped) * 
00330                   speedRatio + rotAtStopped));
00331     if (myPrinting)
00332       printf("forwards %.0f %.0f %.0f %.0f\n", myRotRatio/100.0, rotAtFullForwards - rotAtStopped, speedRatio, rotAtStopped);
00333 
00334   }
00335   // backwards
00336   else if (myTransRatio < -myTransDeadZone)
00337   {
00338     myDesired.setVel(myTransRatio/100.0 * 
00339              fullThrottleBackwards * myThrottleRatio/100.0);
00340     //double totalThrottle = ArMath::fabs(myTransRatio/100.0 * 
00341     //myThrottleRatio/100.0);
00342     double speedRatio = fabs(myRobot->getVel() / fullThrottleForwards);
00343     if (ArMath::fabs(myRotRatio) < myRotDeadZone)
00344       myDesired.setRotVel(0);
00345     else
00346       myDesired.setRotVel(
00347         myRotRatio/100.0 * ((rotAtFullBackwards - rotAtStopped) * 
00348                 speedRatio + rotAtStopped));
00349     if (myPrinting)
00350       printf("backwards %.0f %.0f %.0f %.0f\n", myRotRatio/100.0, rotAtFullForwards - rotAtStopped, speedRatio, rotAtStopped);
00351   }
00352   else
00353   {
00354     myDesired.setVel(0);
00355     if (ArMath::fabs(myRotRatio) < myRotDeadZone)
00356       myDesired.setRotVel(0);
00357     else
00358       myDesired.setRotVel(myRotRatio/100.0 * rotAtStopped);
00359   }
00360   
00361   if (myPrinting)
00362     printf("ratioInput %.0f %.0f\n", myDesired.getVel(), myDesired.getRotVel());
00363 
00364 
00365   // see if we need to up the decel
00366   if ((myRobot->getVel() > 0 && myTransRatio < -50) || 
00367       (myRobot->getVel() < 0 && myTransRatio > 50))
00368   {
00369     if (myPrinting)
00370       printf("Decelerating trans more\n");
00371     myDesired.setTransDecel(myRobot->getTransDecel() * 3, 
00372                 ArActionDesired::MIN_STRENGTH);
00373   }
00374 
00375   // if they have the stick the opposite direction of the velocity
00376   // then let people crank up the deceleration
00377   if ((myRobot->getRotVel() > 0 && myRotRatio < -50) || 
00378       (myRobot->getRotVel() < 0 && myRotRatio > 50))
00379   {
00380     if (myPrinting)
00381       printf("Decelerating rot more\n");
00382     myDesired.setRotDecel(myRobot->getRotDecel() * 3,
00383               ArActionDesired::MIN_STRENGTH);
00384   }
00385 
00386   return &myDesired;
00387 }

Generated on Tue Feb 20 10:51:38 2007 for Aria by  doxygen 1.4.0