00001
00002
00003
00004
00005
00006
00007 #include "urgManualCapture.h"
00008 #include "serialDevice.h"
00009 #include "tcpipDevice.h"
00010 #include <stdio.h>
00011
00012 enum {
00013 LineLength = 64 + 16,
00014 };
00015
00016
00017 URGManualCapture::URGManualCapture(void)
00018 : con(NULL), error_message("Connection device is not specified"),
00019 capture_times(0), oneData_byte(OneDataByte), Timeout(DefaultTimeout),
00020 laser_on(false), remain_byte(0), enableTimestamp(false) {
00021 }
00022
00023
00024 URGManualCapture::~URGManualCapture(void) {
00025 disconnect();
00026 }
00027
00028
00029 const char* URGManualCapture::what(void) {
00030 return error_message.c_str();
00031 }
00032
00033
00034 int URGManualCapture::connect(const char* device, long baudrate) {
00035 disconnect();
00036 con = new SerialDevice();
00037
00038 int ret_value = -1;
00039 long expected_baudrate[] = { 115200, 19200, 57600 };
00040 int n = sizeof(expected_baudrate) / sizeof(expected_baudrate[0]);
00041 char s_message[16];
00042
00043 sprintf(s_message, "SS%06ld\r", baudrate);
00044 for (int try_times = 0; try_times < 2; ++try_times) {
00045 for (int i = 0; i < n; ++i) {
00046
00047 ret_value = con->connect(device, expected_baudrate[i]);
00048 if (ret_value >= 0) {
00049
00050 con->disconnect();
00051 ret_value = con->connect(device, expected_baudrate[i]);
00052 }
00053 error_message = con->what();
00054 if (ret_value < 0) {
00055 return ret_value;
00056 }
00057 con->flush();
00058 con->send(s_message, 9);
00059
00060 char ch, pre_ch = '\0';
00061 while (con->recv(&ch, 1, Timeout) > 0) {
00062 if (isLF(ch) && isLF(pre_ch)) {
00063 error_message = "Success";
00064 con->setBaudrate(baudrate);
00065 return 0;
00066 }
00067 pre_ch = ch;
00068 }
00069 }
00070 }
00071 error_message = "Baudrate adjust fail";
00072 return ConnectionDevice::BaudrateAdjustFail;
00073 }
00074
00075
00076 int URGManualCapture::connectSocket(const char* host, short port) {
00077
00078 disconnect();
00079 con = new TcpipDevice();
00080 int ret_value = con->connect(host, port);
00081 error_message = con->what();
00082
00083 return ret_value;
00084 }
00085
00086
00087 void URGManualCapture::disconnect(void) {
00088 if (con) {
00089 delete con;
00090 con = NULL;
00091 }
00092 }
00093
00094
00095 bool URGManualCapture::isConnected(void) {
00096 if (!con) {
00097 return false;
00098 } else {
00099 if (con->isConnected()) {
00100 return true;
00101 } else {
00102 throw URGCapture_Exception("Connection is disconnected");
00103 }
00104 }
00105 }
00106
00107
00108 void URGManualCapture::setTimestampMode(bool withTimestamp) {
00109 enableTimestamp = withTimestamp;
00110 }
00111
00112
00113 bool URGManualCapture::isLF(char ch) {
00114 return (ch == '\r' || ch == '\n') ? true : false;
00115 }
00116
00117
00118 int URGManualCapture::adjustIndex(int index, int add) {
00119
00120 int a = (index - (index / 65) + ((index >= 65) ? 1 : 0)) % 65;
00121 int b =
00122 (index - ((index + add) / 65) + ((index + add>= 65) ? 1 : 0) + add) % 65;
00123 if (a > b) {
00124 return index + add + 1;
00125 }
00126 return index + add;
00127 }
00128
00129
00130 unsigned char URGManualCapture::encode6bit(char ch) {
00131 return 0x3f & (ch - 0x30);
00132 }
00133
00134
00135
00136 long URGManualCapture::decode(const char* data, int data_byte) {
00137 long value = 0;
00138 for (int i = 0; i < data_byte; ++i) {
00139 value <<= 6;
00140 value &= ~0x3f;
00141 value |= data[i] - 0x30;
00142 }
00143 return value;
00144 }
00145
00146
00147 int URGManualCapture::recvCaptureData(long* data, size_t max_size,
00148 unsigned long* timestamp,
00149 URGInterface::urgParams_t& params) {
00150 #if 0
00151 if (data == NULL) {
00152 return 0;
00153 }
00154 #endif
00155
00156 recv_data.clear();
00157
00158
00159 for (int i = params.first_step; i >= 0; --i) {
00160 recv_data.push_back(19);
00161 }
00162
00163 char message_type = 'M';
00164 char buffer[LineLength];
00165 int line_length;
00166 unsigned long local_timestamp = 0;
00167 for (int i = 0; (line_length = readLine(buffer, Timeout)) >= 0; ++i) {
00168
00169
00170
00171
00172
00173
00174
00175 if ((i >= 6) && (line_length == 0)) {
00176
00177 int data_size = recv_data.size();
00178 size_t min_length =
00179 (static_cast<int>(max_size) < data_size) ? max_size : data_size;
00180 for (size_t i = 0; i < min_length; ++i) {
00181 data[i] = recv_data[i];
00182 }
00183 if (timestamp) {
00184 *timestamp = local_timestamp;
00185 }
00186
00187 return min_length;
00188
00189 } else if (i == 0) {
00190
00191 if ((buffer[0] != 'M') && (buffer[0] != 'G')) {
00192 error_message = "YY 01";
00193
00194 return -1;
00195 }
00196 message_type = buffer[0];
00197
00198 } else if (! strncmp(buffer, "99b", 3)) {
00199
00200 i = 4;
00201
00202 } else if ((i == 1) && (message_type == 'G')) {
00203 i = 4;
00204
00205
00206 if (0) {
00207 laser_on = false;
00208 }
00209
00210 } else if (i == 2) {
00211
00212
00213
00214 if (0) {
00215 laser_on = false;
00216 }
00217
00218 } else if (i == 4) {
00219
00220 if (strncmp(buffer, "99b", 3)) {
00221 error_message = "YY 02";
00222 return -1;
00223 }
00224
00225 } else if (i == 5) {
00226
00227 local_timestamp = decode(buffer, 4);
00228
00229
00230 } else if (i >= 6) {
00231
00232 if (line_length > (64 + 1)) {
00233
00234 line_length = (64 + 1);
00235 }
00236 buffer[line_length -1] = '\0';
00237 int ret = addRecvData(buffer);
00238 if (ret < 0) {
00239 error_message = "YY 03";
00240
00241 return ret;
00242 }
00243 }
00244 }
00245 return -1;
00246 }
00247
00248
00249 int URGManualCapture::readLine(char *buffer, int timeout) {
00250 if (con == NULL) {
00251 return 0;
00252 }
00253
00254 int i;
00255 for (i = 0; i < LineLength -1; ++i) {
00256 char recv_ch;
00257 int n = con->recv(&recv_ch, 1, timeout);
00258 if (n <= 0) {
00259 if (i == 0) {
00260 return -1;
00261 }
00262 break;
00263 }
00264 if (isLF(recv_ch)) {
00265 break;
00266 }
00267 buffer[i] = recv_ch;
00268 }
00269
00270 buffer[i] = '\0';
00271 return i;
00272 }
00273
00274
00275 int URGManualCapture::addRecvData(const char buffer[]) {
00276
00277 const char* pre_p = buffer;
00278 const char* p = pre_p;
00279
00280 if (remain_byte > 0) {
00281 memmove(&remain_data[remain_byte], buffer, oneData_byte - remain_byte);
00282 recv_data.push_back(decode(remain_data, oneData_byte));
00283 pre_p = &buffer[oneData_byte - remain_byte];
00284 p = pre_p;
00285
00286 remain_byte = 0;
00287 }
00288
00289 do {
00290 ++p;
00291 if ((p - pre_p) >= static_cast<int>(oneData_byte)) {
00292 recv_data.push_back(decode(pre_p, oneData_byte));
00293 pre_p = p;
00294 }
00295 } while (*p != '\0');
00296 remain_byte = p - pre_p;
00297 memmove(remain_data, pre_p, remain_byte);
00298
00299 return 0;
00300 }
00301
00302
00303 int URGManualCapture::recvScanData(long data[],
00304 int first, int last, int group,
00305 const char* send_str,
00306 URGInterface::urgParams_t& params,
00307 unsigned long* raw_ticks) {
00308
00309
00310 size_t max_size = last - first +1;
00311 ++capture_times;
00312 return recvCaptureData(data, max_size, raw_ticks, params);
00313
00314 #if 0
00315 char reply[13];
00316 char lf;
00317
00318 if ((con->recv(reply, 13, DefaultTimeout) <= 0) ||
00319 strncmp(send_str, reply, 13)) {
00320 return -1;
00321 }
00322 if ((con->recv(reply, 4, Timeout) <= 0) || (reply[0] != '0')) {
00323 return -3;
00324 }
00325
00326
00327 if (con->recv(reply, 6, Timeout) <= 0) {
00328 return HeaderError;
00329 }
00330
00331 if (raw_ticks) {
00332 *raw_ticks = decode(reply, 4);
00333 }
00334
00335 int num_data = last - first +1;
00336 num_data = (num_data / group) + ((num_data % group == 0) ? 0 : 1);
00337 int data_byte = oneData_byte * num_data;
00338
00339 int total = data_byte;
00340
00341 int filled = 0;
00342
00343 while (total > filled) {
00344 int max = total - filled;
00345 if (max > 65) {
00346 max = 65;
00347 }
00348 int n = con->recv(&recv_buffer[filled], max, Timeout);
00349 if (n <= 0) {
00350 return RecvSizeError;
00351 }
00352 filled += n;
00353 if (n == 65) {
00354 filled -= 1;
00355 }
00356 }
00357
00358 int lf_count = 0;
00359 while (true) {
00360 if (con->recv(&lf, 1, Timeout) <= 0) {
00361 return RecvSizeError;
00362 }
00363 if (!isLF(lf)) {
00364 lf_count = 0;
00365 }
00366 ++lf_count;
00367 if (lf_count >= 2) {
00368 break;
00369 }
00370 }
00371
00372
00373
00374
00375 for (int i = 0; i < first; ++i) {
00376 data[i] = -1;
00377 }
00378 int index = first;
00379 for (int i = 0; (index <= last) && (i < num_data); ++i) {
00380 int num = i * oneData_byte;
00381 #if 0
00382 int actual_index = num + (int)(num / 65);
00383 if ((i > 0) && ((i % 65) == 0) &&
00384 !isLF(recv_buffer[actual_index -1])) {
00385 return MissmatchLF;
00386 }
00387 #endif
00388 int actual_index = num;
00389 for (int j = 0; (index <= last) && (j < group); ++j) {
00390 data[index] =
00391 (encode6bit(recv_buffer[adjustIndex(actual_index, 0)]) << 6)
00392 | encode6bit(recv_buffer[adjustIndex(actual_index, 1)]);
00393 if (oneData_byte == 3) {
00394 data[index] = (data[index] << 6)
00395 | encode6bit(recv_buffer[adjustIndex(actual_index, 2)]);
00396 }
00397 ++index;
00398
00399 }
00400 }
00401 for (int i = last +1; i < params.sense_steps; ++i) {
00402 data[i] = -1;
00403 }
00404 ++capture_times;
00405
00406 #if 0
00407 for (int i = 0; i < params.sense_steps; ++i) {
00408 fprintf(stderr, "%d:%d\n", i, data[i]);
00409 }
00410 fprintf(stderr,"\n");
00411 #endif
00412
00413 return params.sense_steps;
00414 #endif
00415 }
00416
00417
00418 int URGManualCapture::capture(long length[],
00419 int first_index, int last_index, int group,
00420 URGInterface::urgParams_t& params,
00421 unsigned long* raw_timestamp) {
00422
00423 if (first_index > last_index) {
00424 int tmp = first_index; first_index = last_index; last_index = tmp;
00425 }
00426 if (first_index < 0) {
00427 first_index = 0;
00428 }
00429 if (last_index > params.sense_steps -1) {
00430 last_index = params.sense_steps -1;
00431 }
00432 if (group <= 0) {
00433 group = 1;
00434 } else if (group > 99) {
00435 group = 99;
00436 }
00437
00438
00439 char send_str[13];
00440 sprintf(send_str, "GD%04d%04d%02d\n", first_index, last_index, group);
00441 #if 0
00442 if (raw_timestamp) {
00443 send_str[0] = 'g';
00444 }
00445 #endif
00446 con->flush();
00447 con->send(send_str, 13);
00448
00449
00450 int ret = recvScanData(length, first_index, last_index, group,
00451 send_str, params, raw_timestamp);
00452 if (ret < 0) {
00453 error_message = "capture fail.";
00454 }
00455 return ret;
00456 }
00457
00458
00459 int URGManualCapture::getCaptureTimes(void) {
00460 return capture_times;
00461 }
00462
00463
00464 int URGManualCapture::send(const char* data, int size) {
00465 if (!con) {
00466 return ConnectionDevice::NotConnected;
00467 }
00468 return con->send(data, size);
00469 }
00470
00471
00472 int URGManualCapture::recv(char* data, int maxsize, long timeout) {
00473 if (!con) {
00474 return ConnectionDevice::NotConnected;
00475 }
00476 return con->recv(data, maxsize, timeout);
00477 }
00478
00479
00480 int URGManualCapture::recv_line(char* data, int maxsize, long timeout) {
00481 if (!con) {
00482 return ConnectionDevice::NotConnected;
00483 }
00484
00485
00486 int filled = 0;
00487 while (con->recv(&data[filled], ((maxsize - filled > 0) ? 1 : 0),
00488 timeout) > 0) {
00489 if (isLF(data[filled++])) {
00490 --filled;
00491 data[filled] = '\0';
00492
00493 return filled;
00494 }
00495 }
00496 return filled;
00497 }
00498
00499
00500 void URGManualCapture::set_recvTimeout(int timeout) {
00501 Timeout = (timeout < 0) ? DefaultTimeout : timeout;
00502 }
00503
00504
00505 int URGManualCapture::laser(bool on) {
00506
00507 char l_message[9] = "BM\r";
00508
00509 con->flush();
00510 con->send(l_message, 3);
00511
00512 char ch, pre_ch = '\0';
00513 while (con->recv(&ch, 1, Timeout + 200) > 0) {
00514
00515 if (isLF(ch) && isLF(pre_ch)) {
00516 return 0;
00517 }
00518 pre_ch = ch;
00519 }
00520
00521
00522
00523
00524
00525 return 0;
00526 return -1;
00527 }
00528