00001
00002
00003
00004
00005
00006
00007 #include "urgSimulator.h"
00008 #include "urgCtrl.h"
00009 #include "deleteObjects.h"
00010 #include "monitorTask.h"
00011 #include "urgIntersection.h"
00012
00013
00014 URG_Simulator::URG_Simulator(void)
00015 : server(NULL), pre_registered(NULL), enable_timestamp(false) {
00016 }
00017
00018
00019 URG_Simulator::~URG_Simulator(void) {
00020 for_each(sim_urgs.begin(), sim_urgs.end(), DeleteObjects());
00021 }
00022
00023
00024 void URG_Simulator::init(void) {
00025
00026 server = new TcpipServer();
00027 server->activate(URGCtrl::SimulatorPort);
00028 }
00029
00030
00031 void URG_Simulator::recv(void) {
00032
00033 TcpipDevice *con;
00034 if (pre_registered && (con = server->accept(0))) {
00035 ScanInfo* urg = new ScanInfo;
00036 urg->con = con;
00037 urg->obj = pre_registered;
00038 pre_registered = NULL;
00039 sim_urgs.push_back(urg);
00040 }
00041
00042
00043 for (std::list<ScanInfo*>::iterator it = sim_urgs.begin();
00044 it != sim_urgs.end(); ++it) {
00045 if (*it) {
00046 urgDeviceResponse(**it);
00047 }
00048 }
00049 }
00050
00051
00052 void URG_Simulator::exec1msec(unsigned long total_msec) {
00053
00054 for (std::list<ScanInfo*>::iterator it = sim_urgs.begin();
00055 it != sim_urgs.end(); ++it) {
00056 if (*it) {
00057 urgDeviceSimulator(**it, total_msec);
00058 }
00059 }
00060 }
00061
00062
00063 URG_Simulator::ScanInfo::ScanInfo(void)
00064 : con(NULL), obj(NULL),
00065 pre_index(0), raw_timestamp(0),
00066 cmd_handled(true), now_timeAdjustMode(false) {
00067 for (int i = 0; i < 1024; ++i) {
00068 length[i] = 19;
00069 }
00070 }
00071
00072
00073 URG_Simulator::ScanInfo::~ScanInfo(void) {
00074 delete con;
00075 con = NULL;
00076
00077
00078
00079 }
00080
00081
00082 void URG_Simulator::setURGObject(URGCtrl* urg_obj) {
00083
00084
00085 pre_registered = urg_obj;
00086 }
00087
00088
00089 bool URG_Simulator::checkCmdLength(TcpipDevice* con, int require_size) {
00090 return (con->size() < require_size) ? true : false;
00091 }
00092
00093
00094 void URG_Simulator::urgDeviceResponse(URG_Simulator::ScanInfo& urg) {
00095 bool pre_cmd_handled = urg.cmd_handled;
00096 urg.cmd_handled = true;
00097 if (pre_cmd_handled || (urg.con->size() < 1)) {
00098 return;
00099 }
00100
00101 char first_char;
00102 urg.con->copy(&first_char, 1);
00103
00104 if (urg.now_timeAdjustMode && (first_char != 'T')) {
00105
00106 char reply[5];
00107 sprintf(reply, "%c\rE\r\r", first_char);
00108 urg.con->send(reply, 5);
00109 return;
00110 }
00111
00112 char buffer[8];
00113 switch (first_char) {
00114 case 'S':
00115 urg.con->recv(buffer, 8);
00116 break;
00117
00118 case 'V':
00119 if (checkCmdLength(urg.con, 3)) {
00120 break;
00121 }
00122 replyVersionInfo(urg);
00123 break;
00124
00125 case 'B':
00126 if (checkCmdLength(urg.con, 3)) {
00127 break;
00128 }
00129 urg.con->recv(buffer, 3);
00130 urg.con->send("BM\r00P\r\r", 8);
00131 break;
00132
00133 case 'T':
00134 if (checkCmdLength(urg.con, 4)) {
00135 break;
00136 }
00137 replyAdjustTimestamp(urg);
00138 break;
00139
00140
00141 case 'G':
00142 if (checkCmdLength(urg.con, 13)) {
00143 break;
00144 }
00145 replyDataRequest(urg);
00146 break;
00147 }
00148 }
00149
00150
00151 void URG_Simulator::judgeSenseArea(URG_Simulator::ScanInfo& urg,
00152 bool isHandstand,
00153 int from_index, int to_index) {
00154 URGInterface::urgParams_t& params = urg.obj->getParameters();
00155
00156 for (int i = from_index; i < to_index; ++i) {
00157 if (i > params.sense_steps) {
00158 continue;
00159 }
00160 double radian = urg.obj->index2rad(i);
00161 CoordinateCtrl::line_t line;
00162 line.position =
00163 VXV::Position(MonitorTask::getRunPosition()
00164 + VXV::Position(0,0, VXV::Direction::rad(radian)));
00165 line.length = params.length_max;
00166
00167 int dest_index = (!isHandstand) ? i : params.sense_steps - i;
00168 urg.length[dest_index] = getLengthToEnvironment(line, env_polygons);
00169 }
00170 }
00171
00172
00173 void URG_Simulator::urgDeviceSimulator(URG_Simulator::ScanInfo& urg,
00174 unsigned long total_msec) {
00175 URGInterface::urgParams_t& params = urg.obj->getParameters();
00176 int index =
00177 (urg.pre_index + (1000 / params.cycle_msec)) % params.cycle_step_max;
00178 int pre_index = urg.pre_index;
00179 urg.pre_index = index;
00180
00181
00182 if (pre_index <= index) {
00183 if ((pre_index < params.sense_steps) && (params.sense_steps <= index)) {
00184 urg.cmd_handled = false;
00185 } else if (pre_index > index) {
00186 urg.cmd_handled = true;
00187 }
00188 }
00189
00190
00191 if ((pre_index <= index) &&
00192 (pre_index < params.ticks_begin_step) &&
00193 (params.ticks_begin_step <= index)) {
00194 urg.raw_timestamp = total_msec & 0x00ffffff;
00195 }
00196
00197
00198 if (urg.now_timeAdjustMode) {
00199 urg.cmd_handled = false;
00200 urg.raw_timestamp = total_msec & 0x00ffffff;
00201 }
00202
00203
00204 if (urg.obj->isHandstand) {
00205 int tmp = index;
00206 index = params.cycle_step_max - pre_index;
00207 pre_index = params.cycle_step_max - tmp;
00208 }
00209
00210
00211 if (pre_index > index) {
00212 judgeSenseArea(urg,urg.obj->isHandstand, pre_index, params.cycle_step_max);
00213 pre_index = 0;
00214 }
00215 judgeSenseArea(urg, urg.obj->isHandstand, pre_index, index);
00216 }
00217
00218
00219 void URG_Simulator::setURGType(const char* type) {
00220 if (!strcmp("URG-04LX", type)) {
00221 enable_timestamp = true;
00222 }
00223 }
00224
00225
00226 void URG_Simulator::replyVersionInfo(URG_Simulator::ScanInfo& urg) {
00227 char withTimestamp_reply[] =
00228 "VV\r"
00229 "VV\r"
00230 "00P\r"
00231 "VEND:Hokuyo Automatic Co.,Ltd.;[\r"
00232 "PROD:SOKUIKI Sensor TOP-URG UTM-X001S;E\r"
00233 "FIRM:k.1.28b(03/Sep./2007);M\r"
00234 "PROT:SCIP 2.0;N\r"
00235 "SERI:00704464;6\r"
00236 "\r";
00237
00238 char normal_reply[] =
00239 "V\r"
00240 "0\r"
00241 "VEND:Hokuyo Automatic Co.,Ltd.\r"
00242 "PROD:SOKUIKI Sensor URG-X003\r"
00243 "FIRM:0.2.11d,05/05/18 with USB\r"
00244 "PROT:00003,(SCIP 1.0)\r"
00245 "SERI:H0500846\r"
00246 "\r";
00247
00248 char buffer[3];
00249 urg.con->recv(buffer, 3);
00250 if (enable_timestamp) {
00251 urg.con->send(withTimestamp_reply, sizeof(withTimestamp_reply)-1);
00252 } else {
00253 urg.con->send(normal_reply, sizeof(normal_reply)-1);
00254 }
00255 }
00256
00257
00258 void URG_Simulator::replyAdjustTimestamp(URG_Simulator::ScanInfo& urg) {
00259 char buffer[] = { "TMX\r00P\r\r23456\r\r" };
00260 char ticks_buffer[5];
00261 urg.con->recv(buffer, 4);
00262 long ticks;
00263
00264 switch (buffer[2]) {
00265 case '0':
00266 urg.now_timeAdjustMode = true;
00267 urg.con->send(buffer, 9);
00268 break;
00269
00270 case '1':
00271 ticks = static_cast<int>(urg.raw_timestamp);
00272 for (int i = 3; i >= 0; --i) {
00273 ticks_buffer[i] = decodeByte(ticks & 0x3f);
00274 ticks >>= 6;
00275 }
00276 ticks_buffer[5] = '\0';
00277 sprintf(buffer, "TM1\r00P\r%s;\r\r", ticks_buffer);
00278 urg.con->send(buffer, 16);
00279 break;
00280
00281 case '2':
00282 urg.now_timeAdjustMode = false;
00283 urg.con->send(buffer, 9);
00284 break;
00285 }
00286 }
00287
00288
00289 char URG_Simulator::decodeByte(char ch) {
00290 return (((ch & 0x3f) | 0x40) - 0x10) & 0x7f;
00291 }
00292
00293
00294 void URG_Simulator::replyDataRequest(URG_Simulator::ScanInfo& urg) {
00295
00296 enum { LF = '\n' };
00297 char buf[65];
00298 urg.con->recv(buf, 13);
00299
00300
00301 char cmd = buf[0];
00302 char cmd2 = buf[1];
00303 int raw_group = atoi(&buf[10]);
00304 int group = (raw_group <= 0) ? 1 : raw_group;
00305 buf[10] = LF;
00306 int end_index = atoi(&buf[6]);
00307 buf[6] = LF;
00308 int begin_index = atoi(&buf[2]);
00309
00310
00311 sprintf(buf, "%c%c%04d%04d%02d%c",
00312 cmd, cmd2, begin_index, end_index, raw_group, LF);
00313 urg.con->send(buf, static_cast<int>(strlen(buf)));
00314
00315
00316 urg.con->send("00P\r", 4);
00317
00318 unsigned long timestamp = urg.raw_timestamp;
00319 for (int i = 3; i >= 0; --i) {
00320 buf[i] = decodeByte((char)(timestamp & 0x3f));
00321 timestamp >>= 6;
00322 }
00323 buf[4] = ';';
00324 buf[5] = '\r';
00325
00326 urg.con->send(buf, 6);
00327
00328
00329
00330 char buffer[4096];
00331 int total_steps = (end_index - begin_index + 1) / abs(group);
00332 int data_index = 0;
00333 for (int i = 0; i < total_steps; ++i) {
00334 long length = urg.length[i];
00335 buffer[data_index++] = decodeByte((length >> 12) & 0x3f);
00336 buffer[data_index++] = decodeByte((length >> 6) & 0x3f);
00337 buffer[data_index++] = decodeByte(length & 0x3f);
00338 }
00339
00340 int left_byte = data_index;
00341 int sended = 0;
00342 while (left_byte > 0) {
00343 int send_size = left_byte;
00344 if (send_size > 64) {
00345 send_size = 64;
00346 }
00347 urg.con->send(&buffer[sended], send_size);
00348 urg.con->send(";\r", 2);
00349 sended += send_size;
00350 left_byte -= send_size;
00351 }
00352 urg.con->send("\r", 1);
00353
00354 #if 0
00355 int total_steps = (end_index - begin_index + 1) / abs(group);
00356 int data_index = 0;
00357 int sensor_index = 0;
00358 for (int i = 0; i < total_steps; ++i) {
00359 if (i > 0 && i % 32 == 0) {
00360 buf[data_index++] = LF;
00361 urg.con->send(buf, data_index);
00362 data_index = 0;
00363 }
00364
00365 int length = urg.length[sensor_index];
00366 for (int j = 0; j < 3; ++j) {
00367 buf[data_index++] = decodeByte((length >> 12) & 0x3f);
00368 length <<= 6;
00369
00370 if (data_index != 0) {
00371 buf[data_index++] = LF;
00372 }
00373 }
00374 sensor_index += group;
00375 }
00376 buf[data_index++] = LF;
00377 urg.con->send(buf, data_index);
00378 #endif
00379 }
00380
00381
00382 void URG_Simulator::setEnvironment(const std::vector<crd_polygon_t>& objs) {
00383 env_polygons = objs;
00384 }
00385