MOOS 0.2375
|
00001 00002 // 00003 // MOOS - Mission Oriented Operating Suite 00004 // 00005 // A suit of Applications and Libraries for Mobile Robotics Research 00006 // Copyright (C) 2001-2005 Massachusetts Institute of Technology and 00007 // Oxford University. 00008 // 00009 // This software was written by Paul Newman at MIT 2001-2002 and Oxford 00010 // University 2003-2005. email: pnewman@robots.ox.ac.uk. 00011 // 00012 // This file is part of a MOOS Core Component. 00013 // 00014 // This program is free software; you can redistribute it and/or 00015 // modify it under the terms of the GNU General Public License as 00016 // published by the Free Software Foundation; either version 2 of the 00017 // License, or (at your option) any later version. 00018 // 00019 // This program is distributed in the hope that it will be useful, 00020 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00021 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00022 // General Public License for more details. 00023 // 00024 // You should have received a copy of the GNU General Public License 00025 // along with this program; if not, write to the Free Software 00026 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00027 // 02111-1307, USA. 00028 // 00030 #ifdef _WIN32 00031 #pragma warning(disable : 4786) 00032 #endif 00033 00034 00035 #include "MOOSGenLibGlobalHelper.h" 00036 #include "MOOSGenLib/MOOSAssert.h" 00037 00038 #include <algorithm> 00039 #include <iterator> 00040 #include <cctype> 00041 #include <string> 00042 #include <memory> 00043 #include <cstring> 00044 #include <map> 00045 #include <time.h> 00046 #include <stdarg.h> 00047 #include <math.h> 00048 00049 #ifndef _WIN32 00050 #include <unistd.h> 00051 #include <sys/times.h> 00052 #include <sys/time.h> 00053 #include <termios.h> 00054 #include <dirent.h> 00055 #include <errno.h> 00056 #include <pthread.h> 00057 #endif 00058 00059 #ifdef _WIN32 00060 #include "windows.h" 00061 #include "winbase.h" 00062 #include "winnt.h" 00063 #include <conio.h> 00064 #endif 00065 00066 #include <iostream> 00067 #include <sstream> 00068 #include <vector> 00069 #include <iomanip> 00070 00071 00072 00073 #include <sys/types.h> 00074 #include <sys/stat.h> 00075 #include <sys/timeb.h> 00076 #include <stdio.h> 00077 #include <iostream> 00078 00079 #define ENABLE_WIN32_HPMOOSTIME 0 00080 #define MAX_TIME_WARP 100 00081 00082 using namespace std; 00083 00084 #ifndef PI 00085 #define PI 3.141592653 00086 #endif 00087 #ifndef TWO_PI 00088 #define TWO_PI 6.28318530717 00089 #endif 00090 00091 #ifdef _WIN32 00092 typedef std::map<int,bool> THREAD2TRACE_MAP; 00093 #else 00094 typedef std::map<pthread_t,bool> THREAD2TRACE_MAP; 00095 #endif 00096 00097 double gdfMOOSTimeWarp = 1.0; 00098 double gdfMOOSSkew =0.0; 00099 00100 void SetMOOSSkew(double dfSkew) 00101 { 00102 //printf("Clock Skew = %f seconds\n",dfSkew); 00103 gdfMOOSSkew = dfSkew; 00104 00105 //a call to HPMOOSTime() sets up high performance clocks 00106 HPMOOSTime(); 00107 } 00108 00109 double GetMOOSSkew() 00110 { 00111 return gdfMOOSSkew; 00112 } 00113 00114 00115 00119 bool IsLittleEndian() 00120 { 00121 static bool bTested = false; 00122 static bool bLittleEndIn = false; 00123 00124 if(!bTested) 00125 { 00126 short int word = 0x0001; 00127 char *byte = (char *) &word; 00128 bLittleEndIn = byte[0]==1; 00129 bTested = true; 00130 } 00131 00132 return bLittleEndIn; 00133 } 00134 00135 00136 bool gbWin32HPTiming = true; 00137 bool SetWin32HighPrecisionTiming(bool bEnable) 00138 { 00139 #ifndef _WIN32 00140 return false; 00141 #else 00142 gbWin32HPTiming = bEnable; 00143 return true; 00144 #endif 00145 00146 } 00147 00148 00149 double MOOSLocalTime(bool bApplyTimeWarping) 00150 { 00151 #ifndef _WIN32 00152 double dfT=0.0; 00153 struct timeval TimeVal; 00154 00155 if(gettimeofday(&TimeVal,NULL)==0) 00156 { 00157 dfT = TimeVal.tv_sec+TimeVal.tv_usec/1000000.0; 00158 } 00159 else 00160 { 00161 //lost the will to live..... 00162 MOOSAssert(0); 00163 dfT =-1; 00164 } 00165 if(bApplyTimeWarping) 00166 return dfT*gdfMOOSTimeWarp; 00167 else 00168 return dfT; 00169 00170 #else 00171 if( gbWin32HPTiming ) 00172 { 00173 00174 static LARGE_INTEGER liStart; 00175 static LARGE_INTEGER liPerformanceFreq; 00176 static double dfMOOSStart; 00177 static bool bHPTimeInitialised=false; 00178 00179 //to do - we should consider thread saftery here.. 00180 if(!bHPTimeInitialised) 00181 { 00182 00183 //initialise with crude time 00184 struct _timeb timebuffer; 00185 _ftime( &timebuffer ); 00186 dfMOOSStart = timebuffer.time+ ((double)timebuffer.millitm)/1000; 00187 00188 QueryPerformanceCounter(&liStart); 00189 QueryPerformanceFrequency(&liPerformanceFreq); 00190 00191 bHPTimeInitialised=true; 00192 00193 return bApplyTimeWarping ? dfMOOSStart*gdfMOOSTimeWarp :dfMOOSStart; 00194 00195 00196 } 00197 else 00198 { 00199 //use fancy time 00200 LARGE_INTEGER liNow; 00201 QueryPerformanceCounter(&liNow); 00202 00203 double T = dfMOOSStart+(double)(liNow.QuadPart-liStart.QuadPart)/((double)(liPerformanceFreq.QuadPart)); 00204 00205 return bApplyTimeWarping ? T*gdfMOOSTimeWarp :T; 00206 00207 } 00208 00209 00210 00211 } 00212 else 00213 { 00214 //user has elected to use low precision win32 timing 00215 struct _timeb timebuffer; 00216 _ftime( &timebuffer ); 00217 double T = timebuffer.time + ((double)timebuffer.millitm)/1000.0; 00218 00219 return bApplyTimeWarping ? T*gdfMOOSTimeWarp : T; 00220 00221 } 00222 #endif 00223 00224 00225 } 00226 00227 00228 double HPMOOSTime(bool bApplyTimeWarping) 00229 { 00230 return MOOSTime(bApplyTimeWarping); 00231 } 00232 00233 double MOOSTime(bool bApplyTimeWarping) 00234 { 00235 return MOOSLocalTime(bApplyTimeWarping)+gdfMOOSSkew; 00236 } 00237 00238 double GetMOOSTimeWarp() 00239 { 00240 return gdfMOOSTimeWarp; 00241 } 00242 00243 00244 bool SetMOOSTimeWarp(double dfWarp) 00245 { 00246 if(dfWarp>0 && dfWarp<MAX_TIME_WARP) 00247 { 00248 gdfMOOSTimeWarp = dfWarp; 00249 return true; 00250 } 00251 return MOOSFail("Time warp must be positive and less than %f \n",MAX_TIME_WARP); 00252 00253 } 00254 00255 void MOOSPause(int nMS,bool bApplyTimeWarping) 00256 { 00257 if(bApplyTimeWarping) 00258 nMS = int(double(nMS)/gdfMOOSTimeWarp); 00259 #ifdef _WIN32 00260 ::Sleep(nMS); 00261 #else 00262 00263 timespec TimeSpec; 00264 TimeSpec.tv_sec = nMS / 1000; 00265 TimeSpec.tv_nsec = (nMS%1000) *1000000; 00266 00267 nanosleep(&TimeSpec,NULL); 00268 00269 #endif 00270 } 00271 00272 00273 00274 00275 string MOOSChomp(string &sStr, const string &sTk,bool bInsensitive) 00276 { 00277 /*unsigned int*/ size_t nPos = string::npos; 00278 if((nPos =MOOSStrFind(sStr,sTk,bInsensitive))!=string::npos) 00279 { 00280 string sRet; 00281 sRet = sStr.substr(0,nPos); 00282 sStr.erase(0,nPos+sTk.length()); 00283 return sRet; 00284 } 00285 else 00286 { 00287 string sTmp = sStr; 00288 sStr=""; 00289 return sTmp; 00290 } 00291 00292 00293 } 00294 00295 //case insensitive character compare functor 00296 struct CompareInsensitive: public std::binary_function< char, char, bool > 00297 { 00298 bool operator()(char lhs, char rhs) 00299 { 00300 return std::toupper(lhs) == std::toupper(rhs); 00301 } 00302 00303 }; 00304 00305 //case insensitive find 00306 size_t MOOSStrFind(const std::string & sSource,const std::string & sToken,bool bInsensitive) 00307 { 00308 00309 if(bInsensitive) 00310 { 00311 std::string::const_iterator q = std::search( 00312 sSource.begin(), sSource.end(), 00313 sToken.begin(), sToken.end(), 00314 CompareInsensitive()); 00315 if(q==sSource.end()) 00316 return std::string::npos; 00317 else 00318 { 00319 return std::distance(sSource.begin(),q); 00320 } 00321 } 00322 else 00323 { 00324 return sSource.find(sToken); 00325 } 00326 } 00327 00328 00329 bool MOOSValFromString(string & sVal,const string & sStr,const string & sTk,bool bInsensitive) 00330 { 00331 00332 size_t nPos = string::npos; 00333 size_t k = 0; 00334 while((nPos = MOOSStrFind(sStr.substr(k),sTk,bInsensitive))!=string::npos) 00335 { 00336 nPos+=k; 00337 //we have the start of the token at nPos 00338 //we need to be carefull here = there could be many spaces between token and = 00339 /*unsigned int*/ size_t nEqualsPos = sStr.find('=',nPos); 00340 00341 //can we find an "="? 00342 if(nEqualsPos!=string::npos) 00343 { 00344 00345 //there should only be white space twixt token and equals 00346 std::string t = sStr.substr(nPos+sTk.size(),nEqualsPos-(nPos+sTk.size())); 00347 MOOSTrimWhiteSpace(t); 00348 if(!t.empty()) 00349 { 00350 //k = nEqualsPos; 00351 k=nPos+1; 00352 continue; 00353 } 00354 00355 sVal=""; 00356 00357 int nCommaPos =sStr.find(',',nEqualsPos); 00358 00359 sVal.append(sStr,nEqualsPos+1,nCommaPos-nEqualsPos-1); 00360 00361 return true; 00362 } 00363 else 00364 { 00365 return false; 00366 } 00367 00368 } 00369 00370 return false; 00371 } 00372 00373 bool MOOSValFromString(unsigned int & nVal,const string & sStr,const string & sTk,bool bInsensitive) 00374 { 00375 int nIntVal; 00376 bool bSuccess = MOOSValFromString(nIntVal,sStr,sTk,bInsensitive); 00377 if(bSuccess) 00378 nVal = (unsigned int) nIntVal; 00379 return bSuccess; 00380 } 00381 00382 00383 bool MOOSValFromString(int & nVal,const string & sStr,const string & sTk,bool bInsensitive) 00384 { 00385 string sVal; 00386 00387 if(MOOSValFromString(sVal,sStr,sTk,bInsensitive)) 00388 { 00389 00390 /*unsigned int*/ size_t nPos = sVal.find_first_not_of(' '); 00391 00392 if(nPos!=string::npos) 00393 { 00394 char c = sVal[nPos]; 00395 if(isdigit(c) || c=='-' || c=='+') 00396 { 00397 nVal = atoi(sVal.c_str()); 00398 return true; 00399 } 00400 } 00401 00402 } 00403 return false; 00404 } 00405 00406 00407 bool MOOSValFromString(long & nVal,const string & sStr,const string & sTk,bool bInsensitive) 00408 { 00409 string sVal; 00410 00411 if(MOOSValFromString(sVal,sStr,sTk,bInsensitive)) 00412 { 00413 00414 /*unsigned int*/ size_t nPos = sVal.find_first_not_of(' '); 00415 00416 if(nPos!=string::npos) 00417 { 00418 char c = sVal[nPos]; 00419 if(isdigit(c) || c=='-' || c=='+') 00420 { 00421 nVal = atol(sVal.c_str()); 00422 return true; 00423 } 00424 } 00425 00426 } 00427 return false; 00428 } 00429 00430 00431 bool MOOSValFromString(bool & bVal,const string & sStr,const string & sTk,bool bInsensitive) 00432 { 00433 string sVal; 00434 00435 if(MOOSValFromString(sVal,sStr,sTk,bInsensitive)) 00436 { 00437 MOOSRemoveChars(sVal," "); 00438 if(MOOSStrCmp(sVal,"true") || MOOSStrCmp(sVal,"1")) 00439 bVal = true; 00440 else 00441 bVal = false; 00442 00443 return true; 00444 } 00445 00446 return false; 00447 } 00448 00449 00450 bool MOOSValFromString(double & dfVal,const string & sStr,const string & sTk,bool bInsensitive) 00451 { 00452 string sVal; 00453 00454 if(MOOSValFromString(sVal,sStr,sTk,bInsensitive)) 00455 { 00456 00457 /*unsigned int*/ size_t nPos = sVal.find_first_not_of(' '); 00458 00459 if(nPos!=string::npos) 00460 { 00461 char c = sVal[nPos]; 00462 if(isdigit(c) || c=='.' || c=='-' || c=='+') 00463 { 00464 dfVal = atof(sVal.c_str()); 00465 return true; 00466 } 00467 } 00468 00469 } 00470 return false; 00471 } 00472 00473 00474 00475 bool MOOSValFromString(float & fVal,const string & sStr,const string & sTk,bool bInsensitive) 00476 { 00477 string sVal; 00478 00479 if(MOOSValFromString(sVal,sStr,sTk,bInsensitive)) 00480 { 00481 00482 /*unsigned int*/ size_t nPos = sVal.find_first_not_of(' '); 00483 00484 if(nPos!=string::npos) 00485 { 00486 char c = sVal[nPos]; 00487 if(isdigit(c) || c=='.' || c=='-' || c=='+') 00488 { 00489 fVal = static_cast<float> (atof(sVal.c_str())); 00490 return true; 00491 } 00492 } 00493 00494 } 00495 return false; 00496 } 00497 00498 00499 00500 bool MOOSVectorFromString(const string & sStr,std::vector<double> & dfValVec,int & nRows, int & nCols) 00501 { 00502 00503 /*unsigned int*/ size_t nPos = sStr.find('['); 00504 00505 if(nPos==string::npos) 00506 return false; 00507 00508 nRows = atoi( sStr.data()+nPos+1); 00509 00510 00511 //if we have [456] then implicitlyt we mean [456x1] 00512 /*unsigned int*/ size_t nXPos = sStr.find('x',nPos); 00513 00514 nCols = 1; 00515 if(nXPos!=string::npos) 00516 { 00517 nCols = atoi( sStr.data()+nXPos+1); 00518 nPos = nXPos; 00519 } 00520 00521 nPos = sStr.find('{',nPos); 00522 00523 if(nPos==string::npos) 00524 return false; 00525 00526 00527 if(nCols==0 ||nRows==0) 00528 return false; 00529 00530 dfValVec.clear(); 00531 dfValVec.reserve(nRows*nCols); 00532 00533 00534 const char * pStr = sStr.data(); 00535 for(int i = 1; i<=nRows;i++) 00536 { 00537 for(int j = 1; j<=nCols;j++) 00538 { 00539 double dfVal = atof(pStr+nPos+1); 00540 00541 dfValVec.push_back(dfVal); 00542 nPos = sStr.find(',',nPos+1); 00543 } 00544 } 00545 00546 return true; 00547 00548 } 00549 00550 00551 bool MOOSVectorFromString(const string & sStr,std::vector<float> & fValVec,int & nRows, int & nCols) 00552 { 00553 00554 /*unsigned int*/ size_t nPos = sStr.find('['); 00555 00556 if(nPos==string::npos) 00557 return false; 00558 00559 nRows = atoi( sStr.data()+nPos+1); 00560 00561 00562 //if we have [456] then implicitlyt we mean [456x1] 00563 /*unsigned int*/ size_t nXPos = sStr.find('x',nPos); 00564 00565 nCols = 1; 00566 if(nXPos!=string::npos) 00567 { 00568 nCols = atoi( sStr.data()+nXPos+1); 00569 nPos = nXPos; 00570 } 00571 00572 nPos = sStr.find('{',nPos); 00573 00574 if(nPos==string::npos) 00575 return false; 00576 00577 00578 if(nCols==0 ||nRows==0) 00579 return false; 00580 00581 fValVec.clear(); 00582 fValVec.reserve(nRows*nCols); 00583 00584 00585 const char * pStr = sStr.data(); 00586 for(int i = 1; i<=nRows;i++) 00587 { 00588 for(int j = 1; j<=nCols;j++) 00589 { 00590 double dfVal = atof(pStr+nPos+1); 00591 00592 fValVec.push_back(static_cast<float> (dfVal)); 00593 nPos = sStr.find(',',nPos+1); 00594 } 00595 } 00596 00597 return true; 00598 00599 } 00600 00601 00602 00603 bool MOOSVectorFromString(const string & sStr,std::vector<unsigned int> & nValVec,int & nRows, int & nCols) 00604 { 00605 00606 00607 /*unsigned int*/ size_t nPos = sStr.find('['); 00608 00609 if(nPos==string::npos) 00610 return false; 00611 00612 nRows = atoi( sStr.data()+nPos+1); 00613 00614 00615 //if we have [456] then implicitlyt we mean [456x1] 00616 /*unsigned int*/ size_t nXPos = sStr.find('x',nPos); 00617 00618 nCols = 1; 00619 if(nXPos!=string::npos) 00620 { 00621 nCols = atoi( sStr.data()+nXPos+1); 00622 nPos = nXPos; 00623 } 00624 00625 nPos = sStr.find('{',nPos); 00626 00627 if(nPos==string::npos) 00628 return false; 00629 00630 00631 if(nCols==0 ||nRows==0) 00632 return false; 00633 00634 nValVec.clear(); 00635 nValVec.reserve(nRows*nCols); 00636 00637 00638 const char * pStr = sStr.data(); 00639 for(int i = 1; i<=nRows;i++) 00640 { 00641 for(int j = 1; j<=nCols;j++) 00642 { 00643 unsigned int nVal = atoi(pStr+nPos+1); 00644 00645 nValVec.push_back(nVal); 00646 nPos = sStr.find(',',nPos+1); 00647 } 00648 } 00649 00650 return true; 00651 00652 } 00653 00654 bool MOOSValFromString(std::vector<double> &dfValVec, 00655 int &nRows, 00656 int &nCols, 00657 const std::string & sStr, 00658 const std::string & sToken, 00659 bool bInsensitive) 00660 { 00661 /*unsigned int*/ size_t nPos = MOOSStrFind(sStr,sToken+'=',bInsensitive); 00662 00663 if(nPos==string::npos) 00664 return false; 00665 00666 return MOOSVectorFromString(sStr.substr(nPos),dfValVec,nRows,nCols); 00667 00668 } 00669 00670 bool MOOSValFromString(std::vector<unsigned int> &nValVec, 00671 int &nRows, 00672 int &nCols, 00673 const std::string & sStr, 00674 const std::string & sToken, 00675 bool bInsensitive) 00676 { 00677 00678 size_t nPos = MOOSStrFind(sStr,sToken+'=',bInsensitive); 00679 00680 if(nPos==string::npos) 00681 return false; 00682 00683 return MOOSVectorFromString(sStr.substr(nPos),nValVec,nRows,nCols); 00684 } 00685 00686 00687 00688 bool MOOSValFromString(long long & nVal,const string & sStr,const string & sTk,bool bInsensitive) 00689 { 00690 std::string sVal; 00691 00692 if(MOOSValFromString(sVal,sStr,sTk,bInsensitive)) 00693 { 00694 return (std::stringstream(sVal) >> nVal); 00695 } 00696 00697 return false; 00698 } 00699 00700 00701 00702 bool GetNextAlogLineByMessageName(std::istream & Input, 00703 const std::string & sMessageName, 00704 double & dfTime, 00705 std::string & sSource, 00706 std::string & sPayload) 00707 { 00708 00709 while (!Input.eof()) 00710 { 00711 std::string sLine; 00712 std::getline(Input,sLine); 00713 if(!sLine.empty() && sLine[0]!='%') 00714 { 00715 std::string sWhat,sWho; 00716 std::stringstream ss(sLine); 00717 00718 ss>>dfTime; 00719 00720 ss>>sWhat; 00721 00722 if(MOOSStrCmp(sWhat,sMessageName)) 00723 { 00724 ss>>sSource; 00725 std::getline(ss,sPayload); 00726 return true; 00727 } 00728 } 00729 } 00730 return false; 00731 } 00732 00733 00734 double MOOS_ANGLE_WRAP(double dfAng) 00735 { 00736 if(dfAng<PI && dfAng>-PI) 00737 return dfAng; 00738 00739 // Shift so that problem is now to wrap between (0, 2*PI) 00740 dfAng += PI; 00741 00742 // Wrap 00743 dfAng = fmod(dfAng, 2*PI); 00744 00745 // fmod seems to ignore the -ve... 00746 if (dfAng < 0) dfAng += 2*PI; 00747 00748 // Shift back 00749 return (dfAng == 0.0 ? PI : dfAng-PI); 00750 00751 // Old version did not cope with multiple wraps 00752 //return (dfAng+(dfAng>PI ? -TWO_PI :TWO_PI)); 00753 } 00754 00756 bool MOOSAbsLimit(double & dfVal,double dfLimit) 00757 { 00758 if(dfVal>dfLimit) 00759 { 00760 dfVal = dfLimit; 00761 return true; 00762 } 00763 else if(dfVal<-dfLimit) 00764 { 00765 dfVal = -dfLimit; 00766 return true; 00767 } 00768 return false; 00769 } 00770 00771 bool MOOSStrCmp(string s1,string s2) 00772 { 00773 MOOSToUpper(s1); 00774 MOOSToUpper(s2); 00775 00776 return s1 == s2; 00777 00778 } 00779 00780 00781 string MOOSGetDate() 00782 { 00783 #ifndef _WIN32 00784 struct timeb timebuffer; 00785 ftime( &timebuffer ); 00786 00787 char *timeline = ctime( & ( timebuffer.time ) ); 00788 char sResult[100]; 00789 sprintf(sResult,"%s",timeline); 00790 00791 string sAnswer =sResult; 00792 00793 return sAnswer; 00794 #else 00795 struct _timeb timebuffer; 00796 _ftime( &timebuffer ); 00797 00798 char *timeline = ctime( & ( timebuffer.time ) ); 00799 char sResult[100]; 00800 sprintf(sResult,"%s",timeline); 00801 00802 string sAnswer =sResult; 00803 00804 return sAnswer; 00805 #endif 00806 00807 00808 } 00809 00810 00811 bool MOOSWildCmp(const std::string & sPattern, const std::string & sString ) 00812 { 00813 const char * sWild = sPattern.c_str(); 00814 const char * sStr = sString.c_str(); 00815 // Based on code originally written by Jack Handy 00816 00817 const char *cp = NULL, *mp = NULL; 00818 00819 while ((*sStr) && (*sWild != '*')) 00820 { 00821 //no active wild card in place 00822 if ((*sWild != *sStr) && (*sWild != '?')) 00823 { 00824 //no single char wildcard in place and 00825 //differing characters 00826 return false; 00827 } 00828 00829 //step on in lockstep 00830 sWild++; 00831 sStr++; 00832 } 00833 00834 while (*sStr) 00835 { 00836 00837 //still more of sStr to explore 00838 if (*sWild == '*') 00839 { 00840 if (!*++sWild) 00841 { 00842 //this * was the last character in the wildcard string 00843 //any remaining string is fine... 00844 return true; 00845 } 00846 00847 //sWild is now one past the * 00848 mp = sWild; 00849 cp = sStr+1; 00850 } 00851 else if ((*sWild == *sStr) || (*sWild == '?')) 00852 { 00853 //lock step advance 00854 sWild++; 00855 sStr++; 00856 } 00857 else 00858 { 00859 //wildcard active 00860 sWild = mp; 00861 sStr = cp++; 00862 } 00863 } 00864 00865 while (*sWild == '*') 00866 { 00867 sWild++; 00868 } 00869 return !*sWild; 00870 } 00871 00872 00873 string MOOSGetTimeStampString() 00874 { 00875 struct tm *Now; 00876 time_t aclock; 00877 time( &aclock ); 00878 00879 Now = localtime( &aclock ); 00880 //change suggested by toby schneider April 2009 00881 //Now = gmtime( &aclock ); 00882 char sTmp[1000]; 00883 00884 // Print local time as a string 00885 00886 //14_5_1993_____9_30 00887 sprintf(sTmp, "_%d_%d_%d_____%.2d_%.2d", 00888 Now->tm_mday, 00889 Now->tm_mon+1, 00890 Now->tm_year+1900, 00891 Now->tm_hour, 00892 Now->tm_min ); 00893 00894 00895 string sAns = sTmp; 00896 return sAns; 00897 00898 } 00899 00900 void MOOSToUpper(string &str) 00901 { 00902 string::iterator p; 00903 00904 for(p = str.begin();p!=str.end();p++) 00905 { 00906 *p = toupper(*p); 00907 } 00908 } 00909 00910 bool MOOSIsNumeric(string str) 00911 { 00912 MOOSTrimWhiteSpace(str); 00913 if(str.find_first_not_of("1234567890.eE-+")==string::npos) 00914 { 00915 return true; 00916 } 00917 00918 return false; 00919 } 00920 void MOOSTrimWhiteSpace(string &str) 00921 { 00922 if(!str.empty()) 00923 { 00924 /*unsigned int*/ size_t p = str.find_first_not_of(" \t\n\r"); 00925 /*unsigned int*/ size_t q = str.find_last_not_of(" \t\n\r"); 00926 00927 if(p==string::npos || q==string::npos) 00928 { 00929 str=""; 00930 } 00931 else 00932 { 00933 str = str.substr(p,q-p+1); 00934 } 00935 } 00936 } 00937 00938 void MOOSRemoveChars(string & sStr,const string & sTok) 00939 { 00940 00941 for(unsigned int i = 0;i<sTok.length();i++) 00942 { 00943 string::iterator q = remove(sStr.begin(),sStr.end(),sTok[i]); 00944 00945 int n = sStr.length()-(sStr.end()-q); 00946 00947 sStr.resize(n); 00948 } 00949 00950 } 00951 00952 00953 00954 int MOOSGetch() 00955 { 00956 #ifndef _WIN32 00957 00958 int c, fd=0; 00959 struct termios term, oterm; 00960 00961 /* get the terminal settings */ 00962 tcgetattr(fd, &oterm); 00963 00964 /* get a copy of the settings, which we modify */ 00965 memcpy(&term, &oterm, sizeof(term)); 00966 00967 /* put the terminal in non-canonical mode, any 00968 reads will wait until a character has been 00969 pressed. This function will not time out */ 00970 term.c_lflag = term.c_lflag & (!ICANON); 00971 term.c_cc[VMIN] = 1; 00972 term.c_cc[VTIME] = 0; 00973 tcsetattr(fd, TCSANOW, &term); 00974 00975 /* get a character. c is the character */ 00976 c=getchar(); 00977 00978 /* reset the terminal to its original state */ 00979 tcsetattr(fd, TCSANOW, &oterm); 00980 00981 /* return the charcter */ 00982 return c; 00983 #else 00984 return _getch(); 00985 #endif 00986 00987 00988 } 00989 00990 00991 00992 string MOOSFormat(const char * FmtStr,...) 00993 { 00994 const unsigned int MAX_TRACE_STR = 1024; 00995 00996 if(strlen(FmtStr)<MAX_TRACE_STR) 00997 { 00998 //double the size for format length! 00999 char buf[MAX_TRACE_STR*2]; 01000 01001 va_list arg_ptr; 01002 01003 va_start( arg_ptr,FmtStr); 01004 01005 01006 #ifdef _WIN32 01007 int n= _vsnprintf(buf,sizeof(buf),FmtStr,arg_ptr); 01008 #else 01009 int n = vsnprintf(buf,sizeof(buf),FmtStr,arg_ptr); 01010 #endif 01011 01012 if(n==sizeof(buf)) 01013 { 01014 MOOSTrace("WARNING MOOFormat() TRUNCATED TO %d CHARS",sizeof(buf)); 01015 } 01016 01017 va_end( arg_ptr ); 01018 01019 return string(buf); 01020 } 01021 else 01022 { 01023 return "STRING TOO LONG TO FORMAT"; 01024 } 01025 } 01026 01027 01028 01029 01030 bool MOOSFail(const char * FmtStr,...) 01031 { 01032 const unsigned int MAX_TRACE_STR = 1024; 01033 01034 if(strlen(FmtStr)<MAX_TRACE_STR) 01035 { 01036 //double the size for format length! 01037 char buf[MAX_TRACE_STR*2]; 01038 01039 va_list arg_ptr; 01040 01041 va_start( arg_ptr,FmtStr); 01042 01043 #ifdef _WIN32 01044 int n= _vsnprintf(buf,sizeof(buf),FmtStr,arg_ptr); 01045 #else 01046 int n = vsnprintf(buf,sizeof(buf),FmtStr,arg_ptr); 01047 #endif 01048 01049 if(n==sizeof(buf)) 01050 { 01051 MOOSTrace("WARNING MOOFormat() TRUNCATED TO %d CHARS",sizeof(buf)); 01052 } 01053 01054 va_end( arg_ptr ); 01055 01056 MOOSTrace(string(buf)+"\n"); 01057 01058 } 01059 return false; 01060 } 01061 01062 01063 //this is library scope mapping of threadid to a flag 01064 //specifying whether or no a thread should allow MOOSTracing. 01065 THREAD2TRACE_MAP gThread2TraceMap; 01066 01067 void InhibitMOOSTraceInThisThread(bool bInhibit) 01068 { 01069 01070 #ifdef _WIN32 01071 DWORD Me = GetCurrentThreadId(); 01072 #else 01073 pthread_t Me = pthread_self(); 01074 #endif 01075 01076 gThread2TraceMap[Me] = bInhibit; 01077 } 01078 01079 void MOOSTrace(string sStr) 01080 { 01081 MOOSTrace("%s",sStr.c_str()); 01082 } 01083 01084 01085 void MOOSTrace(const char *FmtStr,...) 01086 { 01087 01088 //initially we wqnt to check to see if printing 01089 //from this thread has been inhibited by a call to 01090 // 01091 #ifdef _WIN32 01092 DWORD Me = GetCurrentThreadId(); 01093 #else 01094 pthread_t Me = pthread_self(); 01095 #endif 01096 01097 if(!gThread2TraceMap.empty()) 01098 01099 { 01100 THREAD2TRACE_MAP::iterator p = gThread2TraceMap.find(Me); 01101 01102 //have we been told to be quiet? 01103 if(p!=gThread2TraceMap.end()) 01104 if(p->second==true) 01105 return; 01106 } 01107 01108 const unsigned int MAX_TRACE_STR = 2048; 01109 01110 if(strlen(FmtStr)<MAX_TRACE_STR) 01111 { 01112 //double the size for format length! 01113 char buf[MAX_TRACE_STR*2]; 01114 01115 va_list arg_ptr; 01116 01117 va_start( arg_ptr,FmtStr); 01118 01119 #ifdef _WIN32 01120 int n= _vsnprintf(buf,sizeof(buf),FmtStr,arg_ptr); 01121 #else 01122 int n = vsnprintf(buf,sizeof(buf),FmtStr,arg_ptr); 01123 #endif 01124 01125 if(n==sizeof(buf)) 01126 { 01127 MOOSTrace("WARNING MOOSTrace() TRUNCATED TO %d CHARS",sizeof(buf)); 01128 } 01129 01130 va_end( arg_ptr ); 01131 01132 #ifdef _WIN32 01133 OutputDebugString(buf); 01134 #endif 01135 01136 // arh changed this because if you wanted to add a percent character in the string, it would first 01137 // be processed by the _vsnprintf above, then placed in 'buf'. 01138 // Problem is that fprintf finds the '%' in buf and expects us to provide more arguments! 01139 //fprintf(stderr,buf); 01140 fputs(buf, stderr); 01141 01142 } 01143 } 01144 01145 double MOOSDeg2Rad(double dfDeg) 01146 { 01147 return dfDeg*PI/180.0; 01148 } 01149 01150 double MOOSRad2Deg(double dfRad) 01151 { 01152 return dfRad*180.0/PI; 01153 } 01154 01155 01156 bool MOOSGetValueFromToken(STRING_LIST & sParams,const string & sToken,string & sVal) 01157 { 01158 STRING_LIST::iterator p; 01159 01160 for(p = sParams.begin();p!=sParams.end();p++) 01161 { 01162 string sLine = *p; 01163 01164 if(sLine.find("=")!=string::npos) 01165 { 01166 MOOSRemoveChars(sLine," \t\r"); 01167 01168 string sTok = MOOSChomp(sLine,"="); 01169 01170 if(MOOSStrCmp(sTok,sToken)) 01171 { 01172 sVal = sLine; 01173 return true; 01174 } 01175 } 01176 } 01177 return false; 01178 } 01179 01180 string MOOSThirdPartyStatusString(string sStatusCommand) 01181 { 01182 ostringstream os; 01183 os<<"STATUS:"<<sStatusCommand.c_str()<<","<<ends; 01184 string sAnswer = os.str(); 01185 return sAnswer; 01186 01187 } 01188 01189 01190 string MOOSThirdPartyActuationString(double * pdfRudder,double * pdfElevator,double * pdfThrust) 01191 { 01192 ostringstream os; 01193 01194 os<<"ACTUATION:"; 01195 if(pdfRudder!=NULL) 01196 { 01197 os<<"RUDDER="<<*pdfRudder<<","; 01198 } 01199 if(pdfElevator!=NULL) 01200 { 01201 os<<"ELEVATOR="<<*pdfElevator<<","; 01202 } 01203 if(pdfThrust!=NULL) 01204 { 01205 os<<"THRUST="<<*pdfThrust<<","; 01206 } 01207 os<<ends; 01208 01209 string sAnswer = os.str(); 01210 01211 return sAnswer; 01212 01213 } 01214 01215 01216 double MOOSNormalInv(double dfArea) 01217 { 01218 double dfNormInv[] ={ 01219 0, -2.3263, -2.0537, -1.8808 , -1.7507, -1.6449, -1.5548 , -1.4758, -1.4051, -1.3408, -1.2816, -1.2265, -1.1750, 01220 -1.1264, -1.0803, -1.0364, -0.9945, -0.9542, -0.9154, -0.8779 , -0.8416, -0.8064, -0.7722, -0.7388, -0.7063, -0.6745 , 01221 -0.6433, -0.6128, -0.5828, -0.5534, -0.5244, -0.4959, -0.4677 , -0.4399, -0.4125, -0.3853, -0.3585, -0.3319, -0.3055, 01222 -0.2793, -0.2533, -0.2275, -0.2019, -0.1764, -0.1510, -0.1257 , -0.1004, -0.0753, -0.0502, -0.0251, 0, 0.0251, 01223 0.0502, 0.0753, 0.1004, 0.1257, 0.1510, 0.1764, 0.2019 , 0.2275, 0.2533, 0.2793, 0.3055, 0.3319, 0.3585, 01224 0.3853, 0.4125, 0.4399, 0.4677, 0.4959, 0.5244, 0.5534 , 0.5828, 0.6128, 0.6433, 0.6745, 0.7063, 0.7388, 01225 0.7722, 0.8064, 0.8416, 0.8779, 0.9154, 0.9542, 0.9945 , 1.0364, 1.0803, 1.1264, 1.1750, 1.2265, 1.2816, 01226 1.3408, 1.4051, 1.4758, 1.5548, 1.6449, 1.7507, 1.8808 , 2.0537, 2.3263, 0}; 01227 01228 if(dfArea<0) 01229 return -1e60; 01230 if(dfArea>=1) 01231 return 1e60; 01232 01233 int nNdx = (int)(dfArea*100.0); 01234 01235 return dfNormInv[nNdx]; 01236 01237 01238 01239 } 01240 01241 double MOOSUniformRandom(double dfMin, double dfMax) 01242 { 01243 double dfRand = ((double)rand())/RAND_MAX; 01244 return dfRand*(dfMax-dfMin)+dfMin; 01245 } 01246 01247 int MOOSDiscreteUniform(int nMin, int nMax) 01248 { 01249 double dfVal = (MOOSUniformRandom(nMin,nMax)); 01250 01251 int nVal = (int)(dfVal); 01252 01253 if(dfVal-nVal>0.5) 01254 { 01255 nVal++; 01256 } 01257 01258 return nVal; 01259 01260 } 01261 01262 01263 01264 double MOOSWhiteNoise(double Sigma) 01265 { 01266 double fac, u1, u2, v1, v2, s; 01267 int u; 01268 static int iset = 0; 01269 static double gset; 01270 01271 01272 if (iset == 0) 01273 { 01274 s = 0; 01275 do 01276 { 01277 u = rand (); 01278 u1 = (double) u / RAND_MAX; 01279 u = rand (); 01280 u2 = (double) u / RAND_MAX; 01281 v1 = 2 * u1 - 1; 01282 v2 = 2 * u2 - 1; 01283 s = v1 * v1 + v2 * v2; 01284 } while (s > 1); 01285 01286 01287 fac = sqrt ((-2 * log (s)) / s); 01288 01289 01290 gset = (v1 * fac); 01291 iset = 1; 01292 v2 = v2 * fac; 01293 return v2*Sigma; 01294 } 01295 else 01296 { 01297 iset = 0; 01298 return gset*Sigma; 01299 } 01300 } 01301 01302 01303 01304 01307 void Progress(double dfPC) 01308 { 01309 if(dfPC>=1.0) 01310 { 01311 MOOSTrace("\n"); 01312 } 01313 else 01314 { 01315 char T[40]; 01316 memset(T,'\0',sizeof(T)); 01317 int n = (int)(dfPC*sizeof(T)); 01318 memset(T,'*',n); 01319 printf("\r%.2f %s",dfPC,T); 01320 } 01321 } 01322 01323 01324 01326 std::string DoubleVector2String(const std::vector<double> & V) 01327 { 01328 std::stringstream ss; 01329 Write(ss,V); 01330 return ss.str(); 01331 } 01332 01334 std::stringstream & Write (std::stringstream & os,const std::vector<double> & Vec) 01335 { 01336 int nRows = Vec.size(); 01337 01338 os<<std::setiosflags(std::ios::scientific); 01339 os<<std::setprecision(3); 01340 01341 os <<'['<<nRows<<"x1]{"; 01342 01343 os.unsetf(std::ios::scientific); 01344 01345 for ( int i = 0; i<nRows; i++ ) 01346 { 01347 os.setf(std::ios::fixed); 01348 os<<std::setprecision(4); 01349 os<<Vec[i]; 01350 if(i!=nRows-1) 01351 { 01352 os<<','; 01353 } 01354 } 01355 os<<"}"; 01356 01357 return os; 01358 } 01359 01361 std::stringstream & Write (std::stringstream & os,const std::vector<int> & Vec) 01362 { 01363 int nRows = Vec.size(); 01364 01365 os <<'['<<nRows<<"x1]{"; 01366 01367 for ( int i = 0; i<nRows; i++ ) 01368 { 01369 os<<Vec[i]; 01370 if(i!=nRows-1) 01371 { 01372 os<<','; 01373 } 01374 } 01375 os<<"}"; 01376 01377 return os; 01378 } 01379 01382 bool GetDirectoryContents(const std::string & sPath, 01383 std::list<std::string> &sContents, bool bFiles) 01384 { 01385 #ifdef _WIN32 01386 WIN32_FIND_DATA sfd; 01387 std::string sTemplate = sPath+"/*.*"; 01388 HANDLE h = FindFirstFile( sTemplate.c_str(), &sfd ); 01389 int n = 0; 01390 if ( h != INVALID_HANDLE_VALUE ) 01391 { 01392 do 01393 { 01394 std::string sPossible = std::string(sfd.cFileName); 01395 //look to remove . and .. 01396 if(sPossible!="." && sPossible!="..") 01397 { 01398 if(bFiles && !(sfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 01399 { 01400 // do something with the file name sfd.cFileName... 01401 sContents.push_front(sPossible); 01402 } 01403 else if(!bFiles && (sfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) 01404 { 01405 // do something with the file name sfd.cFileName... 01406 sContents.push_front(sPossible); 01407 } 01408 } 01409 01410 } while ( FindNextFile( h, &sfd ) ); 01411 } 01412 else 01413 { 01414 return MOOSFail("failed to read directory %s",sPath.c_str()); 01415 } 01416 01417 return true; 01418 #else 01419 01420 struct dirent **namelist; 01421 int n; 01422 01423 //system call... 01424 n = scandir(sPath.c_str(), &namelist, 0, alphasort); 01425 01426 if (n < 0) 01427 { 01428 //uh oh... 01429 return MOOSFail("error reading directory contents %s\n",strerror(errno)); 01430 } 01431 else 01432 { 01433 while(n--) 01434 { 01435 01436 std::string sName(namelist[n]->d_name); 01437 std::string sFullName = sPath+"/"+sName; 01438 01439 //ask a few pertinent questions. 01440 struct stat FileStatus; 01441 stat(sFullName.c_str(),&FileStatus); 01442 01443 //look to remove . and .. 01444 if(sName!="." && sName!="..") 01445 { 01446 01447 if(bFiles &&S_ISREG(FileStatus.st_mode)) 01448 { 01449 //only want to get regular files 01450 sContents.push_front(sName); 01451 } 01452 else if(!bFiles && S_ISDIR(FileStatus.st_mode)) 01453 { 01454 //only want directories 01455 sContents.push_front(sName); 01456 } 01457 } 01458 //C-like clean up.. 01459 free(namelist[n]); 01460 } 01461 //C-like clean up 01462 free(namelist); 01463 } 01464 01465 return true; 01466 #endif 01467 } 01468 01470 bool MOOSFileParts(std::string sFullPath, std::string & sPath,std::string &sFile,std::string & sExtension) 01471 { 01472 /*unsigned int*/ size_t nBreak; 01473 /*unsigned int*/ size_t nFS = sFullPath.find_last_of("/"); 01474 01475 #ifdef _WIN32 01476 //Windows user use either forward ot backslash to delimit (or even a combination...) 01477 /*unsigned int*/ size_t nBS = sFullPath.find_last_of("\\"); 01478 if(nBS!=std::string::npos) 01479 { 01480 if(nFS!=std::string::npos) 01481 { 01482 //look like a mixture - which is the final one 01483 nBreak=nBS>nFS ? nBS:nFS; 01484 } 01485 else 01486 { 01487 //looks like they are using only back slashes 01488 nBreak= nBS; 01489 } 01490 } 01491 else 01492 { 01493 //looks like they are using nix style forward slashes 01494 nBreak = nFS; 01495 } 01496 #else 01497 nBreak = nFS; 01498 #endif 01499 01500 std::string sFullFile; 01501 if(nBreak==std::string::npos) 01502 { 01503 //there is no path 01504 sPath = ""; 01505 sFullFile = sFullPath; 01506 } 01507 else 01508 { 01509 //split path and file 01510 sPath = sFullPath.substr(0,nBreak); 01511 sFullFile = sFullPath.substr(nBreak+1); 01512 } 01513 01514 //finally look to split on "." for extension if it is there. 01515 // sFile = MOOSChomp(sFullFile,"."); 01516 // sExtension = sFullFile; 01517 size_t nDot = sFullFile.find_last_of("."); 01518 if (nDot==std::string::npos) 01519 { 01520 // No extension: 01521 sFile = sFullFile; 01522 sExtension = ""; 01523 } 01524 else 01525 { 01526 // Split extension: 01527 sFile = sFullFile.substr(0,nDot); 01528 sExtension = sFullFile.substr(nDot+1); 01529 } 01530 return true; 01531 } 01532 01533 01534 bool MOOSCreateDirectory(const std::string & sDirectory) 01535 { 01536 01537 #if _WIN32 01538 int bOK = ::CreateDirectory(sDirectory.c_str(),NULL); 01539 01540 if(!bOK) 01541 { 01542 DWORD TheError = GetLastError(); 01543 01544 if(TheError!=ERROR_ALREADY_EXISTS) 01545 { 01546 01547 LPVOID lpMsgBuf; 01548 FormatMessage( 01549 FORMAT_MESSAGE_ALLOCATE_BUFFER | 01550 FORMAT_MESSAGE_FROM_SYSTEM | 01551 FORMAT_MESSAGE_IGNORE_INSERTS, 01552 NULL, 01553 TheError, 01554 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language 01555 (LPTSTR) &lpMsgBuf, 01556 0, 01557 NULL 01558 ); 01559 // Process any inserts in lpMsgBuf. 01560 // ... 01561 // Display the string. 01562 MOOSTrace("Error %ld making directory : \"%s\"\n",TheError,(LPCTSTR)lpMsgBuf); 01563 01564 // Free the buffer. 01565 LocalFree( lpMsgBuf ); 01566 01567 return false; 01568 } 01569 01570 } 01571 #else 01572 if(mkdir(sDirectory.c_str(),0755)==-1) 01573 { 01574 switch(errno) 01575 { 01576 case EEXIST: 01577 break; 01578 default: 01579 MOOSTrace("Error %ld making directory : \"%s\"\n",errno,strerror(errno)); 01580 return false; 01581 } 01582 } 01583 01584 #endif 01585 01586 01587 01588 return true; 01589 }