Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

LogNode.cc

Go to the documentation of this file.
00001 #include "LogNode.h"
00002 #include "Shared/get_time.h"
00003 #include "Shared/string_util.h"
00004 #include "Shared/ProjectInterface.h"
00005 #include "Shared/WorldState.h"
00006 #include "Shared/MarkScope.h"
00007 #include "Events/EventRouter.h"
00008 #include "Events/FilterBankEvent.h"
00009 #include "Motion/PostureEngine.h"
00010 #include "Vision/JPEGGenerator.h"
00011 #include "Vision/PNGGenerator.h"
00012 #include <sys/types.h>
00013 #include <sys/stat.h>
00014 #include <errno.h>
00015 #include <sstream>
00016 #include <iomanip>
00017 
00018 #ifndef PLATFORM_APERIOS
00019 REGISTER_CONTROL_INSTANCE(LogToDisk,new BehaviorSwitchControl<LogNode>("Log to Disk",false),"Status Reports");
00020 #endif
00021 
00022 using namespace std; 
00023 
00024 void LogNode::postStart() {
00025   StateNode::postStart();
00026   if(!logSensors && !logImages)
00027     return;
00028   
00029   bool ispng=true;
00030   
00031   // add event listeners
00032   string stdcomp = string_util::makeUpper(compression);
00033   if(logImages && stdcomp.size()==0) {
00034     cerr << getName() << ": compression format not specified, defaulting to PNG" << endl;
00035     stdcomp = "PNG";
00036   }
00037   if(logImages) {
00038     if(stdcomp!="JPEG" || stdcomp!="JPG") {
00039       ispng=false;
00040       erouter->addListener(this,EventBase::visJPEGEGID,ProjectInterface::visColorJPEGSID,EventBase::activateETID);
00041     } else if(stdcomp!="PNG") {
00042       ispng=true;
00043       erouter->addListener(this,EventBase::visPNGEGID,ProjectInterface::visColorPNGSID,EventBase::activateETID);
00044     } else {
00045       cerr << getName() << ": Unknown compression format " << compression << " (png or jpeg please)" << endl;
00046       if(!logSensors)
00047         return;
00048     }
00049   }
00050   if(logSensors) {
00051     erouter->addListener(this,EventBase::sensorEGID);
00052   }
00053   
00054   // set up file system path
00055   path=string_util::tildeExpansion(basepath);
00056   if(!incrementNameIfExists) {
00057     if(path.size()!=0)
00058       path+='/';
00059     path+=basename;
00060   } else {
00061     if(path.size()!=0)
00062       path+='/';
00063     string name=basename+"000";
00064     struct stat sb;
00065     for(unsigned int i=0; stat((path+name).c_str(),&sb)==0; ++i) {
00066       stringstream nameass;
00067       nameass << basename << std::setw(3) << std::setfill('0') << i;
00068       name=nameass.str();
00069     }
00070     path+=name;
00071   }
00072   struct stat sb;
00073   if(stat(path.c_str(),&sb)==0) {
00074     if(!(sb.st_mode&S_IFDIR)) {
00075       cerr << getName() << ": could not create log directory " << path << " (a file by that name already exists)" << endl;
00076       erouter->removeListener(this);
00077       return;
00078     }
00079   } else {
00080     cout << "Creating " << path << " for log data" << endl;
00081     if(mkdir(path.c_str(),0755)!=0) {
00082       int err=errno;
00083       cerr << getName() << ": could not create log directory " << path << " (" << strerror(err) << ")" << endl;
00084       erouter->removeListener(this);
00085       return;
00086     }
00087   }
00088   
00089   // create index file
00090   indexFile.open((path+'/'+basename+".txt").c_str(), ios_base::out | ios_base::trunc);
00091   if(!indexFile) {
00092     cerr << getName() << ": could not create index file " << (path+'/'+basename+".txt") << endl;
00093     erouter->removeListener(this);
00094     return;
00095   }
00096   fileCount = 0;
00097   startTime = get_time();
00098   sensorStartFrame = imageStartFrame = -1U; // flag to cause value to be reassigned to next event
00099   indexFile << "First frame " << ProjectInterface::defRawCameraGenerator->getFrameNumber() << " timestamp: " << startTime << std::endl;
00100   if(initial) {
00101     if(logImages) {
00102       FilterBankGenerator* fbk = NULL;
00103       if(ispng)
00104         fbk = ProjectInterface::defColorPNGGenerator;
00105       else
00106         fbk = ProjectInterface::defColorJPEGGenerator;
00107       writeImage(startTime, *fbk, ispng);
00108     }
00109     if(logSensors) {
00110       writeSensor(startTime);
00111     }
00112   }
00113 }
00114 
00115 void LogNode::doEvent() {
00116   switch(event->getGeneratorID()) {
00117     
00118     case EventBase::visJPEGEGID:{
00119       const FilterBankEvent& fbk = dynamic_cast<const FilterBankEvent&>(*event);
00120       writeImage(event->getTimeStamp(),*fbk.getSource(),false);
00121     } break;
00122     case EventBase::visPNGEGID: {
00123       const FilterBankEvent& fbk = dynamic_cast<const FilterBankEvent&>(*event);
00124       writeImage(event->getTimeStamp(),*fbk.getSource(),true);
00125     } break;
00126       
00127     case EventBase::sensorEGID: {
00128       writeSensor(event->getTimeStamp());
00129     } break;
00130       
00131     default:
00132       std::cerr << getName() << ": unhandled event: " << event->getDescription() << std::endl;
00133   }
00134 }
00135 
00136 //! Just like a behavior, called when it's time to stop doing your thing
00137 void LogNode::stop() {
00138   indexFile.close();
00139   StateNode::stop(); // do this last (required)
00140 }
00141 
00142 void LogNode::writeImage(unsigned int time, FilterBankGenerator& fbk, bool isPNG) {
00143   if(imageStartFrame==-1U)
00144     imageStartFrame = fbk.getFrameNumber();
00145   
00146   unsigned char * data = fbk.getImage(ProjectInterface::fullLayer,0);
00147   size_t datasize = fbk.getImageSize(ProjectInterface::fullLayer,0);
00148   std::stringstream name;
00149   name << basename << std::setw(6) << std::setfill('0') << (time - startTime) << (isPNG ? ".png" : ".jpg");
00150   std::ofstream of((path+'/'+name.str()).c_str());
00151   if(!of) {
00152     std::cerr << "*** WARNING could not open file for saving \"" << (path+'/'+name.str()) << "\"" << std::endl;
00153     return;
00154   }         
00155   of.write(reinterpret_cast<char*>(data),datasize);
00156   if(!of) {
00157     std::cerr << "*** WARNING saving of " << (path+'/'+name.str()) << " failed " << std::endl;
00158     return;
00159   }
00160   indexFile << name.str() << '\t' << fileCount++ << '\t' << (fbk.getFrameNumber() - imageStartFrame) << '\t' << (time-startTime) << std::endl;
00161 }
00162 
00163 void LogNode::writeSensor(unsigned int time) {
00164   if(sensorStartFrame==-1U)
00165     sensorStartFrame = ::state->frameNumber;
00166   PostureEngine pose;
00167   pose.setSaveFormat(true,::state);
00168   std::stringstream name;
00169   name << basename << std::setw(6) << std::setfill('0') << (time - startTime) << ".pos";
00170   
00171   FILE* f = fopen((path+'/'+name.str()).c_str(),"w");
00172   if(f==NULL) {
00173     std::cerr << "*** WARNING could not open file for saving \"" << (path+'/'+name.str()) << "\"" << std::endl;
00174     return;
00175   }
00176   unsigned int sz = pose.saveFileStream(f);
00177   if(sz==0) {
00178     std::cerr << "*** WARNING saving of " << (path+'/'+name.str()) << " failed " << std::endl;
00179     fclose(f);
00180     return;
00181   }
00182   int err=fclose(f);
00183   if(err!=0) {
00184     std::cerr << "*** WARNING error " << err << " while closing " << (path+'/'+name.str()) << std::endl;
00185     return;
00186   }
00187   
00188   indexFile << name.str() << '\t' << fileCount++ << '\t' << (state->frameNumber - sensorStartFrame) << '\t' << (time-startTime) << std::endl;
00189 }
00190 
00191 
00192 
00193 /*! @file
00194  * @brief 
00195  * @author Ethan Tira-Thompson (ejt) (Creator)
00196  */

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:44 2016 by Doxygen 1.6.3