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

vcc4CameraExample.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 
00051 /*
00052   This class is the core of this demo, it adds itself to the robot given
00053   as a user task, then drives the PTZ camera from the keyboard
00054 */
00055 class KeyPTU
00056 {
00057 public:
00058   // constructor
00059   KeyPTU(ArRobot *robot);
00060   // destructor, its just empty
00061   ~KeyPTU(void) {}
00062   
00063   void up(void);
00064   void down(void);
00065   void left(void);
00066   void right(void);
00067 
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 
00075   void c(void);
00076   void h(void);
00077   void i(void);
00078   void p(void);
00079   void x(void);
00080   void z(void);
00081 
00082   void r(void);
00083   // the callback function
00084   void drive(void);
00085 
00086 protected:
00087 
00088   ArTime myExerciseTime;
00089 
00090   int myPanSlew;
00091   int myTiltSlew;
00092   int myPosIncrement;
00093   int mySlewIncrement;
00094   int myZoomIncrement;
00095 
00096   bool myMonitor;
00097   bool myInit;
00098   bool myAbsolute;
00099   bool myExercise;
00100 
00101   void exercise(void) { myExercise = !myExercise; }
00102   void autoupdate(void);
00103 
00104   ArFunctorC<KeyPTU> myUpCB;
00105   ArFunctorC<KeyPTU> myDownCB;
00106   ArFunctorC<KeyPTU> myLeftCB;
00107   ArFunctorC<KeyPTU> myRightCB;
00108 
00109   ArFunctorC<KeyPTU> myPlusCB;
00110   ArFunctorC<KeyPTU> myMinusCB;
00111   ArFunctorC<KeyPTU> myGreaterCB;
00112   ArFunctorC<KeyPTU> myLessCB;
00113   ArFunctorC<KeyPTU> myQuestionCB;
00114   ArFunctorC<KeyPTU> mySCB;
00115 
00116   ArFunctorC<KeyPTU> myECB;
00117   ArFunctorC<KeyPTU> myACB;
00118 
00119   ArFunctorC<KeyPTU> myCCB;
00120   ArFunctorC<KeyPTU> myHCB;
00121   ArFunctorC<KeyPTU> myICB;
00122   ArFunctorC<KeyPTU> myPCB;
00123   ArFunctorC<KeyPTU> myXCB;
00124   ArFunctorC<KeyPTU> myZCB;
00125 
00126   ArFunctorC<KeyPTU> myRCB;
00127 
00128   // the PTU
00129   ArVCC4 myPTU;
00130 
00131   // the serial connection, in case we are connected to a computer
00132   // serial port
00133   ArSerialConnection myCon;
00134 
00135   // whether or not we've requested that the Camera initialize itself
00136   bool myPTUInitRequested;
00137   // pointer to the robot
00138   ArRobot *myRobot;
00139   // callback for the drive function
00140   ArFunctorC<KeyPTU> myDriveCB;
00141 };
00142 
00143 /*
00144   Constructor, sets the robot pointer, and some initial values, also note the
00145   use of constructor chaining on myPTU and myDriveCB.
00146 */
00147 KeyPTU::KeyPTU(ArRobot *robot) :
00148   myUpCB(this, &KeyPTU::up),
00149   myDownCB(this, &KeyPTU::down),
00150   myLeftCB(this, &KeyPTU::left),
00151   myRightCB(this, &KeyPTU::right),
00152   myPlusCB(this, &KeyPTU::plus),
00153   myMinusCB(this, &KeyPTU::minus),
00154   myGreaterCB(this, &KeyPTU::greater),
00155   myLessCB(this, &KeyPTU::less),
00156   myQuestionCB(this, &KeyPTU::question),
00157   mySCB(this, &KeyPTU::status),
00158   myECB(this, &KeyPTU::exercise),
00159   myACB(this, &KeyPTU::autoupdate),
00160   myCCB(this, &KeyPTU::c),
00161   myHCB(this, &KeyPTU::h),
00162   myICB(this, &KeyPTU::i),
00163   myPCB(this, &KeyPTU::p),
00164   myXCB(this, &KeyPTU::x),
00165   myZCB(this, &KeyPTU::z),
00166   myRCB(this, &KeyPTU::r),
00167 
00168   myPTU(robot),
00169   myDriveCB(this, &KeyPTU::drive)
00170 {
00171   // set the robot pointer and add the KeyPTU as user task
00172   ArKeyHandler *keyHandler;
00173   myRobot = robot;
00174   myRobot->addSensorInterpTask("KeyPTU", 50, &myDriveCB);
00175 
00176   myPTU.setLEDControlMode(2);
00177   myExerciseTime.setToNow();
00178   myExercise = false;
00179 
00180 //  SETPORT Uncomment the following to run the camera off
00181 //  of the computer's serial port, rather than the microcontroller
00182 
00183 // uncomment below here
00184 /*
00185 #ifdef WIN32
00186   myCon.setPort("COM2");
00187 #else
00188   myCon.setPort("/dev/ttyS0");
00189 #endif
00190   myPTU.setDeviceConnection(&myCon);
00191 */
00192 // to here
00193 
00194   // or use this next line to set the aux port 
00195  //myPTU.setAuxPort(2);
00196 
00197 
00198   if ((keyHandler = Aria::getKeyHandler()) == NULL)
00199   {
00200     keyHandler = new ArKeyHandler;
00201     Aria::setKeyHandler(keyHandler);
00202     myRobot->attachKeyHandler(keyHandler);
00203   }
00204 
00205   if (!keyHandler->addKeyHandler(ArKeyHandler::UP, &myUpCB))
00206     ArLog::log(ArLog::Terse, "The key handler already has a key for up, keydrive will not work correctly.");
00207   if (!keyHandler->addKeyHandler(ArKeyHandler::DOWN, &myDownCB))
00208     ArLog::log(ArLog::Terse, "The key handler already has a key for down, keydrive will not work correctly.");
00209   if (!keyHandler->addKeyHandler(ArKeyHandler::LEFT, &myLeftCB))
00210     ArLog::log(ArLog::Terse,  
00211 "The key handler already has a key for left, keydrive will not work correctly.");
00212   if (!keyHandler->addKeyHandler(ArKeyHandler::RIGHT, &myRightCB))
00213     ArLog::log(ArLog::Terse,  
00214 "The key handler already has a key for right, keydrive will not work correctly.");
00215 
00216   if (!keyHandler->addKeyHandler('+', &myPlusCB))
00217     ArLog::log(ArLog::Terse,
00218 "The key handler already has a key for '+', keydrive will not work correctly.");
00219   if (!keyHandler->addKeyHandler('-', &myMinusCB))
00220     ArLog::log(ArLog::Terse,
00221 "The key handler already has a key for '-', keydrive will not work correctly.");
00222   if (!keyHandler->addKeyHandler('>', &myGreaterCB))
00223     ArLog::log(ArLog::Terse,
00224 "The key handler already has a key for '>', keydrive will not work correctly.");
00225   if (!keyHandler->addKeyHandler('<', &myLessCB))
00226     ArLog::log(ArLog::Terse,
00227 "The key handler already has a key for '<', keydrive will not work correctly.");
00228   if (!keyHandler->addKeyHandler('?', &myQuestionCB))
00229     ArLog::log(ArLog::Terse,
00230 "The key handler already has a key for '?', keydrive will not work correctly.");
00231 
00232   if (!keyHandler->addKeyHandler('c', &myCCB))
00233     ArLog::log(ArLog::Terse,
00234 "The key handler already has a key for 'C', keydrive will not work correctly.");
00235   if (!keyHandler->addKeyHandler('h', &myHCB))
00236     ArLog::log(ArLog::Terse,
00237 "The key handler already has a key for 'H', keydrive will not work correctly.");
00238   if (!keyHandler->addKeyHandler('i', &myICB))
00239     ArLog::log(ArLog::Terse,
00240 "The key handler already has a key for 'I', keydrive will not work correctly.");
00241   if (!keyHandler->addKeyHandler('p', &myPCB))
00242     ArLog::log(ArLog::Terse,
00243 "The key handler already has a key for 'P', keydrive will not work correctly.");
00244   if (!keyHandler->addKeyHandler('r', &myRCB))
00245     ArLog::log(ArLog::Terse,
00246 "The key handler already has a key for 'R', keydrive will not work correctly.");
00247 
00248   if (!keyHandler->addKeyHandler('s', &mySCB))
00249     ArLog::log(ArLog::Terse,
00250 "The key handler already has a key for 'S', keydrive will not work correctly.");
00251   if (!keyHandler->addKeyHandler('x', &myXCB))
00252     ArLog::log(ArLog::Terse,
00253 "The key handler already has a key for 'X', keydrive will not work correctly.");
00254   if (!keyHandler->addKeyHandler('z', &myZCB))
00255     ArLog::log(ArLog::Terse,
00256 "The key handler already has a key for 'Z', keydrive will not work correctly.");
00257   if (!keyHandler->addKeyHandler('a', &myACB))
00258     ArLog::log(ArLog::Terse, "The key handler already has a key for 'A', keydrive will not work correctly.");
00259   if (!keyHandler->addKeyHandler('e', &myECB))
00260     ArLog::log(ArLog::Terse, "The key handler already has a key for 'E', keydrive will not work correctly.");
00261 
00262 
00263 
00264   // initialize some variables
00265 
00266   myPTUInitRequested = false;
00267   myPosIncrement = 1;
00268   mySlewIncrement = 5;
00269   myZoomIncrement = 50;
00270 
00271 }
00272 
00273 void KeyPTU::autoupdate(void)
00274 {
00275   if (myPTU.getAutoUpdate())
00276     myPTU.disableAutoUpdate();
00277   else
00278     myPTU.enableAutoUpdate();
00279 }
00280 
00281 void KeyPTU::right(void)
00282 {
00283   myPTU.panRel(myPosIncrement);
00284 }
00285 
00286 void KeyPTU::left(void)
00287 {
00288   myPTU.panRel(-myPosIncrement);
00289 }
00290 
00291 void KeyPTU::up(void)
00292 {
00293   myPTU.tiltRel(myPosIncrement);
00294 }
00295 
00296 void KeyPTU::down(void)
00297 {
00298   myPTU.tiltRel(-myPosIncrement);
00299 }
00300 
00301 void KeyPTU::x(void)
00302 {
00303   myPTU.zoom(myPTU.getZoom() + myZoomIncrement);
00304 }
00305 
00306 void KeyPTU::c(void)
00307 {
00308   myPTU.zoom(myPTU.getZoom() - myZoomIncrement);
00309 }
00310 
00311 void KeyPTU::i(void)
00312 {
00313   myPTU.init();
00314 }
00315 
00316 void KeyPTU::plus(void)
00317 {
00318   myPTU.panSlew(myPTU.getPanSlew() + mySlewIncrement);
00319   myPTU.tiltSlew(myPTU.getTiltSlew() + mySlewIncrement);
00320 
00321   status();
00322 }
00323 
00324 void KeyPTU::minus(void)
00325 {
00326   myPTU.panSlew(myPTU.getPanSlew() - mySlewIncrement);
00327   myPTU.tiltSlew(myPTU.getTiltSlew() - mySlewIncrement);
00328 
00329   status();
00330 }
00331 
00332 void KeyPTU::greater(void)
00333 {
00334   myPosIncrement += 1;
00335   
00336   if (myPosIncrement > myPTU.getMaxPosPan())            //Use pan range as reference for largest allowable positional increment
00337     myPosIncrement = myPTU.getMaxPosPan();
00338 
00339   status();
00340 }
00341 
00342 void KeyPTU::less(void)
00343 {
00344   myPosIncrement -= 1;
00345 
00346   if (myPosIncrement < 0)
00347     myPosIncrement = 0;
00348 
00349   status();
00350 }
00351 
00352 
00353 void KeyPTU::z(void)
00354 {
00355   myPTU.panTilt(0,0);
00356   myPTU.zoom(0);
00357   status();
00358 }
00359 
00360 
00361 void KeyPTU::r(void)
00362 {
00363   myPTU.reset();
00364 }
00365 
00366 
00367 void KeyPTU::question(void)
00368 {
00369   ArLog::log(ArLog::Normal, "\r\nCommands:\r\n_________________\r\n");
00370   ArLog::log(ArLog::Normal, "UP,DOWN     -- tilt up/down by 1 increment");
00371   ArLog::log(ArLog::Normal, "LEFT,RIGHT  -- pan left/right by 1 increment");
00372   ArLog::log(ArLog::Normal, "X,C         -- zoom in/out by 50 units (2140 max)");
00373   ArLog::log(ArLog::Normal, "I           -- initialize PTU to default settings");
00374   ArLog::log(ArLog::Normal, ">,<         -- increase/decrease the positional increment by 1 degree");
00375   ArLog::log(ArLog::Normal, "+,-         -- increase/decrease the slew by 5 degrees/sec");
00376   ArLog::log(ArLog::Normal, "Z           -- move pan and tilt axes to zero");
00377   ArLog::log(ArLog::Normal, "E       -- toggle exercise mode");
00378   ArLog::log(ArLog::Normal, "A       -- toggle autoupdate mode");
00379   ArLog::log(ArLog::Normal, "H           -- Halt all motion");
00380   ArLog::log(ArLog::Normal, "S           -- Status of camera position and variable values");
00381   ArLog::log(ArLog::Normal, "P           -- Power on/off the camera");
00382   ArLog::log(ArLog::Normal, "R           -- Reset the camera");
00383   ArLog::log(ArLog::Normal, "ESC         -- Exit program");
00384   ArLog::log(ArLog::Normal, "\r\n");
00385 }
00386 
00387 void KeyPTU::status(void)
00388 {
00389   ArLog::log(ArLog::Normal, "\r\nStatus:\r\n_________________________\r\n");
00390   ArLog::log(ArLog::Normal, "Pan Position       =  %.0f deg", myPTU.getPan());
00391   ArLog::log(ArLog::Normal, "Tilt Position      =  %.0f deg", myPTU.getTilt());
00392   ArLog::log(ArLog::Normal, "Zoom Position      =  %d", myPTU.getZoom());
00393   ArLog::log(ArLog::Normal, "Pan Slew           =  %d deg/s", myPTU.getPanSlew());
00394   ArLog::log(ArLog::Normal, "Tilt Slew          =  %d deg/s", myPTU.getTiltSlew());
00395   ArLog::log(ArLog::Normal, "Position Increment =  %d deg", myPosIncrement);
00396   ArLog::log(ArLog::Normal, "Autoupdate         =  %d", myPTU.getAutoUpdate());
00397   ArLog::log(ArLog::Normal, "Exercise           =  %d", myExercise);
00398   if (myPTU.getPower())
00399     ArLog::log(ArLog::Normal, "Power is ON");
00400   else
00401     ArLog::log(ArLog::Normal, "Power is OFF");
00402   ArLog::log(ArLog::Normal, "\r\n");
00403 }
00404 
00405 void KeyPTU::h(void)
00406 {
00407   myPTU.haltPanTilt();
00408   myPTU.haltZoom();
00409 }
00410 
00411 void KeyPTU::p(void)
00412 {
00413   if (myPTU.getPower())
00414     myPTU.power(0);
00415   else
00416     myPTU.power(1);
00417 
00418   status();
00419 }
00420 
00421 // the important function
00422 void KeyPTU::drive(void)
00423 {
00424   // if the PTU isn't initialized, initialize it here... it has to be 
00425   // done here instead of above because it needs to be done when the 
00426   // robot is connected
00427   if (!myPTUInitRequested && !myPTU.isInitted() && myRobot->isConnected())
00428   {
00429     printf("\nWaiting for Camera to Initialize\n");
00430     myAbsolute = true;
00431     myPTUInitRequested = true;
00432     myPTU.init();
00433   }
00434 
00435   // if the camera hasn't initialized yet, then just return
00436   if (myPTUInitRequested && !myPTU.isInitted())
00437   {
00438     return;
00439   }
00440 
00441   if (myPTUInitRequested && myPTU.isInitted())
00442   {
00443     myPTUInitRequested = false;
00444     myPanSlew = myPTU.getPanSlew();
00445     myTiltSlew = myPTU.getTiltSlew();
00446     printf("Done.\n");
00447     question();
00448   }
00449 
00450   if (myExerciseTime.secSince() > 5 && myExercise)
00451   {
00452     int pan,tilt;
00453 
00454     if (ArMath::random()%2)
00455       pan = ArMath::random()%((int)myPTU.getMaxPosPan());
00456     else
00457       pan = -ArMath::random()%((int)myPTU.getMaxNegPan());
00458 
00459     if (ArMath::random()%2)
00460       tilt = ArMath::random()%((int)myPTU.getMaxPosTilt());
00461     else
00462       tilt = -ArMath::random()%((int)myPTU.getMaxNegTilt());
00463 
00464     myPTU.panTilt(pan, tilt);
00465     //printf("** %d\n", myRobot->getEstop());
00466     //printf("--> %x\n", myRobot->getFlags());
00467     myExerciseTime.setToNow();
00468   }
00469 
00470 }
00471 
00472 int main(int argc, char **argv) 
00473 {
00474   // just some stuff for returns
00475   std::string str;
00476   // robots connection
00477   ArSerialConnection con;
00478 
00479   // the robot, this turns state reflection off
00480   ArRobot robot(NULL, false);
00481   // the joydrive as defined above, this also adds itself as a user task
00482   KeyPTU ptu(&robot);
00483 
00484   // mandatory init
00485   Aria::init();
00486 
00487   //ArLog::init(ArLog::StdOut, ArLog::Normal, NULL, true);
00488 
00489   con.setPort(ArUtil::COM1);
00490   // set the connection on the robot
00491   robot.setDeviceConnection(&con);
00492 
00493   // connect, if we fail, exit
00494   if (!robot.blockingConnect())
00495   {
00496     printf("Could not connect to robot... exiting\n");
00497     Aria::shutdown();
00498     return 1;
00499   }
00500 
00501 
00502   // turn off the sonar, enable the motors, turn off amigobot sounds
00503   robot.comInt(ArCommands::SONAR, 0);
00504   robot.comInt(ArCommands::ENABLE, 1);
00505   robot.comInt(ArCommands::SOUNDTOG, 0);
00506 
00507   printf("Press '?' for available commands\r\n");
00508   // run, if we lose connection to the robot, exit
00509   robot.run(true);
00510   
00511   // shutdown and go away
00512   Aria::shutdown();
00513   return 0;
00514 }
00515 

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