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
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
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
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;
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
00137 void LogNode::stop() {
00138 indexFile.close();
00139 StateNode::stop();
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
00194
00195
00196