urgCtrl.cpp

00001 /*
00002   URG の制御クラス
00003   Satofumi KAMIMURA
00004   $Id$
00005 */
00006 
00007 #include "urgCtrl.h"
00008 #include "urgAutoCapture.h"
00009 #include "fileUtils.h"
00010 #include "ticksPosition.h"
00011 #include <stdio.h>
00012 #include <memory>
00013 
00014 
00015 #ifndef B5_CONF_FILE
00016 #define B5_CONF_FILE "defaultargs"
00017 #endif
00018 #ifndef PACKAGE_STR_VERSION
00019 #define PACKAGE_STR_VERSION "2.0.0"
00020 #endif
00021 
00022 static const char* const B5conf = B5_CONF_FILE;
00023 static const char* const FirstMessage = "Connection device is not specified";
00024 static const char* const NotConnected = "URG is not connected";
00025 bool URGCtrl::isVersionPrinted = false;
00026 bool URGCtrl::isHelpPrinted = false;
00027 
00028 
00029 URGCtrl::URGCtrl(void)
00030   : con(NULL), isHandstand(false), eachDataByte(2), enableOver4096(false),
00031     error_message(FirstMessage),
00032     ignore_beginTimeAdjust(false), pre_module_ticks(0), total_msec(0),
00033     to_simulator(false), enableTimestamp(false) {
00034 
00035   params.cycle_step_max = 1024;
00036   params.first_step = -1024 * 135 / 360;
00037   params.sense_steps = SenseSteps;
00038   params.rotate_direction = +1;
00039   params.cycle_msec = 100;
00040   params.length_min = 20;
00041   params.length_max = 4094;
00042   params.ticks_begin_step = 44;
00043 
00044   for (int i = 0; i < SenseSteps; ++i) {
00045     length[i] = -1;
00046   }
00047 }
00048 
00049 
00050 URGCtrl::~URGCtrl(void) {
00051   disconnect();
00052 }
00053 
00054 
00055 const char* URGCtrl::what(void) {
00056   return error_message.c_str();
00057 }
00058 
00059 
00060 void URGCtrl::setHandstand(bool on) {
00061   isHandstand = on;
00062 }
00063 
00064 
00065 int URGCtrl::connect(const char* device, long baudrate, bool autoCapture) {
00066   disconnect();
00067 
00068   con = (autoCapture) ? new URGAutoCapture() : new URGManualCapture();
00069 #if 0
00070   con = new UrgCtrlCapture;
00071   if (autoCapture) {
00072     // !!!
00073   }
00074 #endif
00075   int ret_value = con->connect(device, baudrate);
00076   error_message = con->what();
00077   if (ret_value < 0) {
00078     return ret_value;
00079   }
00080 
00081   // バージョン情報の読み出し
00082   checkVersion();
00083 
00084   if (enableTimestamp) {
00085     initTicksInfo();
00086   }
00087   con->laser(true);
00088   return ret_value;
00089 }
00090 
00091 
00092 void URGCtrl::printVersion(void) {
00093   printf("URG Ctrl Library " PACKAGE_STR_VERSION "\n");
00094 }
00095 
00096 
00097 void URGCtrl::printHelp(void) {
00098   printf("\n"
00099          "----- URG Ctrl Library -----\n"
00100          "Options:\n"
00101          "-h,--help             Display this information\n"
00102          "-v,--version          Display URG Library version\n"
00103          "-s,--simulator        Connect to URG device simulator\n"
00104          "--urg_port=[device]   Specify connection device\n"
00105          "--urg_baudrate=[bps]  Specify connection baudrate\n"
00106          "--urg_handstand       Adjust URG settings\n"
00107          "\n");
00108 }
00109 
00110 
00111 bool URGCtrl::parseArgs(int* ret_value, int argc, char *argv[],
00112                         bool autoCapture) {
00113   char* device = NULL;
00114   long baudrate = DefaultBaudrate;
00115   bool help = false;
00116   bool version = false;
00117 
00118   for (int i = 0; i < argc; ++i) {
00119     if (!strncmp("--urg_port=", argv[i], 11) && (strlen(argv[i]) > 11)) {
00120       device = &argv[i][11];
00121 
00122     } else if (!strncmp("--urg_baudrate=", argv[i], 15) &&
00123                (strlen(argv[i]) > 15)) {
00124       baudrate = atoi(&argv[i][15]);
00125 
00126     } else if (!strcmp("--urg_handstand", argv[i])) {
00127       isHandstand = true;
00128 
00129     } else if (!strcmp("--simulator", argv[i]) || !strcmp("-s", argv[i])) {
00130       to_simulator = true;
00131 
00132     } else if (!strcmp("--help", argv[i]) || !strcmp("-h", argv[i])) {
00133       help = true;
00134 
00135     } else if (!strcmp("--version", argv[i]) || !strcmp("-v", argv[i])) {
00136       version = true;
00137     }
00138   }
00139 
00140   if (version && !isVersionPrinted) {
00141     // バージョン情報の出力
00142     printVersion();
00143     isVersionPrinted = true;
00144   }
00145   if (help && !isHelpPrinted) {
00146     // 使用例の表示
00147     printHelp();
00148     isHelpPrinted = true;
00149   }
00150 
00151   if (to_simulator) {
00152     return false;
00153   }
00154   if (device) {
00155     // デバイス接続
00156     *ret_value = connect(device, baudrate, autoCapture);
00157     return true;
00158   }
00159   return false;
00160 }
00161 
00162 
00163 int URGCtrl::connect(int argc, char *argv[], bool autoCapture) {
00164   disconnect();
00165 
00166   int ret_value = -1;
00167   if (parseArgs(&ret_value, argc-1, &argv[1], autoCapture)) {
00168     return ret_value;
00169   }
00170   // デフォルト接続
00171   return connect(autoCapture);
00172 }
00173 
00174 
00175 int URGCtrl::connect(bool autoCapture) {
00176   disconnect();
00177   const char* home_str = getenv("HOME");
00178   std::string home_path = std::string((home_str ? home_str : ".")) + "/.vxv";
00179   const char* path[] = { ".", home_path.c_str(), NULL };
00180   std::string fname = VXV::searchFile(B5conf, path);
00181   if (!fname.empty()) {
00182     std::vector<char*> args;
00183     VXV::createArgs(args, fname.c_str());
00184     int ret_value = -1;
00185     bool ret = parseArgs(&ret_value,
00186                          static_cast<int>(args.size()), &args[0], autoCapture);
00187     VXV::deleteArgs(args);
00188     if (!to_simulator && ret) {
00189       return ret_value;
00190     }
00191   }
00192 
00193   // --urg_handstand を反映させるため、B5conf を評価してから接続している
00194   // !!! --urg_handstand かどうかを記録し、再生時にはそれを用いるようにすべき
00195   if (to_simulator) {
00196     return connectSocket("localhost", (short)SimulatorPort, autoCapture);
00197   }
00198 
00199   return -1;
00200 }
00201 
00202 
00203 int URGCtrl::connectSocket(const char* host, short port, bool autoCapture) {
00204   disconnect();
00205 
00206   con = (autoCapture) ? new URGAutoCapture() : new URGManualCapture();
00207   int ret_value = con->connectSocket(host, port);
00208   error_message = con->what();
00209 
00210   // バージョン情報の読み出し
00211   checkVersion();
00212 
00213   if (enableTimestamp) {
00214     initTicksInfo();
00215   }
00216   return ret_value;
00217 }
00218 
00219 
00220 void URGCtrl::disconnect(void) {
00221   if (con) {
00222     delete con;
00223     con = NULL;
00224   }
00225   error_message = FirstMessage;
00226 }
00227 
00228 
00229 bool URGCtrl::isConnected(void) {
00230   return (con && con->isConnected()) ? true : false;
00231 }
00232 
00233 
00234 int URGCtrl::raw_capture(long length[],
00235                          int first_index, int last_index, int group,
00236                          unsigned long* raw_timestamp) {
00237   return con->capture(length, first_index, last_index, group,
00238                       params, raw_timestamp);
00239 }
00240 
00241 
00242 int URGCtrl::capture(int first_index, int last_index, int group) {
00243   if (!isConnected()) {
00244     throw URG_Exception(NotConnected);
00245   }
00246 
00247   int n;
00248   if (enableTimestamp) {
00249     unsigned long raw_ticks = 0;
00250     n = raw_capture(length, first_index, last_index, group, &raw_ticks);
00251     //fprintf(stderr, "UrgCtrl::n = %d\n", n);
00252     crd_ticks =
00253       getModuleTicks(updateTicksDiff(static_cast<unsigned short>(raw_ticks)));
00254     //fprintf(stderr, "crd_ticks: %d\n", crd_ticks);
00255   } else {
00256     n = raw_capture(length, first_index, last_index, group);
00257   }
00258   crd_position = getCrdPosition();
00259 
00260   if (isHandstand) {
00261     for (int i = (params.sense_steps) >> 1; i >= 0; --i) {
00262       long tmp = length[i];
00263       length[i] = length[params.sense_steps-1 - i];
00264       length[params.sense_steps-1 - i] = tmp;
00265     }
00266   }
00267   return n;
00268 }
00269 
00270 
00271 int URGCtrl::capture(int group) {
00272   return capture(0, params.sense_steps -1, group);
00273 }
00274 
00275 
00276 int URGCtrl::getCaptureTimes(void) {
00277   if (!isConnected()) {
00278     throw URG_Exception(NotConnected);
00279   }
00280   return con->getCaptureTimes();
00281 }
00282 
00283 
00284 void URGCtrl::convert(void) {
00285   convert(crd_position);
00286 }
00287 
00288 
00289 void URGCtrl::convert(const VXV::Position3D& position) {
00290   TicksPosition ticksPos;
00291   ticksPos.add(position, 0);
00292   convert(ticksPos);
00293 }
00294 
00295 
00296 int URGCtrl::getIndexTicks(int index) {
00297 
00298   int actual_index = (isHandstand) ? params.sense_steps - index : index;
00299   long ticks = static_cast<long>(1.0 * params.cycle_msec *
00300                                  (actual_index - params.ticks_begin_step)
00301                                  / params.cycle_step_max);
00302   return ticks;
00303 }
00304 
00305 
00306 void URGCtrl::convert(const VXV::TicksPositionInterface& ticksPos) {
00307 
00308   long pre_ticks = crd_ticks + getIndexTicks(0);
00309   long now_ticks = pre_ticks;
00310   VXV::Position3D urg_pos = ticksPos.getPosition(now_ticks);
00311   VXV::Position3D pre_urg_pos = urg_pos;
00312   VXV::Matrix4D convert = VXV::createConvertMatrix(urg_pos);
00313   crd_points.clear();
00314   for (int i = 0; i < params.sense_steps; ++i) {
00315     // 点毎の位置の計算
00316     now_ticks = crd_ticks + getIndexTicks(i);
00317     if (pre_ticks != now_ticks) {
00318       pre_ticks = now_ticks;
00319       urg_pos = ticksPos.getPosition(now_ticks);
00320       if (pre_urg_pos == urg_pos) {
00321         // !!! 何があったんだろうね、ここ
00322 
00323       } else {
00324         pre_urg_pos = urg_pos;
00325         //fprintf(stderr, "urg_pos: %d\n", urg_pos.zt.to_deg());
00326         convert = VXV::createConvertMatrix(urg_pos);
00327       }
00328     }
00329     // 点毎に座標変換
00330     long l = length[i];
00331     if ((l > params.length_min) && (l < params.length_max)) {
00332       VXV::Position3D point;
00333       point.x = static_cast<int>(length[i] * cos(index2rad(i)));
00334       point.y = static_cast<int>(length[i] * sin(index2rad(i)));
00335       VXV::convert(point, point, convert);
00336       crd_points.push_back(VXV::Grid3D(point.x, point.y, point.z));
00337     }
00338   }
00339 }
00340 
00341 
00342 void URGCtrl::set_recvTimeout(int timeout) {
00343   con->set_recvTimeout(timeout);
00344 }
00345 

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