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

ArSyncLoop.cpp

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

Generated on Wed Oct 19 12:56:37 2005 for Aria by  doxygen 1.4.0