00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00106
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
00116
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 }