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

dpptuExample.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 "Aria.h"
00027 
00050 /*
00051   This class is the core of this demo, it adds itself to the robot given
00052   as a user task, and contains key handler callbacks to control the PTU.
00053 */
00054 class KeyPTU
00055 {
00056 public:
00057   // constructor
00058   KeyPTU(ArRobot *robot);
00059   // destructor, its just empty
00060   ~KeyPTU(void) {}
00061   
00062   void up(void);
00063   void down(void);
00064   void left(void);
00065   void right(void);
00066   void space(void);
00067   void i(void);
00068   void plus(void);
00069   void minus(void);
00070   void greater(void);
00071   void less(void);
00072   void question(void);
00073   void status(void);
00074   void a(void);
00075   void z(void);
00076   void m(void);
00077   void h(void);
00078   void r(void);
00079 
00080   // the callback function
00081   void drive(void);
00082 
00083 protected:
00084   int myPanValPTU;
00085   int myTiltValPTU;
00086 
00087   int myDesiredPanPos;
00088   int myDesiredTiltPos;
00089   int mySlew;
00090   int myPosIncrement;
00091   int mySlewIncrement;
00092 
00093   int posIncIncrement;
00094 
00095   bool myMonitor;
00096   bool myReset;
00097   bool myInit;
00098   bool myAbsolute;
00099 
00100   ArFunctorC<KeyPTU> myUpCB;
00101   ArFunctorC<KeyPTU> myDownCB;
00102   ArFunctorC<KeyPTU> myLeftCB;
00103   ArFunctorC<KeyPTU> myRightCB;
00104   ArFunctorC<KeyPTU> mySpaceCB;
00105   ArFunctorC<KeyPTU> myICB;
00106   ArFunctorC<KeyPTU> myPlusCB;
00107   ArFunctorC<KeyPTU> myMinusCB;
00108   ArFunctorC<KeyPTU> myGreaterCB;
00109   ArFunctorC<KeyPTU> myLessCB;
00110   ArFunctorC<KeyPTU> myQuestionCB;
00111   ArFunctorC<KeyPTU> mySCB;
00112   ArFunctorC<KeyPTU> myACB;
00113   ArFunctorC<KeyPTU> myZCB;
00114   ArFunctorC<KeyPTU> myMCB;
00115   ArFunctorC<KeyPTU> myHCB;
00116   ArFunctorC<KeyPTU> myRCB;
00117 
00118 
00119   // the PTU
00120   ArDPPTU myPTU;
00121 
00122   // whether the PTU has been inited or not
00123   bool myPTUInited;
00124   // pointer to the robot
00125   ArRobot *myRobot;
00126   // callback for the drive function
00127   ArFunctorC<KeyPTU> myDriveCB;
00128 };
00129 
00130 /*
00131   Constructor, sets the robot pointer, and some initial values, also note the
00132   use of constructor chaining on myPTU and myDriveCB.
00133 */
00134 KeyPTU::KeyPTU(ArRobot *robot) :
00135   myUpCB(this, &KeyPTU::up),
00136   myDownCB(this, &KeyPTU::down),
00137   myLeftCB(this, &KeyPTU::left),
00138   myRightCB(this, &KeyPTU::right),
00139   mySpaceCB(this, &KeyPTU::space),
00140   myICB(this, &KeyPTU::i),
00141   myPlusCB(this, &KeyPTU::plus),
00142   myMinusCB(this, &KeyPTU::minus),
00143   myGreaterCB(this, &KeyPTU::greater),
00144   myLessCB(this, &KeyPTU::less),
00145   myQuestionCB(this, &KeyPTU::question),
00146   mySCB(this, &KeyPTU::status),
00147   myACB(this, &KeyPTU::a),
00148   myZCB(this, &KeyPTU::z),
00149   myMCB(this, &KeyPTU::m),
00150   myHCB(this, &KeyPTU::h),
00151   myRCB(this, &KeyPTU::r),
00152   myPTU(robot),
00153   myDriveCB(this, &KeyPTU::drive)
00154 {
00155   // set the robot pointer and add the KeyPTU as user task
00156   ArKeyHandler *keyHandler;
00157   myRobot = robot;
00158   myRobot->addSensorInterpTask("KeyPTU", 50, &myDriveCB);
00159 
00160   if ((keyHandler = Aria::getKeyHandler()) == NULL)
00161   {
00162     keyHandler = new ArKeyHandler;
00163     Aria::setKeyHandler(keyHandler);
00164     myRobot->attachKeyHandler(keyHandler);
00165   }
00166 
00167   if (!keyHandler->addKeyHandler(ArKeyHandler::UP, &myUpCB))
00168     ArLog::log(ArLog::Terse, "The key handler already has a key for up, keydrive will not work correctly.");
00169   if (!keyHandler->addKeyHandler(ArKeyHandler::DOWN, &myDownCB))
00170     ArLog::log(ArLog::Terse, "The key handler already has a key for down, keydrive will not work correctly.");
00171   if (!keyHandler->addKeyHandler(ArKeyHandler::LEFT, &myLeftCB))
00172     ArLog::log(ArLog::Terse,  
00173 "The key handler already has a key for left, keydrive will not work correctly.");
00174   if (!keyHandler->addKeyHandler(ArKeyHandler::RIGHT, &myRightCB))
00175     ArLog::log(ArLog::Terse,  
00176 "The key handler already has a key for right, keydrive will not work correctly.");
00177   if (!keyHandler->addKeyHandler(ArKeyHandler::SPACE, &mySpaceCB))
00178     ArLog::log(ArLog::Terse,
00179 "The key handler already has a key for space, keydrive will not work correctly.");
00180   if (!keyHandler->addKeyHandler('i', &myICB))
00181     ArLog::log(ArLog::Terse,
00182 "The key handler already has a key for 'i', keydrive will not work correctly.");
00183   if (!keyHandler->addKeyHandler('+', &myPlusCB))
00184     ArLog::log(ArLog::Terse,
00185 "The key handler already has a key for '+', keydrive will not work correctly.");
00186   if (!keyHandler->addKeyHandler('-', &myMinusCB))
00187     ArLog::log(ArLog::Terse,
00188 "The key handler already has a key for '-', keydrive will not work correctly.");
00189   if (!keyHandler->addKeyHandler('>', &myGreaterCB))
00190     ArLog::log(ArLog::Terse,
00191 "The key handler already has a key for '>', keydrive will not work correctly.");
00192   if (!keyHandler->addKeyHandler('<', &myLessCB))
00193     ArLog::log(ArLog::Terse,
00194 "The key handler already has a key for '<', keydrive will not work correctly.");
00195   if (!keyHandler->addKeyHandler('?', &myQuestionCB))
00196     ArLog::log(ArLog::Terse,
00197 "The key handler already has a key for '?', keydrive will not work correctly.");
00198   if (!keyHandler->addKeyHandler('s', &mySCB))
00199     ArLog::log(ArLog::Terse,
00200 "The key handler already has a key for 'S', keydrive will not work correctly.");
00201   if (!keyHandler->addKeyHandler('a', &myACB))
00202     ArLog::log(ArLog::Terse,
00203 "The key handler already has a key for 'A', keydrive will not work correctly.");
00204   if (!keyHandler->addKeyHandler('z', &myZCB))
00205     ArLog::log(ArLog::Terse,
00206 "The key handler already has a key for 'Z', keydrive will not work correctly.");
00207   if (!keyHandler->addKeyHandler('m', &myMCB))
00208     ArLog::log(ArLog::Terse,
00209 "The key handler already has a key for 'M', keydrive will not work correctly.");
00210   if (!keyHandler->addKeyHandler('h', &myHCB))
00211     ArLog::log(ArLog::Terse,
00212 "The key handler already has a key for 'H', keydrive will not work correctly.");
00213   if (!keyHandler->addKeyHandler('r', &myRCB))
00214     ArLog::log(ArLog::Terse,
00215 "The key handler already has a key for 'R', keydrive will not work correctly.");
00216 
00217   // initialize some variables
00218   myReset = false;
00219   myInit = true;
00220   myDesiredPanPos = 0;
00221   myDesiredTiltPos = 0;
00222   myPosIncrement = 1;
00223   mySlewIncrement = 1;
00224   myPTUInited = false;
00225   posIncIncrement = 1;
00226   myMonitor = false;
00227 
00228 }
00229 
00230 
00231 
00232 void KeyPTU::left(void)
00233 {
00234   myDesiredPanPos += myPosIncrement;
00235 
00236   if (myDesiredPanPos > myPTU.getMaxPosPan())
00237     myDesiredPanPos = myPTU.getMaxPosPan();
00238 }
00239 
00240 void KeyPTU::right(void)
00241 {
00242   myDesiredPanPos -= myPosIncrement;
00243 
00244   if (myDesiredPanPos < myPTU.getMaxNegPan())
00245     myDesiredPanPos = myPTU.getMaxNegPan();
00246 }
00247 
00248 void KeyPTU::up(void)
00249 {
00250   myDesiredTiltPos += myPosIncrement;
00251  
00252   if (myDesiredTiltPos > myPTU.getMaxPosTilt())
00253     myDesiredTiltPos = myPTU.getMaxPosTilt();
00254 }
00255 
00256 void KeyPTU::down(void)
00257 {
00258   myDesiredTiltPos -= myPosIncrement;
00259 
00260   if (myDesiredTiltPos < myPTU.getMaxNegTilt())
00261     myDesiredTiltPos = myPTU.getMaxNegTilt();
00262 }
00263 
00264 void KeyPTU::space(void)
00265 {
00266   myReset = true;
00267 }
00268 
00269 void KeyPTU::i(void)
00270 {
00271   myInit = true;
00272 }
00273 
00274 void KeyPTU::plus(void)
00275 {
00276   mySlew += mySlewIncrement;
00277 
00278   if (mySlew > myPTU.getMaxPanSlew())
00279     mySlew = myPTU.getMaxPanSlew();
00280 
00281   status();
00282 }
00283 
00284 void KeyPTU::minus(void)
00285 {
00286   mySlew -= mySlewIncrement;
00287 
00288   if (mySlew < myPTU.getMinPanSlew())
00289     mySlew = myPTU.getMinPanSlew();
00290 
00291   status();
00292 }
00293 
00294 void KeyPTU::greater(void)
00295 {
00296   myPosIncrement += posIncIncrement;
00297   
00298   if (myPosIncrement > myPTU.getMaxPosPan())
00299     myPosIncrement = myPTU.getMaxPosPan();
00300 
00301   status();
00302 }
00303 
00304 void KeyPTU::less(void)
00305 {
00306   myPosIncrement -= posIncIncrement;
00307 
00308   if (myPosIncrement < 0)
00309     myPosIncrement = 0;
00310 
00311   status();
00312 }
00313 
00314 void KeyPTU::a(void)
00315 {
00316   myPTU.awaitExec();   
00317   ArLog::log(ArLog::Normal, "AwaitExecution command sent");
00318 }
00319 
00320 void KeyPTU::z(void)
00321 {
00322   myPTU.pan(0);
00323   myPTU.awaitExec();
00324   myPTU.tilt(0);
00325   myPTU.awaitExec();
00326   myDesiredPanPos = 0;
00327   myDesiredTiltPos = 0;
00328   status();
00329 }
00330 
00331 void KeyPTU::question(void)
00332 {
00333   ArLog::log(ArLog::Normal, "\r\nCommands:\r\n_________________\r\n");
00334   ArLog::log(ArLog::Normal, "UP,DOWN    -- tilt up/down by one positional increment");
00335   ArLog::log(ArLog::Normal, "LEFT,RIGHT -- pan left/right by one positional increment");
00336   ArLog::log(ArLog::Normal, "SPACE      -- perform reset calibration");
00337   ArLog::log(ArLog::Normal, "I          -- initialize PTU to default settings");
00338   ArLog::log(ArLog::Normal, "<,>        -- increase/decrease the posIncrement by 1 degree");
00339   ArLog::log(ArLog::Normal, "+,-        -- increase/decrease the speed by 1 degree/sec");
00340   ArLog::log(ArLog::Normal, "A          -- awaits the completion of last issued positional command");
00341   ArLog::log(ArLog::Normal, "R          -- change pan/tilt movements to relative or absolute movements");
00342   ArLog::log(ArLog::Normal, "Z          -- move pan and tilt axes to zero");
00343   ArLog::log(ArLog::Normal, "M          -- Enter or Exit monitor mode");
00344   ArLog::log(ArLog::Normal, "H          -- Halt all motion");
00345   ArLog::log(ArLog::Normal, "S          -- print current variable values");
00346   ArLog::log(ArLog::Normal, "ESC        -- exit program");
00347   ArLog::log(ArLog::Normal, "\r\n");
00348 }
00349 
00350 void KeyPTU::status(void)
00351 {
00352   ArLog::log(ArLog::Normal, "\r\nStatus:\r\n_________________\r\n");
00353   ArLog::log(ArLog::Normal, "Pan Position       = %d deg", myPTU.getPan());
00354   ArLog::log(ArLog::Normal, "Tilt Position      = %d deg", myPTU.getTilt());
00355   ArLog::log(ArLog::Normal, "Pan Slew Rate      = %d deg/sec", myPTU.getPanSlew());
00356   ArLog::log(ArLog::Normal, "Tilt Slew Rate     = %d deg/sec", myPTU.getTiltSlew());
00357   ArLog::log(ArLog::Normal, "Position Increment = %d deg", myPosIncrement);
00358   if (myAbsolute)
00359     ArLog::log(ArLog::Normal, "Positional-movements using absolute commands");
00360   else
00361     ArLog::log(ArLog::Normal, "Positional-movements using relative commands");
00362   ArLog::log(ArLog::Normal, "\r\n");
00363 }
00364 
00365 void KeyPTU::m(void)
00366 {
00367   if (!myMonitor)
00368   {
00369     ArLog::log(ArLog::Normal, "Entering Monitor mode - hit 'M' to disable");
00370     myMonitor = true;
00371     myPTU.initMon(-60,60,30,-30);
00372   }
00373   else
00374   {
00375     myPTU.blank();  //Blank packet exits monitor mode
00376     myMonitor = false;
00377   }
00378 }
00379 
00380 void KeyPTU::h(void)
00381 {
00382   myPTU.haltAll();
00383 }
00384 
00385 void KeyPTU::r(void)
00386 {
00387   if (!myAbsolute)
00388   {
00389     myAbsolute = true;
00390   }
00391   else
00392   {
00393     myAbsolute = false;
00394   }
00395   status();
00396 }
00397 
00398 
00399 // the important function
00400 void KeyPTU::drive(void)
00401 {
00402 
00403   // if the PTU isn't initialized, initialize it here... it has to be 
00404   // done here instead of above because it needs to be done when the 
00405   // robot is connected
00406   if (!myPTUInited && myRobot->isConnected())
00407   {
00408     myPTU.init();
00409     myPTU.resetCalib();
00410     myPTU.awaitExec();
00411     myPTU.regStatPower();
00412     myPTU.regMotPower();
00413     mySlew = myPTU.getPanSlew(); //uses only pan slew rate
00414     myPTU.awaitExec();
00415     myPTUInited = true;
00416     myInit = false;
00417     myAbsolute = true;
00418   }
00419 
00420   if (myInit == true)
00421   {
00422     myPTU.init();
00423     myInit = false;
00424     myDesiredPanPos = myPTU.getPan();
00425     myDesiredTiltPos = myPTU.getTilt();
00426     mySlew = myPTU.getPanSlew(); //uses only pan slew rate
00427     myReset = false;
00428   }
00429 
00430   if (myReset == true)
00431   {
00432     myPTU.resetCalib();
00433     myPTU.awaitExec();
00434     myDesiredPanPos = myPTU.getPan();
00435     myDesiredTiltPos = myPTU.getTilt();
00436     myReset = false;
00437   }
00438   else
00439   {
00440 
00441     if (myDesiredPanPos != myPTU.getPan())
00442     {
00443       if (myAbsolute)
00444         myPTU.pan(myDesiredPanPos);
00445       else
00446         myPTU.panRel(myDesiredPanPos - myPTU.getPan());
00447     }
00448 
00449     if (myDesiredTiltPos != myPTU.getTilt())
00450     {
00451       if (myAbsolute)
00452         myPTU.tilt(myDesiredTiltPos);
00453       else
00454         myPTU.tiltRel(myDesiredTiltPos - myPTU.getTilt());
00455     }
00456 
00457     if (mySlew != myPTU.getPanSlew())
00458     {
00459       myPTU.panSlew(mySlew);
00460       myPTU.tiltSlew(mySlew);
00461     }
00462 
00463   }
00464 
00465 }
00466 
00467 int main(int argc, char **argv) 
00468 {
00469   std::string str;
00470   int ret;
00471   
00472   Aria::init();
00473 
00474   // command-line arguments and robots connection
00475   ArArgumentParser argParser(&argc, argv);
00476   argParser.loadDefaultArguments();
00477   ArSimpleConnector con(&argParser);
00478 
00479   // the robot, but turn state reflection off (so we have no mobility control in
00480   // this program)
00481   ArRobot robot(NULL, false);
00482 
00483   // an object for keyboard control, class defined above, this also adds itself as a user task
00484   KeyPTU ptu(&robot);
00485 
00486   // parse command-line arguments (i.e. connection options for simple connector)
00487   if(!Aria::parseArgs())
00488   {
00489     Aria::logOptions();
00490     return 1;
00491   }
00492 
00493   // connect to the robot
00494   if (!con.connectRobot(&robot))
00495   {
00496     ArLog::log(ArLog::Terse, "Error connecting to robot!");
00497     Aria::shutdown();
00498     return 1;
00499   }
00500 
00501 
00502   // turn off the sonar
00503   robot.comInt(ArCommands::SONAR, 0);
00504 
00505   printf("Press '?' for available commands\r\n");
00506 
00507   // run, if we lose connection to the robot, exit
00508   robot.run(true);
00509   
00510   Aria::shutdown();
00511   return 0;
00512 }
00513 

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