00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "surveyor_comms.h"
00026
00027 #include <errno.h>
00028 #include <assert.h>
00029 #include <fcntl.h>
00030 #include <sys/stat.h>
00031 #include <sys/ioctl.h>
00032 #include <termios.h>
00033 #include <math.h>
00034 #include <stdio.h>
00035 #include <unistd.h>
00036 #include <stdlib.h>
00037 #include <sys/time.h>
00038 #include <time.h>
00039 #include <string.h>
00040
00041
00042
00043
00044 srv1_comm_t *
00045 srv1_create(const char *port)
00046 {
00047 srv1_comm_t *ret = (srv1_comm_t *) malloc(sizeof(srv1_comm_t));
00048
00049 ret->fd = -1;
00050 ret->image_mode = SRV1_IMAGE_OFF;
00051 ret->set_image_mode = SRV1_IMAGE_OFF;
00052 ret->need_ir = 0;
00053
00054 ret->frame_size = 0;
00055
00056 ret->vx = 0.0;
00057 ret->va = 0.0;
00058
00059 ret->frame = NULL;
00060
00061 strncpy(ret->port, port, sizeof(ret->port) - 1);
00062
00063 return ret;
00064 }
00065
00066
00067
00068
00069 int
00070 flip_nonblock(int fd)
00071 {
00072 int flags;
00073 if ((flags = fcntl(fd, F_GETFL)) < 0)
00074 {
00075 perror("surveyor_flip_nonblock():fcntl():");
00076 close(fd);
00077 return -1;
00078 }
00079
00080 if (fcntl(fd, F_SETFL, flags ^ O_NONBLOCK) < 0)
00081 {
00082 perror("surveyor_flip_nonblock():fcntl():");
00083 close(fd);
00084 return -1;
00085 }
00086
00087 return 0;
00088 }
00089
00090 int32_t
00091 msecsub(struct timeval a, struct timeval b)
00092 {
00093 return ((a.tv_sec - b.tv_sec) * 1000000) + (a.tv_usec - b.tv_usec);
00094 }
00095
00096
00097
00098
00099
00100 int
00101 read_limited(int fd, char *buf, int bytes, int microsecs)
00102 {
00103 flip_nonblock(fd);
00104
00105 struct timeval begin, now;
00106 gettimeofday(&begin, NULL);
00107
00108 int needtoread = bytes;
00109 int readresult;
00110
00111 for (;;)
00112 {
00113 gettimeofday(&now, NULL);
00114 if (msecsub(now, begin) > microsecs)
00115 {
00116 printf(
00117 "read_limited():Warning: CARLOS timed out (%d microsecs).\n",
00118 msecsub(now, begin));
00119 flip_nonblock(fd);
00120 return (bytes - needtoread);
00121 }
00122
00123 if ((readresult = read(fd, buf + (bytes - needtoread), needtoread))
00124 < 0)
00125 {
00126 if (errno != EAGAIN)
00127 {
00128 perror("read_limited():read()");
00129 flip_nonblock(fd);
00130 return -1;
00131 }
00132 }
00133 else
00134 {
00135 needtoread = needtoread - readresult;
00136 if (needtoread == 0)
00137 {
00138 break;
00139 }
00140 }
00141
00142 usleep(20);
00143 }
00144
00145 flip_nonblock(fd);
00146 return bytes;
00147 }
00148
00149
00150
00151
00152
00153 int
00154 srv1_flush_input(srv1_comm_t *x)
00155 {
00156 int res;
00157 ioctl(x->fd, TIOCINQ, (char *) &res);
00158 tcflush(x->fd, TCIFLUSH);
00159 return res;
00160 }
00161
00162 int
00163 srv1_open(srv1_comm_t *x)
00164 {
00165
00166 struct termios term;
00167
00168 int fd;
00169
00170 printf("Opening connection to Surveyor on %s...", x->port);
00171
00172
00173
00174 if ((fd = open(x->port, O_RDWR | O_NONBLOCK, 00644)) < 0)
00175 {
00176 perror("surveyor_open():open():");
00177 return 0;
00178 }
00179
00180 if (tcflush(fd, TCIFLUSH) < 0)
00181 {
00182 perror("surveyor_open():tcflush():");
00183 close(fd);
00184 return 0;
00185 }
00186
00187 if (tcgetattr(fd, &term) < 0)
00188 {
00189 perror("surveyor_open():tcgetattr():");
00190 close(fd);
00191 return 0;
00192 }
00193
00194 cfmakeraw(&term);
00195 cfsetispeed(&term, B115200);
00196 cfsetospeed(&term, B115200);
00197
00198 if (tcsetattr(fd, TCSAFLUSH, &term) < 0)
00199 {
00200 perror("surveyor_open():tcsetattr():");
00201 close(fd);
00202 return 0;
00203 }
00204
00205
00206 flip_nonblock(fd);
00207
00208 puts("Done.");
00209
00210 x->fd = fd;
00211
00212 return 1;
00213 }
00214
00215 void
00216 srv1_close(srv1_comm_t *x)
00217 {
00218 printf("\nNow closing: srv1_close()\n");
00219 srv1_set_speed(x, 0, 0);
00220
00221 close(x->fd);
00222 }
00223
00224 void
00225 srv1_destroy(srv1_comm_t *x)
00226 {
00227 if (x->frame != NULL)
00228 {
00229 free(x->frame);
00230 }
00231
00232 if (x->fd != -1)
00233 {
00234 srv1_close(x);
00235 }
00236
00237 free(x);
00238 return;
00239 }
00240
00241 int
00242 srv1_init(srv1_comm_t *x)
00243 {
00244 assert(x);
00245
00246 if (srv1_open(x) == 0)
00247 {
00248
00249 return 0;
00250 }
00251
00252
00253 char buf[256];
00254 if (write(x->fd, "V", 1) < 0)
00255 {
00256 printf("srv1_init(): can't write to port %s!\n", x->port);
00257 return 0;
00258 }
00259
00260 int spot = 0;
00261 memset(buf, 0, 256);
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 do
00273 {
00274 int num = read(x->fd, buf + spot, 1);
00275 if (num != 1)
00276 {
00277 printf("srv1_init(): Can't read a byte from surveyor!\n");
00278 return 0;
00279 }
00280 spot++;
00281 }
00282 while (buf[spot - 1] != '\n');
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 printf("srv1_init(): successful init. HW %s", buf + 2);
00297
00298 return 1;
00299 }
00300
00301 double
00302 calc_forward(signed char speed)
00303 {
00304 unsigned char speedg = (speed > 0 ? speed : -speed);
00305 if (speedg < 20)
00306 {
00307 return 0;
00308 }
00309 double i3 = 5.5277e-7;
00310 double j3 = -0.00016261;
00311 double k3 = 0.01628;
00312 double l3 = -0.26129;
00313
00314 double x = k3 * speedg;
00315 double y = j3 * speedg * speedg;
00316 double z = i3 * speedg * speedg * speedg;
00317 double result = l3 + x + y + z;
00318 printf("calc_forward(%d) = %f + %f + %f + %f = %f\n", speed, l3, x, y, z,
00319 result);
00320 return (speed > 0 ? result : -result);
00321 }
00322
00323 signed char
00324 calc_speed_hackish(double dx)
00325 {
00326 if (fabs(dx) > SRV1_MAX_VEL_X)
00327 {
00328 printf("srv1_set_speed(): warning: speed out of range.\n");
00329 return (dx > 0.0 ? 127 : -127);
00330 }
00331
00332 if (fabs(dx) < 0.05)
00333 {
00334 return 0;
00335 }
00336
00337 signed char current = 20;
00338
00339 for (;;)
00340 {
00341 current = current + 1;
00342 if (calc_forward(current) > fabs(dx))
00343 {
00344 return (dx < 0.0 ? -(current - 1) : current - 1);
00345 }
00346 }
00347 }
00348
00349 double
00350 calc_angular(int left, int right)
00351 {
00352 double basis = 0.234;
00353 printf("calc_angular(%d, %d) = %f\n", left, right, (calc_forward(right)
00354 - calc_forward(left)) / basis);
00355 return (calc_forward(right) - calc_forward(left)) / basis;
00356 }
00357
00358 void
00359 calc_rot_hackish(double dx, signed char *left, signed char *right)
00360 {
00361 int direction = 0;
00362 int l = *left;
00363 int r = *right;
00364 double angular = 0;
00365
00366 if (fabs(dx) < 0.05)
00367 {
00368 return;
00369 }
00370
00371 if (l == 0)
00372 {
00373 while ((l > -127) && (l < 127) && (r > -127) && (r < 127))
00374 {
00375 angular = calc_angular(l, r);
00376 if (angular < dx)
00377 {
00378 if (direction == -1)
00379 {
00380 break;
00381 }
00382 if (r < 20)
00383 {
00384 r = 20;
00385 l = -r;
00386 }
00387
00388 l--;
00389 r++;
00390 direction = 1;
00391 }
00392 if (angular > dx)
00393 {
00394 if (direction == 1)
00395 {
00396 break;
00397 }
00398 if (l < 20)
00399 {
00400 l = 20;
00401 r = -l;
00402 }
00403 l++;
00404 r--;
00405 direction = -1;
00406 }
00407 }
00408
00409 }
00410 else if (l > 0)
00411 {
00412 while ((l < 127) && (r < 127))
00413 {
00414 angular = calc_angular(l, r);
00415 if (angular < dx)
00416 {
00417 if (direction == -1)
00418 {
00419 break;
00420 }
00421
00422 r++;
00423 direction = 1;
00424 }
00425 if (angular > dx)
00426 {
00427 if (direction == 1)
00428 {
00429 break;
00430 }
00431 l++;
00432 direction = -1;
00433 }
00434 }
00435
00436 }
00437 else
00438 {
00439 while ((l > -127) && (r > -127))
00440 {
00441 angular = calc_angular(l, r);
00442 if (angular < dx)
00443 {
00444 if (direction == -1)
00445 {
00446 break;
00447 }
00448
00449 l--;
00450 direction = 1;
00451 }
00452 if (angular > dx)
00453 {
00454 if (direction == 1)
00455 {
00456 break;
00457 }
00458 r--;
00459 direction = -1;
00460 }
00461 }
00462 }
00463
00464 if (((r == 127) || (r == -127) || (l == 127) || (l == -127)) && (fabs(dx
00465 - calc_angular(l, r)) > 0.01))
00466 {
00467 printf(
00468 "srv1_set_speed(): warning: can't achieve %f rotation. got %f.\n",
00469 dx, calc_angular(l, r));
00470 }
00471
00472 *right = r;
00473 *left = l;
00474 }
00475
00476 int
00477 srv1_set_motors(srv1_comm_t *x, signed char l, signed char r, double t)
00478 {
00479 char cmdbuf[4];
00480
00481 char runtime;
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492 runtime = 0;
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505
00506 cmdbuf[0] = 'M';
00507 cmdbuf[1] = l;
00508 cmdbuf[2] = r;
00509 cmdbuf[3] = runtime;
00510
00511 if (write(x->fd, cmdbuf, 4) < 0)
00512 {
00513
00514
00515 }
00516
00517
00518 if (read_limited(x->fd, cmdbuf, 2, 250000) == 2)
00519 {
00520 if (cmdbuf[0] == '#' && cmdbuf[1] == 'M')
00521 {
00522 return 1;
00523 }
00524 printf("srv1_set_speed(): warning: failed response: %c%c!!!\n",
00525 cmdbuf[0], cmdbuf[1]);
00526 int bytes = srv1_flush_input(x);
00527 printf("srv1: flushed %d bytes from input buffer\n", bytes);
00528
00529 }
00530
00531 return 0;
00532 }
00533
00534 int
00535 srv1_set_speed(srv1_comm_t *x, double dx, double dw)
00536 {
00537
00538 signed char leftspeed;
00539 signed char rightspeed;
00540
00541 printf("srv1_set_speed(): debug: dx: %2.2f dw: %2.2f\n", dx, dw);
00542 leftspeed = calc_speed_hackish(dx);
00543
00544 rightspeed = leftspeed;
00545
00546 x->vx = calc_forward(leftspeed);
00547
00548 calc_rot_hackish(dw, &leftspeed, &rightspeed);
00549
00550 x->va = calc_angular(leftspeed, rightspeed);
00551
00552
00553
00554 return srv1_set_motors(x, leftspeed, rightspeed, 0.0);
00555 }
00556
00557 int
00558 srv1_fill_image(srv1_comm_t *x)
00559 {
00560
00561
00562
00563
00564 char specbuf[10];
00565
00566 memset(specbuf, 0, 10);
00567
00568 if (x->set_image_mode != x->image_mode)
00569 {
00570 if (x->image_mode != SRV1_IMAGE_OFF)
00571 {
00572 printf("srv1_fill_image(): setting image mode '%c'\n",
00573 x->image_mode);
00574 if (write(x->fd, &(x->image_mode), 1) < 0)
00575 {
00576 return 0;
00577 }
00578
00579 int done = read_limited(x->fd, specbuf, 2, 500000);
00580
00581 if (done != 2)
00582 {
00583
00584 int btsdead = srv1_flush_input(x);
00585 printf("srv1_fill_image(): discarded %d bytes.\n", btsdead);
00586 return 0;
00587 }
00588
00589 if (specbuf[0] != '#' || specbuf[1] != x->image_mode)
00590 {
00591 printf(
00592 "srv1_fill_image(): didn't get correct response from image size set: %s\n",
00593 specbuf);
00594 int btsdead = srv1_flush_input(x);
00595 printf("srv1_fill_image(): discarded %d bytes.\n", btsdead);
00596 return 0;
00597 }
00598 else
00599 {
00600 x->set_image_mode = x->image_mode;
00601 }
00602 }
00603 else
00604 {
00605 x->set_image_mode = x->image_mode;
00606 }
00607 }
00608
00609 if (x->set_image_mode == SRV1_IMAGE_OFF)
00610 {
00611 return 1;
00612 }
00613 printf("srv1_fill_image(): Image Mode '%c'\n", x->set_image_mode);
00614 int tries = 1;
00615 for (;;)
00616 {
00617 if (write(x->fd, "I", 1) < 0)
00618 {
00619
00620 return 0;
00621 }
00622
00623 printf("srv1_fill_image(): getting spec.\n");
00624
00625 memset(specbuf, 0, 10);
00626 int done = read_limited(x->fd, specbuf, 10, 500000);
00627
00628 if (done != 10)
00629 {
00630 int btsdead = srv1_flush_input(x);
00631 if (tries < 10)
00632 {
00633 tries++;
00634
00635 continue;
00636 }
00637
00638 printf(
00639 "srv1_fill_image(): didn't get spec (got %d bytes: %s). flushed %d bytes.\n",
00640 done, specbuf, btsdead);
00641 return 0;
00642 }
00643 else
00644 {
00645 break;
00646 }
00647 }
00648
00649 if (strncmp("##IMJ", specbuf, 5) != 0)
00650 {
00651 int btsdead = srv1_flush_input(x);
00652 printf("srv1_fill_image(): incorrect response from I, flushed %d\n",
00653 btsdead);
00654 return 0;
00655 }
00656 int s0 = (unsigned char) specbuf[6];
00657 int s1 = (unsigned char) specbuf[7];
00658 int s2 = (unsigned char) specbuf[8];
00659 int s3 = (unsigned char) specbuf[9];
00660
00661 x->frame_size = s0 + (s1 * 256) + (s2 * 256 * 256) + (s3 * 256 * 256 * 256);
00662
00663 printf("srv1_fill_image(): specbuf: %c%c%c%c%c%c\n", specbuf[0], specbuf[1],
00664 specbuf[2], specbuf[3], specbuf[4], specbuf[5]);
00665 printf(
00666 "srv1_fill_image(): frame_size = %d + (%d * 256) + (%d * 256 * 256) + (%d * 256 * 256 * 256) = %d\n",
00667 s0, s1, s2, s3, x->frame_size);
00668
00669
00670
00671 if (x->frame == NULL)
00672 {
00673 x->frame = (char *) malloc(x->frame_size);
00674 }
00675 else
00676 {
00677 x->frame = (char *) realloc(x->frame, x->frame_size);
00678 }
00679
00680
00681 read_limited(x->fd, x->frame, x->frame_size, 1500000);
00682
00683
00684
00685
00686 return 1;
00687 }
00688
00689 int
00690 srv1_fill_ir(srv1_comm_t *x)
00691 {
00692 if (write(x->fd, "B", 1) < 0)
00693 {
00694 return 0;
00695 }
00696
00697 char buf[80];
00698 memset(buf, 0, 80);
00699 int done = read_limited(x->fd, buf, 46, 500000);
00700
00701 if (done != 46)
00702 {
00703
00704 int btsdead = srv1_flush_input(x);
00705 printf("srv1_fill_ir(): discarded %d bytes.\n", btsdead);
00706 return 0;
00707 }
00708
00709 if (strncmp(buf, "##BounceIR - ", 13) != 0)
00710 {
00711 int btsdead = srv1_flush_input(x);
00712 printf(
00713 "srv1_fill_ir(): IR return had wrong header '%s', discarded %d bytes.\n",
00714 buf, btsdead);
00715 return 0;
00716 }
00717
00718 sscanf(buf + 13, "%x", &(x->bouncedir[0]));
00719 sscanf(buf + 21, "%x", &(x->bouncedir[1]));
00720 sscanf(buf + 29, "%x", &(x->bouncedir[2]));
00721 sscanf(buf + 37, "%x", &(x->bouncedir[3]));
00722
00723 return 1;
00724 }
00725
00726 int
00727 srv1_read_sensors(srv1_comm_t *x)
00728 {
00729
00730
00731 srv1_fill_image(x);
00732
00733
00734 return 1;
00735 }
00736
00737 int
00738 srv1_reset_comms(srv1_comm_t *x)
00739 {
00740 return 1;
00741 }
00742
00743 double
00744 srv1_range_to_distance(int rangereading)
00745 {
00746
00747
00748
00749
00750 double a = -6.0333e-5 * rangereading * rangereading * rangereading;
00751 double b = 1.2986e-2 * rangereading * rangereading;
00752 double c = -9.6280e-1 * rangereading;
00753 double d = 4.3082e1;
00754
00755 return a + b + c + d;
00756 }
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783
00784
00785
00786
00787
00788
00789
00790
00791
00792
00793
00794
00795
00796
00797