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

ArMode.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 "ArMode.h"
00029 #include "ArRobot.h"
00030 #include "ariaInternal.h"
00031 
00032 ArMode *ArMode::ourActiveMode = NULL;
00033 ArGlobalFunctor *ArMode::ourHelpCB = NULL;
00034 std::list<ArMode *> ArMode::ourModes;
00035 
00047 AREXPORT ArMode::ArMode(ArRobot *robot, const char *name, char key, 
00048             char key2) :
00049   myActivateCB(this, &ArMode::activate),
00050   myDeactivateCB(this, &ArMode::deactivate),
00051   myUserTaskCB(this, &ArMode::userTask)
00052 {
00053   ArKeyHandler *keyHandler;
00054   myName = name;
00055   myRobot = robot;
00056   myKey = key;
00057   myKey2 = key2;
00058   // see if there is already a keyhandler, if not make one for ourselves
00059   if ((keyHandler = Aria::getKeyHandler()) == NULL)
00060   {
00061     keyHandler = new ArKeyHandler;
00062     Aria::setKeyHandler(keyHandler);
00063     if (myRobot != NULL)
00064       myRobot->attachKeyHandler(keyHandler);
00065     else
00066       ArLog::log(ArLog::Terse, "ArMode: No robot to attach a keyHandler to, keyHandling won't work... either make your own keyHandler and drive it yourself, make a keyhandler and attach it to a robot, or give this a robot to attach to.");
00067   }  
00068   if (ourHelpCB == NULL)
00069   {
00070     ourHelpCB = new ArGlobalFunctor(&ArMode::baseHelp);
00071     if (!keyHandler->addKeyHandler('h', ourHelpCB))
00072       ArLog::log(ArLog::Terse, "The key handler already has a key for 'h', ArMode will not be invoked on an 'h' keypress.");
00073     if (!keyHandler->addKeyHandler('H', ourHelpCB))
00074       ArLog::log(ArLog::Terse, "The key handler already has a key for 'H', ArMode will not be invoked on an 'H' keypress.");
00075     if (!keyHandler->addKeyHandler('?', ourHelpCB))
00076       ArLog::log(ArLog::Terse, "The key handler already has a key for '?', ArMode will not be invoked on an '?' keypress.");
00077     if (!keyHandler->addKeyHandler('/', ourHelpCB))
00078       ArLog::log(ArLog::Terse, "The key handler already has a key for '/', ArMode will not be invoked on an '/' keypress.");
00079 
00080   }
00081 
00082   // now that we have one, add our keys as callbacks, print out big
00083   // warning messages if they fail
00084   if (myKey != '\0')
00085     if (!keyHandler->addKeyHandler(myKey, &myActivateCB))
00086       ArLog::log(ArLog::Terse, "The key handler already has a key for '%c', ArMode will not work correctly.", myKey);
00087   if (myKey2 != '\0')
00088     if (!keyHandler->addKeyHandler(myKey2, &myActivateCB))
00089       ArLog::log(ArLog::Terse, "The key handler already has a key for '%c', ArMode will not work correctly.", myKey2);
00090 
00091   // toss this mode into our list of modes
00092   ourModes.push_front(this);
00093 }
00094 
00095 AREXPORT ArMode::~ArMode()
00096 {
00097   ArKeyHandler *keyHandler;
00098   if ((keyHandler = Aria::getKeyHandler()) != NULL)
00099   {
00100     if (myKey != '\0')
00101       keyHandler->remKeyHandler(myKey);
00102     if (myKey2 != '\0')
00103       keyHandler->remKeyHandler(myKey2);
00104   }
00105   if (myRobot != NULL)
00106     myRobot->remUserTask(&myUserTaskCB);
00107 }
00108 
00115 AREXPORT bool ArMode::baseActivate(void)
00116 {
00117   if (ourActiveMode == this)
00118     return false;
00119   if (myRobot != NULL)
00120   {
00121     myRobot->addUserTask(myName.c_str(), 50, &myUserTaskCB);
00122   }
00123   if (ourActiveMode != NULL)
00124     ourActiveMode->deactivate();
00125   ourActiveMode = this;
00126   if (myRobot != NULL)
00127   {
00128     myRobot->stop();
00129     myRobot->clearDirectMotion();
00130   }
00131   
00132   baseHelp();
00133   return true;
00134 }
00135 
00140 AREXPORT bool ArMode::baseDeactivate(void)
00141 {
00142   if (myRobot != NULL)
00143     myRobot->remUserTask(&myUserTaskCB);
00144   if (ourActiveMode == this)
00145   {
00146     ourActiveMode = NULL;
00147     return true;
00148   }
00149   return false;
00150 }
00151 
00152 AREXPORT const char *ArMode::getName(void)
00153 {
00154   return myName.c_str();
00155 }
00156 
00157 AREXPORT char ArMode::getKey(void)
00158 {
00159   return myKey;
00160 }
00161 
00162 AREXPORT char ArMode::getKey2(void)
00163 {
00164   return myKey2;
00165 }
00166 
00167 AREXPORT void ArMode::baseHelp(void)
00168 {
00169   std::list<ArMode *>::iterator it;
00170   ArLog::log(ArLog::Terse, "\n\nYou can do these actions with these keys:\n");
00171   ArLog::log(ArLog::Terse, "quit: escape");
00172   ArLog::log(ArLog::Terse, "help: 'h' or 'H' or '?' or '/'");
00173   ArLog::log(ArLog::Terse, "\nYou can switch to other modes with these keys:");
00174   for (it = ourModes.begin(); it != ourModes.end(); ++it)
00175   {
00176     ArLog::log(ArLog::Terse, "%30s mode: '%c' or '%c'", (*it)->getName(), 
00177            (*it)->getKey(), (*it)->getKey2());
00178   }
00179   if (ourActiveMode == NULL)
00180     ArLog::log(ArLog::Terse, "You are in no mode currently.");
00181   else
00182   {
00183     ArLog::log(ArLog::Terse, "You are in '%s' mode currently.\n",
00184            ourActiveMode->getName());
00185     ourActiveMode->help();
00186   }
00187 }
00188 
00189 void ArMode::addKeyHandler(int keyToHandle, ArFunctor *functor)
00190 {
00191   ArKeyHandler *keyHandler;
00192   std::string charStr;
00193 
00194   // see if there is already a keyhandler, if not something is wrong
00195   // (since constructor should make one if there isn't one yet
00196   if ((keyHandler = Aria::getKeyHandler()) == NULL)
00197   {
00198     ArLog::log(ArLog::Terse,"ArMode '%s'::keyHandler: There should already be a key handler, but there isn't... mode won't work right.", getName());
00199     return;
00200   }
00201   if (!keyHandler->addKeyHandler(keyToHandle, functor))
00202   {
00203     switch (keyToHandle) {
00204     case ArKeyHandler::UP:
00205       charStr = "Up";
00206       break;
00207     case ArKeyHandler::DOWN:
00208       charStr = "Down";
00209       break;
00210     case ArKeyHandler::LEFT:
00211       charStr = "Left";
00212       break;
00213     case ArKeyHandler::RIGHT:
00214       charStr = "Right";
00215       break;
00216     case ArKeyHandler::ESCAPE:
00217       charStr = "Escape";
00218       break;
00219     case ArKeyHandler::F1:
00220       charStr = "F1";
00221       break;
00222     case ArKeyHandler::F2:
00223       charStr = "F2";
00224       break;
00225     case ArKeyHandler::F3:
00226       charStr = "F3";
00227       break;
00228     case ArKeyHandler::F4:
00229       charStr = "F4";
00230       break;
00231     case ArKeyHandler::SPACE:
00232       charStr = "Space";
00233       break;
00234     case ArKeyHandler::TAB:
00235       charStr = "Tab";
00236       break;
00237     case ArKeyHandler::ENTER:
00238       charStr = "Enter";
00239       break;
00240     case ArKeyHandler::BACKSPACE:
00241       charStr = "Backspace";
00242       break;
00243     default:
00244       charStr = (char)keyToHandle;
00245       break;
00246     }
00247     ArLog::log(ArLog::Terse,  
00248            "ArMode '%s': The key handler has a duplicate key for '%s' so the mode may not work right.", getName(), charStr.c_str());
00249   }
00250   
00251 }
00252 
00253 void ArMode::remKeyHandler(ArFunctor *functor)
00254 {
00255   ArKeyHandler *keyHandler;
00256   std::string charStr;
00257 
00258   // see if there is already a keyhandler, if not something is wrong
00259   // (since constructor should make one if there isn't one yet
00260   if ((keyHandler = Aria::getKeyHandler()) == NULL)
00261   {
00262     ArLog::log(ArLog::Terse,"ArMode '%s'::keyHandler: There should already be a key handler, but there isn't... mode won't work right.", getName());
00263     return;
00264   }
00265   if (!keyHandler->remKeyHandler(functor))
00266     ArLog::log(ArLog::Terse,  
00267            "ArMode '%s': The key handler already didn't have the given functor so the mode may not be working right.", getName());
00268 }
00269   

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