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 and others 00010 // at MIT 2001-2002 and Oxford University 2003-2005. 00011 // email: pnewman@robots.ox.ac.uk. 00012 // 00013 // This file is part of a MOOS Basic (Common) Application. 00014 // 00015 // This program is free software; you can redistribute it and/or 00016 // modify it under the terms of the GNU General Public License as 00017 // published by the Free Software Foundation; either version 2 of the 00018 // License, or (at your option) any later version. 00019 // 00020 // This program is distributed in the hope that it will be useful, 00021 // but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00023 // General Public License for more details. 00024 // 00025 // You should have received a copy of the GNU General Public License 00026 // along with this program; if not, write to the Free Software 00027 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00028 // 02111-1307, USA. 00029 // 00031 00032 00033 // MOOSRemote.cpp: implementation of the CMOOSRemote class. 00034 // 00036 #ifdef _WIN32 00037 #pragma warning(disable : 4786) 00038 #endif 00039 00040 00041 00042 #include <MOOSLIB/MOOSLib.h> 00043 #include <MOOSGenLib/MOOSGenLib.h> 00044 #include <iostream> 00045 #include <sstream> 00046 #include <iterator> 00047 #include <algorithm> 00048 #include <iomanip> 00049 #include "MOOSRemote.h" 00050 #include <stdio.h> 00051 #include <MOOSUtilityLib/ThirdPartyRequest.h> 00052 00053 00054 00055 using namespace std; 00056 00057 00058 #define WD_PERIOD 3.0 00059 #define HUMAN_TIMEOUT 20.0 00060 00062 // Construction/Destruction 00064 00065 #ifdef _WIN32 00066 00067 DWORD WINAPI WDLoopProc( LPVOID lpParameter) 00068 { 00069 00070 CMOOSRemote* pMe = (CMOOSRemote*)lpParameter; 00071 00072 return pMe->WDLoop(); 00073 } 00074 00075 DWORD WINAPI MailLoopProc( LPVOID lpParameter) 00076 { 00077 00078 CMOOSRemote* pMe = (CMOOSRemote*)lpParameter; 00079 00080 return pMe->MailLoop(); 00081 } 00082 00083 #else 00084 00085 void * WDLoopProc( void * lpParameter) 00086 { 00087 00088 MOOSTrace("starting watchdog thread..."); 00089 CMOOSRemote* pMe = (CMOOSRemote*)lpParameter; 00090 00091 pMe->WDLoop(); 00092 00093 return NULL; 00094 } 00095 00096 void * MailLoopProc( void * lpParameter) 00097 { 00098 00099 MOOSTrace("starting mail reading thread,,,\n"); 00100 CMOOSRemote* pMe = (CMOOSRemote*)lpParameter; 00101 00102 pMe->MailLoop(); 00103 00104 return NULL; 00105 } 00106 00107 00108 #endif 00109 00110 00111 00112 CMOOSRemote::CMOOSRemote() 00113 { 00114 m_dfCurrentElevator = 0; 00115 m_dfCurrentRudder = 0; 00116 m_dfCurrentThrust = 0; 00117 m_bQuit = true; 00118 m_bManualOveride = true; 00119 m_dfTimeLastSent = MOOSTime(); 00120 m_dfTimeLastAck = MOOSTime(); 00121 00122 EnableMailLoop(true); 00123 00124 } 00125 00126 CMOOSRemote::~CMOOSRemote() 00127 { 00128 } 00129 00130 bool CMOOSRemote::StopThreads() 00131 { 00132 m_bQuit = true; 00133 int i = 0; 00134 00135 #ifdef _WIN32 00136 WaitForSingleObject(m_hWDThread,INFINITE); 00137 #else 00138 void * Result; 00139 pthread_join( (pthread_t)m_nWDThreadID,&Result); 00140 #endif 00141 00142 return true; 00143 } 00144 00145 bool CMOOSRemote::StartThreads() 00146 { 00147 m_bQuit = false; 00148 00149 #ifdef _WIN32 00150 //this is the main WD thread 00151 m_hWDThread = ::CreateThread( NULL, 00152 0, 00153 WDLoopProc, 00154 this, 00155 CREATE_SUSPENDED, 00156 &m_nWDThreadID); 00157 ResumeThread(m_hWDThread); 00158 00159 //this is the main WD thread 00160 m_hMailThread = ::CreateThread( NULL, 00161 0, 00162 MailLoopProc, 00163 this, 00164 CREATE_SUSPENDED, 00165 &m_nMailThreadID); 00166 ResumeThread(m_hMailThread); 00167 00168 00169 #else 00170 00171 00172 int Status = pthread_create( (pthread_t*)& m_nWDThreadID,NULL,WDLoopProc,this); 00173 00174 if(Status!=0) 00175 { 00176 return false; 00177 } 00178 00179 00180 Status = pthread_create( (pthread_t*)& m_nMailThreadID,NULL,MailLoopProc,this); 00181 00182 if(Status!=0) 00183 { 00184 return false; 00185 } 00186 00187 00188 00189 #endif 00190 00191 return true; 00192 } 00193 00194 00195 00196 //overloaded version of Run (don't want default behaviour 00197 bool CMOOSRemote::Run( const char * sName, 00198 const char * sMissionFile) 00199 { 00200 //save absolutely crucial info... 00201 m_sAppName = sName; 00202 m_MissionReader.SetAppName(m_sAppName); 00203 m_sMOOSName = m_sAppName; 00204 m_sMissionFile = sMissionFile; 00205 00206 //what time did we start? 00207 m_dfAppStartTime = MOOSTime(); 00208 00209 //can we see the mission file 00210 if(sMissionFile!=NULL) 00211 { 00212 if(!m_MissionReader.SetFile(m_sMissionFile.c_str())) 00213 { 00214 MOOSTrace("Warning Mission File not found\n"); 00215 // return false; 00216 } 00217 } 00218 00219 //can we start the communications ? 00220 if(!ConfigureComms()) 00221 { 00222 return false; 00223 } 00224 00225 //start WD 00226 StartThreads(); 00227 00228 MOOSPause(1000); 00229 00230 OnStartUp(); 00231 00232 while(!m_bQuit) 00233 { 00234 char cCmd = MOOSGetch(); 00235 00236 HitInputWD(); 00237 00238 switch(cCmd) 00239 { 00240 case '?': 00241 case 'h': 00242 PrintHelp(); 00243 break; 00244 00245 case '`': 00246 HitInputWD(); 00247 MOOSTrace("Ok\n"); 00248 break; 00249 00250 case '\n': 00251 case '\r': 00252 MOOSTrace(">\n"); 00253 break; 00254 00255 00256 case 'q': 00257 MOOSTrace("really quit? (y)"); 00258 if(MOOSGetch()=='y') 00259 { 00260 MOOSTrace("iRemote is shutting down...making things safe:\n"); 00261 MOOSTrace("Setting all to zero\n"); 00262 00263 m_dfCurrentThrust = 0; 00264 m_dfCurrentRudder =0; 00265 m_dfCurrentElevator = 0; 00266 00267 MOOSTrace("Turning Manual Control On\n"); 00268 SetManualOveride(true); 00269 00270 MOOSTrace("bye...\n"); 00271 MOOSPause(1000); 00272 m_bQuit = true; 00273 } 00274 else 00275 { 00276 MOOSTrace("cancelled\n"); 00277 } 00278 break; 00279 00280 case 'm': 00281 m_dfCurrentRudder+=2.0; 00282 MOOSTrace("Setting RudderTo %7.3f\n",m_dfCurrentRudder); 00283 break; 00284 00285 case 'n': 00286 m_dfCurrentRudder-=2.0; 00287 MOOSTrace("Setting RudderTo %7.3f\n",m_dfCurrentRudder); 00288 break; 00289 00290 case ',': 00291 m_dfCurrentRudder=0; 00292 MOOSTrace("Setting RudderTo %7.3f\n",m_dfCurrentRudder); 00293 break; 00294 00295 00296 case ' ': 00297 m_dfCurrentThrust = 0; 00298 m_dfCurrentRudder =0; 00299 m_dfCurrentElevator = 0; 00300 MOOSTrace("Setting all to zero\n"); 00301 SendDesired(); 00302 SetManualOveride(true); 00303 00304 break; 00305 00306 case 'z': 00307 m_dfCurrentThrust -= 2.0; 00308 if(m_dfCurrentThrust<=-100) 00309 { 00310 m_dfCurrentThrust=-100; 00311 } 00312 MOOSTrace("Setting Thrust to %7.3f\n",m_dfCurrentThrust); 00313 break; 00314 00315 case 'Z': 00316 m_dfCurrentThrust = -100.0; 00317 MOOSTrace("Setting Thrust to %7.3f\n",m_dfCurrentThrust); 00318 break; 00319 00320 case 'a': 00321 m_dfCurrentThrust += 2.0; 00322 if(m_dfCurrentThrust>=100) 00323 { 00324 m_dfCurrentThrust=100; 00325 } 00326 00327 MOOSTrace("Setting Thrust to %7.3f \n",m_dfCurrentThrust); 00328 break; 00329 00330 case 'A': 00331 m_dfCurrentThrust = 100.0; 00332 MOOSTrace("Setting Thrust to %7.3f\n",m_dfCurrentThrust); 00333 break; 00334 00335 00336 case 'p': 00337 m_dfCurrentElevator += 2.0; 00338 MOOSTrace("Setting Elevator to %7.3f\n",m_dfCurrentElevator); 00339 break; 00340 00341 case 'l': 00342 m_dfCurrentElevator -= 2.0; 00343 MOOSTrace("Setting Elevator to %7.3f\n",m_dfCurrentElevator); 00344 break; 00345 00346 case 'r': 00347 m_Comms.Notify("ZERO_RUDDER",true); 00348 MOOSTrace("Setting Rudder Zero...\n"); 00349 m_dfCurrentRudder = 0; 00350 break; 00351 00352 case 'e': 00353 m_Comms.Notify("ZERO_ELEVATOR",true); 00354 MOOSTrace("Setting Elevator Zero...\n"); 00355 m_dfCurrentElevator = 0; 00356 break; 00357 00358 00359 case '/': 00360 m_Comms.Notify("COLLISION_OK",true); 00361 MOOSTrace("Clearing Collision Flag"); 00362 break; 00363 00364 case 'O': 00365 case 'o': 00366 SetManualOveride(!m_bManualOveride); 00367 break; 00368 00369 case 'B': 00370 MOOSTrace("Press N for oN and F for off\n"); 00371 cCmd = MOOSGetch(); 00372 switch(cCmd) 00373 { 00374 case 'N': 00375 m_Comms.Notify("BATTERY_CONTROL","ON"); 00376 MOOSTrace("turning battery on...\n"); 00377 break; 00378 case 'F': 00379 m_Comms.Notify("BATTERY_CONTROL","OFF"); 00380 MOOSTrace("turning battery off...\n"); 00381 break; 00382 default: 00383 MOOSTrace("cancelled"); 00384 break; 00385 } 00386 break; 00387 00388 case 'R': 00389 MOOSTrace("really restart Helm? (y/n):"); 00390 cCmd = MOOSGetch(); 00391 if(cCmd=='y') 00392 { 00393 m_Comms.Notify("RESTART_HELM","TRUE"); 00394 MOOSTrace("Sending RESTART_HELM signal\n"); 00395 } 00396 else 00397 { 00398 MOOSTrace("cancelled\n"); 00399 } 00400 break; 00401 00402 case 'F': 00403 FetchDB(); 00404 break; 00405 00406 case 'I': 00407 ReStartAll(); 00408 break; 00409 00410 00411 case 'Q': 00412 MOOSTrace("LSQ Filter Enable - Press N for on F for off:"); 00413 cCmd = MOOSGetch(); 00414 switch(cCmd) 00415 { 00416 case 'N': 00417 m_Comms.Notify("LSQ_ENABLE","TRUE"); 00418 MOOSTrace("Sending LSQ_ENABLE = TRUE signal\n"); 00419 break; 00420 case 'F': 00421 m_Comms.Notify("LSQ_ENABLE","FALSE"); 00422 MOOSTrace("Sending LSQ_ENABLE = FALSE signal\n"); 00423 break; 00424 default: 00425 MOOSTrace("cancelled\n"); 00426 break; 00427 } 00428 break; 00429 00430 case 'K': 00431 MOOSTrace("EKF Filter Enable - Press N for on F for off:"); 00432 cCmd = MOOSGetch(); 00433 switch(cCmd) 00434 { 00435 case 'N': 00436 m_Comms.Notify("EKF_ENABLE","TRUE"); 00437 MOOSTrace("Sending EKF_ENABLE = TRUE signal\n"); 00438 break; 00439 case 'F': 00440 m_Comms.Notify("EKF_ENABLE","FALSE"); 00441 MOOSTrace("Sending EKF_ENABLE = FALSE signal\n"); 00442 break; 00443 default: 00444 MOOSTrace("cancelled\n"); 00445 break; 00446 } 00447 break; 00448 00449 case '+': 00450 PrintCustomSummary(); 00451 break; 00452 case '@': 00453 HandleSAS(); 00454 break; 00455 00456 00457 00458 case 'C': 00459 MOOSTrace("really reset DB? (y/n):"); 00460 cCmd = MOOSGetch(); 00461 if(cCmd=='y') 00462 { 00463 MOOSMSG_LIST List; 00464 MOOSTrace("Sending \"DB_CLEAR\" signal\n"); 00465 m_Comms.ServerRequest("DB_CLEAR",List); 00466 } 00467 else 00468 { 00469 MOOSTrace("cancelled\n"); 00470 } 00471 break; 00472 00473 case 'S': 00474 m_Comms.Notify("SIM_RESET","TRUE"); 00475 MOOSTrace("Resetting simulator...\n"); 00476 break; 00477 00478 case 'G': 00479 m_Comms.Notify("LOGGER_RESTART","TRUE"); 00480 MOOSTrace("Restarting Logger...\n"); 00481 break; 00482 00483 case 'D': 00484 m_Comms.Notify("ZERO_DEPTH","TRUE"); 00485 MOOSTrace("zeroing depth sensor...\n"); 00486 break; 00487 00488 case 'H': 00489 m_Comms.Notify("RESET_ACTUATION","TRUE"); 00490 MOOSTrace("resetting actuation...\n"); 00491 00492 m_dfCurrentThrust = 0; 00493 m_dfCurrentRudder =0; 00494 m_dfCurrentElevator = 0; 00495 break; 00496 00497 case 'W': 00498 DoWiggle(); 00499 break; 00500 00501 case 'V': 00502 MOOSTrace("really restart Navigator? (y/n):\a"); 00503 cCmd = MOOSGetch(); 00504 if(cCmd=='y') 00505 { 00506 m_Comms.Notify("RESTART_NAV","TRUE"); 00507 MOOSTrace("Sending RESTART_NAV signal\n"); 00508 } 00509 else 00510 { 00511 MOOSTrace("cancelled\n"); 00512 } 00513 break; 00514 00515 00516 case 'T': 00517 MOOSTrace("Requesting Navigation Status...\n"); 00518 m_Comms.Notify("NAV_SUMMARY_REQUEST","TRUE"); 00519 break; 00520 00521 case 'Y': 00522 { 00523 MOOSTrace("DVL Summary On? (y/n) "); 00524 cCmd = MOOSGetch(); 00525 if(cCmd=='y') 00526 { 00527 m_Comms.Notify("DVL_SUMMARY_REQUIRED","TRUE"); 00528 MOOSTrace("Turning summary on...\n"); 00529 } 00530 else 00531 { 00532 m_Comms.Notify("DVL_SUMMARY_REQUIRED","FALSE"); 00533 MOOSTrace("Turning summary off...\n"); 00534 } 00535 } 00536 break; 00537 00538 case 'U': 00539 case 'u': 00540 HandleScheduler(); 00541 break; 00542 00543 case '*': 00544 PrintNavSummary(); 00545 break; 00546 00547 case 'J': 00548 HandleThirdPartyTask(); 00549 break; 00550 00551 00552 default: 00553 if(!DoCustomKey(cCmd) && !DoCustomJournal(cCmd)) 00554 { 00555 MOOSTrace("%c is not a command. Press \"?\" for key mappings\n",cCmd); 00556 continue; 00557 } 00558 break; 00559 00560 } 00561 00562 00563 SendDesired(); 00564 00565 } 00566 00567 StopThreads(); 00568 00569 return true; 00570 } 00571 00572 00573 00574 void CMOOSRemote::PrintHelp() 00575 { 00576 00577 const char *Help[] = { 00578 "` Acknowledge", 00579 "W Actuation Test", 00580 "O Toggle MANUAL OVERIDE", 00581 "R RESTART Helm", 00582 "C Clear Server", 00583 "S Reset Simulator", 00584 "G Restart Logger", 00585 "D Zero Depth Sensor", 00586 "H Restart Actuation Driver", 00587 "F Fetch DataBase", 00588 "U Scheduler Control", 00589 "m Rudder Right", 00590 "n Rudder Left", 00591 ", Rudder Zero", 00592 "/ Clear Collision Flag", 00593 "r Rudder Set Home", 00594 "a Thrust Increase", 00595 "z Thrust Decrease", 00596 "A Full Ahead", 00597 "Z Full Reverse", 00598 "p Elevator Up", 00599 "l Elevator Down", 00600 "e Elevator Set Home", 00601 "B Battery Control", 00602 "T Navigation Status", 00603 "V Reset Navigator", 00604 "Q LSQ on/off", 00605 "K EKF on/off", 00606 "* Show NAV_*", 00607 "J Thirdparty Task", 00608 "Y DVL Summary on off", 00609 "@ SAS Control", 00610 "+ Custom Summary", 00611 00612 00613 "q Quit", 00614 00615 "space ALL zero", 00616 "?/h Help", 00617 "\n" 00618 00619 }; 00620 00621 00622 00623 for(int i = 0;i<sizeof(Help)/sizeof(char*);i++) 00624 { 00625 MOOSTrace("%s\n",Help[i]); 00626 } 00627 00628 MOOSTrace("Custom Bindings:\n"); 00629 00630 CUSTOMKEY_MAP::iterator p; 00631 00632 for(p=m_CustomKeys.begin();p!=m_CustomKeys.end();p++) 00633 { 00634 CCustomKey & rKey = p->second; 00635 00636 MOOSTrace("%c %s with %s\n", 00637 rKey.m_cChar, 00638 rKey.m_sKey.c_str(), 00639 rKey.m_sVal.c_str()); 00640 } 00641 00642 00643 00644 } 00645 00646 bool CMOOSRemote::MailLoop() 00647 { 00648 m_bRunMailLoop = true; 00649 while(!m_bQuit) 00650 { 00651 MOOSPause(300); 00652 00653 MOOSMSG_LIST MailIn; 00654 if(m_bRunMailLoop && m_Comms.Fetch(MailIn)) 00655 { 00656 //process mail 00657 //simply write out 00658 MOOSMSG_LIST::iterator p; 00659 00660 //make it in time order 00661 MailIn.sort(); 00662 MailIn.reverse(); 00663 00664 for(p = MailIn.begin();p!=MailIn.end();p++) 00665 { 00666 00667 if(p->IsSkewed(MOOSTime())) 00668 continue; 00669 if(MOOSStrCmp(p->m_sKey,"NAV_SUMMARY")) 00670 { 00671 DoNavSummary(*p); 00672 } 00673 else 00674 00675 if(p->GetKey().find("DEBUG")!=string::npos) 00676 { 00677 //we print MOOS_DEBUG messages to the screen 00678 string sMsg = p->m_sVal; 00679 MOOSRemoveChars(sMsg,"\r\n"); 00680 00681 MOOSTrace(">%-10s @ %7.2f \"%s\"\n", 00682 p->m_sSrc.c_str(), 00683 p->m_dfTime-GetAppStartTime(), 00684 sMsg.c_str()); 00685 } 00686 00687 else 00688 { 00689 CUSTOMJOURNAL_MAP::iterator w = m_CustomJournals.find(p->GetKey()); 00690 if(w!=m_CustomJournals.end()) 00691 { 00692 w->second.Add(p->GetAsString()); 00693 } 00694 00695 } 00696 } 00697 00698 00699 UpdateMOOSVariables(MailIn); 00700 00701 } 00702 00703 } 00704 return true; 00705 } 00706 00707 00708 00709 bool CMOOSRemote::WDLoop() 00710 { 00711 MOOSTrace("WD Loop is running...\n"); 00712 while(!m_bQuit) 00713 { 00714 MOOSPause((int)(1000*WD_PERIOD*0.8)); 00715 if(MOOSTime()-m_dfTimeLastSent>WD_PERIOD) 00716 { 00717 SendDesired(); 00718 } 00719 00720 if(m_bManualOveride) 00721 { 00722 double dfDT = MOOSTime()-m_dfTimeLastAck; 00723 00724 if(dfDT>HUMAN_TIMEOUT*0.5 && dfDT<HUMAN_TIMEOUT*0.65) 00725 { 00726 MOOSTrace("Requesting Operator Acknowledgement... (hit `)\n\a"); 00727 } 00728 if(dfDT>HUMAN_TIMEOUT) 00729 { 00730 m_dfCurrentRudder=0; 00731 m_dfCurrentThrust=0; 00732 m_dfCurrentElevator = 0; 00733 SendDesired(); 00734 if(dfDT<HUMAN_TIMEOUT+2) 00735 { 00736 MOOSTrace("No operator input : ALLSTOPPED @ %f\n",MOOSTime()-m_dfAppStartTime); 00737 00738 } 00739 } 00740 } 00741 } 00742 00743 return true; 00744 } 00745 00746 bool CMOOSRemote::SendDesired() 00747 { 00748 m_Lock.Lock(); 00749 if(m_Comms.IsConnected()) 00750 { 00751 if(m_bManualOveride) 00752 { 00753 m_Comms.Notify("DESIRED_RUDDER",m_dfCurrentRudder); 00754 m_Comms.Notify("DESIRED_THRUST",m_dfCurrentThrust); 00755 m_Comms.Notify("DESIRED_ELEVATOR",m_dfCurrentElevator); 00756 //MOOSTrace("Sending Control @ %12.3f\n",MOOSTime()); 00757 m_dfTimeLastSent = MOOSTime(); 00758 } 00759 } 00760 m_Lock.UnLock(); 00761 return true; 00762 } 00763 00764 00765 bool CMOOSRemote::FetchDB() 00766 { 00767 EnableMailLoop(false); 00768 00769 MOOSTrace("\n\n****** DB Fetch ******\n"); 00770 00771 MOOSMSG_LIST MsgList; 00772 if(m_Comms.ServerRequest("ALL",MsgList)) 00773 { 00774 MOOSMSG_LIST::iterator p; 00775 for(p=MsgList.begin();p!=MsgList.end();p++) 00776 { 00777 CMOOSMsg & rMsg = *p; 00778 ostringstream os; 00779 //ostrstream os; 00780 00781 os<<setw(22); 00782 os<<rMsg.m_sKey.c_str(); 00783 os<<" "; 00784 00785 00786 os<<setw(16); 00787 os<<rMsg.m_sSrc.c_str(); 00788 os<<" "; 00789 00790 os<<setw(9); 00791 os<<rMsg.m_dfTime; 00792 os<<" "; 00793 00794 os<<setw(10); 00795 switch(rMsg.m_cDataType) 00796 { 00797 case MOOS_STRING: 00798 os<<rMsg.m_sVal.c_str(); 00799 break; 00800 case MOOS_NOT_SET: 00801 os<<"*"; 00802 break; 00803 case MOOS_BINARY_STRING: 00804 os<<rMsg.GetAsString().c_str(); 00805 break; 00806 00807 default: 00808 os<<" "; 00809 break; 00810 } 00811 00812 os<<" "; 00813 os<<setw(14); 00814 switch(rMsg.m_cDataType) 00815 { 00816 case MOOS_DOUBLE: 00817 os<<rMsg.m_dfVal; 00818 break; 00819 00820 case MOOS_NOT_SET: 00821 os<<"*"; 00822 break; 00823 00824 default: 00825 os<<" "; 00826 break; 00827 } 00828 00829 00830 os<<endl<<ends; 00831 00832 string sText = os.str(); 00833 MOOSTrace("%s",sText.c_str()); 00834 00835 //os.rdbuf()->freeze(0); 00836 00837 } 00838 } 00839 else 00840 { 00841 MOOSTrace("DB failed to talk to me\n"); 00842 } 00843 00844 //renable mail loop... 00845 EnableMailLoop(true); 00846 00847 return true; 00848 } 00849 00850 bool CMOOSRemote::OnStartUp() 00851 { 00852 00853 00854 MakeCustomSummary(); 00855 00856 MakeCustomJournals(); 00857 00858 MakeCustomKeys(); 00859 00860 00861 m_NavVars["NAV_X"] = CNavVar("NAV_X","X(m)",1.0); 00862 m_NavVars["NAV_Y"] = CNavVar("NAV_Y","Y(m)",1.0); 00863 m_NavVars["NAV_Z"] = CNavVar("NAV_Z","Z(m)",1.0); 00864 m_NavVars["NAV_YAW"] = CNavVar("NAV_YAW","Heading(deg)",-MOOSRad2Deg(1.0)); 00865 m_NavVars["NAV_ALTITUDE"] = CNavVar("NAV_ALTITIUDE","Altitude(m)",1.0); 00866 m_NavVars["NAV_DEPTH"] = CNavVar("NAV_DEPTH","Depth(m)",1.0); 00867 m_NavVars["NAV_SPEED"] = CNavVar("NAV_SPEED","Speed(m/s)",1.0); 00868 00869 00870 //print all the bindings.. 00871 //PrintHelp(); 00872 00873 MOOSPause(1000); 00874 MOOSTrace("\n******** Welcome to the MOOS **********\n>"); 00875 00876 return true; 00877 } 00878 00879 00880 00881 00882 bool CMOOSRemote::MakeCustomKeys() 00883 { 00884 STRING_LIST sParams; 00885 00886 if(m_MissionReader.GetConfiguration(GetAppName(),sParams)) 00887 { 00888 STRING_LIST::iterator p; 00889 00890 for(p = sParams.begin();p!=sParams.end();p++) 00891 { 00892 string sLine = *p; 00893 string sTok,sVal; 00894 m_MissionReader.GetTokenValPair(sLine,sTok,sVal); 00895 00896 00897 00898 if(MOOSStrCmp(sTok,"CUSTOMKEY")) 00899 { 00900 00901 MOOSRemoveChars(sVal," "); 00902 string sChar = MOOSChomp(sVal,":"); 00903 string sKey = MOOSChomp(sVal,"@"); 00904 MOOSRemoveChars(sVal,"\""); 00905 string sTx = MOOSChomp(sVal,"$"); 00906 00907 bool bIsNumeric = MOOSIsNumeric(sTx); 00908 bool bAskToConfirm = (sVal == "confirm"); 00909 00910 if(!sChar.empty()) 00911 { 00912 00913 CCustomKey NewKey; 00914 NewKey.m_cChar = sChar[0]; 00915 NewKey.m_sKey = sKey; 00916 NewKey.m_sVal = sTx; 00917 NewKey.bIsNumeric = bIsNumeric; 00918 NewKey.bAskToConfirm = bAskToConfirm; 00919 00920 if(isdigit(NewKey.m_cChar)) 00921 { 00922 m_CustomKeys[NewKey.m_cChar] = NewKey; 00923 } 00924 else 00925 { 00926 MOOSTrace("CMOOSRemote: can only bind custom keys to numeric characters!\n"); 00927 } 00928 } 00929 00930 } 00931 } 00932 } 00933 return true; 00934 } 00935 00936 bool CMOOSRemote::OnConnectToServer() 00937 { 00938 //subscribe to ALL debug text messages 00939 m_Comms.Register("MOOS_DEBUG",0); 00940 m_Comms.Register("NAV_SUMMARY",1.5); 00941 00942 RegisterMOOSVariables(); 00943 00944 00945 //initially always take control... 00946 return SetManualOveride(true); 00947 } 00948 00949 bool CMOOSRemote::SetManualOveride(bool bOveride) 00950 { 00951 m_bManualOveride = bOveride; 00952 if(m_bManualOveride) 00953 { 00954 00955 m_dfCurrentThrust = 0; 00956 m_dfCurrentRudder =0; 00957 m_dfCurrentElevator = 0; 00958 SendDesired(); 00959 00960 //tell the helm to shut up 00961 m_Comms.Notify("MOOS_MANUAL_OVERIDE","TRUE"); 00962 //wait for a suitable time 00963 MOOSPause(500); 00964 00965 //trap case where helm sent a command in the between 00966 //being told to go off line and reaching this point 00967 SendDesired(); 00968 } 00969 else 00970 { 00971 MOOSTrace("really relinquish manual control? (y/n)\n"); 00972 char c = MOOSGetch(); 00973 if(c=='y') 00974 { 00975 m_Comms.Notify("MOOS_MANUAL_OVERIDE","FALSE"); 00976 } 00977 else 00978 { 00979 MOOSTrace("Cancelled: "); 00980 m_bManualOveride = true; 00981 } 00982 } 00983 00984 MOOSTrace("Manual Control is %s!\n",m_bManualOveride?"on":"off"); 00985 00986 00987 return true; 00988 } 00989 00990 bool CMOOSRemote::DoWiggle() 00991 { 00992 if(!m_bManualOveride) 00993 { 00994 MOOSTrace("Can only test actuation in manual mode\n"); 00995 return false; 00996 } 00997 MOOSTrace("Actuation Check...\n"); 00998 00999 01000 //rudder 01001 m_dfCurrentRudder = 30; 01002 MOOSTrace("Rudder...%7.3f\n",m_dfCurrentRudder); 01003 SendDesired(); 01004 MOOSPause(5000); 01005 01006 m_dfCurrentRudder = -30; 01007 MOOSTrace("Rudder...%7.3f\n",m_dfCurrentRudder); 01008 SendDesired(); 01009 MOOSPause(5000); 01010 m_dfCurrentRudder = 0; 01011 HitInputWD(); 01012 01013 //elevator 01014 m_dfCurrentElevator = 30; 01015 MOOSTrace("Elevator...%7.3f\n",m_dfCurrentElevator); 01016 SendDesired(); 01017 MOOSPause(5000); 01018 01019 m_dfCurrentElevator = -30; 01020 MOOSTrace("Elevator...%7.3f\n",m_dfCurrentElevator); 01021 SendDesired(); 01022 MOOSPause(5000); 01023 m_dfCurrentElevator = 0; 01024 HitInputWD(); 01025 01026 //thruster 01027 m_dfCurrentThrust = -100; 01028 MOOSTrace("Thrust...%7.3f\n",m_dfCurrentThrust); 01029 SendDesired(); 01030 MOOSPause(5000); 01031 m_dfCurrentThrust = 100; 01032 MOOSTrace("Thrust...%7.3f\n",m_dfCurrentThrust); 01033 SendDesired(); 01034 MOOSPause(5000); 01035 m_dfCurrentThrust = 0; 01036 SendDesired(); 01037 HitInputWD(); 01038 01039 MOOSTrace("\nComplete...\n"); 01040 01041 return true; 01042 01043 } 01044 01045 bool CMOOSRemote::HitInputWD() 01046 { 01047 m_dfTimeLastAck = MOOSTime(); 01048 return true; 01049 } 01050 01051 bool CMOOSRemote::DoCustomJournal(char cCmd) 01052 { 01053 CUSTOMJOURNAL_MAP::iterator p; 01054 for(p = m_CustomJournals.begin();p!=m_CustomJournals.end();p++) 01055 { 01056 if(p->second.m_cKey==cCmd) 01057 { 01058 MOOSTrace("\nJournal Entries for \"%s\" :\n ",p->first.c_str()); 01059 STRING_LIST Cpy = p->second.m_Entries; 01060 std::copy(Cpy.begin(),Cpy.end(),std::ostream_iterator<std::string>(std::cout,"\n ")); 01061 return true; 01062 } 01063 } 01064 return false; 01065 } 01066 01067 bool CMOOSRemote::DoCustomKey(char cCmd) 01068 { 01069 //look after custom key bindings 01070 CUSTOMKEY_MAP::iterator p = m_CustomKeys.find(cCmd); 01071 bool confirmed = true; 01072 01073 if(p!=m_CustomKeys.end()) 01074 { 01075 CCustomKey & rKey = p->second; 01076 if(rKey.bAskToConfirm) 01077 { 01078 MOOSTrace("Press 'y' to confirm command: " + rKey.m_sVal + "\n"); 01079 char cResponse = MOOSGetch(); 01080 confirmed = (cResponse == 'y'); 01081 } 01082 if(confirmed) 01083 { 01084 if(rKey.bIsNumeric) 01085 { 01086 m_Comms.Notify(rKey.m_sKey,atof(rKey.m_sVal.c_str())); 01087 MOOSTrace("CustomKey[%c] : %s {%f}\n", 01088 rKey.m_cChar, 01089 rKey.m_sKey.c_str(), 01090 atof(rKey.m_sVal.c_str())); 01091 } 01092 else 01093 { 01094 m_Comms.Notify(rKey.m_sKey,rKey.m_sVal); 01095 MOOSTrace("CustomKey[%c] : %s {%s}\n", 01096 rKey.m_cChar, 01097 rKey.m_sKey.c_str(), 01098 rKey.m_sVal.c_str()); 01099 } 01100 } 01101 else 01102 { 01103 MOOSTrace("Command Cancelled\n"); 01104 } 01105 return true; 01106 } 01107 else 01108 { 01109 return false; 01110 } 01111 } 01112 01113 bool CMOOSRemote::HandleTopDownCal() 01114 { 01115 MOOSTrace("S to start space to stop...\n"); 01116 MOOSTrace("F to set focus...\n"); 01117 MOOSTrace("C to calculate...\n"); 01118 01119 char cCmd = MOOSGetch(); 01120 switch(cCmd) 01121 { 01122 case ' ': 01123 m_Comms.Notify("TOP_DOWN_CAL_CONTROL","STOP"); 01124 MOOSTrace("sending TDC stop command\n"); 01125 break; 01126 case 'S': 01127 m_Comms.Notify("TOP_DOWN_CAL_CONTROL","START"); 01128 MOOSTrace("sending TDC start command\n"); 01129 break; 01130 01131 case 'C': 01132 m_Comms.Notify("TOP_DOWN_CAL_CONTROL","CALCULATE"); 01133 MOOSTrace("sending TDC CALCULATE command\n"); 01134 break; 01135 01136 case 'F': 01137 { 01138 MOOSTrace("enter beacon channel to focus on:"); 01139 //don't use cin! 01140 int nChan; 01141 cin>>nChan; 01142 01143 //confirm 01144 MOOSTrace(" Select Channel %d? (y/n)\n",nChan); 01145 if(MOOSGetch()=='y') 01146 { 01147 string sCmd = MOOSFormat("FOCUS=%d",nChan); 01148 m_Comms.Notify("TOP_DOWN_CAL_CONTROL",sCmd.c_str()); 01149 MOOSTrace("sending TDC set focus %s",sCmd.c_str()); 01150 } 01151 else 01152 { 01153 MOOSTrace("cancelled\n"); 01154 } 01155 } 01156 break; 01157 default: 01158 MOOSTrace("cancelled\n"); 01159 break; 01160 } 01161 01162 return true; 01163 } 01164 01165 bool CMOOSRemote::EnableMailLoop(bool bEnable) 01166 { 01167 m_bRunMailLoop = bEnable; 01168 return true; 01169 } 01170 01171 bool CMOOSRemote::DoNavSummary(CMOOSMsg &Msg) 01172 { 01173 01174 map<string,double> NavVarsValue; 01175 map<string,bool> NavVarsValid; 01176 01177 while(!Msg.m_sVal.empty()) 01178 { 01179 string sLump = MOOSChomp(Msg.m_sVal,","); 01180 01181 string sWhat = MOOSChomp(sLump,"="); 01182 01183 double dfVal = atof(sLump.c_str()); 01184 01185 MOOSChomp(sLump,"@"); 01186 01187 double dfTime = atof(sLump.c_str()); 01188 NAVVAR_MAP::iterator p= m_NavVars.find(sWhat); 01189 01190 if(p!=m_NavVars.end()) 01191 { 01192 CNavVar & rVar = p->second; 01193 rVar.m_dfVal = dfVal; 01194 rVar.m_dfTime = dfTime; 01195 } 01196 } 01197 01198 return true; 01199 } 01200 01201 bool CMOOSRemote::PrintNavSummary() 01202 { 01203 STRING_LIST ToPrint; 01204 ToPrint.push_back("NAV_X"); 01205 ToPrint.push_back("NAV_Y"); 01206 ToPrint.push_back("NAV_Z"); 01207 ToPrint.push_back("NAV_YAW"); 01208 ToPrint.push_back("NAV_ALTITUDE"); 01209 ToPrint.push_back("NAV_DEPTH"); 01210 ToPrint.push_back("NAV_SPEED"); 01211 01212 01213 01214 ostringstream os; 01215 // ostrstream os; 01216 01217 os<<"Navigation Summary:"<<endl; 01218 01219 01220 STRING_LIST::iterator p; 01221 01222 for(p = ToPrint.begin();p!=ToPrint.end();p++) 01223 { 01224 string sWhat = *p; 01225 NAVVAR_MAP::iterator q = m_NavVars.find(sWhat); 01226 01227 if(q!=m_NavVars.end()) 01228 { 01229 CNavVar & rVar = q->second; 01230 01231 //make left justified 01232 os.setf(ios::left); 01233 os<<setw(15)<<rVar.m_sPrintName.c_str()<<"t="; 01234 01235 os.setf(ios::fixed); 01236 01237 if(rVar.m_dfTime==-1) 01238 { 01239 os<<setw(10)<<"****"; 01240 os<<setw(3)<<" : "; 01241 os<<setw(10)<<"****"; 01242 } 01243 else 01244 { 01245 os<<setw(10)<<setprecision(1)<<rVar.m_dfTime; 01246 os<<setw(3)<<" : "; 01247 os<<setw(10)<<setprecision(1)<<rVar.m_dfVal*rVar.m_dfScaleBy; 01248 } 01249 os<<endl; 01250 // os.unsetf(ios::right); 01251 01252 } 01253 } 01254 os<<ends; 01255 01256 01257 MOOSTrace("%s",string(os.str()).c_str()); 01258 01259 // os.rdbuf()->freeze(0); 01260 01261 return true; 01262 } 01263 01264 bool CMOOSRemote::HandleScheduler() 01265 { 01266 MOOSTrace("Scheduler Control:\nspace to stop \ns to start\nr to restart\n\a"); 01267 char cCmd = MOOSGetch(); 01268 01269 if(cCmd=='r') 01270 { 01271 m_Comms.Notify("RESTART_SCHEDULER","TRUE"); 01272 MOOSTrace("Sending RESTART_SCHEDULER signal\n"); 01273 } 01274 else if(cCmd=='s') 01275 { 01276 m_Comms.Notify("SCHEDULER_CONTROL","ON"); 01277 MOOSTrace("Turning Scheduler on..\n"); 01278 } 01279 else if(cCmd==' ') 01280 { 01281 m_Comms.Notify("SCHEDULER_CONTROL","OFF"); 01282 MOOSTrace("Turning Scheduler off..\n"); 01283 } 01284 else 01285 { 01286 MOOSTrace("cancelled\n"); 01287 } 01288 01289 return true; 01290 } 01291 01292 bool CMOOSRemote::HandleThirdPartyTask() 01293 { 01294 MOOSTrace("Thirdparty Task Creation:\n"); 01295 MOOSTrace("W for WayPoint\n"); 01296 MOOSTrace("H for Heading\n"); 01297 01298 char cCmd = MOOSGetch(); 01299 01300 switch(cCmd) 01301 { 01302 case 'W': 01303 MakeWayPoint(); 01304 break; 01305 case 'H': 01306 MakeHeading(); 01307 break; 01308 default: 01309 MOOSTrace("Cancelled\n"); 01310 } 01311 return true; 01312 } 01313 01314 bool CMOOSRemote::MakeWayPoint() 01315 { 01316 double dfX=0; 01317 double dfY=0; 01318 double dfThrust =0; 01319 01320 MOOSTrace("Enter X location (MOOSGrid):"); 01321 if(scanf("%lf",&dfX)==0) 01322 return false; 01323 01324 MOOSTrace("Enter T location (MOOSGrid):"); 01325 if(scanf("%lf",&dfY)==0) 01326 return false; 01327 01328 MOOSTrace("Enter Thrust location 0-100:"); 01329 if(scanf("%lf",&dfThrust)==0) 01330 return false; 01331 01332 01333 CThirdPartyRequest Request; 01334 01335 //we need to specify who we are...job@client 01336 Request.SetClientInfo("CONSOLE",GetAppName()); 01337 01338 //set task info 01339 Request.SetTaskInfo("GOTOWAYPOINT"); 01340 01341 01342 //format location 01343 string sLocation = MOOSFormat("%f,%f",dfX,dfY); 01344 Request.AddProperty("LOCATION",sLocation); 01345 01346 //format thrust 01347 string sThrust = MOOSFormat("%f",dfThrust); 01348 Request.AddProperty("Thrust",sThrust); 01349 01350 01351 //add other properties for waypoint... 01352 Request.AddProperty("NAME","iRemoteWaypoint"); 01353 Request.AddProperty("PRIORITY","3"); 01354 Request.AddProperty("INITIALSTATE","ON"); 01355 Request.AddProperty("TIMEOUT","200"); 01356 Request.AddProperty("RADIUS","10"); 01357 Request.AddProperty("FinishFlag","iRemoteWayPoint_DONE"); 01358 01359 //get the object to format a string.... 01360 string sRequest = Request.ExecuteRequest(); 01361 01362 //send it... 01363 m_Comms.Notify("THIRDPARTY_REQUEST",sRequest); 01364 01365 MOOSTrace("Request sent:\n%s\n",sRequest.c_str()); 01366 01367 01368 return true; 01369 } 01370 01371 bool CMOOSRemote::MakeHeading() 01372 { 01373 double dfHeading=0; 01374 double dfThrust =0; 01375 01376 MOOSTrace("Enter Heading :"); 01377 if(scanf("%lf",&dfHeading)==0) 01378 return false; 01379 01380 MOOSTrace("Enter Thrust 0-100:"); 01381 if(scanf("%lf",&dfThrust)==0) 01382 return false; 01383 01384 01385 CThirdPartyRequest Request; 01386 01387 //we need to specify who we are...job@client 01388 Request.SetClientInfo("CONSOLE",GetAppName()); 01389 01390 //set task info 01391 Request.SetTaskInfo("CONSTANTHEADING"); 01392 01393 01394 //format heading 01395 string sHeading = MOOSFormat("%f",dfHeading); 01396 Request.AddProperty("HEADING",sHeading); 01397 01398 //format thrust 01399 string sThrust = MOOSFormat("%f",dfThrust); 01400 Request.AddProperty("Thrust",sThrust); 01401 01402 01403 //add other properties for waypoint... 01404 Request.AddProperty("NAME","iRemoteHeading"); 01405 Request.AddProperty("PRIORITY","3"); 01406 Request.AddProperty("INITIALSTATE","ON"); 01407 Request.AddProperty("TIMEOUT","200"); 01408 Request.AddProperty("LOGPID","TRUE"); 01409 Request.AddProperty("FinishFlag","iRemoteHeading_DONE"); 01410 01411 //get the object to format a string.... 01412 string sRequest = Request.ExecuteRequest(); 01413 01414 //send it... 01415 m_Comms.Notify("THIRDPARTY_REQUEST",sRequest); 01416 01417 MOOSTrace("Request sent:\n%s\n",sRequest.c_str()); 01418 01419 return true; 01420 } 01421 01422 bool CMOOSRemote::ReStartAll() 01423 { 01424 char Confirm; 01425 MOOSTrace("COMPLETE RESTART..."); 01426 01427 //get control.. 01428 SetManualOveride(true); 01429 01430 //ask 01431 MOOSTrace("Restart navigation? (y/n)"); 01432 if((Confirm = MOOSGetch())=='y') 01433 { 01434 MOOSTrace("Restarting Navigation...\n"); 01435 m_Comms.Notify("RESTART_NAV","TRUE"); 01436 } 01437 01438 MOOSTrace("Restart helm? (y/n)"); 01439 if((Confirm = MOOSGetch())=='y') 01440 { 01441 MOOSTrace("Restarting Helm...\n"); 01442 m_Comms.Notify("RESTART_HELM","TRUE"); 01443 } 01444 01445 MOOSTrace("New Log file? (y/n)"); 01446 if((Confirm = MOOSGetch())=='y') 01447 { 01448 MOOSTrace("Restarting Logger...\n"); 01449 m_Comms.Notify("LOGGER_RESTART","TRUE"); 01450 } 01451 01452 MOOSTrace("Wait....\n"); 01453 MOOSPause(2000); 01454 01455 01456 PrintNavSummary(); 01457 01458 MOOSTrace("*** Check Navigation before launching\n ***"); 01459 01460 return true; 01461 } 01462 01463 bool CMOOSRemote::HandleSAS() 01464 { 01465 MOOSTrace("****** SAS CONTROL: ********\n"); 01466 MOOSTrace("R: Restart\n"); 01467 MOOSTrace("n: oN\n"); 01468 MOOSTrace("f: ofF\n"); 01469 01470 switch(MOOSGetch()) 01471 { 01472 case 'R': 01473 case 'r': 01474 m_Comms.Notify("SAS_CONTROL","RESTART"); 01475 MOOSTrace("Restartin' SAS...\n"); 01476 break; 01477 case 'n': 01478 case 'N': 01479 m_Comms.Notify("SAS_CONTROL","ON"); 01480 MOOSTrace("Turning SAS pingin' on...\n"); 01481 break; 01482 case 'f': 01483 case 'F': 01484 m_Comms.Notify("SAS_CONTROL","OFF"); 01485 MOOSTrace("Turning SAS pingin' orf....\n"); 01486 break; 01487 default: 01488 MOOSTrace("cancelled\n"); 01489 break; 01490 } 01491 01492 return true; 01493 } 01494 01495 01496 01497 01498 01499 bool CMOOSRemote::MakeCustomJournals() 01500 { 01501 01502 STRING_LIST sParams; 01503 if(m_MissionReader.GetConfiguration(GetAppName(),sParams)) 01504 { 01505 STRING_LIST::iterator p; 01506 01507 for(p = sParams.begin();p!=sParams.end();p++) 01508 { 01509 string sLine = *p; 01510 string sTok,sVal; 01511 m_MissionReader.GetTokenValPair(sLine,sTok,sVal); 01512 01513 //CUSTOMJOURNAL = Name = <MOOSNAME>, Key = <key>, History = Size , Period = <Time> 01514 if(MOOSStrCmp(sTok,"CUSTOMJOURNAL")) 01515 { 01516 std::string sName; 01517 if(!MOOSValFromString(sName,sVal,"Name")) 01518 { 01519 MOOSTrace("Error in CUSTOMJOURNAL string -> no \"Name\" field\n"); 01520 continue; 01521 } 01522 std::string sKey; 01523 if(!MOOSValFromString(sKey,sVal,"Key")) 01524 { 01525 MOOSTrace("Error in CUSTOMJOURNAL string -> no \"Key\" field\n"); 01526 continue; 01527 } 01528 int nSize=10; 01529 if(!MOOSValFromString(nSize,sVal,"History")) 01530 { 01531 } 01532 01533 double dfT=0; 01534 if(!MOOSValFromString(dfT,sVal,"Period")) 01535 { 01536 } 01537 01538 01539 char cKey = sKey[0]; 01540 01541 if(sKey.size()!=1 || !isdigit(cKey)) 01542 { 01543 MOOSTrace("error CustomJournal \"Key\" must be a character\n"); 01544 continue; 01545 } 01546 01547 01548 01549 MOOSTrace(" Journal Started for %s:\n bound to \"%c\"\n history of %d\n collecting %s \n", 01550 sName.c_str(), 01551 cKey, 01552 nSize, 01553 dfT>0 ? MOOSFormat("at %f Hz",1.0/dfT).c_str() : "every notification"); 01554 01555 m_CustomJournals[sName] = CJournal(sName,nSize,cKey);; 01556 01557 AddMOOSVariable(sName,sName,"",dfT); 01558 01559 } 01560 } 01561 } 01562 01563 RegisterMOOSVariables(); 01564 01565 return true; 01566 } 01567 01568 01569 01570 bool CMOOSRemote::MakeCustomSummary() 01571 { 01572 01573 STRING_LIST sParams; 01574 if(m_MissionReader.GetConfiguration(GetAppName(),sParams)) 01575 { 01576 STRING_LIST::iterator p; 01577 01578 for(p = sParams.begin();p!=sParams.end();p++) 01579 { 01580 string sLine = *p; 01581 string sTok,sVal; 01582 m_MissionReader.GetTokenValPair(sLine,sTok,sVal); 01583 01584 if(MOOSStrCmp(sTok,"CUSTOMSUMMARY")) 01585 { 01586 m_CustomSummaryList.push_front(sVal); 01587 01588 AddMOOSVariable(sVal,sVal,"",0.2); 01589 } 01590 } 01591 } 01592 01593 RegisterMOOSVariables(); 01594 01595 return true; 01596 } 01597 01598 01599 01600 bool CMOOSRemote::PrintCustomSummary() 01601 { 01602 ostringstream os; 01603 01604 os<<"\n****** User Custom Summary ******"<<endl; 01605 01606 STRING_LIST::iterator p; 01607 01608 for(p = m_CustomSummaryList.begin();p!=m_CustomSummaryList.end();p++) 01609 { 01610 string sWhat = *p; 01611 01612 CMOOSVariable * pVar = GetMOOSVar(sWhat); 01613 01614 if(pVar==NULL) 01615 continue; 01616 01617 //make left justified 01618 os.setf(ios::left); 01619 os<<setw(20)<<sWhat.c_str()<<"t="; 01620 01621 os.setf(ios::fixed); 01622 01623 if(!pVar->IsFresh()) 01624 { 01625 os<<setw(10)<<"****"; 01626 os<<setw(3)<<" : "; 01627 os<<setw(10)<<"****"; 01628 } 01629 else 01630 { 01631 os<<setw(10)<<setprecision(1)<<pVar->GetTime()-GetAppStartTime(); 01632 os<<setw(3)<<" : "; 01633 01634 if(pVar->IsDouble()) 01635 { 01636 os<<setw(10)<<setprecision(1)<<pVar->GetDoubleVal(); 01637 } 01638 else 01639 { 01640 os<<setw(10)<<pVar->GetStringVal().c_str();; 01641 } 01642 } 01643 os<<endl; 01644 } 01645 os<<ends; 01646 01647 MOOSTrace("%s",string(os.str()).c_str()); 01648 01649 return true; 01650 01651 }