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

ArSyncLoop.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 "ArSyncLoop.h"
00029 #include "ArLog.h"
00030 #include "ariaUtil.h"
00031 #include "ArRobot.h"
00032 
00033 
00034 AREXPORT ArSyncLoop::ArSyncLoop() :
00035   ArASyncTask(),
00036   myStopRunIfNotConnected(false),
00037   myRobot(0)
00038 {
00039   setThreadName("ArSyncLoop");
00040 }
00041 
00042 AREXPORT ArSyncLoop::~ArSyncLoop()
00043 {
00044 }
00045 
00046 AREXPORT void ArSyncLoop::setRobot(ArRobot *robot)
00047 {
00048   myRobot=robot;
00049 }
00050 
00051 AREXPORT void ArSyncLoop::stopRunIfNotConnected(bool stopRun)
00052 {
00053   myStopRunIfNotConnected = stopRun;
00054 }
00055 
00056 AREXPORT void * ArSyncLoop::runThread(void *arg)
00057 {
00058   threadStarted();
00059 
00060   long timeToSleep;
00061   ArTime loopEndTime;
00062   std::list<ArFunctor *> *runList;
00063   std::list<ArFunctor *>::iterator iter;
00064   ArTime lastLoop;
00065   bool firstLoop = true;
00066   bool warned = false;
00067 
00068   if (!myRobot)
00069   {
00070     ArLog::log(ArLog::Terse, "ArSyncLoop::runThread: Trying to run the synchronous loop without a robot.");
00071     return(0);
00072   }
00073 
00074   if (!myRobot->getSyncTaskRoot())
00075   {
00076     ArLog::log(ArLog::Terse, "ArSyncLoop::runThread: Can not run the synchronous loop without a task tree");
00077     return(0);
00078   }
00079 
00080   while (myRunning)
00081   {
00082 
00083     myRobot->lock();
00084     if (!firstLoop && !warned && !myRobot->getNoTimeWarningThisCycle() && 
00085     myRobot->getCycleWarningTime() != 0 && 
00086     lastLoop.mSecSince() > (signed int) myRobot->getCycleWarningTime())
00087     {
00088       ArLog::log(ArLog::Normal, 
00089  "Warning: ArRobot cycle took too long because the loop was waiting for lock.");
00090       ArLog::log(ArLog::Normal,
00091          "\tThe cycle took %u ms, (%u ms normal %u ms warning)", 
00092          lastLoop.mSecSince(), myRobot->getCycleTime(), 
00093          myRobot->getCycleWarningTime());
00094     }
00095     myRobot->setNoTimeWarningThisCycle(false);
00096     firstLoop = false;
00097     warned = false;
00098     lastLoop.setToNow();
00099 
00100     loopEndTime.setToNow();
00101     loopEndTime.addMSec(myRobot->getCycleTime());
00102     myRobot->incCounter();
00103     myRobot->unlock();
00104 
00105     // note that all the stuff beyond here should maybe have a lock
00106     // but it should be okay because its just getting data
00107     myRobot->getSyncTaskRoot()->run();
00108     if (myStopRunIfNotConnected && !myRobot->isConnected())
00109     {
00110       if (myRunning)
00111     ArLog::log(ArLog::Normal, "Exiting robot run because of lost connection.");
00112       break;
00113     }
00114     timeToSleep = loopEndTime.mSecTo();
00115     // if the cycles chained and we're connected the packet handler will be 
00116     // doing the timing for us
00117     if (myRobot->isCycleChained() && myRobot->isConnected())
00118       timeToSleep = 0;
00119 
00120     if (!myRobot->getNoTimeWarningThisCycle() && 
00121     myRobot->getCycleWarningTime() != 0 && 
00122     lastLoop.mSecSince() > (signed int) myRobot->getCycleWarningTime())
00123     {
00124       ArLog::log(ArLog::Normal, 
00125     "Warning: ArRobot sync tasks too long at %u ms, (%u ms normal %u ms warning)", 
00126          lastLoop.mSecSince(), myRobot->getCycleTime(), 
00127          myRobot->getCycleWarningTime());
00128       warned = true;
00129     }
00130     
00131 
00132     if (timeToSleep > 0)
00133       ArUtil::sleep(timeToSleep);
00134   }   
00135   myRobot->lock();
00136   myRobot->wakeAllRunExitWaitingThreads();
00137   myRobot->unlock();
00138 
00139   myRobot->lock();
00140   runList=myRobot->getRunExitListCopy();
00141   myRobot->unlock();
00142   for (iter=runList->begin();
00143        iter != runList->end(); ++iter)
00144     (*iter)->invoke();
00145   delete runList;
00146 
00147   return(0);
00148 }

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