Jafar
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
sensorManager.hpp
Go to the documentation of this file.
00001 
00013 #ifndef SENSOR_MANAGER_HPP_
00014 #define SENSOR_MANAGER_HPP_
00015 
00016 #include "rtslam/sensorAbstract.hpp"
00017 
00018 #define DEBUG_SENSORMANAGER 0
00019 
00020 namespace jafar {
00021 namespace rtslam {
00022 
00039   class SensorManagerAbstract
00040   {
00041     protected:
00042       map_ptr_t mapPtr;
00043       double start_date;
00044       bool all_init;
00045     public:
00046     
00047     struct ProcessInfo
00048     {
00049       sensor_ptr_t sen;
00050       unsigned id;
00051       bool no_more_data; // in offline mode, all of the sensors have no more data, so we stop everything
00052       double date;
00053       double arrival;
00054       double date_next; // date of next data arrival
00055       ProcessInfo(sensor_ptr_t sen, unsigned id, double date, double arrival, double date_next):
00056         sen(sen), id(id), no_more_data(false), date(date), arrival(arrival), date_next(date_next) {}
00057       //ProcessInfo(sensor_ptr_t sen, unsigned id, double date): sen(sen), id(id), no_more_data(false), date(date), date_next(-1.) {}
00058       ProcessInfo(bool no_more_data, bool date_next): sen(), id(0), no_more_data(no_more_data), date(-1.), arrival(-1.), date_next(date_next) {}
00059       ProcessInfo(): sen(), id(0), no_more_data(false), date(-1.), arrival(-1.), date_next(-1.) {}
00060     };
00061 
00062     SensorManagerAbstract(map_ptr_t mapPtr): mapPtr(mapPtr), start_date(0.), all_init(false) {}
00063     
00064     virtual void logData(sensor_ptr_t sen, double start_date, double waitedmove_date, double moved_date, double processed_date) {}
00065     virtual void printStats() {}
00066 
00067     bool allInit() { return all_init; }
00068     void setStartDate(double start_date) { this->start_date = start_date; }
00069     virtual ProcessInfo getNextDataToUse_func(double currentTime) = 0;
00070 
00071     ProcessInfo getNextDataToUse(double currentTime)
00072     {
00073       ProcessInfo pinfo;
00074       while (true)
00075       {
00076         pinfo = getNextDataToUse_func(currentTime);
00077         if (pinfo.sen && !pinfo.sen->getUseForInit() && pinfo.date < start_date)
00078           pinfo.sen->discard(pinfo.id);
00079         else
00080           break;
00081       }
00082       return pinfo;
00083     }
00084     
00088     int getNextDataToInit(ProcessInfo &result)
00089     {
00090       // TODO set an order for init
00091       RawInfos infos;
00092       bool hasSensorMissingData = false;
00093       sensor_ptr_t oldestSen; unsigned oldestId = 0; double oldestTimestamp = 1e20; double oldestArrival = 1e20; double oldestNextArrival = 1e20;
00094       for (MapAbstract::RobotList::iterator robIter = mapPtr->robotList().begin();
00095         robIter != mapPtr->robotList().end(); ++robIter)
00096       {
00097         for (RobotAbstract::SensorList::iterator senIter = (*robIter)->sensorList().begin();
00098           senIter != (*robIter)->sensorList().end(); ++senIter)
00099         {
00100           if ((*senIter)->getUseForInit())
00101           {
00102             (*senIter)->queryAvailableRaws(infos);
00103             if (infos.available.size() > 0)
00104             {
00105               RawInfo &info = infos.available.front();
00106               if (info.timestamp > start_date) // if we anyway don't have data before the start date, use the first one
00107               {
00108                 if (info.timestamp < oldestTimestamp) { oldestSen = (*senIter); oldestId = info.id; oldestTimestamp = info.timestamp; }
00109               } else // else find the last one before the start date
00110               {
00111                 for(std::vector<RawInfo>::reverse_iterator rawIter = infos.available.rbegin(); rawIter != infos.available.rend(); ++rawIter)
00112                   if ((*rawIter).timestamp <= start_date)
00113                   {
00114                     if ((*rawIter).timestamp < oldestTimestamp)
00115                     {
00116                       oldestSen = (*senIter); oldestId = (*rawIter).id;
00117                       oldestTimestamp = (*rawIter).timestamp; oldestArrival = (*rawIter).arrival;
00118                       oldestNextArrival = infos.next.arrival;
00119                     }
00120                     break;
00121                   }
00122               }
00123             } else
00124               hasSensorMissingData = true;
00125           }
00126         }
00127       }
00128 
00129       
00130       if (hasSensorMissingData) return 1; else
00131       {
00132         if (!oldestSen) return 0; else
00133         {
00134           result = ProcessInfo(oldestSen, oldestId, oldestTimestamp, oldestArrival, oldestNextArrival);
00135           return 2;
00136         }
00137       }
00138     }
00139 
00140     virtual void stop() {}
00141   };
00142 
00143   
00153   class SensorManagerOffline: public SensorManagerAbstract
00154   {
00155     protected:
00156       bool replay;
00157       bool first;
00158       std::fstream fb;
00159 
00160       size_t sen_id;
00161       double raw_date;
00162 
00163       bool wait_data;
00164 
00165     public:
00166             SensorManagerOffline(map_ptr_t mapPtr, std::string replay_path = ""):
00167               SensorManagerAbstract(mapPtr), replay(false), first(true), wait_data(false)
00168       {
00169         if (replay_path.size() != 0)
00170         {
00171           replay = true;
00172           std::string file_dat = replay_path + "/replay.dat";
00173           fb.open(file_dat.c_str(), std::ios_base::in | std::ios_base::binary);
00174           if (fb.fail()) { std::cerr << "SensorManagerOffline: could not read file " << file_dat << ", disabling replay" << std::endl; replay = false; }
00175         }
00176       }
00177       
00178       virtual ProcessInfo getNextDataToUse_func(double currentTime)
00179       {
00180         ProcessInfo result;
00181         RawInfo info;
00182 
00183         if (replay)
00184         {
00185           if (first)
00186           {
00187             for(MapAbstract::RobotList::iterator robIter = mapPtr->robotList().begin();
00188               robIter != mapPtr->robotList().end(); ++robIter)
00189             {
00190               size_t size;
00191               fb.read((char*)&size, sizeof(size_t));
00192               if (size != (*robIter)->state.size())
00193                 { std::cerr << "SensorManager replay: robot state size is " << (*robIter)->state.size() << " but replay file has size " << size << std::endl; return result; }
00194               for(size_t i = 0; i < size; ++i) fb.read((char*)&((*robIter)->state.x()(i)), sizeof(double));
00195               for(size_t i = 0; i < size; ++i) for(size_t j = i; j < size; ++j) fb.read((char*)&((*robIter)->state.P()(i,j)), sizeof(double));
00196               for(size_t i = 0; i < 3; ++i) fb.read((char*)&((*robIter)->start_pos_export(i)), sizeof(double));
00197               for(size_t i = 0; i < 3; ++i) fb.read((char*)&((*robIter)->start_pos_abs(i)), sizeof(double));
00198               fb.read((char*)&((*robIter)->is_start_pos_abs_init), sizeof(bool));
00199             }
00200             first = false;
00201           }
00202 
00203           if (!wait_data)
00204           {
00205             fb.read((char*)&sen_id, sizeof(size_t));
00206             fb.read((char*)&raw_date, sizeof(double));
00207             if (fb.eof()) { result.no_more_data = true; return result; }
00208           }
00209           JFR_VVDEBUG("next data to get is sensor " << sen_id << " at " << std::setprecision(16) << raw_date << std::setprecision(6));
00210 
00211           for (MapAbstract::RobotList::iterator robIter = mapPtr->robotList().begin();
00212             robIter != mapPtr->robotList().end(); ++robIter)
00213           {
00214             for (RobotAbstract::SensorList::iterator senIter = (*robIter)->sensorList().begin();
00215               senIter != (*robIter)->sensorList().end(); ++senIter)
00216             {
00217               if ((*senIter)->id() == sen_id)
00218               {
00219                 int status;
00220                 while (true)
00221                 {
00222                   status = (*senIter)->queryNextAvailableRaw(info);
00223                   if (status != 0 || info.timestamp >= raw_date-1e-9) break;
00224                   (*senIter)->discard(info.id);
00225                 }
00226                 if (status == -1) wait_data = true;
00227                 if (status == -2)
00228                 {
00229                   std::cerr << "SensorManagerOffline: missing data from sensor " << sen_id << " at " << std::setprecision(16) << raw_date << std::endl;
00230                   result.no_more_data = true;
00231                 }
00232                 if (status == 0)
00233                 {
00234                   wait_data = false;
00235                   result.id = info.id;
00236                   result.sen = (*senIter);
00237                   result.date = info.timestamp;
00238                 }
00239                 return result;
00240               }
00241             }
00242           }
00243           std::cerr << "SensorManagerOffline: sensor " << sen_id << " not found !" << std::endl;
00244           return result;
00245         } else
00246         {
00247           if (!all_init)
00248           {
00249             ProcessInfo result;
00250             int res;
00251             do {
00252               res = getNextDataToInit(result);
00253               if (res == 0) { all_init = true; break; } else
00254               if (res == 2) { return result; } else
00255               usleep(1000);
00256             } while (res == 1);
00257           }
00258 
00259           result.no_more_data = true;
00260           wait_data = false;
00261           for (MapAbstract::RobotList::iterator robIter = mapPtr->robotList().begin();
00262             robIter != mapPtr->robotList().end(); ++robIter)
00263           {
00264             for (RobotAbstract::SensorList::iterator senIter = (*robIter)->sensorList().begin();
00265               senIter != (*robIter)->sensorList().end(); ++senIter)
00266             {
00267               if (!(*senIter)->isEnabled()) continue;
00268               int status = (*senIter)->queryNextAvailableRaw(info);
00269               if (status == -1) wait_data = true;
00270               if (status != -2) result.no_more_data = false;
00271               if (status == 0 && (result.date < 0 || info.timestamp < result.date))
00272               {
00273                 result.id = info.id;
00274                 result.sen = (*senIter);
00275                 result.date = info.timestamp;
00276               }
00277             }
00278           }
00279 
00280           if (wait_data == true) result.sen.reset();
00281           return result;
00282         }
00283       }
00284     
00285       virtual void stop() { if (replay) fb.close(); }
00286   };
00287 
00288 
00289 
00304   class SensorManagerOnline: public SensorManagerAbstract
00305   {
00306     protected:
00307       struct SenInfo
00308       {
00309         sensor_ptr_t sen;
00310         RawInfos infos;
00311         int res;
00312         size_t first_ok;
00313         size_t num_ok;
00314       };
00315       bool dump;
00316       bool first;
00317       std::fstream fl;
00318       std::fstream fb;
00319       kernel::LoggerTask *loggerTask;
00320 
00321       class LoggableReplayInitialState: public kernel::Loggable
00322       {
00323        private:
00324         std::fstream &fl;
00325         std::fstream &fb;
00326         jblas::vec stateX;
00327         jblas::sym_mat stateP;
00328         jblas::vec start_pos_export;
00329         jblas::vec start_pos_abs;
00330         bool is_start_pos_abs_init;
00331 
00332        public:
00333         LoggableReplayInitialState(std::fstream &fl, std::fstream &fb, jblas::vec stateX, jblas::sym_mat stateP, jblas::vec start_pos_export, jblas::vec start_pos_abs, bool is_start_pos_abs_init):
00334           fl(fl), fb(fb), stateX(stateX), stateP(stateP), start_pos_export(start_pos_export), start_pos_abs(start_pos_abs), is_start_pos_abs_init(is_start_pos_abs_init) {}
00335         virtual void log()
00336         {
00337           fl << stateX << std::endl;
00338           fl << stateP << std::endl;
00339           fl << start_pos_export << std::endl;
00340           fl << start_pos_abs << std::endl;
00341           fl << is_start_pos_abs_init << std::endl;
00342 
00343           size_t size = stateX.size();
00344           fb.write((char*)&size, sizeof(size_t));
00345           for(size_t i = 0; i < size; ++i) fb.write((char*)&(stateX(i)), sizeof(double));
00346           for(size_t i = 0; i < size; ++i) for(size_t j = i; j < size; ++j) fb.write((char*)&(stateP(i,j)), sizeof(double));
00347           for(size_t i = 0; i < 3; ++i) fb.write((char*)&(start_pos_export(i)), sizeof(double));
00348           for(size_t i = 0; i < 3; ++i) fb.write((char*)&(start_pos_abs(i)), sizeof(double));
00349           fb.write((char*)&is_start_pos_abs_init, sizeof(bool));
00350         }
00351       };
00352 
00353       class LoggableReplay: public kernel::Loggable
00354       {
00355        private:
00356         std::fstream &fl;
00357         std::fstream &fb;
00358         size_t sen_id;
00359         std::string sen_name;
00360         size_t raw_id;
00361         double raw_date;
00362 
00363        public:
00364         LoggableReplay(std::fstream &fl, std::fstream &fb, size_t sen_id, std::string sen_name, size_t raw_id, double raw_date):
00365           fl(fl), fb(fb), sen_id(sen_id), sen_name(sen_name), raw_id(raw_id), raw_date(raw_date) {}
00366         virtual void log()
00367         {
00368           fl << sen_id << "\t" << sen_name << "\t" << raw_id << "\t" << std::setprecision(19) << raw_date << std::endl;
00369 
00370           fb.write((char*)&sen_id, sizeof(size_t));
00371           fb.write((char*)&raw_date, sizeof(double));
00372         }
00373       };
00374 
00375       class LoggableChronogram: public kernel::Loggable
00376       {
00377        protected:
00378         std::fstream &fc;
00379         enum { tSenProcessed, tWaitedNoData, tWaitedData, tZappedDataAccident, tZappedDataPurpose } type;
00380         sensor_ptr_t sen;
00381         unsigned id;
00382         double raw_date, arrival_date, start_date, waitedmove_date, moved_date, processed_date;
00383 
00384        public:
00385         LoggableChronogram(std::fstream &fc, sensor_ptr_t sen, unsigned id, double raw_date, double arrival_date, double start_date, double waitedmove_date, double moved_date, double processed_date):
00386           fc(fc), sen(sen), id(id), raw_date(raw_date), arrival_date(arrival_date), start_date(start_date), waitedmove_date(waitedmove_date), moved_date(moved_date), processed_date(processed_date)
00387         { type = tSenProcessed; }
00388         LoggableChronogram(std::fstream &fc, sensor_ptr_t sen, unsigned id, double raw_date, double arrival_date):
00389           fc(fc), sen(sen), id(id), raw_date(raw_date), arrival_date(arrival_date)
00390         { type = tSenProcessed; }
00391         void complete(double start_date, double waitedmove_date, double moved_date, double processed_date)
00392         {
00393           this->waitedmove_date = waitedmove_date; this->moved_date = moved_date;
00394           this->processed_date = processed_date; this->start_date = start_date;
00395           JFR_ASSERT(type == tSenProcessed, "");
00396         }
00397         LoggableChronogram(std::fstream &fc, double waitbegin_date, double waitend_date):
00398           fc(fc), raw_date(waitbegin_date), arrival_date(waitend_date)
00399         { type = tWaitedNoData; }
00400         LoggableChronogram(std::fstream &fc, sensor_ptr_t sen, double waitbegin_date, double waitend_date):
00401           fc(fc), sen(sen), raw_date(waitbegin_date), arrival_date(waitend_date)
00402         { type = tWaitedData; }
00403 
00404         virtual void log()
00405         {
00406           fc << std::setprecision(16) << sen->name() << "\t" << sen->id() << "\t" << id << "\t"
00407              << raw_date << "\t" << arrival_date << "\t" << start_date << "\t"
00408              << waitedmove_date << "\t" << moved_date << "\t" << processed_date << std::endl;
00409         }
00410         friend class SensorManagerOnline;
00411       };
00412 
00413       LoggableChronogram *loggableChronogram;
00414       std::fstream fc;
00415 
00416 
00417       // stats
00418       struct SenStats
00419       {
00420         double total_time, min_time, max_time;
00421         int nIntegrated, nMissed;
00422         SenStats(): total_time(0.), min_time(1e3), max_time(0.), nIntegrated(0), nMissed(0) {}
00423       };
00424       std::map<int,SenStats> senStats;
00425 
00426       struct GlobalStats
00427       {
00428         double start_date, stop_date;
00429         double wait_estimator, wait_sensor;
00430         double move;
00431         GlobalStats(): start_date(-1.), stop_date(-1.), wait_estimator(0.), wait_sensor(0.), move(0.) {}
00432       } globalStats;
00433 
00434       void printStats()
00435       {
00436         std::cout << "SensorManager Stats ------" << std::endl;
00437         globalStats.start_date = globalStats.stop_date - globalStats.start_date;
00438         std::cout << "Work time: " << globalStats.start_date << "s (100%)" << std::endl;
00439         std::cout << "Wait sensor time: " << globalStats.wait_sensor << "s (" << globalStats.wait_sensor/globalStats.start_date*100 << "%)" << std::endl;
00440         std::cout << "Wait estimator time: " << globalStats.wait_estimator << "s (" << globalStats.wait_estimator/globalStats.start_date*100 << "%)" << std::endl;
00441         std::cout << "Move time: " << globalStats.move << "s (" << globalStats.move/globalStats.start_date*100 << "%)" << std::endl;
00442         for (std::map<int,SenStats>::iterator it = senStats.begin(); it != senStats.end(); ++it)
00443         {
00444           std::cout << "Sensor " << it->first << " process time: " << it->second.total_time << "s (" << it->second.total_time/globalStats.start_date*100 << "%, min/avg/max "
00445            << it->second.min_time*1000 << "/" << (it->second.total_time/it->second.nIntegrated)*1000 << "/" << it->second.max_time*1000 << " ms) ; integration rate: "
00446            << it->second.nIntegrated/(double)(it->second.nIntegrated+it->second.nMissed)*100 << "% (" << it->second.nIntegrated
00447            << "/" << it->second.nIntegrated+it->second.nMissed << ")" << std::endl;
00448         }
00449       }
00450 
00451     public:
00452       SensorManagerOnline(map_ptr_t mapPtr, std::string dump_path = "", kernel::LoggerTask *loggerTask = NULL):
00453         SensorManagerAbstract(mapPtr), loggerTask(loggerTask)
00454       {
00455         first = true;
00456         dump = false;
00457         if (dump_path.size() != 0)
00458         {
00459           dump = true;
00460           std::string file_log = dump_path + "/replay.log";
00461           std::string file_dat = dump_path + "/replay.dat";
00462           fl.open(file_log.c_str(), std::ios_base::out);
00463           fb.open(file_dat.c_str(), std::ios_base::out | std::ios_base::binary);
00464           std::string file_chrono = dump_path + "/chronogram.log";
00465           fc.open(file_chrono.c_str(), std::ios_base::out);
00466         }
00467 
00468       }
00469 
00470       inline void do_dump(ProcessInfo const &info, int missed)
00471       {
00472         if (dump)
00473         {
00474           loggerTask->push(new LoggableReplay(fl, fb, info.sen->id(), info.sen->name(), info.id, info.date));
00475           loggableChronogram = new LoggableChronogram(fc, info.sen, info.id, info.date, info.arrival);
00476         }
00477         globalStats.wait_sensor += kernel::Clock::getTime()-globalStats.stop_date;
00478         senStats[info.sen->id()].nMissed += missed;
00479       }
00480 
00481       virtual ProcessInfo getNextDataToUse_func(double currentTime)
00482       {
00483         // TODO when we don't receive data from a sensor for some time we should put it in some state
00484         // stop waiting for these data, and if we receive them again then we start waiting again
00485         // (eg GPS, or external loc...)
00486 
00487         if (first) { globalStats.start_date = globalStats.stop_date = start_date; }
00488 
00489 
00490         if (dump && first)
00491         {
00492           for(MapAbstract::RobotList::iterator robIter = mapPtr->robotList().begin(); robIter != mapPtr->robotList().end(); ++robIter)
00493             loggerTask->push(new LoggableReplayInitialState(fl, fb, (*robIter)->state.x(), (*robIter)->state.P(), (*robIter)->start_pos_export, (*robIter)->start_pos_abs, (*robIter)->is_start_pos_abs_init));
00494           first = false;
00495         }
00496 
00497         // ensure all sensors are init
00498         if (!all_init)
00499         {
00500           ProcessInfo result;
00501           int res;
00502           do {
00503             res = getNextDataToInit(result);
00504             if (res == 0) { all_init = true; break; } else
00505             if (res == 2) { do_dump(result, 0); return result; } else
00506             usleep(1000);
00507           } while (res == 1);
00508         }
00509 
00510         // extract information
00511         std::vector<SenInfo> infos;
00512         for(MapAbstract::RobotList::iterator robIter = mapPtr->robotList().begin();
00513           robIter != mapPtr->robotList().end(); ++robIter)
00514         {
00515           for(RobotAbstract::SensorList::iterator senIter = (*robIter)->sensorList().begin();
00516             senIter != (*robIter)->sensorList().end(); ++senIter)
00517           {
00518             if (!(*senIter)->isEnabled()) continue;
00519             SenInfo info;
00520             info.sen = *senIter;
00521             info.res = info.sen->queryAvailableRaws(info.infos);
00522             infos.push_back(info);
00523           }
00524         }
00525 
00526         // find largest possible date of data than can be integrated now
00527         // it is the min of the nexts dates over all the sensors, except if it is late
00528         const double delay_margin = 2.2;
00529         double tnow = kernel::Clock::getTime();
00530         double max_date = tnow + 3600;
00531         double max_arrival = -1;
00532         for(std::vector<SenInfo>::iterator it = infos.begin(); it != infos.end(); ++it)
00533         {
00534           double next_arrival = it->infos.next.timestamp + (it->infos.next.arrival-it->infos.next.timestamp)*delay_margin; // add some margin to arrival
00535           double next_timestamp = it->infos.next.timestamp - 0.002;
00536           if (next_arrival > tnow && next_timestamp < max_date) { max_date = next_timestamp; max_arrival = next_arrival; }
00537         }
00538 
00539         // set first_ok and num_ok (data between currentTime of the filter and max_date)
00540         for(std::vector<SenInfo>::iterator it = infos.begin(); it != infos.end(); ++it)
00541         {
00542           SenInfo &info = *it;
00543           int i = 0;
00544           for(; i < (int)info.infos.available.size(); ++i)
00545             if (info.infos.available[i].timestamp >= currentTime) break;
00546           info.first_ok = i;
00547           for(; i < (int)info.infos.available.size(); ++i)
00548             if (info.infos.available[i].timestamp > max_date) break;
00549           info.num_ok = i-info.first_ok;
00550         }
00551 
00552         // check if we are late
00553         // ie if all sensors have at least 2 data waiting (except those that don't provide data anymore)
00554         size_t min_data = 1000;
00555         for(std::vector<SenInfo>::iterator it = infos.begin(); it != infos.end(); ++it)
00556           if ((it->num_ok < min_data) && (it->infos.next.timestamp + (it->infos.next.arrival-it->infos.next.timestamp)*delay_margin > tnow))
00557             min_data = it->num_ok;
00558         bool late = (min_data > 1);
00559 
00560         #if DEBUG_SENSORMANAGER
00561         std::cout << std::setprecision(16) << tnow << ": min_date " << currentTime << " max_date " << max_date << ", min_data " << min_data << std::endl;
00562         #endif
00563 
00564         // find the best candidate to integrate now
00565         // it is the oldest among oldest "all" and newest "latest" that are
00566         // available and older than max_date
00567         bool no_more_data;
00568         std::vector<SenInfo>::iterator best_candidate;
00569         RawInfo *best_candidate_info;
00570         double oldest_date;
00571 
00572         for(int t = 0; t < 2; t++)
00573         {
00574           no_more_data = true;
00575           best_candidate = infos.end();
00576           best_candidate_info = NULL;
00577           oldest_date = tnow + 3600;
00578           for(std::vector<SenInfo>::iterator it = infos.begin(); it != infos.end(); ++it)
00579           {
00580             #if DEBUG_SENSORMANAGER
00581             std::cout << "\tsen " << it->sen->id() << "(" << it->res << "," << it->first_ok << "," << it->num_ok << "," << it->infos.available.size() << ")";
00582             #endif
00583             if (it->res != -2) no_more_data = false;
00584             if (it->num_ok > 0)
00585             {
00586               RawInfo &info = it->infos.available[it->first_ok];
00587               if (info.timestamp < oldest_date) { best_candidate = it; best_candidate_info = &info; oldest_date = info.timestamp; }
00588               #if DEBUG_SENSORMANAGER
00589               std::cout << std::setprecision(16) << " " << info.timestamp;
00590               #endif
00591             }
00592             #if DEBUG_SENSORMANAGER
00593             if (it->infos.available.size() > 0)
00594               std::cout << " (first " << std::setprecision(16) << it->infos.available.front().timestamp << " last " << it->infos.available.back().timestamp << ")";
00595             std::cout << std::setprecision(16) << " (next " << it->infos.next.timestamp << std::setprecision(6) << " delay " << (it->infos.next.arrival-it->infos.next.timestamp) << ")" << std::endl;
00596             #endif
00597           }
00598 
00599           // if late remove data
00600           if (t == 0 && late && !best_candidate->infos.integrate_all && (best_candidate->sen->missed_data+1 <= min_data-1))
00601           {
00602             int n_remove = std::min(best_candidate->num_ok-1, min_data-1 - best_candidate->sen->missed_data);
00603             #if DEBUG_SENSORMANAGER
00604             std::cout << "LATE! remove " << n_remove << " data from sen " << best_candidate->sen->id() << "(prev missed " << best_candidate->sen->missed_data << ") and start again" << std::endl;
00605             #endif
00606             best_candidate->first_ok += n_remove;
00607             best_candidate->sen->missed_data += n_remove;
00608           } else
00609           break;
00610         }
00611 
00612         // return result
00613         if (best_candidate_info)
00614         {
00615           ProcessInfo result(best_candidate->sen, best_candidate_info->id, best_candidate_info->timestamp, best_candidate_info->arrival, best_candidate->infos.next.arrival);
00616           result.sen->missed_data = 0;
00617           do_dump(result, best_candidate->first_ok);
00618           #if DEBUG_SENSORMANAGER
00619           std::cout << "\t" << best_candidate->sen->id() << " <- select"  << std::endl;
00620           #endif
00621 
00622           return result;
00623         }
00624         else
00625         {
00626           #if DEBUG_SENSORMANAGER
00627           std::cout << "\tnone <- select" << std::endl;
00628           #endif
00629           return ProcessInfo(no_more_data, max_arrival); // wait
00630         }
00631       }
00632 
00633       virtual void stop()
00634       {
00635         if (dump)
00636         {
00637           loggerTask->push(new LoggableClose(fl));
00638           loggerTask->push(new LoggableClose(fb));
00639           loggerTask->push(new LoggableClose(fc));
00640           std::cout << "Waiting that SensorManager logs are closed by logging task..."; std::cout.flush();
00641           while (fb.is_open() || fl.is_open() || fc.is_open()) usleep(100000);
00642           std::cout << "OK." << std::endl;
00643         }
00644       }
00645 
00646       virtual void logData(sensor_ptr_t sen, double start_date, double waitedmove_date, double moved_date, double processed_date)
00647       {
00648         if (dump)
00649         {
00650           JFR_ASSERT(sen->id() == loggableChronogram->sen->id(), "Sensor inconsistency in SensorManager::logData");
00651           loggableChronogram->complete(start_date, waitedmove_date, moved_date, processed_date);
00652           loggerTask->push(loggableChronogram);
00653           loggableChronogram = NULL;
00654         }
00655         globalStats.move += moved_date-waitedmove_date;
00656         globalStats.wait_estimator += waitedmove_date-start_date;
00657         globalStats.stop_date = processed_date;
00658         SenStats &s = senStats[sen->id()];
00659         double process_time = processed_date-moved_date;
00660         s.total_time += process_time;
00661         if (process_time < s.min_time) s.min_time = process_time;
00662         if (process_time > s.max_time) s.max_time = process_time;
00663         s.nIntegrated++;
00664       }
00665 
00666   };
00667 
00668   
00669 }}
00670 
00671 #endif // SENSORMANAGER_HPP
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated on Wed Oct 15 2014 00:37:27 for Jafar by doxygen 1.7.6.1
LAAS-CNRS