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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00040
00042
00043
00044
00045 #include <stdlib.h>
00046 #include <stdio.h>
00047 #include <math.h>
00048 #include <string.h>
00049 #include <unistd.h>
00050
00051
00052
00053
00054 #include <ros/ros.h>
00055 #include <ros/time.h>
00056 #include <std_msgs/String.h>
00057 #include <std_msgs/Float32.h>
00058 #include <std_msgs/Int8.h>
00059 #include <std_msgs/Int16.h>
00060 #include <std_msgs/Bool.h>
00061 #include <std_msgs/Empty.h>
00062 #include <geometry_msgs/Point32.h>
00063 #include <geometry_msgs/Pose2D.h>
00064
00065 #define PI 3.1415
00066
00067 float info_battery, info_driverF;
00068 int info_temp, range_msg1, range_msg2, range_msg3, encoderRead1, encoderRead2;
00069
00070 int x=0, y=0, xTemp=0 , yTemp=0;
00071 float teta=0, tetaTemp=0;
00072
00073 int xFinal=0, yFinal=0;
00074 float tetaFinal=0;
00075
00076 float dist=0,alfa=0,phi=0;
00077
00078 float r_wheel=39.0, r_robot=185.0;
00079
00080 int vMove = 25, vRotate = 20;
00081
00082
00083 int reactiveRange = 35;
00084
00085 int samples = 10;
00086 float sonar1Samples[10], sonar2Samples[10], sonar3Samples[10];
00087 int counter1 = 0, counter2 = 0, counter3 = 0;
00088
00089
00090
00091
00092 ros::Publisher pub_traxbotInfo;
00093 ros::Publisher pub_sonars;
00094
00095
00096
00097 ros::Publisher pub_moveMotors;
00098 ros::Publisher pub_stopMotors;
00099 ros::Publisher pub_encodersReset;
00100 ros::Publisher pub_encodersRead;
00101
00102
00103 ros::Publisher pub_odometry;
00104
00105
00106
00107
00108
00109 ros::Subscriber sub_driverFirmware;
00110 ros::Subscriber sub_batteryPower;
00111 ros::Subscriber sub_driverTemperature;
00112
00113
00114 ros::Subscriber sub_encoderRead1;
00115 ros::Subscriber sub_encoderRead2;
00116
00117
00118 ros::Subscriber sub_range1;
00119 ros::Subscriber sub_range2;
00120 ros::Subscriber sub_range3;
00121
00122
00123 float median(int n, float x[]) {
00124 float temp;
00125 int i, j;
00126
00127 for(i=0; i<n-1; i++) {
00128 for(j=i+1; j<n; j++) {
00129 if(x[j] < x[i]) {
00130
00131 temp = x[i];
00132 x[i] = x[j];
00133 x[j] = temp;
00134 }
00135 }
00136 }
00137
00138 if(n%2==0) {
00139
00140 return((x[n/2] + x[n/2 - 1]) / 2.0);
00141 } else {
00142
00143 return x[n/2];
00144 }
00145 }
00146
00147
00148 void enable_encodersRead() {
00149
00150 std_msgs::Empty enable1;
00151 pub_encodersRead.publish(enable1);
00152 ros::spinOnce();
00153
00154 }
00155
00156
00157 void enable_encodersReset() {
00158
00159 std_msgs::Empty enable2;
00160 pub_encodersReset.publish(enable2);
00161 ros::spinOnce();
00162 printf("ENCODERS RESET\n");
00163 }
00164
00165
00166 void enable_stopMotors() {
00167
00168 std_msgs::Empty enable3;
00169 pub_stopMotors.publish(enable3);
00170 ros::spinOnce();
00171 printf("STOP MOTORS\n");
00172
00173 }
00174
00175 void enable_infoData() {
00176
00177 std_msgs::Empty enable4;
00178 pub_traxbotInfo.publish(enable4);
00179 ros::spinOnce();
00180 }
00181
00182
00183
00184 void encoder1_readCB(const std_msgs::Int16::ConstPtr& pulses1) {
00185
00186 encoderRead1 = pulses1->data;
00187
00188 }
00189
00190 void encoder2_readCB(const std_msgs::Int16::ConstPtr& pulses2) {
00191
00192 encoderRead2 = pulses2->data;
00193
00194 }
00195
00196 void batteryPowerCB(const std_msgs::Float32::ConstPtr& battery) {
00197
00198 info_battery = battery->data;
00199 }
00200
00201 void firmwareVersionCB(const std_msgs::Float32::ConstPtr& firmwareV) {
00202
00203 info_driverF = firmwareV->data;
00204 }
00205
00206 void temperatureCB(const std_msgs::Int8::ConstPtr& temp) {
00207
00208 info_temp = temp->data;
00209 }
00210
00211 void sonar1CB(const std_msgs::Int16::ConstPtr& sonar1) {
00212
00213 range_msg1 = sonar1->data;
00214
00215 sonar1Samples[counter1] = sonar1->data;
00216
00217 if (counter1 == 0) {
00218
00219 range_msg1 = sonar1Samples[0];
00220
00221 }
00222
00223 counter1++;
00224
00225 if ( counter1 >= samples) {
00226 counter1=0;
00227 range_msg1 = int(floor(median(samples, sonar1Samples)));
00228 }
00229
00230 }
00231
00232 void sonar2CB(const std_msgs::Int16::ConstPtr& sonar2) {
00233
00234 range_msg2 = sonar2->data;
00235
00236 sonar2Samples[counter2] = sonar2->data;
00237
00238 if (counter2 == 0) {
00239
00240 range_msg2 = sonar2Samples[0];
00241 }
00242
00243 counter2++;
00244
00245 if ( counter2 >= samples) {
00246 counter2=0;
00247 range_msg2 = int(floor(median(samples, sonar2Samples)));
00248 }
00249
00250 }
00251
00252 void sonar3CB(const std_msgs::Int16::ConstPtr& sonar3) {
00253
00254 range_msg3 = sonar3->data;
00255
00256
00257 sonar3Samples[counter3] = abs(sonar3->data);
00258
00259 if (counter3 == 0) {
00260
00261 range_msg3 = sonar3Samples[0];
00262 }
00263
00264 counter3++;
00265
00266 if ( counter3 >= samples) {
00267 counter3 = 0;
00268 range_msg3 = int(floor(median(samples, sonar3Samples)));
00269 }
00270
00271
00272 }
00273
00274
00275 void moveMotors(int speed1, int speed2, int way) {
00276
00277 geometry_msgs::Point32 move;
00278
00279 move.x = speed1;
00280 move.y = speed2;
00281 move.z = way;
00282
00283 pub_moveMotors.publish(move);
00284 ros::spinOnce();
00285 printf("START MOTORS\n");
00286
00287 }
00288
00289 bool powerCheck( float batteryValue) {
00290 bool check;
00291
00292 if (batteryValue<=2) {
00293
00294 check=0;
00295 } else {
00296 check=1;
00297 }
00298
00299 return check;
00300
00301 }
00302
00303 float pulse2dist (int pulse) {
00304
00305 return ((pulse*1000)/11600);
00306
00307 }
00308
00309
00310 int encodersRead(){
00311
00312 enable_encodersRead();
00313 ros::spinOnce();
00314 int enco1 = abs(encoderRead1);
00315 int enco2 = abs(encoderRead2);
00316 int enco=round((enco1+enco2)/2.0);
00317
00318 return enco;
00319 }
00320
00321
00322 void calcOdometryDist(float dist, float alfa) {
00323
00324 geometry_msgs::Pose2D odm;
00325 float D = dist;
00326
00327 teta = tetaTemp + alfa;
00328
00329 if (teta < -180) {
00330 teta+=360;
00331 }else if (teta > 180){
00332 teta-=360;
00333 }
00334
00335 x = xTemp + round(D*cos(teta * (PI/180)));
00336 y = yTemp + round(D*sin(teta * (PI/180)));
00337
00338 tetaTemp = teta;
00339 xTemp = x;
00340 yTemp = y;
00341
00342 odm.x = x;
00343 odm.y = y;
00344 odm.theta = teta;
00345
00346 pub_odometry.publish(odm);
00347 ros::spinOnce();
00348
00349 printf("GLOBAL ODOMETRY UPDATED x:%d y:%d theta:%f\n",x,y,teta);
00350 }
00351
00352
00353 void move(float dist, int speed1, int speed2)
00354 {
00355 long poss1=0, poss_dist=0, poss1_buf=0;
00356 int cnt = 0;
00357
00358 printf("START MOVE()\n");
00359
00360 poss_dist = dist;
00361 printf("Goal position %ld mm\n", poss_dist);
00362
00363 moveMotors(speed1, speed2, 0);
00364
00365
00366 while(poss1 < poss_dist){
00367
00368 usleep(100000);
00369
00370 poss1 = pulse2dist ( encodersRead() );
00371 printf("Actual distance: %ld\n",poss1);
00372
00373 calcOdometryDist((poss1-poss1_buf), 0);
00374 poss1_buf = poss1;
00375 }
00376
00377 printf("ARRIVE TO GOAL with more %d mm.\n", (poss1-poss_dist));
00378
00379 usleep(100000);
00380 enable_stopMotors();
00381 ros::spinOnce();
00382
00383 usleep(100000);
00384 enable_encodersReset();
00385 ros::spinOnce();
00386
00387 while (cnt<5) {
00388 usleep(100000);
00389 enable_encodersRead();
00390 ros::spinOnce();
00391 ++cnt;
00392 }
00393
00394 printf("FINISH MOVE()\n");
00395
00396 }
00397
00398
00399 void rotate(float angle, int speed){
00400
00401 int poss_dist=0, cnt=0, direction=1;
00402 float ang = 0, ang_buf=0;
00403
00404 printf("START ROTATE()\n");
00405
00406 if (angle != 0) {
00407
00408 poss_dist=((1750.0*angle)/360.0)*(r_robot/r_wheel);
00409
00410 printf("Goal position %d pulses. %f degrees\n", poss_dist,angle);
00411
00412
00413 while(abs(ang) <= abs(angle)){
00414 ++cnt;
00415 usleep(100000);
00416
00417 ang=(r_wheel/r_robot)*(poss_dist/abs(poss_dist))*encodersRead()*360.0/1750.0;
00418
00419 printf("Actual angle: %f\n", ang);
00420
00421 if (cnt<2) {
00422
00423 if (poss_dist>0 ) {
00424 moveMotors(speed,speed,1);
00425 printf("Turn Left\n");
00426 } else {
00427 moveMotors(speed,speed,2);
00428 printf("Turn Right\n");
00429 }
00430 }
00431
00432 calcOdometryDist(0.0, (ang-ang_buf));
00433 ang_buf = ang;
00434
00435 }
00436
00437 }
00438
00439 if (ang <0 && ang!=0) {
00440 ang=ang+5;
00441 calcOdometryDist(0.0, (ang-ang_buf));
00442 }
00443
00444 if (ang >0 && ang!=0) {
00445 ang=ang-5;
00446 calcOdometryDist(0.0, (ang-ang_buf));
00447 }
00448
00449 printf("ARRIVE TO GOAL with more %f degrees\n", (ang-angle));
00450
00451 usleep(100000);
00452 enable_stopMotors();
00453 ros::spinOnce();
00454
00455
00456 usleep(100000);
00457 enable_encodersReset();
00458 ros::spinOnce();
00459
00460 cnt=0;
00461 while (cnt<5) {
00462 usleep(100000);
00463 enable_encodersRead();
00464 ros::spinOnce();
00465 ++cnt;
00466 }
00467
00468 printf("FINISH ROTATE()\n");
00469 }
00470
00471
00472 void goTo(int x, int y, float teta, int xFinal, int yFinal, float tetaFinal){
00473
00474 printf("START GO TO()\n");
00475
00476 dist=sqrt(pow(xFinal-x,2)+pow(yFinal-y,2));
00477 alfa=atan2((yFinal-y),(xFinal-x))*180.0/PI;
00478 phi=alfa-teta;
00479
00480
00481 if (abs(phi)>180)
00482 {
00483 phi=phi-(abs(phi)/phi)*360.0;
00484 }
00485
00486
00487 printf("PHI ROTATION: %d \n", phi);
00488 rotate(phi,vRotate);
00489
00490
00491 printf("LINEAR MOVE: %d \n", dist);
00492 move(dist,vMove,vMove);
00493
00494
00495
00496 phi=tetaFinal-alfa;
00497
00498 if (tetaFinal==0){ tetaFinal=190;}
00499
00500 if ((tetaFinal>-180) && (tetaFinal<=180)) {
00501 printf("FINAL ROTATION: %d \n", phi);
00502 rotate(phi,vRotate);
00503 teta=tetaFinal;
00504
00505 }else{
00506 teta=alfa;
00507 }
00508
00509 printf("FINISH GO TO()\n");
00510 }
00511
00512
00513 void squareTest(int side_width, int way, int cycles) {
00514
00515 printf("START SQUARE TEST()\n");
00516
00517 int cnt = 0;
00518
00519 while (cnt < cycles) {
00520
00521 switch (way) {
00522
00523 case 0:
00524
00525 goTo(x,y,teta,0,side_width,0);
00526 goTo(x,y,teta,side_width,side_width,0);
00527 goTo(x,y,teta,side_width,0,0);
00528 goTo(x,y,teta,0,0,0);
00529
00530
00531 break;
00532
00533 case 1:
00534 goTo(x,y,teta,side_width,0,0);
00535 goTo(x,y,teta,side_width,side_width,0);
00536 goTo(x,y,teta,0,side_width,0);
00537 goTo(x,y,teta,0,0,0);
00538
00539 break;
00540
00541 default:
00542 break;
00543 }
00544 ++cnt;
00545 }
00546
00547
00548 printf("FINISH SQUARE TEST()\n");
00549
00550 }
00551
00552
00553 void reactiveNavigation() {
00554
00555 int cnt = 0;
00556
00557 while(cnt < 30000){
00558
00559 moveMotors(vMove, vMove, 0);
00560 usleep(10000);
00561 ros::spinOnce();
00562
00563
00564 ROS_INFO("Moving... Sonar1: [%d], Sonar2: [%d], Sonar3: [%d]\n",range_msg1,range_msg2,range_msg3);
00565
00566 while (range_msg1 <= reactiveRange || range_msg2 <= reactiveRange || range_msg3 <= reactiveRange ) {
00567
00568
00569 ROS_INFO("Obstacle detected... Sonar1: [%d], Sonar2: [%d], Sonar3: [%d]\n",range_msg1,range_msg2,range_msg3);
00570 ros::spinOnce();
00571
00572
00573 if (range_msg3 <= range_msg2) {
00574
00575
00576 while (range_msg1<=reactiveRange || range_msg3<=reactiveRange) {
00577 usleep(10000);
00578 rotate(10,vRotate);
00579
00580 ROS_INFO("ROTATION LEFT... Sonar1: [%d], Sonar2: [%d], Sonar3: [%d]\n",range_msg1,range_msg2,range_msg3);
00581 ros::spinOnce();
00582 }
00583
00584
00585 } else {
00586
00587 while (range_msg1<=reactiveRange || range_msg2<=reactiveRange) {
00588 usleep(10000);
00589 rotate(-10,vRotate);
00590 ROS_INFO("ROTATION RIGHT... Sonar1: [%d], Sonar2: [%d], Sonar3: [%d]\n",range_msg1,range_msg2,range_msg3);
00591 ros::spinOnce();
00592 }
00593 }
00594
00595 }
00596 ++cnt;
00597 }
00598
00599 usleep(100000);
00600 enable_stopMotors();
00601 ros::spinOnce();
00602
00603 usleep(100000);
00604 enable_encodersReset();
00605 ros::spinOnce();
00606
00607 }
00608
00609
00610 void stepTest() {
00611
00612 goTo(x,y,teta,400,0,0);
00613 goTo(x,y,teta,400,400,0);
00614 goTo(x,y,teta,800,400,0);
00615 goTo(x,y,teta,800,800,0);
00616 goTo(x,y,teta,1200,800,0);
00617 goTo(x,y,teta,1200,1200,0);
00618 }
00619
00620
00621 int main(int argc, char** argv)
00622 {
00623 ros::init(argc, argv, "Traxbot_DriverTest");
00624 ros::NodeHandle nh;
00625
00626 ROS_INFO("ROS in TraxBot: Start ROS driver test...");
00627
00628
00629
00630 sub_range1 = nh.subscribe("/sonar_traxbot_front", 1, sonar1CB);
00631 sub_range2 = nh.subscribe("/sonar_traxbot_right", 1, sonar2CB);
00632 sub_range3 = nh.subscribe("/sonar_traxbot_left", 1, sonar3CB);
00633 sub_encoderRead1 = nh.subscribe("/encoderRead1", 1, encoder1_readCB);
00634 sub_encoderRead2 = nh.subscribe("/encoderRead2", 1, encoder2_readCB);
00635 sub_batteryPower = nh.subscribe("/batteryPower", 1, batteryPowerCB);
00636 sub_driverTemperature = nh.subscribe("/driverTemperature", 1, temperatureCB);
00637 sub_driverFirmware = nh.subscribe("/driverFirmware", 1, firmwareVersionCB);
00638
00639
00640 pub_moveMotors = nh.advertise<geometry_msgs::Point32>("/moveMotors", 1);
00641 pub_traxbotInfo = nh.advertise<std_msgs::Empty>("/traxbotInfo", 1);
00642 pub_sonars = nh.advertise<std_msgs::Empty>("/sonars", 1);
00643 pub_stopMotors = nh.advertise<std_msgs::Empty>("/stopMotors", 1);
00644 pub_encodersReset = nh.advertise<std_msgs::Empty>("/encodersReset", 1);
00645 pub_encodersRead = nh.advertise<std_msgs::Empty>("/encodersRead", 1);
00646 pub_odometry = nh.advertise<geometry_msgs::Pose2D>("/odometry", 1);
00647
00648 ros::Rate loop_rate(10);
00649
00650 int count=0;
00651
00652
00653
00654 while( ros::ok()){
00655
00656
00657 if (count <= 1) {
00658 enable_encodersReset();
00659 enable_stopMotors();
00660 }
00661
00662 if (count == 150) {
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672 }
00673
00674 printf("count: %d\n",count);
00675 ++count;
00676 ros::spinOnce();
00677 loop_rate.sleep();
00678
00679 }
00680
00681
00682
00683 ROS_INFO("DONE");
00684
00685 }