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

ArServerMode.cpp

Go to the documentation of this file.
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 #include "ArExport.h"
00028 #include "ArServerMode.h"
00029 
00030 AREXPORT bool ArServerMode::ourActiveModeLocked = false;
00031 AREXPORT bool ArServerMode::ourActiveModeWillUnlockIfRequested = false;
00032 AREXPORT ArServerMode *ArServerMode::ourActiveMode = NULL;
00033 AREXPORT ArServerMode *ArServerMode::ourNextActiveMode = NULL;
00034 AREXPORT std::list<ArServerMode *> ArServerMode::ourDefaultModes;
00035 AREXPORT std::list<ArServerMode *> ArServerMode::ourRequestedActivateModes;
00036 AREXPORT std::list<ArServerMode *> ArServerMode::ourModes;
00037 bool ArServerMode::ourUserTaskAdded = false;
00038 ArGlobalFunctor ArServerMode::ourUserTaskCB(ArServerMode::modeUserTask);
00039 AREXPORT std::multimap<std::string, std::string> ArServerMode::ourModeDataMap;
00040 AREXPORT ArMutex ArServerMode::ourModeDataMapMutex;
00041 AREXPORT ArGlobalFunctor2<ArServerClient *, 
00042                           ArNetPacket *> ArServerMode::ourGetModeDataListCB(
00043                                   ArServerMode::getModeDataList);
00044 AREXPORT ArGlobalFunctor2<ArServerClient *, 
00045                           ArNetPacket *> ArServerMode::ourGetModeInfoCB(
00046                                   ArServerMode::getModeInfo);
00047 AREXPORT bool ArServerMode::ourLastActiveModeLocked = false;
00048 AREXPORT ArServerMode *ArServerMode::ourLastActiveMode = NULL; 
00049 AREXPORT bool ArServerMode::ourLastActiveModeWillUnlockIfRequested = false;
00050 
00051 
00052 AREXPORT void ArServerMode::modeUserTask(void)
00053 {
00054   if (ourActiveMode != NULL)
00055   {
00056     ourActiveMode->userTask();
00057   }
00058   else
00059   {
00060     std::list<ArServerMode *>::iterator it;
00061     for (it = ourDefaultModes.begin(); 
00062          it != ourDefaultModes.end() && ourActiveMode == NULL;
00063          it++)
00064     {
00065       ArLog::log(ArLog::Terse, "Checking default on %s mode", (*it)->getName());
00066       (*it)->checkDefault();
00067       if (ourActiveMode != NULL)
00068       {
00069         ArLog::log(ArLog::Normal, "Activated %s mode as default", (*it)->getName());
00070         return;
00071       }
00072     }
00073   }
00074 }
00075 
00076 AREXPORT ArServerMode::ArServerMode(ArRobot *robot, ArServerBase *server, 
00077                                     const char *name)
00078 {
00079   myVerboseLogLevel = ArLog::Verbose;
00080   myRobot = robot;
00081   myServer = server;
00082   myName = name;
00083   myIsActive = false;
00084   myStatusSetThisCycle = false;
00085   ourModes.push_front(this);
00086   myHasSetActivityTime = false;
00087   if (!ourUserTaskAdded)
00088   {
00089     ourUserTaskAdded = true;
00090     myRobot->addUserTask("server mode", 50, &ourUserTaskCB);
00091     myServer->addData("getModeDataList", "Gets the list of commands associated with modes.", 
00092                       &ourGetModeDataListCB,
00093                       "none", 
00094                       "ubyte4: numData;  repeating numData times, string: mode; string: data", 
00095                       "RobotInfo", "RETURN_SINGLE");
00096     myServer->addData("getModeInfo", "Gets the current mode active and if its locked and will or won't unlock (for lists of which commands are with which mdoes use getModeDataList) commands associated with modes.", 
00097                       &ourGetModeInfoCB,
00098                       "none", 
00099                       "string: mode; uByte: locked (1 == locked, 0 == unlocked); uByte: willUnlockIfRequested (1 == will, 0 == won't)",
00100                       "RobotInfo", "RETURN_SINGLE");
00101   }
00102 }
00103 
00104 AREXPORT ArServerMode::~ArServerMode()
00105 {
00106 
00107 }
00108 
00109 AREXPORT void ArServerMode::lockMode(bool willUnlockIfRequested)
00110 {
00111   if (!myIsActive || ourActiveMode != this)
00112   {
00113     ArLog::log(myVerboseLogLevel, "ArServerMode::lockMode: mode %s could not lock because it is not active", getName());
00114     return;
00115   }
00116   ourActiveModeLocked = true;
00117   ourActiveModeWillUnlockIfRequested = willUnlockIfRequested;
00118   ArLog::log(myVerboseLogLevel, "Locked into %s mode, will unlock %s", 
00119              getName(), ArUtil::convertBool(willUnlockIfRequested));
00120   checkBroadcastModeInfoPacket();
00121 }
00122 
00123 AREXPORT void ArServerMode::unlockMode(void)
00124 {
00125   if (!myIsActive || ourActiveMode != this)
00126   {
00127     ArLog::log(myVerboseLogLevel, "ArServerMode::unlockMode: mode %s could not unlock because it is not locked", getName());
00128     return;
00129   }
00130   ourActiveModeLocked = false;
00131   ourActiveModeWillUnlockIfRequested = false;
00132   ArLog::log(myVerboseLogLevel, "Unlocked from %s mode", getName());
00133   checkBroadcastModeInfoPacket();
00134 }
00135 
00136 
00138 AREXPORT bool ArServerMode::willUnlockIfRequested(void)
00139 {
00140   if (ourActiveMode == NULL || !ourActiveModeLocked || 
00141       (ourActiveModeLocked && ourActiveModeWillUnlockIfRequested))
00142     return true;
00143   else
00144     return false;
00145 }
00146 
00147        
00148 
00149 
00158 AREXPORT bool ArServerMode::baseActivate(void)
00159 {
00160 
00161   // if we're locked then return false so nothing else activates
00162   if (ourActiveMode != NULL && ourActiveMode != this && ourActiveModeLocked)
00163   {
00164     ArLog::log(myVerboseLogLevel, "Could not switch to %s mode because of lock.", 
00165                getName());
00166     // request our active mode to unlock
00167     ourActiveMode->requestUnlock();
00168 
00169 
00170     ourRequestedActivateModes.remove(this);
00171     ArLog::log(myVerboseLogLevel, "Mode %s wants to be activated.");
00172     ourRequestedActivateModes.push_front(this);
00173     return false;
00174   }
00175   ourNextActiveMode = this;
00176   if (ourActiveMode != NULL)
00177     ourActiveMode->deactivate();
00178   myIsActive = true;
00179   myActivityTimeMutex.lock();
00180   myActivityTime.setToNow(); 
00181   myActivityTimeMutex.unlock();
00182 
00183   /*
00184   if (myRobot != NULL)
00185   {
00186     myRobot->addUserTask(myName.c_str(), 50, &myUserTaskCB);
00187   }
00188   */
00189   ourActiveMode = this;
00190   ourNextActiveMode = NULL;
00191   if (myRobot != NULL)
00192   {
00193     myRobot->stop();
00194     myRobot->clearDirectMotion();
00195   }
00197   myActivateCallbacks.invoke();
00199   ArLog::log(myVerboseLogLevel, "Activated %s mode", getName());
00200   checkBroadcastModeInfoPacket();
00201   return true;
00202 }
00203 
00208 AREXPORT void ArServerMode::baseDeactivate(void)
00209 {
00210   std::list<ArServerMode *>::iterator it;
00211 
00212   for (it = ourDefaultModes.begin(); 
00213        it != ourDefaultModes.end();
00214        it++)
00215   {
00216     ArLog::log(myVerboseLogLevel, "defaults are %s mode", (*it)->getName());
00217   }
00218   
00219   // if we're the active mode, we're deactivating, and we're locked, then unlock
00220   if (ourActiveMode != NULL && ourActiveMode == this && ourActiveModeLocked)
00221     unlockMode();
00222   /*
00223   if (myRobot != NULL)
00224     myRobot->remUserTask(&myUserTaskCB);
00225   */
00226   myIsActive = false;
00227   if (ourActiveMode == this)
00228   {
00229     ourActiveMode = NULL;
00230   }
00231   myDeactivateCallbacks.invoke();
00232   ArLog::log(myVerboseLogLevel, "Deactivated %s mode", getName());
00233   if (ourNextActiveMode == NULL)
00234   {
00235     // walk through until one of these is ready
00236     while ((it = ourRequestedActivateModes.begin()) != 
00237            ourRequestedActivateModes.end())
00238     {
00239       ArLog::log(myVerboseLogLevel,"Trying to activate %s", (*it)->getName());
00240       (*it)->activate();
00241       ourRequestedActivateModes.pop_front();
00242       if (ourActiveMode != NULL)
00243       {
00244         ArLog::log(myVerboseLogLevel, "and did, clearing requested activate modes");
00245         // now clear out the old modes so that we don't wind up
00246         // stacking too much
00247         ourRequestedActivateModes.clear();
00248         return;
00249       }
00250     }
00251     // now clear out the old modes so that we don't wind up stacking
00252     // too much (should be empty anyways here, just make sure
00253     ourRequestedActivateModes.clear();
00254 
00255     for (it = ourDefaultModes.begin(); 
00256          it != ourDefaultModes.end() && ourActiveMode == NULL;
00257          it++)
00258     {
00259       ArLog::log(ArLog::Terse, "Checking default on %s mode", (*it)->getName());
00260       (*it)->checkDefault();
00261       if (ourActiveMode != NULL)
00262       {
00263         //printf("and did\n");
00264         return;
00265       }
00266     }
00267   }
00268 }
00269 
00274 AREXPORT void ArServerMode::addAsDefaultMode(ArListPos::Pos pos)
00275 {
00276   ArLog::log(ArLog::Normal, "Mode %s added as default mode", getName());
00277   if (pos == ArListPos::LAST)
00278     ourDefaultModes.push_back(this);
00279   else if (pos == ArListPos::FIRST)
00280     ourDefaultModes.push_front(this);
00281   else
00282   {
00283     ArLog::log(ArLog::Terse, "ArServerMode::addAsDefaultMode: bad list position.");
00284     ourDefaultModes.push_front(this);
00285   }
00286 }
00287 
00288 AREXPORT ArTime ArServerMode::getActivityTime(void) 
00289 { 
00290   ArTime ret;
00291   myActivityTimeMutex.lock();
00292   ret = myActivityTime;
00293   myActivityTimeMutex.unlock();
00294   return ret;
00295 }
00296 
00297 AREXPORT void ArServerMode::setActivityTimeToNow(void)     
00298 { 
00299   myActivityTimeMutex.lock();
00300   myHasSetActivityTime = true; 
00301   myActivityTime.setToNow(); 
00302   myActivityTimeMutex.unlock();
00303 }
00304 
00305 AREXPORT int ArServerMode::getActiveModeActivityTimeSecSince(void) 
00306 { 
00307   // chop this to an int so its easier to use, if you care about it
00308   // use the getActivityTime on the ourActiveMode
00309   if (ourActiveMode != NULL)
00310     return (int)ourActiveMode->getActivityTime().secSince();
00311   else
00312     return 0;
00313 }
00314 
00322 AREXPORT bool ArServerMode::addModeData(
00323         const char *name, const char *description,
00324         ArFunctor2<ArServerClient *, ArNetPacket *> *functor,
00325         const char *argumentDescription, const char *returnDescription,
00326         const char *commandGroup, const char *dataFlags)
00327 {
00328   if (myServer->addData(name, description, functor, argumentDescription,
00329                         returnDescription, commandGroup, dataFlags))
00330   {
00331     ourModeDataMapMutex.lock();
00332     ourModeDataMap.insert(std::pair<std::string, std::string>(myName, name));
00333     ourModeDataMapMutex.unlock();
00334     return true;
00335   }
00336   else
00337   {
00338     ArLog::log(ArLog::Normal, "ArServerMode %s: Could not add mode data %s",
00339                myName.c_str(), name);
00340     return false;
00341   }
00342       
00343 }
00344 
00348 AREXPORT void ArServerMode::getModeDataList(ArServerClient *client, 
00349                                             ArNetPacket *packet)
00350 
00351 {
00352   ourModeDataMapMutex.lock();
00353   ArNetPacket sending;
00354   sending.uByte4ToBuf(ourModeDataMap.size());
00355   std::multimap<std::string, std::string>::iterator it;
00356   for (it = ourModeDataMap.begin(); it != ourModeDataMap.end(); it++)
00357   {
00358     sending.strToBuf((*it).first.c_str());
00359     sending.strToBuf((*it).second.c_str());
00360   }
00361   ourModeDataMapMutex.unlock();
00362   client->sendPacketTcp(&sending);
00363 }
00364 
00368 AREXPORT void ArServerMode::getModeInfo(ArServerClient *client, 
00369                                         ArNetPacket *packet)
00370 {
00371   ArNetPacket sending;
00372   buildModeInfoPacket(&sending);
00373   client->sendPacketTcp(&sending);
00374 }
00375 
00376 AREXPORT void ArServerMode::buildModeInfoPacket(ArNetPacket *sending)
00377 {  
00378   if (ourActiveMode != NULL)
00379   {
00380     sending->strToBuf(ourActiveMode->getName());
00381     if (ourActiveModeLocked)
00382       sending->uByteToBuf(1);
00383     else
00384       sending->uByteToBuf(0);
00385     if (ourActiveModeWillUnlockIfRequested)
00386       sending->uByteToBuf(1);
00387     else
00388       sending->uByteToBuf(0);
00389   }
00390   else
00391   {
00392     sending->strToBuf("");
00393     sending->uByteToBuf(0);
00394     sending->uByteToBuf(0);
00395   }
00396   return;
00397 }
00398 
00399 AREXPORT void ArServerMode::checkBroadcastModeInfoPacket(void)
00400 {
00401   if (ourActiveMode != ourLastActiveMode || 
00402       ourActiveModeLocked != ourLastActiveModeLocked ||
00403       ourActiveModeWillUnlockIfRequested != 
00404               ourLastActiveModeWillUnlockIfRequested)
00405   {
00406     ArNetPacket sending;
00407     buildModeInfoPacket(&sending);
00408     myServer->broadcastPacketTcp(&sending, "getModeInfo");
00409   }
00410   
00411   ourLastActiveMode = ourActiveMode;
00412   ourLastActiveModeLocked = ourActiveModeLocked;
00413   ourLastActiveModeWillUnlockIfRequested = ourActiveModeWillUnlockIfRequested;
00414 }
00415 
00416 AREXPORT ArServerMode* ArServerMode::getActiveMode(void) 
00417 { return ourActiveMode; }
00418   
00419 AREXPORT std::list<ArServerMode *> *ArServerMode::getRequestedActivateModes(void)
00420 {
00421   return &ourRequestedActivateModes;
00422 }

Generated on Tue Feb 20 10:51:50 2007 for ArNetworking by  doxygen 1.4.0