DataLogger.cpp
Go to the documentation of this file.
00001 // -*- C++ -*-
00010 #include "hrpsys/util/Hrpsys.h"
00011 #include "hrpsys/idl/pointcloud.hh"
00012 #include "hrpsys/idl/RobotHardwareService.hh"
00013 #include "DataLogger.h"
00014 
00015 
00016 typedef coil::Guard<coil::Mutex> Guard;
00017 
00018 // Module specification
00019 // <rtc-template block="module_spec">
00020 static const char* nullcomponent_spec[] =
00021   {
00022     "implementation_id", "DataLogger",
00023     "type_name",         "DataLogger",
00024     "description",       "data logger component",
00025     "version",           HRPSYS_PACKAGE_VERSION,
00026     "vendor",            "AIST",
00027     "category",          "example",
00028     "activity_type",     "DataFlowComponent",
00029     "max_instance",      "10",
00030     "language",          "C++",
00031     "lang_type",         "compile",
00032     // Configuration variables
00033     "conf.default.log_precision", "0",
00034     ""
00035   };
00036 // </rtc-template>
00037 
00038 #define LOG_SET_PRECISION(strm)                                         \
00039     int prc;                                                            \
00040     if (precision != 0) {                                               \
00041         prc = os.precision();                                           \
00042         os << std::scientific << std::setprecision(precision);          \
00043     }                                                                   \
00044 
00045 #define LOG_UNSET_PRECISION(strm)                                       \
00046     if (precision != 0)                                                 \
00047         os << std::fixed << std::setprecision(prc);                     \
00048 
00049 void printData(std::ostream& os, const RTC::Acceleration3D& data, unsigned int precision = 0)
00050 {
00051     LOG_SET_PRECISION(os);
00052     os << data.ax << " " << data.ay << " " << data.az << " ";
00053     LOG_UNSET_PRECISION(os);
00054 }
00055 
00056 void printData(std::ostream& os, const RTC::Velocity2D& data, unsigned int precision = 0)
00057 {
00058     LOG_SET_PRECISION(os);
00059     os << data.vx << " " << data.vy << " " << data.va << " ";
00060     LOG_UNSET_PRECISION(os);
00061 }
00062 
00063 void printData(std::ostream& os, const RTC::Pose3D& data, unsigned int precision = 0)
00064 {
00065     LOG_SET_PRECISION(os);
00066     os << data.position.x << " " << data.position.y << " " 
00067        << data.position.z << " " << data.orientation.r << " "
00068        << data.orientation.p << " " << data.orientation.y << " ";
00069     LOG_UNSET_PRECISION(os);
00070 }
00071 
00072 void printData(std::ostream& os, const RTC::AngularVelocity3D& data, unsigned int precision = 0)
00073 {
00074     LOG_SET_PRECISION(os);
00075     os << data.avx << " " << data.avy << " " << data.avz << " ";
00076     LOG_UNSET_PRECISION(os);
00077 }
00078 
00079 void printData(std::ostream& os, const RTC::Point3D& data, unsigned int precision = 0)
00080 {
00081     LOG_SET_PRECISION(os);
00082     os << data.x << " " << data.y << " " << data.z << " ";
00083     LOG_UNSET_PRECISION(os);
00084 }
00085 
00086 void printData(std::ostream& os, const RTC::Orientation3D& data, unsigned int precision = 0)
00087 {
00088     LOG_SET_PRECISION(os);
00089     os << data.r << " " << data.p << " " << data.y << " ";
00090     LOG_UNSET_PRECISION(os);
00091 }
00092 
00093 void printData(std::ostream& os, const PointCloudTypes::PointCloud& data, unsigned int precision = 0)
00094 {
00095   uint npoint = data.data.length()/data.point_step;
00096   os << data.width << " " << data.height << " " << data.type << " " << npoint;
00097   float *ptr = (float *)data.data.get_buffer();
00098   std::string type(data.type);
00099   if (type != "xyz" && type != "xyzrgb"){
00100     std::cerr << "point cloud type(" << type << ") is not supported" 
00101               << std::endl;
00102     return;
00103   } 
00104   for (uint i=0; i<npoint ;i++){
00105     os << " " << *ptr++ << " " << *ptr++ << " " << *ptr++;
00106     if (type == "xyzrgb"){
00107       unsigned char *rgb = (unsigned char *)ptr;
00108       os << " " << (int)rgb[0] << " " << (int)rgb[1] << " " << (int)rgb[2];
00109       ptr++;
00110     }
00111   }
00112 } 
00113 
00114 template<class T>
00115 std::ostream& operator<<(std::ostream& os, const _CORBA_Unbounded_Sequence<T > & data)
00116 {
00117   for (unsigned int j=0; j<data.length(); j++){
00118     os << data[j] << " ";
00119   }
00120   return os;
00121 }
00122 
00123 std::ostream& operator<<(std::ostream& os, const OpenHRP::RobotHardwareService::DblSequence6 & data)
00124 {
00125   for (unsigned int j=0; j<data.length(); j++){
00126     os << data[j] << " ";
00127   }
00128   return os;
00129 }
00130 
00131 std::ostream& operator<<(std::ostream& os, const OpenHRP::RobotHardwareService::DblSequence3 & data)
00132 {
00133   for (unsigned int j=0; j<data.length(); j++){
00134     os << data[j] << " ";
00135   }
00136   return os;
00137 }
00138 
00139 std::ostream& operator<<(std::ostream& os, const OpenHRP::RobotHardwareService::BatteryState & data)
00140 {
00141   os << data.voltage << " " << data.current << " " << data.soc << " ";
00142   return os;
00143 }
00144 
00145 template <class T>
00146 void printData(std::ostream& os, const T& data, unsigned int precision = 0)
00147 {
00148     LOG_SET_PRECISION(os);
00149     for (unsigned int j=0; j<data.length(); j++){
00150         os << data[j] << " ";
00151     }
00152     LOG_UNSET_PRECISION(os);
00153 }
00154 
00155 void printData(std::ostream& os, double data, unsigned int precision = 0)
00156 {
00157     LOG_SET_PRECISION(os);
00158     os << data << " ";
00159     LOG_UNSET_PRECISION(os);
00160 }
00161 
00162 void printData(std::ostream& os, const OpenHRP::RobotHardwareService::RobotState2& data, unsigned int precision = 0)
00163 {
00164   printData(os, data.angle, precision);
00165   printData(os, data.command, precision);
00166   printData(os, data.torque, precision);
00167   printData(os, data.servoState, precision);
00168   printData(os, data.force, precision);
00169   printData(os, data.rateGyro, precision);
00170   printData(os, data.accel, precision);
00171   printData(os, data.batteries, precision);
00172   printData(os, data.voltage, precision);
00173   printData(os, data.current, precision);
00174   printData(os, data.temperature, precision);
00175 }
00176 
00177 template <class T>
00178 class LoggerPort : public LoggerPortBase
00179 {
00180 public:
00181     LoggerPort(const char *name) : m_port(name, m_data) {}
00182     const char *name(){
00183         return m_port.name();
00184     }
00185     virtual void dumpLog(std::ostream& os, unsigned int precision = 0){
00186         os.setf(std::ios::fixed, std::ios::floatfield);
00187         for (unsigned int i=0; i<m_log.size(); i++){
00188             printLog(os, m_log[i], precision);
00189         }
00190     }
00191     void printLog(std::ostream& os, T &data, unsigned int precision = 0){
00192         os << std::setprecision(6) << (data.tm.sec + data.tm.nsec/1e9) << " ";
00193         // data
00194         printData(os, data.data, precision);
00195         os << std::endl;
00196     }
00197     InPort<T>& port(){
00198             return m_port;
00199     }
00200     void log(){
00201         if (m_port.isNew()){
00202             m_port.read();
00203             m_log.push_back(m_data);
00204             while (m_log.size() > m_maxLength){
00205                 m_log.pop_front();
00206             }
00207         }
00208     }
00209     void clear(){
00210         m_log.clear();
00211     }
00212 protected:
00213     InPort<T> m_port;
00214     T m_data;
00215     std::deque<T> m_log;
00216 };
00217 
00218 class LoggerPortForPointCloud : public LoggerPort<PointCloudTypes::PointCloud>
00219 {
00220 public:
00221     LoggerPortForPointCloud(const char *name) : LoggerPort<PointCloudTypes::PointCloud>(name) {}
00222     void dumpLog(std::ostream& os, unsigned int precision = 0){
00223         os.setf(std::ios::fixed, std::ios::floatfield);
00224         for (unsigned int i=0; i<m_log.size(); i++){
00225             // time
00226             os << std::setprecision(6) << (m_log[i].tm.sec + m_log[i].tm.nsec/1e9) << " ";
00227             // data
00228             printData(os, m_log[i], precision);
00229             os << std::endl;
00230         }
00231     }
00232 };
00233 
00234 DataLogger::DataLogger(RTC::Manager* manager)
00235   : RTC::DataFlowComponentBase(manager),
00236     // <rtc-template block="initializer">
00237     m_emergencySignalIn("emergencySignal", m_emergencySignal),
00238     m_DataLoggerServicePort("DataLoggerService"),
00239     // </rtc-template>
00240     m_suspendFlag(false),
00241     m_log_precision(0),
00242         dummy(0)
00243 {
00244   m_service0.setLogger(this);
00245 }
00246 
00247 DataLogger::~DataLogger()
00248 {
00249 }
00250 
00251 
00252 
00253 RTC::ReturnCode_t DataLogger::onInitialize()
00254 {
00255   std::cerr << "[" << m_profile.instance_name << "] onInitialize()" << std::endl;
00256   bindParameter("log_precision", m_log_precision, "0");
00257 
00258   // Registration: InPort/OutPort/Service
00259   // <rtc-template block="registration">
00260   // Set InPort buffers
00261   addInPort("emergencySignal", m_emergencySignalIn);
00262 
00263   // Set OutPort buffer
00264   
00265   // Set service provider to Ports
00266   m_DataLoggerServicePort.registerProvider("service0", "DataLoggerService", m_service0);
00267   
00268   // Set service consumers to Ports
00269   
00270   // Set CORBA Service Ports
00271   addPort(m_DataLoggerServicePort);
00272   
00273   // </rtc-template>
00274   // <rtc-template block="bind_config">
00275   // Bind variables and configuration variable
00276   
00277   // </rtc-template>
00278 
00279   return RTC::RTC_OK;
00280 }
00281 
00282 
00283 
00284 /*
00285 RTC::ReturnCode_t DataLogger::onFinalize()
00286 {
00287   return RTC::RTC_OK;
00288 }
00289 */
00290 
00291 /*
00292 RTC::ReturnCode_t DataLogger::onStartup(RTC::UniqueId ec_id)
00293 {
00294   return RTC::RTC_OK;
00295 }
00296 */
00297 
00298 /*
00299 RTC::ReturnCode_t DataLogger::onShutdown(RTC::UniqueId ec_id)
00300 {
00301   return RTC::RTC_OK;
00302 }
00303 */
00304 
00305 RTC::ReturnCode_t DataLogger::onActivated(RTC::UniqueId ec_id)
00306 {
00307   return RTC::RTC_OK;
00308 }
00309 
00310 RTC::ReturnCode_t DataLogger::onDeactivated(RTC::UniqueId ec_id)
00311 {
00312   return RTC::RTC_OK;
00313 }
00314 
00315 RTC::ReturnCode_t DataLogger::onExecute(RTC::UniqueId ec_id)
00316 {
00317   if (ec_id == 0){
00318     if (m_emergencySignalIn.isNew()){
00319         m_emergencySignalIn.read();
00320         time_t sec = time(NULL);
00321         struct tm *tm_ = localtime(&sec);
00322         char date[20];
00323         strftime(date,20, "%Y-%m-%d", tm_);
00324         char basename[30];
00325         sprintf(basename, "emglog-%s-%02d%02d",
00326                 date, tm_->tm_hour, tm_->tm_min);
00327         std::cout << "received emergency signal. saving log files("
00328                   << basename << ")" << std::endl;
00329         save(basename);
00330         while (m_emergencySignalIn.isNew()){
00331             m_emergencySignalIn.read();
00332         }
00333     }
00334   }else{
00335     Guard guard(m_suspendFlagMutex);
00336     
00337     if (m_suspendFlag) return RTC::RTC_OK;
00338     
00339     for (unsigned int i=0; i<m_ports.size(); i++){
00340       m_ports[i]->log();
00341     }
00342   }
00343   return RTC::RTC_OK;
00344 }
00345 
00346 /*
00347 RTC::ReturnCode_t DataLogger::onAborting(RTC::UniqueId ec_id)
00348 {
00349   return RTC::RTC_OK;
00350 }
00351 */
00352 
00353 /*
00354 RTC::ReturnCode_t DataLogger::onError(RTC::UniqueId ec_id)
00355 {
00356   return RTC::RTC_OK;
00357 }
00358 */
00359 
00360 /*
00361 RTC::ReturnCode_t DataLogger::onReset(RTC::UniqueId ec_id)
00362 {
00363   return RTC::RTC_OK;
00364 }
00365 */
00366 
00367 /*
00368 RTC::ReturnCode_t DataLogger::onStateUpdate(RTC::UniqueId ec_id)
00369 {
00370   return RTC::RTC_OK;
00371 }
00372 */
00373 
00374 /*
00375 RTC::ReturnCode_t DataLogger::onRateChanged(RTC::UniqueId ec_id)
00376 {
00377   return RTC::RTC_OK;
00378 }
00379 */
00380 
00381 bool DataLogger::add(const char *i_type, const char *i_name)
00382 {
00383   suspendLogging();
00384   for (unsigned int i=0; i<m_ports.size(); i++){
00385       if (strcmp(m_ports[i]->name(),i_name) == 0){
00386           std::cerr << "Logger port named \"" << i_name << "\" already exists"
00387                     << std::endl;
00388           resumeLogging();
00389           return false;
00390       }
00391   }  
00392 
00393   LoggerPortBase *new_port=NULL;
00394   if (strcmp(i_type, "TimedDoubleSeq")==0){
00395       LoggerPort<TimedDoubleSeq> *lp = new LoggerPort<TimedDoubleSeq>(i_name);
00396       new_port = lp;
00397       if (!addInPort(i_name, lp->port())) {
00398           resumeLogging();
00399           return false;
00400       }
00401   }else if (strcmp(i_type, "TimedLongSeq")==0){
00402       LoggerPort<TimedLongSeq> *lp = new LoggerPort<TimedLongSeq>(i_name);
00403       new_port = lp;
00404       if (!addInPort(i_name, lp->port())) {
00405           resumeLogging();
00406           return false;
00407       }
00408   }else if (strcmp(i_type, "TimedBooleanSeq")==0){
00409       LoggerPort<TimedBooleanSeq> *lp = new LoggerPort<TimedBooleanSeq>(i_name);
00410       new_port = lp;
00411       if (!addInPort(i_name, lp->port())) {
00412           resumeLogging();
00413           return false;
00414       }
00415   }else if (strcmp(i_type, "TimedLongSeqSeq")==0){
00416       LoggerPort<OpenHRP::TimedLongSeqSeq> *lp = new LoggerPort<OpenHRP::TimedLongSeqSeq>(i_name);
00417       new_port = lp;
00418       if (!addInPort(i_name, lp->port())) {
00419           resumeLogging();
00420           return false;
00421       }
00422   }else if (strcmp(i_type, "TimedPoint3D")==0){
00423       LoggerPort<TimedPoint3D> *lp = new LoggerPort<TimedPoint3D>(i_name);
00424       new_port = lp;
00425       if (!addInPort(i_name, lp->port())) {
00426           resumeLogging();
00427           return false;
00428       }
00429   }else if (strcmp(i_type, "TimedOrientation3D")==0){
00430       LoggerPort<TimedOrientation3D> *lp = new LoggerPort<TimedOrientation3D>(i_name);
00431       new_port = lp;
00432       if (!addInPort(i_name, lp->port())) {
00433           resumeLogging();
00434           return false;
00435       }
00436   }else if (strcmp(i_type, "TimedAcceleration3D")==0){
00437       LoggerPort<TimedAcceleration3D> *lp = new LoggerPort<TimedAcceleration3D>(i_name);
00438       new_port = lp;
00439       if (!addInPort(i_name, lp->port())) {
00440           resumeLogging();
00441           return false;
00442       }
00443   }else if (strcmp(i_type, "TimedAngularVelocity3D")==0){
00444       LoggerPort<TimedAngularVelocity3D> *lp = new LoggerPort<TimedAngularVelocity3D>(i_name);
00445       new_port = lp;
00446       if (!addInPort(i_name, lp->port())) {
00447           resumeLogging();
00448           return false;
00449       }
00450   }else if (strcmp(i_type, "TimedVelocity2D")==0){
00451       LoggerPort<TimedVelocity2D> *lp = new LoggerPort<TimedVelocity2D>(i_name);
00452       new_port = lp;
00453       if (!addInPort(i_name, lp->port())) {
00454           resumeLogging();
00455           return false;
00456       }
00457   }else if (strcmp(i_type, "TimedPose3D")==0){
00458       LoggerPort<TimedPose3D> *lp = new LoggerPort<TimedPose3D>(i_name);
00459       new_port = lp;
00460       if (!addInPort(i_name, lp->port())) {
00461           resumeLogging();
00462           return false;
00463       }
00464   }else if (strcmp(i_type, "PointCloud")==0){
00465     LoggerPort<PointCloudTypes::PointCloud> *lp = new LoggerPortForPointCloud(i_name);
00466       new_port = lp;
00467       if (!addInPort(i_name, lp->port())) {
00468           resumeLogging();
00469           return false;
00470       }
00471   }else if (strcmp(i_type, "TimedRobotState2")==0){
00472     LoggerPort<OpenHRP::RobotHardwareService::TimedRobotState2> *lp = new LoggerPort<OpenHRP::RobotHardwareService::TimedRobotState2>(i_name);
00473     new_port = lp;
00474     if (!addInPort(i_name, lp->port())) {
00475         resumeLogging();
00476         return false;
00477     }
00478   }else{
00479       std::cout << "DataLogger: unsupported data type(" << i_type << ")"
00480                 << std::endl;
00481       resumeLogging();
00482       return false;
00483   }
00484   m_ports.push_back(new_port);
00485   resumeLogging();
00486   return true;
00487 }
00488 
00489 bool DataLogger::save(const char *i_basename)
00490 {
00491   suspendLogging();
00492   bool ret = true;
00493   for (unsigned int i=0; i<m_ports.size(); i++){
00494     std::string fname = i_basename;
00495     fname.append(".");
00496     fname.append(m_ports[i]->name());
00497     std::ofstream ofs(fname.c_str());
00498     if (ofs.is_open()){
00499       m_ports[i]->dumpLog(ofs, m_log_precision);
00500     }else{
00501       std::cerr << "[" << m_profile.instance_name << "] failed to open(" << fname << ")" << std::endl;
00502       ret = false;
00503     }
00504   }
00505   if (ret) std::cerr << "[" << m_profile.instance_name << "] Save log to " << i_basename << ".*" << std::endl;
00506   resumeLogging();
00507   return ret;
00508 }
00509 
00510 bool DataLogger::clear()
00511 {
00512   suspendLogging();
00513   for (unsigned int i=0; i<m_ports.size(); i++){
00514     m_ports[i]->clear();
00515   }
00516   std::cerr << "[" << m_profile.instance_name << "] Log cleared" << std::endl;
00517   resumeLogging();
00518   return true;
00519 }
00520 
00521 void DataLogger::suspendLogging()
00522 {
00523   Guard guard(m_suspendFlagMutex);
00524   m_suspendFlag = true;
00525 }
00526 
00527 void DataLogger::resumeLogging()
00528 {
00529   Guard guard(m_suspendFlagMutex);
00530   m_suspendFlag = false;
00531 }
00532 
00533 void DataLogger::maxLength(unsigned int len)
00534 {
00535   suspendLogging();
00536   for (unsigned int i=0; i<m_ports.size(); i++){
00537     m_ports[i]->maxLength(len);
00538   }
00539   std::cerr << "[" << m_profile.instance_name << "] Log max length is set to " << len << std::endl;
00540   resumeLogging();
00541 }
00542 
00543 extern "C"
00544 {
00545 
00546   void DataLoggerInit(RTC::Manager* manager)
00547   {
00548     RTC::Properties profile(nullcomponent_spec);
00549     manager->registerFactory(profile,
00550                              RTC::Create<DataLogger>,
00551                              RTC::Delete<DataLogger>);
00552   }
00553 
00554 };
00555 
00556 


hrpsys
Author(s): AIST, Fumio Kanehiro
autogenerated on Wed Sep 6 2017 02:35:54