mURGCtrl.cpp

00001 /*
00002   モニタ対応の URG 制御クラス
00003   Satofumi KAMIMURA
00004   $Id$
00005 */
00006 
00007 #include "mURGCtrl.h"
00008 #include "parseArgs.h"
00009 #include <string.h>
00010 
00011 
00012 #ifndef PACKAGE_STR_VERSION
00013 #define PACKAGE_STR_VERSION "0.0.0"
00014 #endif
00015 
00016 
00017 URG_Simulator* mURGCtrl::simulator = NULL;
00018 int mURGCtrl::sim_add_count = 0;
00019 bool mURGCtrl::isVersionPrinted = false;
00020 bool mURGCtrl::isHelpPrinted = false;
00021 
00022 
00023 mURGCtrl::mURGCtrl(void)
00024   : cond(SDL_CreateCond()), mutex(SDL_CreateMutex()),
00025     mon(vmonitor::getObject()), MonitorMode(Monitor::Unknown),
00026     pre_captureTimes(0), pre_ret_value(0),
00027     playback_isconnected(false), no_record(false) {
00028 }
00029 
00030 
00031 mURGCtrl::~mURGCtrl(void) {
00032 
00033   if (isConnected()) {
00034     --sim_add_count;
00035     if (sim_add_count == 0) {
00036       mon->del(simulator);
00037       delete simulator;
00038     }
00039   }
00040   SDL_DestroyMutex(mutex);
00041   SDL_DestroyCond(cond);
00042 }
00043 
00044 
00045 void mURGCtrl::printVersion(void) {
00046   printf("URG Ctrl Library with Monitor " PACKAGE_STR_VERSION "\n");
00047 }
00048 
00049 
00050 void mURGCtrl::printHelp(void) {
00051   printf("\n"
00052          "----- URG Ctrl Library with Monitor -----\n"
00053          "Options:\n"
00054          "None\n"
00055          "\n");
00056 }
00057 
00058 
00059 void mURGCtrl::parseArgs(int argc, char* argv[]) {
00060   bool help = false;
00061   bool version = false;
00062 
00063   for (int i = 0; i < argc; ++i) {
00064     if (!strcmp("--help", argv[i]) || !strcmp("-h", argv[i])) {
00065       help = true;
00066 
00067     } else if (!strcmp("--version", argv[i]) || !strcmp("-v", argv[i])) {
00068       version = true;
00069     }
00070   }
00071   if (version && !isVersionPrinted) {
00072     printVersion();
00073     isVersionPrinted = true;
00074   }
00075   if (help && !isHelpPrinted) {
00076     printHelp();
00077     isHelpPrinted = true;
00078   }
00079 }
00080 
00081 
00082 bool mURGCtrl::isConnected(void) {
00083   if (MonitorMode == Monitor::Playback) {
00084     return playback_isconnected;
00085   } else {
00086     return URGCtrl::isConnected();
00087   }
00088 }
00089 
00090 
00091 int mURGCtrl::connect(bool autoCapture, const char* device, long baudrate) {
00092   if (MonitorMode == Monitor::Playback) {
00093     // バージョン情報の読み出し
00094     checkVersion();
00095     if (enableTimestamp) {
00096       initTicksInfo();
00097     }
00098     return 0;
00099   }
00100   return URGCtrl::connect(device, baudrate, autoCapture);
00101 }
00102 
00103 
00104 int mURGCtrl::connect(bool autoCapture) {
00105   if (MonitorMode == Monitor::Playback) {
00106     //to_simulator = false;
00107   }
00108   return URGCtrl::connect(autoCapture);
00109 }
00110 
00111 
00112 int mURGCtrl::connect(int argc, char *argv[], bool autoCapture) {
00113 
00114   MonitorMode = mon->connect(argc, argv);
00115   switch (MonitorMode) {
00116   case Monitor::Playback:
00117     playback_isconnected = true;
00118     to_simulator = true;
00119 
00120   case Monitor::Simulator:
00121     if (!simulator) {
00122       simulator = new URG_Simulator();
00123       simulator->setURGType(mon->getURGType());
00124       simulator->setEnvironment(mon->env->getPolygonsReference());
00125     }
00126   }
00127   // !!! connect() を呼んで接続が行われなかったら破綻するはず。~ 込みで
00128   if (sim_add_count <= 0) {
00129     if (simulator) {
00130       simulator->setURGObject(this);
00131     }
00132     mon->add(simulator);
00133   }
00134   ++sim_add_count;
00135 
00136   parseArgs(argc-1, &argv[1]);
00137   int ret = URGCtrl::connect(argc, argv, autoCapture);
00138   if (MonitorMode == Monitor::Playback) {
00139     mon->del(simulator);
00140     --sim_add_count;
00141   }
00142   return ret;
00143 }
00144 
00145 
00146 void mURGCtrl::writeLogData(int ret_value, unsigned long ticks,
00147                             unsigned long raw_timestamp) {
00148   int captureTimes = URGCtrl::getCaptureTimes();
00149   mon->log->lock();
00150   mon->log->writeTag("urg", "capture", ticks);
00151   fprintf(mon->log->fd, " times=%d", captureTimes);
00152 
00153   if (captureTimes != pre_captureTimes) {
00154     fprintf(mon->log->fd, " ret=%d", ret_value);
00155     if (enableTimestamp) {
00156       fprintf(mon->log->fd, " raw_timestamp=%lu", raw_timestamp);
00157     }
00158     if (ret_value >= 0) {
00159       fprintf(mon->log->fd, " data=\"%ld", length[0]);
00160       for (int i = 1; i < ret_value; ++i) {
00161         fprintf(mon->log->fd, ",%ld", length[i]);
00162       }
00163       fprintf(mon->log->fd, "\"");
00164     }
00165   }
00166   mon->log->writeTagEnd();
00167   mon->log->unlock();
00168   pre_captureTimes = captureTimes;
00169 }
00170 
00171 
00172 void mURGCtrl::readLogData(int *ret_value, unsigned long* raw_timestamp) {
00173   mon->log->lock();
00174   unsigned long ticks = mon->log->readTag("urg", "capture");
00175 
00176   const char* line = mon->log->getLineBuffer();
00177   char data_buf[6000];
00178   int times = 0;
00179   int ret = 0;
00180 
00181   if (enableTimestamp) {
00182     sscanf(line, "%*s %*s times=%d ret=%d raw_timestamp=%lu %s",
00183            &times, &ret, raw_timestamp, data_buf);
00184   } else {
00185     sscanf(line, "%*s %*s times=%d ret=%d %s", &times, &ret, data_buf);
00186   }
00187 
00188   if (times == pre_captureTimes) {
00189     // 前回と同じデータを返す
00190     memcpy(length, pre_length, sizeof(length[0]) * SenseSteps);
00191     *ret_value = pre_ret_value;
00192 
00193   } else {
00194     // センサ値をログから取得
00195     *ret_value = ret;
00196     pre_ret_value = *ret_value;
00197 
00198     char *p = data_buf + strlen("data=\"");
00199     for (int i = 0; i < ret; ++i) {
00200       sscanf(p, "%ld", &length[i]);
00201       p = strchr(p, ',') + 1;
00202     }
00203     memcpy(pre_length, length, sizeof(length[0]) * SenseSteps);
00204     pre_captureTimes = times;
00205   }
00206   mon->log->unlock();
00207   mon->task->waitToTicks(ticks, cond, mutex);
00208 }
00209 
00210 
00211 void mURGCtrl::writeVersionInfo(int ret_value, char lines[][LineLength],
00212                                 unsigned long ticks) {
00213   mon->log->lock();
00214   mon->log->writeTag("urg", "getVersionInfo", ticks);
00215   fprintf(mon->log->fd, " ret=%d", ret_value);
00216   if (ret_value >= 0) {
00217     fprintf(mon->log->fd, " \"%s;%s;%s;%s;%s;%s;%s;\"",
00218             lines[0], lines[1], lines[2],
00219             lines[3], lines[4], lines[5], lines[6]);
00220   }
00221   mon->log->writeTagEnd();
00222   mon->log->unlock();
00223 }
00224 
00225 
00226 void mURGCtrl::readVersionInfo(int* ret_value, char lines[][LineLength]) {
00227   mon->log->lock();
00228   unsigned long ticks = mon->log->readTag("urg", "getVersionInfo");
00229 
00230   const char* line = mon->log->getLineBuffer();
00231   sscanf(line, "%*s %*s ret=%d", ret_value);
00232   if (*ret_value >= 0) {
00233     const char* begin = strchr(line, '\"') +1;
00234     for (int i = 0; i < 7; ++i) {
00235       const char *end = strchr(begin, ';');
00236       memcpy(lines[i], begin, end - begin);
00237       lines[i][end - begin] = '\0';
00238       begin = end + 1;
00239     }
00240   }
00241   mon->log->unlock();
00242 
00243   mon->task->waitToTicks(ticks, cond, mutex);
00244 }
00245 
00246 
00247 int mURGCtrl::getVersionInfo(char lines[][LineLength]) {
00248   int ret_value = -1;
00249   if (MonitorMode == Monitor::Playback) {
00250     // ログからの読み出し
00251     readVersionInfo(&ret_value, lines);
00252 
00253   } else {
00254     // ログへの書き込み
00255     ret_value = URGCtrl::getVersionInfo(lines);
00256     writeVersionInfo(ret_value, lines, mon->getTicks());
00257   }
00258   return ret_value;
00259 }
00260 
00261 
00262 int mURGCtrl::raw_capture(long length[],
00263                           int first_index, int last_index, int group,
00264                           unsigned long* raw_timestamp) {
00265   int ret_value = -1;
00266   if (MonitorMode == Monitor::Playback) {
00267     // ログからの読み出し
00268     readLogData(&ret_value, raw_timestamp);
00269 
00270   } else {
00271     // ログへの書き込み
00272     if (raw_timestamp != NULL) {
00273       ret_value = URGCtrl::raw_capture(length, first_index, last_index, group,
00274                                        raw_timestamp);
00275       writeLogData(ret_value, mon->getTicks(), *raw_timestamp);
00276     } else {
00277       ret_value = URGCtrl::raw_capture(length, first_index, last_index, group);
00278       writeLogData(ret_value, mon->getTicks(), 0);
00279     }
00280   }
00281   return ret_value;
00282 }
00283 
00284 
00285 int mURGCtrl::getCaptureTimes(void) {
00286   int ret_times = 0;
00287 
00288   mon->log->lock();
00289   if (MonitorMode == Monitor::Playback) {
00290     // ログからの読み出し
00291     unsigned long ticks = mon->log->readTag("urg", "getCaptureTimes");
00292     const char* line = mon->log->getLineBuffer();
00293     sscanf(line, "%*s %*s ret=%d", &ret_times);
00294     mon->log->unlock();
00295     mon->task->waitToTicks(ticks, cond, mutex);
00296 
00297   } else {
00298     // ログへの書き込み
00299     ret_times = URGCtrl::getCaptureTimes();
00300     mon->log->writeTag("urg", "getCaptureTimes", mon->getTicks());
00301     fprintf(mon->log->fd, " ret=%d", ret_times);
00302     mon->log->writeTagEnd();
00303     mon->log->unlock();
00304   }
00305   return ret_times;
00306 }
00307 
00308 
00309 unsigned long mURGCtrl::getHostTicks(void) {
00310   unsigned long host_ticks = 0;
00311 
00312   mon->log->lock();
00313   if (MonitorMode == Monitor::Playback) {
00314     // ログからの読み出し
00315     unsigned long ticks = mon->log->readTag("urg", "getHostTicks");
00316     const char* line = mon->log->getLineBuffer();
00317     sscanf(line, "%*s %*s ret=%lu", &host_ticks);
00318     mon->log->unlock();
00319     mon->task->waitToTicks(ticks, cond, mutex);
00320 
00321   } else {
00322     // ログへの書き込み
00323     host_ticks = URGCtrl::getHostTicks();
00324     mon->log->writeTag("urg", "getHostTicks", mon->getTicks());
00325     fprintf(mon->log->fd, " ret=%lu", host_ticks);
00326     mon->log->writeTagEnd();
00327     mon->log->unlock();
00328   }
00329   return host_ticks;
00330 }
00331 
00332 
00333 void mURGCtrl::beginTimeAdjust(void) {
00334   if (MonitorMode != Monitor::Playback) {
00335     URGCtrl::beginTimeAdjust();
00336   }
00337 }
00338 
00339 
00340 void mURGCtrl::endTimeAdjust(void) {
00341   if (MonitorMode != Monitor::Playback) {
00342     URGCtrl::endTimeAdjust();
00343   }
00344 }
00345 
00346 
00347 unsigned long mURGCtrl::getURGTimestamp(void) {
00348   unsigned long raw_ticks = 0;
00349 
00350   mon->log->lock();
00351   if (MonitorMode == Monitor::Playback) {
00352     // ログからの読み出し
00353     unsigned long ticks = mon->log->readTag("urg", "getURGTimestamp");
00354     const char* line = mon->log->getLineBuffer();
00355     sscanf(line, "%*s %*s ret=%lu", &raw_ticks);
00356     mon->log->unlock();
00357     mon->task->waitToTicks(ticks, cond, mutex);
00358 
00359   } else {
00360     // ログへの書き込み
00361     raw_ticks = URGCtrl::getURGTimestamp();
00362     mon->log->writeTag("urg", "getURGTimestamp", mon->getTicks());
00363     fprintf(mon->log->fd, " ret=%lu", raw_ticks);
00364     mon->log->writeTagEnd();
00365     mon->log->unlock();
00366   }
00367   return raw_ticks;
00368 }
00369 

Generated on Mon Apr 13 22:52:03 2009 by  doxygen 1.5.7.1