00001
00031 #include "base_motor_driver.h"
00032
00034
00035 BaseMotor::BaseMotor() :
00036 motor_order("M\n\r"), _corrected_data(0), _distance1(0.0), _distance2(0.0), _before_distance1(0.0),
00037 _before_distance2(0.0), _fd_motor1(-1), _fd_motor2(-1)
00038 {
00039
00040 }
00041
00043
00044 BaseMotor::~BaseMotor()
00045 {
00046 }
00047
00049
00050 int BaseMotor::init_communication()
00051 {
00052 int result;
00053 struct termios newtio1, newtio2;
00054 char DEFINE0[] = "HO\n\r";
00055
00056 struct sembuf sem_in[] = {0, -1, 0};
00057 struct sembuf sem_out[] = {0, 1, 0};
00058
00059
00060 int semFD;
00061
00062 _fd_motor1 = open(DEVICE_NAME1, O_RDWR | O_NOCTTY);
00063 if (_fd_motor1 < 0) {
00064 ROS_INFO("[BASE_MOTOR_DRIVER] Error while opening puerto serie 0 del motor %s:'%s'", DEVICE_NAME1,
00065 strerror(errno));
00066 return (1);
00067 }
00068
00069 _fd_motor2 = open(DEVICE_NAME2, O_RDWR | O_NOCTTY);
00070 if (_fd_motor2 < 0) {
00071 ROS_INFO("[BASE_MOTOR_DRIVER] Error while opening puerto serie 0 del motor %s:'%s'", DEVICE_NAME2,
00072 strerror(errno));
00073 return (1);
00074 }
00075
00076
00077 bzero((void *) &newtio1, sizeof(newtio1));
00078
00079
00080 newtio1.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
00081 newtio1.c_iflag = IGNPAR | ICRNL;
00082 newtio1.c_oflag = 0;
00083 newtio1.c_lflag = ECHO | ICANON;
00084
00085
00086 newtio1.c_cc[VINTR] = 0;
00087 newtio1.c_cc[VQUIT] = 0;
00088 newtio1.c_cc[VERASE] = 0;
00089 newtio1.c_cc[VKILL] = 0;
00090 newtio1.c_cc[VEOF] = 4;
00091 newtio1.c_cc[VSWTC] = 0;
00092 newtio1.c_cc[VSTART] = 0;
00093 newtio1.c_cc[VSTOP] = 0;
00094 newtio1.c_cc[VSUSP] = 0;
00095 newtio1.c_cc[VEOL] = 0;
00096 newtio1.c_cc[VREPRINT] = 0;
00097 newtio1.c_cc[VDISCARD] = 0;
00098 newtio1.c_cc[VWERASE] = 0;
00099 newtio1.c_cc[VLNEXT] = 0;
00100 newtio1.c_cc[VEOL2] = 0;
00101
00102
00103 newtio1.c_cc[VTIME] = 0;
00104 newtio1.c_cc[VMIN] = 1;
00105
00106
00107 tcflush(_fd_motor1, TCIFLUSH);
00108 result = tcsetattr(_fd_motor1, TCSANOW, &newtio1);
00109
00110 if (result) {
00111 ROS_INFO("[BASE_MOTOR_DRIVER] Configuando puerto serie del motor %s:'%s'", DEVICE_NAME1, strerror(errno));
00112 return (2);
00113 }
00114
00115
00116 bzero((void *) &newtio2, sizeof(newtio2));
00117
00118
00119 newtio2.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD;
00120 newtio2.c_iflag = IGNPAR | ICRNL;
00121 newtio2.c_oflag = 0;
00122 newtio2.c_lflag = ECHO | ICANON;
00123
00124
00125 newtio2.c_cc[VINTR] = 0;
00126 newtio2.c_cc[VQUIT] = 0;
00127 newtio2.c_cc[VERASE] = 0;
00128 newtio2.c_cc[VKILL] = 0;
00129 newtio2.c_cc[VEOF] = 4;
00130 newtio2.c_cc[VSWTC] = 0;
00131 newtio2.c_cc[VSTART] = 0;
00132 newtio2.c_cc[VSTOP] = 0;
00133 newtio2.c_cc[VSUSP] = 0;
00134 newtio2.c_cc[VEOL] = 0;
00135 newtio2.c_cc[VREPRINT] = 0;
00136 newtio2.c_cc[VDISCARD] = 0;
00137 newtio2.c_cc[VWERASE] = 0;
00138 newtio2.c_cc[VLNEXT] = 0;
00139 newtio2.c_cc[VEOL2] = 0;
00140
00141
00142 newtio2.c_cc[VTIME] = 0;
00143 newtio2.c_cc[VMIN] = 1;
00144
00145
00146 tcflush(_fd_motor2, TCIFLUSH);
00147 result = tcsetattr(_fd_motor2, TCSANOW, &newtio2);
00148
00149 if (result) {
00150 ROS_INFO("[BASE_MOTOR_DRIVER] Configuando puerto serie del motor %s:'%s'", DEVICE_NAME2, strerror(errno));
00151 return (2);
00152 }
00153
00154
00155 int returnValue = access(SEM_FILENAME, F_OK);
00156 if (returnValue != 0) {
00157 ROS_DEBUG("[BASE_MOTOR_DRIVER] access() returned an error %i='%s'", returnValue, strerror(errno));
00158 if (creat(SEM_FILENAME, S_IRUSR | S_IWUSR) == -1) {
00159 ROS_INFO("[BASE_MOTOR_DRIVER] ACCESS:Error creando el fichero de claves:'%s'", strerror(errno));
00160 }
00161 }
00162 SEMFDID = ftok(SEM_FILENAME, 'S');
00163 if (SEMFDID == (key_t) -1) {
00164 ROS_INFO("[BASE_MOTOR_DRIVER] Errro while creating the key SEMFDID:'%s'", strerror(errno));
00165 exit(EXIT_FAILURE);
00166 }
00167
00168
00169 ROS_DEBUG("[BASE_MOTOR_DRIVER] Creacion del semaforo de control de acceso del puerto de comunicaciones:SEMFDID:%i",
00170 SEMFDID);
00171 semFD = semget(SEMFDID, 1, IPC_CREAT | 0666);
00172 if (semFD < 0) {
00173 ROS_INFO("[BASE_MOTOR_DRIVER] Errro while creating el semaforo para el puerto de comunicaciones:semFD:%i, '%s'",
00174 semFD, strerror(errno));
00175 return (3);
00176 }
00177
00178 returnValue = semctl(semFD, 0, SETVAL, 1);
00179 if (returnValue != 0) {
00180 ROS_INFO("[BASE_MOTOR_DRIVER] Error while semctl:semFD:%i, '%s'", semFD, strerror(errno));
00181 }
00182
00183 bzero((void *) &_current_cinematic, sizeof(cinematic_data));
00184 bzero((void *) &_last_cinematic, sizeof(cinematic_data));
00185 bzero((void *) &_current_estimated, sizeof(cinematic_data));
00186 bzero((void *) &_before_estimated, sizeof(cinematic_data));
00187
00188 _distance1 = _distance2 = _before_distance1 = _before_distance2 = 0.0;
00189
00190
00191
00192 semctl(semFD, 0, SETVAL, 1);
00193
00194 ROS_DEBUG("[BASE_MOTOR_DRIVER] SEM en inicioComunicacionMotores: %d", semctl( semFD, 0,GETVAL,0));
00195
00196 semop(semFD, sem_in, 1);
00197
00198 write(_fd_motor1, DEFINE0, 4);
00199 write(_fd_motor2, DEFINE0, 4);
00200 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", DEFINE0, DEFINE0);
00201
00202 write(_fd_motor1, ACCELERATION, 6);
00203 write(_fd_motor2, ACCELERATION, 6);
00204 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", ACCELERATION, ACCELERATION);
00205
00206 write(_fd_motor1, DECELERATION, 7);
00207 write(_fd_motor2, DECELERATION, 7);
00208 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", DECELERATION, DECELERATION);
00209
00210 write(_fd_motor1, VELOCITY_MAX, 8);
00211 write(_fd_motor2, VELOCITY_MAX, 8);
00212 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", VELOCITY_MAX, VELOCITY_MAX);
00213
00214 #ifdef DEBUG_ODO
00215 char buf1[64];
00216 int res;
00217 int i;
00218 static const char POSM1[] = "GSP\n\r";
00219 bzero((void *) buf1, 64);
00220 write(_fd_motor1, POSM1, 5);
00221 ROS_DEBUG("[BASE_MOTOR_DRIVER] Leido: ");
00222 i = 0;
00223 res = read(_fd_motor1, buf1, 62);
00224 read(_fd_motor1, &buf1[63], 1);
00225 ROS_DEBUG("[BASE_MOTOR_DRIVER] Velocidad máxima :'%s':%d", buf1, res);
00226 #endif
00227
00228
00229 semop(semFD, sem_out, 1);
00230
00231
00232 return (0);
00233 }
00234
00236
00237 int BaseMotor::end_communication()
00238 {
00239 int semFD;
00240 struct sembuf sem_in[] = {0, -1, 0};
00241 struct sembuf arg[] = {0, 0, 0};
00242 char buf[] = "V0\n\r";
00243
00244 if ((semFD = semget(SEMFDID, 1, 0)) == -1) {
00245 ROS_INFO("[BASE_MOTOR_DRIVER] finComunicacionesMotores semget:'%s'", strerror(errno));
00246 return (1);
00247 }
00248
00249
00250 ROS_DEBUG("[BASE_MOTOR_DRIVER] SEM en finComunicacionMotores: %d", semctl( semFD, 0,GETVAL,0));
00251 semop(semFD, sem_in, 1);
00252
00253 write(_fd_motor1, buf, 4);
00254 write(_fd_motor2, buf, 4);
00255 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", buf, buf);
00256
00257
00258
00259 close(_fd_motor1);
00260 close(_fd_motor2);
00261
00262
00263 if (semctl(semFD, 0, IPC_RMID, arg) == -1) {
00264 ROS_INFO("[BASE_MOTOR_DRIVER] finComunicacionesMotores semctl:'%s'", strerror(errno));
00265
00266 return (2);
00267 }
00268 ROS_DEBUG("[BASE_MOTOR_DRIVER] Saliendo de fin comunicaciones");
00269
00270 return 0;
00271 }
00272
00274
00275 int BaseMotor::enable_motors()
00276 {
00277 int r;
00278 if ((r = enable_disable_motor(&_fd_motor1, "EN\r")) != 0) {
00279 ROS_INFO("[BASE_MOTOR_DRIVER] Error habilitando motor 1! Error %d", r);
00280 return r;
00281 }
00282 if ((r = enable_disable_motor(&_fd_motor2, "EN\r")) != 0) {
00283 ROS_INFO("[BASE_MOTOR_DRIVER] Error habilitando motor 2! Error %d", r);
00284 return r;
00285 }
00286
00287 return 0;
00288 }
00289
00291
00292 int BaseMotor::disable_motors()
00293 {
00294 int r;
00295 if ((r = enable_disable_motor(&_fd_motor1, "DI\r")) != 0) {
00296 ROS_INFO("[BASE_MOTOR_DRIVER] Error inhabilitando motor 1! Error %d", r);
00297 return r;
00298 }
00299 if ((r = enable_disable_motor(&_fd_motor2, "DI\r")) != 0) {
00300 ROS_INFO("[BASE_MOTOR_DRIVER] Error inhabilitando motor 2! Error %d", r);
00301 return r;
00302 }
00303
00304 return 0;
00305 }
00306
00308
00309 int BaseMotor::enable_disable_motor(int *fd, const char *order)
00310 {
00311 char bufOut[64], bufIn[64];
00312
00313 char comando[4];
00314 const char comandoGST[] = "GST\n\r";
00315 struct sembuf sem_in[] = {0, -1, 0};
00316 struct sembuf sem_out[] = {0, 1, 0};
00317 int res, l, semFD;
00318
00319 int intentos = 3;
00320 char c;
00321
00322 if (strlen(order) > 3) {
00323 ROS_INFO("[BASE_MOTOR_DRIVER] Error en la longitud del comando EN/DI");
00324 return -3;
00325 }
00326 bzero((void *) comando, 4);
00327 strcat(comando, order);
00328 if (comando[2] != '\r') {
00329 comando[2] = '\r';
00330 }
00331 l = strlen(comando);
00332
00333 bzero((void *) bufOut, 64);
00334 bzero((void *) bufIn, 64);
00335
00336 if ((semFD = semget(SEMFDID, 1, 0)) < 0) {
00337 ROS_INFO("[BASE_MOTOR_DRIVER] Error adquiriendo el semaforo en enable_disable_motor:'%s'", strerror(errno));
00338 return (-4);
00339 }
00340
00341 while(intentos >= 0) {
00342 intentos--;
00343 l = strlen(comando);
00344
00345
00346 if (semop(semFD, sem_in, 1) != 0) {
00347 ROS_INFO("[BASE_MOTOR_DRIVER] Error inicio zona exclusiva write enable_disable_motor -> (%i) \"'%s'\"",
00348 errno, strerror(errno));
00349 return -4;
00350 }
00351
00352 res = write(*fd, comando, l);
00353 if (res != l) {
00354 ROS_INFO("[BASE_MOTOR_DRIVER] Error escribiendo a _fd_motor1: escritos %d bytes de %d", res, l);
00355 ROS_DEBUG("[BASE_MOTOR_DRIVER] (%i) \"'%s'\"/n/n", errno, strerror(errno));
00356 continue;
00357 }
00358
00359
00360 l = strlen(comandoGST);
00361 res = write(*fd, comandoGST, l);
00362 if (res != l) {
00363 ROS_INFO("[BASE_MOTOR_DRIVER] Error escribiendo a _fd_motor1: escritos %d bytes de %d", res, l);
00364 ROS_DEBUG("[BASE_MOTOR_DRIVER] (%i) \"'%s'\"", errno, strerror(errno));
00365 continue;
00366 }
00367
00368
00369
00370 res = read(*fd, bufIn, 62);
00371 read(*fd, &bufIn[63], 1);
00372 if (semop(semFD, sem_out, 1) != 0) {
00373 ROS_INFO("[BASE_MOTOR_DRIVER] Error fin zona exclusiva read enable_disable_motor -> (%i) \"'%s'\"", errno,
00374 strerror(errno));
00375 return -4;
00376 }
00377
00378 if (res < SIZE_REPORT_GST) {
00379 ROS_INFO("[BASE_MOTOR_DRIVER] Error leyendo a fd: leidos %d bytes", res);
00380 ROS_DEBUG("[BASE_MOTOR_DRIVER] (%i) \"'%s'\"", errno, strerror(errno));
00381 continue;
00382 }
00383
00384
00385 c = bufIn[3];
00386
00387 if (strstr(comando, "EN") != NULL) {
00388
00389 if (c == '1') {
00390 return 0;
00391 }
00392 else {
00393 ROS_DEBUG("[BASE_MOTOR_DRIVER] Intento fallido. Restan %d intentos", intentos);
00394 }
00395 }
00396
00397 else if (strstr(comando, "DI") != NULL) {
00398
00399 if (c == '0') {
00400 return 0;
00401 }
00402 else {
00403 ROS_DEBUG("[BASE_MOTOR_DRIVER] Intento fallido. Restan %d intentos", intentos);
00404 }
00405 }
00406
00407 else {
00408 ROS_INFO("[BASE_MOTOR_DRIVER] Error comprobando el éxito de nuestro comando inapropiado: \"'%s'\"",
00409 comando);
00410 return -3;
00411 }
00412 }
00413
00414 ROS_DEBUG("[BASE_MOTOR_DRIVER] ¡INTENTOS AGOTADOS!");
00415 return -2;
00416 }
00417
00419
00420 int BaseMotor::read_data(cinematic_data* data)
00421 {
00422 return read_data_variable_time_diff(data, PERIOD);
00423 }
00424
00426
00427 int BaseMotor::read_data_variable_time_diff(cinematic_data *data, double time_since_last_call)
00428 {
00429 static const char GNM1[] = "GN\n\r";
00430 static const char GNM2[] = "GN\n\r";
00431 static const char POSM1[] = "POS\n\r";
00432 static const char POSM2[] = "POS\n\r";
00433
00434 char buf1[64], buf2[64], buf3[64], buf4[64];
00435
00436 struct sembuf sem_in[] = {0, -1, 0};
00437 struct sembuf sem_out[] = {0, 1, 0};
00438
00439 double v, w, deltaD1, deltaD2, deltaD, deltaTheta;
00440 int semFD;
00441
00442 bzero((void *) buf1, 64);
00443 bzero((void *) buf2, 64);
00444 bzero((void *) buf3, 64);
00445 bzero((void *) buf4, 64);
00446
00447 if ((semFD = semget(SEMFDID, 1, 0)) < 0) {
00448 ROS_INFO("[BASE_MOTOR_DRIVER] Adquiriendo el semaforo en leeDatosMotores:'%s'", strerror(errno));
00449 return (1);
00450 }
00451
00452
00453 ROS_DEBUG("[BASE_MOTOR_DRIVER] SEM en leeDatosMotores: %d", semctl( semFD, 0,GETVAL,0));
00454 int returnValue = semop(semFD, sem_in, 1);
00455 if (returnValue != 0) {
00456 ROS_INFO("[BASE_MOTOR_DRIVER] Error while semop:'%s'", strerror(errno));
00457 }
00458
00459
00460 ROS_DEBUG("[BASE_MOTOR_DRIVER] Sending POSM1:'%s'", POSM1);
00461 write(_fd_motor1, POSM1, 5);
00462
00463
00464 read(_fd_motor1, buf1, 62);
00465 read(_fd_motor1, &buf1[63], 1);
00466 ROS_DEBUG("[BASE_MOTOR_DRIVER] Received buf1:'%s'", buf1);
00467
00468 ROS_DEBUG("[BASE_MOTOR_DRIVER] Sending POSM2:'%s'", POSM2);
00469 write(_fd_motor2, POSM2, 5);
00470
00471
00472 read(_fd_motor2, buf2, 62);
00473 read(_fd_motor2, &buf2[63], 1);
00474 ROS_DEBUG("[BASE_MOTOR_DRIVER] Received buf2:'%s'", buf2);
00475
00476
00477 ROS_DEBUG("[BASE_MOTOR_DRIVER] Sending GNM1:'%s'", GNM1);
00478 write(_fd_motor1, GNM1, 4);
00479
00480
00481 read(_fd_motor1, buf3, 62);
00482 read(_fd_motor1, &buf3[63], 1);
00483 ROS_DEBUG("[BASE_MOTOR_DRIVER] Received buf3:'%s'", buf3);
00484
00485 ROS_DEBUG("[BASE_MOTOR_DRIVER] Sending GNM2:'%s'", GNM2);
00486 write(_fd_motor2, GNM2, 4);
00487
00488
00489 read(_fd_motor2, buf4, 62);
00490 read(_fd_motor2, &buf4[63], 1);
00491 ROS_DEBUG("[BASE_MOTOR_DRIVER] Received buf4:'%s'", buf4);
00492
00493 semop(semFD, sem_out, 1);
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504 _before_distance1 = _distance1;
00505
00506 _distance1 = (atof(buf1) * M_PI * WHEEL_DIAMETER) / (PULSES_PER_REVOLUTION * REDUCTION);
00507 _before_distance2 = _distance2;
00508 _distance2 = (atof(buf2) * M_PI * WHEEL_DIAMETER) / (PULSES_PER_REVOLUTION * REDUCTION);
00509
00510 deltaD1 = _distance1 - _before_distance1;
00511 deltaD2 = _distance2 - _before_distance2;
00512
00513 deltaD = (deltaD1 + deltaD2) * 0.5;
00514 deltaTheta = (deltaD2 - deltaD1) / (AXIS_LENGTH);
00515
00516
00517 v = deltaD / time_since_last_call;
00518
00519
00520 w = deltaTheta / time_since_last_call;
00521
00522 _current_cinematic.theta = _last_cinematic.theta + deltaTheta;
00523 _current_cinematic.x = _last_cinematic.x + deltaD * cos(_current_cinematic.theta);
00524 _current_cinematic.y = _last_cinematic.y + deltaD * sin(_current_cinematic.theta);
00525 _current_cinematic.v = v;
00526 _current_cinematic.w = w;
00527
00528 ROS_DEBUG("[BASE_MOTOR_DRIVER] x:%.4f mm y:%.4f mm theta:%.4f rad v:%.4f mm.sec-1 w:%.4f rad.sec-1",
00529 _current_cinematic.x, _current_cinematic.y, _current_cinematic.theta, _current_cinematic.v,
00530 _current_cinematic.w);
00531
00532
00533 _last_cinematic.theta = _current_cinematic.theta;
00534 _last_cinematic.x = _current_cinematic.x;
00535 _last_cinematic.y = _current_cinematic.y;
00536 _last_cinematic.v = _current_cinematic.v;
00537 _last_cinematic.w = _current_cinematic.w;
00538
00539
00540 data->theta = _current_cinematic.theta;
00541 data->x = _current_cinematic.x;
00542 data->y = _current_cinematic.y;
00543 data->v = _current_cinematic.v;
00544 data->w = _current_cinematic.w;
00545
00546
00547 data->w = data->w * 360.0 * (0.5) / M_PI;
00548 data->theta = data->theta * 360.0 * (0.5) / M_PI;
00549
00550 ROS_DEBUG("[BASE_MOTOR_DRIVER] data: x=%.4f y=%.4f theta=%.4f grados, v=%.4f w=%.4f", data->x, data->y,
00551 data->theta, data->v, data->w);
00552
00553 if (_corrected_data) {
00554 _current_estimated.theta = _before_estimated.theta + deltaTheta;
00555 _current_estimated.x = _before_estimated.x + deltaD * cos(_current_estimated.theta);
00556 _current_estimated.y = _before_estimated.y + deltaD * sin(_current_estimated.theta);
00557 _current_estimated.v = v;
00558 _current_estimated.w = w;
00559
00560 _before_estimated.theta = _current_estimated.theta;
00561 _before_estimated.x = _current_estimated.x;
00562 _before_estimated.y = _current_estimated.y;
00563 _before_estimated.v = _current_estimated.v;
00564 _before_estimated.w = _current_estimated.w;
00565 }
00566 else {
00567 _current_estimated.theta = _current_cinematic.theta;
00568 _current_estimated.x = _current_cinematic.x;
00569 _current_estimated.y = _current_cinematic.y;
00570 _current_estimated.v = v;
00571 _current_estimated.w = w;
00572
00573 _before_estimated.theta = _last_cinematic.theta;
00574 _before_estimated.x = _last_cinematic.x;
00575 _before_estimated.y = _last_cinematic.y;
00576 _before_estimated.v = _last_cinematic.v;
00577 _before_estimated.w = _last_cinematic.w;
00578 }
00579
00580 return (0);
00581 }
00582
00584
00585 int BaseMotor::set_velocity(double v, double w)
00586 {
00587 char buf1[64], buf2[64];
00588 long int vm1, vm2;
00589 int l1, l2;
00590 int semFD;
00591 struct sembuf sem_in[] = {0, -1, 0};
00592 struct sembuf sem_out[] = {0, 1, 0};
00593
00594
00595 w = w * 2.0 * M_PI / (360.0);
00596
00597
00598 double v1 = v - w * AXIS_LENGTH * 0.5;
00599 double v2 = v + w * AXIS_LENGTH * 0.5;
00600
00601
00602 vm1 = (long int) ((v1 * 60 * REDUCTION) / (M_PI * WHEEL_DIAMETER));
00603 vm2 = (long int) ((v2 * 60 * REDUCTION) / (M_PI * WHEEL_DIAMETER));
00604 ROS_DEBUG_NAMED("base_motor_driver", "[BASE_MOTOR_DRIVER] Motor instructions: %li, %li", vm1, vm2);
00605
00606 bzero((void *) buf1, 64);
00607 bzero((void *) buf2, 64);
00608
00609 sprintf(buf1, "V%ld\n\r", vm1);
00610 sprintf(buf2, "V%ld\n\r", vm2);
00611
00612
00613 for (l1 = 0; (buf1[l1] != '\0') && (l1 < 63); l1++) {
00614 }
00615
00616 for (l2 = 0; (buf2[l2] != '\0') && (l2 < 63); l2++) {
00617 }
00618
00619 if ((semFD = semget(SEMFDID, 1, 0)) < 0) {
00620 ROS_INFO("[BASE_MOTOR_DRIVER] Adquiriendo el semaforo en leeDatosMotores:'%s'", strerror(errno));
00621 return (1);
00622 }
00623
00624
00625 ROS_DEBUG_NAMED("base_motor_driver", "[BASE_MOTOR_DRIVER] SEM en colocaVelocidadMotores: %d",
00626 semctl( semFD, 0,GETVAL,0));
00627 semop(semFD, sem_in, 1);
00628
00629
00630 write(_fd_motor1, VELOCITY_MAX, 9);
00631 write(_fd_motor2, VELOCITY_MAX, 9);
00632 ROS_DEBUG_NAMED("base_motor_driver", "[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", VELOCITY_MAX,
00633 VELOCITY_MAX);
00634
00635 write(_fd_motor1, buf1, l1);
00636 write(_fd_motor2, buf2, l2);
00637 ROS_DEBUG_NAMED("base_motor_driver", "[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", buf1, buf2);
00638
00639 int returnValue = semop(semFD, sem_out, 1);
00640 if (returnValue != 0) {
00641 ROS_INFO("[BASE_MOTOR_DRIVER] Error while semop:semFD:%i, '%s'", semFD, strerror(errno));
00642 }
00643
00644 ROS_DEBUG_NAMED("base_motor_driver", "[BASE_MOTOR_DRIVER] v %f w %f vm1 %ld vm2 %ld, v * w: %f", v, w, vm1, vm2,
00645 v * w);
00646
00647 return (0);
00648 }
00649
00651
00652 int BaseMotor::set_displacement_velocity(double d, double v, double w)
00653 {
00654 char buf[64], buf1[64], buf2[64];
00655 long int dm;
00656 int l, l1, l2;
00657 double v1, v2;
00658 long int vm1, vm2;
00659 int grados;
00660 int semFD;
00661 struct sembuf sem_in[] = {0, -1, 0};
00662 struct sembuf sem_out[] = {0, 1, 0};
00663 cinematic_data dVelocidad;
00664
00665
00666 grados = (int) ((d * PULSES_PER_REVOLUTION * REDUCTION) / (360));
00667 dm = (long int) (grados * 0.713);
00668 bzero((void *) buf, 64);
00669 sprintf(buf, "LR%ld\n\r", dm);
00670 for (l = 0; (buf[l] != '\0') && (l < 63); l++)
00671 ;
00672
00673
00674 w = w * 2.0 * M_PI / (360.0);
00675
00676
00677 v1 = v - w * AXIS_LENGTH * 0.5;
00678 v2 = v + w * AXIS_LENGTH * 0.5;
00679 vm1 = (long int) ((v1 * 60 * REDUCTION) / (M_PI * WHEEL_DIAMETER));
00680 vm2 = (long int) ((v2 * 60 * REDUCTION) / (M_PI * WHEEL_DIAMETER));
00681 bzero((void *) buf1, 64);
00682 bzero((void *) buf2, 64);
00683 sprintf(buf1, "SP%ld\n\r", vm1);
00684 sprintf(buf2, "SP%ld\n\r", vm2);
00685 for (l1 = 0; (buf1[l1] != '\0') && (l1 < 63); l1++)
00686 ;
00687 for (l2 = 0; (buf2[l2] != '\0') && (l2 < 63); l2++)
00688 ;
00689
00690 if ((semFD = semget(SEMFDID, 1, 0)) < 0) {
00691 ROS_INFO("[BASE_MOTOR_DRIVER] Adquiriendo el semaforo en leeDatosMotores:'%s'", strerror(errno));
00692 return (1);
00693 }
00694
00695
00696 ROS_DEBUG("[BASE_MOTOR_DRIVER] SEM en colocaVelocidadDesplazamiento: %d", semctl( semFD, 0,GETVAL,0));
00697 semop(semFD, sem_in, 1);
00698
00699
00700 write(_fd_motor1, buf1, l1);
00701 write(_fd_motor2, buf2, l2);
00702 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", buf1, buf2);
00703
00704
00705 write(_fd_motor1, buf, l);
00706 write(_fd_motor2, buf, l);
00707 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", buf, buf);
00708
00709
00710 write(_fd_motor1, motor_order.c_str(), 3);
00711 write(_fd_motor2, motor_order.c_str(), 3);
00712 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", motor_order.c_str(), motor_order.c_str());
00713
00714 semop(semFD, sem_out, 1);
00715
00716 ROS_DEBUG("[BASE_MOTOR_DRIVER] colocaVelocidadDesplazamiento");
00717 ROS_DEBUG("[BASE_MOTOR_DRIVER] d=%f dm=%ld l=%i ", d, dm, l);
00718 ROS_DEBUG("[BASE_MOTOR_DRIVER] v %f w %f v1 %.4f v2 %.4f vm1 %ld vm2 %ld", v, w, v1, v2, vm1, vm2);
00719
00720 return (0);
00721 }
00722
00724
00725 int BaseMotor::move_ahead(double distance)
00726 {
00727 char buf[64];
00728 long int dm;
00729 int l;
00730 int semFD;
00731 struct sembuf sem_in[] = {0, -1, 0};
00732 struct sembuf sem_out[] = {0, 1, 0};
00733
00734 dm = (long int) ((distance * PULSES_PER_REVOLUTION * REDUCTION) / (M_PI * WHEEL_DIAMETER));
00735
00736 bzero((void *) buf, 64);
00737
00738 sprintf(buf, "LR%ld\n\r", dm);
00739
00740 for (l = 0; (buf[l] != '\0') && (l < 63); l++)
00741 ;
00742
00743 if ((semFD = semget(SEMFDID, 1, 0)) < 0) {
00744 ROS_INFO("[BASE_MOTOR_DRIVER] Adquiriendo el semaforo en leeDatosMotores:'%s'", strerror(errno));
00745 return (1);
00746 }
00747
00748
00749 ROS_DEBUG("[BASE_MOTOR_DRIVER] SEM en moverLineaRecta: %d", semctl( semFD, 0,GETVAL,0));
00750 semop(semFD, sem_in, 1);
00751
00752 write(_fd_motor1, VELOCITY_MAX, 9);
00753 write(_fd_motor2, VELOCITY_MAX, 9);
00754 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", VELOCITY_MAX, VELOCITY_MAX);
00755
00756 write(_fd_motor1, buf, l);
00757 write(_fd_motor2, buf, l);
00758 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", buf, buf);
00759
00760 write(_fd_motor1, motor_order.c_str(), 3);
00761 write(_fd_motor2, motor_order.c_str(), 3);
00762 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", motor_order.c_str(), motor_order.c_str());
00763
00764 semop(semFD, sem_out, 1);
00765
00766 ROS_DEBUG("[BASE_MOTOR_DRIVER] distance: %f, dm: %ld, l: %i ", distance, dm, l);
00767
00768 return (0);
00769 }
00770
00772
00773 int BaseMotor::relative_turn(double theta)
00774 {
00775 char buf1[64], buf2[64];
00776 char buf3[] = "M\n\r";
00777 long int dm;
00778 int l1, l2;
00779 int semFD;
00780 struct sembuf sem_in[] = {0, -1, 0};
00781 struct sembuf sem_out[] = {0, 1, 0};
00782 cinematic_data dVelocidad;
00783
00784 ROS_DEBUG("[BASE_MOTOR_DRIVER] Motores: Me piden girar %f grados", theta);
00785
00786 theta = theta * REDUCTION * PULSES_PER_REVOLUTION / 360.0;
00787
00788 dm = (long int) theta * AXIS_LENGTH / WHEEL_DIAMETER;
00789 bzero((void *) buf1, 64);
00790 bzero((void *) buf2, 64);
00791
00792 sprintf(buf1, "LR%ld\n\r", (-1) * dm);
00793 sprintf(buf2, "LR%ld\n\r", dm);
00794
00795 for (l1 = 0; (buf1[l1] != '\0') && (l1 < 63); l1++)
00796 ;
00797 for (l2 = 0; (buf2[l2] != '\0') && (l2 < 63); l2++)
00798 ;
00799
00800 if ((semFD = semget(SEMFDID, 1, 0)) < 0) {
00801 ROS_INFO("[BASE_MOTOR_DRIVER] Adquiriendo el semaforo en leeDatosMotores:'%s'", strerror(errno));
00802 return (1);
00803 }
00804
00805
00806 ROS_DEBUG("[BASE_MOTOR_DRIVER] SEM en giroRelativo: %d", semctl( semFD, 0,GETVAL,0));
00807 semop(semFD, sem_in, 1);
00808
00809 write(_fd_motor1, VELOCITY_MAX, 9);
00810 write(_fd_motor2, VELOCITY_MAX, 9);
00811 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", VELOCITY_MAX, VELOCITY_MAX);
00812
00813 write(_fd_motor1, buf1, l1);
00814 write(_fd_motor2, buf2, l2);
00815 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", buf1, buf2);
00816
00817 write(_fd_motor2, buf3, 3);
00818 write(_fd_motor1, buf3, 3);
00819 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", buf3, buf3);
00820
00821 semop(semFD, sem_out, 1);
00822
00823 ROS_DEBUG("[BASE_MOTOR_DRIVER] theta %.4f dm %ld l1 %i b1 '%s' b2 '%s' '%s'", theta, dm, l1, buf1, buf2, buf3);
00824
00825 return (0);
00826 }
00827
00829
00830 int BaseMotor::reset_odometry()
00831 {
00832 char DEFINE0[] = "HO\n\r";
00833 int semFD;
00834 struct sembuf sem_in[] = {0, -1, 0};
00835 struct sembuf sem_out[] = {0, 1, 0};
00836 if ((semFD = semget(SEMFDID, 1, 0)) < 0) {
00837 ROS_INFO("[BASE_MOTOR_DRIVER] Adquiriendo el semaforo en resetOdometry:'%s'", strerror(errno));
00838 return (1);
00839 }
00840
00841 bzero((void *) &_current_cinematic, sizeof(cinematic_data));
00842 bzero((void *) &_last_cinematic, sizeof(cinematic_data));
00843 _distance1 = _distance2 = _before_distance1 = _before_distance2 = 0.0;
00844
00845 ROS_DEBUG("[BASE_MOTOR_DRIVER] SEM en resetOdometry: %d", semctl(semFD, 0,GETVAL,0));
00846
00847
00848 semop(semFD, sem_in, 1);
00849 write(_fd_motor1, DEFINE0, 4);
00850 write(_fd_motor2, DEFINE0, 4);
00851 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", DEFINE0, DEFINE0);
00852
00853 semop(semFD, sem_out, 1);
00854
00855 return (0);
00856 }
00857
00859
00860 int BaseMotor::update_odometry(double x, double y, double theta)
00861 {
00862 char DEFINE0[] = "HO\n\r";
00863 int semFD;
00864 struct sembuf sem_in[] = {0, -1, 0};
00865 struct sembuf sem_out[] = {0, 1, 0};
00866
00867 if ((semFD = semget(SEMFDID, 1, 0)) < 0) {
00868 ROS_INFO("[BASE_MOTOR_DRIVER] Adquiriendo el semaforo en actualizarOdometria:'%s'", strerror(errno));
00869 return (1);
00870 }
00871
00872 _distance1 = _distance2 = _before_distance1 = _before_distance2 = 0.0;
00873
00874 _current_cinematic.x = x;
00875 _current_cinematic.y = y;
00876 _current_cinematic.theta = theta;
00877
00878
00879 _last_cinematic.x = _current_cinematic.x;
00880 _last_cinematic.y = _current_cinematic.y;
00881 _last_cinematic.theta = _current_cinematic.theta;
00882
00883 ROS_DEBUG("[BASE_MOTOR_DRIVER] SEM en resetOdometry: %d", semctl( semFD, 0,GETVAL,0));
00884
00885
00886 semop(semFD, sem_in, 1);
00887
00888 write(_fd_motor1, DEFINE0, 4);
00889 write(_fd_motor2, DEFINE0, 4);
00890
00891 ROS_DEBUG("[BASE_MOTOR_DRIVER] Enviado M1: '%s' Enviado M2: '%s'", DEFINE0, DEFINE0);
00892
00893 semop(semFD, sem_out, 1);
00894
00895
00896 return (0);
00897 }
00898
00900
00901 cinematic_data * BaseMotor::get_estimate_position()
00902 {
00903 cinematic_data *data;
00904
00905 data->x = _current_estimated.x;
00906 data->y = _current_estimated.y;
00907 data->theta = _current_estimated.theta;
00908 data->v = _current_estimated.v;
00909 data->w = _current_estimated.w;
00910
00911 return data;
00912 }
00913
00915
00916 int BaseMotor::set_estimate_position(double x, double y, double theta)
00917 {
00918 _current_estimated.x = x;
00919 _current_estimated.y = y;
00920 _current_estimated.theta = theta;
00921
00922
00923 _before_estimated.x = _current_estimated.x;
00924 _before_estimated.y = _current_estimated.y;
00925 _before_estimated.theta = _current_estimated.theta;
00926 _corrected_data = 1;
00927
00928 return (0);
00929 }
00930