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;
00052 double date;
00053 double arrival;
00054 double date_next;
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
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
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)
00107 {
00108 if (info.timestamp < oldestTimestamp) { oldestSen = (*senIter); oldestId = info.id; oldestTimestamp = info.timestamp; }
00109 } else
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
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
00484
00485
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
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
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
00527
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;
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
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
00553
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
00565
00566
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
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
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);
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