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

ArActionRatioInput.cpp

00001 /*
00002 ActivMedia Robotics Interface for Applications (ARIA)
00003 Copyright (C) 2004,2005 ActivMedia Robotics, LLC
00004 
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 ActivMedia Robotics for information about a commercial version of ARIA at 
00022 robots@activmedia.com or 
00023 ActivMedia Robotics, 19 Columbia Drive, Amherst, NH 03031; 800-639-9481
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   //ArLog::log(ArLog::Normal, "Calling");
00272   // call the callbacks that'll set our ratios
00273   for (it = myFireCallbacks.begin(); it != myFireCallbacks.end(); it++)
00274   {
00275     (*it).second->invoke();
00276     /*ArLog::log(ArLog::Normal, "Called %s now %g %g %g\n", 
00277                (*it).second->getName(), 
00278                myTransRatio, myRotRatio, myThrottleRatio);
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   //printf("%g %g %g %g %g\n", fullThrottleForwards, fullThrottleBackwards, rotAtFullForwards, rotAtFullBackwards, rotAtStopped);
00316   // forwards
00317   if (myTransRatio > myTransDeadZone)
00318   {
00319     myDesired.setVel(myTransRatio/100.0 * 
00320                      fullThrottleForwards * myThrottleRatio/100.0);
00321     //double totalThrottle = ArMath::fabs(myTransRatio/100.0 * 
00322     //myThrottleRatio/100.0);
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   // backwards
00335   else if (myTransRatio < -myTransDeadZone)
00336   {
00337     myDesired.setVel(myTransRatio/100.0 * 
00338                      fullThrottleBackwards * myThrottleRatio/100.0);
00339     //double totalThrottle = ArMath::fabs(myTransRatio/100.0 * 
00340     //myThrottleRatio/100.0);
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   // see if we need to up the decel
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   // if they have the stick the opposite direction of the velocity
00375   // then let people crank up the deceleration
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 }

Generated on Wed Oct 19 12:56:34 2005 for Aria by  doxygen 1.4.0