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 }