sweep_laser_scan_client.c
Go to the documentation of this file.
00001 #include <ncurses.h>
00002 #include <playerc.h>
00003 #include <string>
00004 #include <math.h>
00005 #include <stdio.h>
00006 #include <cstdlib>
00007 #include <getopt.h>
00008 #include <iostream>
00009 using namespace std;
00010 //#define M_PI        3.14159265358979323846
00011 // Convert radians to degrees
00012 #define RAD2DEG(r) (float)((r) * 180 / M_PI)
00013 // Convert degrees to radians
00014 #define DEG2RAD(d) (float)((d) * M_PI / 180)
00015 
00016 #define HOSTNAME "localhost"
00017 
00018 // what diference between angles is considered 0?
00019 #define EPS 0.01
00020 
00021 void home (playerc_client_t *client, playerc_actarray_t *device, int joint);
00022 void homeall (playerc_client_t *client, playerc_actarray_t *device);
00023 void sweep (playerc_client_t *client, playerc_actarray_t *device, 
00024             int actuator, float next_pos,  float speed);
00025 float go_to_pose (playerc_client_t *client, playerc_actarray_t *device, 
00026                   int actuator, float min_angle, float max_angle);
00027 void rotate (playerc_client_t *client, playerc_actarray_t *device, 
00028            int actuator, float angle, float speed);
00029 void print_data (playerc_actarray_t *device);
00030 void laser_power_on_off(playerc_client_t *client, playerc_laser_t *device_laser, bool sw);
00031 void usage_ ();
00032 //public struct for command line arguments
00033 static struct
00034 {
00035   char *program;
00036   std::string log_filename;     
00037   float start_angle;
00038   float end_angle;
00039   int interface;
00040   int rot_joint;
00041   //in rad/s
00042   float rot_speed;
00043   int loop;   
00044 } g_options;
00045 
00046 
00047 int main (int argc, char  **argv)
00048 {
00049 
00051   // Parse options
00053   g_options.program = argv[0];
00054  //set options to some impossible values
00055  g_options.log_filename = " ";
00056  g_options.start_angle = -1000;
00057  g_options.end_angle = -1000;
00058  g_options.interface = -1000;
00059  g_options.rot_joint = -1000;
00060  g_options.rot_speed = -1000;
00061  g_options.loop = 0;
00062  //use custom given log filename
00063  bool log_filename_from_time = false;
00064 
00065  while (1)
00066    {
00067      //for some reason specifying "optional_argument" results in empty valued option, 
00068      //thus all of them come with "required_argument" despite being optional  
00069      static struct option long_options[] = {
00070        {"help", no_argument, 0, 'h'},
00071        {"start_angle", required_argument, 0, 's'},
00072        {"end_angle", required_argument, 0, 'e'},
00073        {"interface", required_argument, 0, 'i'},
00074        {"rot_joint", required_argument, 0, 'j'},
00075        {"rot_speed", required_argument, 0, 'v'},
00076        {"log_filename", required_argument, 0, 'f'},
00077        {"loop", required_argument, 0, 'l'},
00078      };
00079      int option_index = 0;
00080      int c = getopt_long(argc, argv, "s:e:i:j:v:f:hl:", long_options, &option_index);
00081      if (c == -1) 
00082        {
00083          //usage_();
00084          break;
00085        }
00086      switch (c)
00087        {
00088        case 'h':
00089          usage_();
00090          break;
00091        case 's':
00092          g_options.start_angle = atof(optarg);
00093          break;
00094        case 'e':
00095          g_options.end_angle = atof(optarg);
00096          break;
00097        case 'i':
00098          g_options.interface = atoi(optarg);
00099          break;
00100        case 'j':
00101          g_options.rot_joint = atoi(optarg);
00102          break;
00103        case 'v':
00104          g_options.rot_speed = atof(optarg);
00105          break;
00106        case 'l':
00107          g_options.loop = atoi(optarg);
00108          break;
00109        case 'f':
00110           g_options.log_filename.assign(optarg);
00111           cerr << "log: " << g_options.log_filename << endl;
00112           break;
00113        }
00114    }
00115 
00116  if (g_options.interface == -1000)
00117    {
00118      cerr << "Error: You have to specify interface (-i)" << endl;
00119      exit(0);
00120    }
00121  if (g_options.start_angle  == -1000)
00122    {
00123      cerr << "Error: You have to specify start_angle (-s)" << endl;
00124      exit(0);
00125    }
00126  if (g_options.end_angle  == -1000)
00127    {
00128      cerr << "Error: You have to specify end_angle (-e)" << endl;
00129      exit(0);
00130    }
00131  if (g_options.rot_joint == -1000)
00132    {
00133      cerr << "Error: You have to specify rotational joint (-j)" << endl;
00134      exit(0);
00135    }
00136  if (g_options.rot_speed == -1000)
00137    {
00138    cerr << "Warning: Setting rot speed to 0.1 rad/s" << endl;
00139    g_options.rot_speed = 0.05;
00140    }
00141  if(g_options.log_filename == "")
00142    {
00143      cerr << "Warning: Using auto-generated log filenames!" << endl; 
00144      log_filename_from_time = true;
00145    }
00146 
00147 
00149  // main begins
00151  // exit(0);
00152 
00153  // Set the current actuator as the gripper (default)
00154   int delta_rot = 10;
00155   
00156   char logFileName[80];
00157   struct timeval t1;
00158   playerc_client_t *client;
00159   int t, i, j;
00160   void *rdevice;
00161   int port = 6665;
00162   playerc_actarray_t *device_actarray;
00163   playerc_laser_t *device_laser;
00164   playerc_log_t *device_log;
00165   client = playerc_client_create (NULL, HOSTNAME, port);
00166   playerc_client_connect (client);
00167 
00168   //return from go_to_pose
00169   float next_pos;
00170   
00171   device_actarray  = playerc_actarray_create (client, g_options.interface);
00172   device_laser  = playerc_laser_create (client, 0);
00173   device_log       = playerc_log_create      (client, 0);
00174 
00175   playerc_actarray_subscribe (device_actarray, PLAYER_OPEN_MODE);
00176   playerc_log_subscribe      (device_log, PLAYER_OPEN_MODE);
00177   playerc_laser_subscribe      (device_laser, PLAYER_OPEN_MODE);
00178 
00179   playerc_log_set_filename (device_log, g_options.log_filename.c_str());
00180   initscr ();
00181   refresh ();
00182   cbreak ();
00183   
00184   for (t = 0; t < 20; t++)
00185     rdevice = playerc_client_read (client);
00186 
00187   int current_actuator = device_actarray->actuators_count - 1;
00188   
00189   nodelay (stdscr, TRUE);
00190   keypad (stdscr, TRUE);
00191   
00192   printw ("Legend: 'p' - pause logging, 'r' - start/resume logging into from time generated log files, 'h' - home all cubes\n");
00193   printw ("        'b' - start/resume logging into cli passed log files\n");
00194   printw ("        's' - sweep a cube (selected using '1'-'%d')\n", device_actarray->actuators_count - 1);
00195   printw ("        'o' - home one cube, 'x' - exit\n"); refresh ();
00196   
00197   mvprintw (20, 0, "Logging : disabled\n"); refresh ();
00198   
00199   int key;
00200  
00201   if(g_options.loop == 1)
00202     {
00203       cerr << "loop   " << g_options.loop << endl;
00204       //exit(0);
00205       while (key != 'x')
00206         {
00207           laser_power_on_off(client, device_laser, false);
00208           rdevice = playerc_client_read (client);
00209           print_data (device_actarray);
00210           key = getch ();
00211           mvprintw (4, 0, "Keystroke: %d\n", key); refresh ();
00212           next_pos = go_to_pose(client, device_actarray, g_options.rot_joint, g_options.start_angle, g_options.end_angle);
00213           sweep (client, device_actarray, g_options.rot_joint, next_pos, g_options.rot_speed);
00214           if (next_pos == g_options.end_angle) 
00215             laser_power_on_off(client, device_laser, true);
00216           while (fabs(next_pos  -   RAD2DEG (device_actarray->actuators_data[g_options.rot_joint].position)) > EPS)
00217             {
00218               playerc_client_read (client);
00219               mvprintw (22, 0,  "Angle  %f\n", fabs(next_pos  -   RAD2DEG (device_actarray->actuators_data[g_options.rot_joint].position))); refresh();
00220               //sleep(1);
00221             }
00222         }
00223     }
00224  
00225   while (key != 'x')
00226   {
00227     rdevice = playerc_client_read (client);
00228 
00229     print_data (device_actarray);
00230     key = getch ();
00231     mvprintw (4, 0, "Keystroke: %d\n", key); refresh ();
00232      
00233     switch (key)
00234       {
00235       case '1':
00236         current_actuator = 0;
00237         break;
00238       case '2':
00239         current_actuator = 1;
00240         break;
00241       case '3':
00242         current_actuator = 2;
00243         break;
00244       case '4':
00245         current_actuator = 3;
00246         break;
00247       case '5':
00248         current_actuator = 4;
00249         break;
00250       case '6':
00251         current_actuator = 5;
00252         break;
00253       case '7':
00254         current_actuator = 6;
00255         break;
00256         
00257         // Left arrow
00258       case 260:
00259         delta_rot--;
00260         mvprintw (22, 0, "Delta : %d\n", delta_rot); refresh ();
00261         break;
00262         
00263         // Right arrow
00264       case 261:
00265         delta_rot++;
00266         mvprintw (22, 0, "Delta : %d\n", delta_rot); refresh ();
00267         break;
00268         
00269       case '-':
00270         // move - 10
00271         // rotate (client, device_actarray, current_actuator, -delta_rot, 0.1);
00272         mvprintw (21, 0, "Moving - with %d\n", delta_rot); refresh ();
00273         break;
00274       case '+':
00275         // move + 10
00276         //rotate (client, device_actarray, current_actuator, delta_rot, 0.1);
00277         mvprintw (21, 0, "Moving + with %d\n", delta_rot); refresh ();
00278         break;
00279         
00280       case 'p':
00281         // pause logging
00282         playerc_log_set_write_state (device_log, 0);
00283         mvprintw (20, 0, "Logging : disabled\n"); refresh ();
00284         break;
00285       case 'r':
00286         // resume logging
00287         if(log_filename_from_time)
00288           {
00289             gettimeofday(&t1, NULL);
00290             sprintf (logFileName, "%d.log", t1.tv_sec);
00291             playerc_log_set_filename (device_log, logFileName);
00292             playerc_log_set_write_state (device_log, 1);
00293             mvprintw (20, 0, "Logging : enabled\n"); refresh ();
00294           }
00295         else
00296           {
00297               mvprintw(20, 0, "This option not possible, use __\"b\"__ key to resume logging\n"); refresh();
00298           }
00299         break;
00300       case 'b':
00301         // resume logging, override custom log file
00302         // from g_options.log_filename;
00303         if(!log_filename_from_time)
00304           {
00305             //playerc_log_set_filename (device_log, g_options.log_filename.c_str());
00306             playerc_log_set_write_state (device_log, 1);
00307             mvprintw (20, 0, "Logging : enabled\n"); refresh ();
00308           }
00309         else
00310           {
00311             mvprintw(20, 0, "This option not possible, use __\"r\"__ key to resume logging\n"); refresh();
00312           }
00313         break;
00314       case 'h':
00315         // home
00316         homeall (client, device_actarray);
00317         break;
00318       case 'o':
00319         // home
00320         home (client, device_actarray, current_actuator);
00321         break;
00322       case 's':
00323         next_pos = go_to_pose(client, device_actarray, g_options.rot_joint, g_options.start_angle, g_options.end_angle);
00324         sweep (client, device_actarray, g_options.rot_joint, next_pos, g_options.rot_speed);
00325         break;
00326       }
00327     mvprintw (23, 0, "Current actuator: %d\n", (current_actuator + 1)); refresh ();
00328   }
00329  
00330   printw ("unsubscribing\n");refresh ();
00331   playerc_actarray_unsubscribe (device_actarray);
00332   playerc_actarray_destroy (device_actarray);
00333   
00334   playerc_log_unsubscribe (device_log);
00335   playerc_log_destroy (device_log);
00336 
00337   playerc_laser_unsubscribe (device_laser);
00338   playerc_laser_destroy (device_laser);
00339   
00340   endwin ();
00341   return 0;
00342 }
00343 
00344 // ---[ Home one cube
00345 void
00346     home (playerc_client_t *client, playerc_actarray_t *device, int joint)
00347 {
00348     int i;
00349 
00350     playerc_actarray_home_cmd (device, joint);
00351     do {
00352         playerc_client_read (client);
00353         print_data (device);
00354     }   
00355     while ((device->actuators_data[joint].state != PLAYER_ACTARRAY_ACTSTATE_IDLE) &&
00356            (device->actuators_data[joint].state != PLAYER_ACTARRAY_ACTSTATE_BRAKED));
00357 }
00358 
00359 // ---[ Home all cubes
00360 void
00361     homeall (playerc_client_t *client, playerc_actarray_t *device)
00362 {
00363     int i;
00364     playerc_actarray_power (device, 1);
00365     
00366     for (i = 6; i > -1; i--)
00367     {
00368         playerc_actarray_home_cmd (device, i);
00369         mvprintw (21, 0, "Homing %d\n", i); refresh ();
00370         do {
00371             playerc_client_read (client);
00372             print_data (device);
00373         }       
00374         while ((device->actuators_data[i].state != PLAYER_ACTARRAY_ACTSTATE_IDLE) &&
00375                (device->actuators_data[i].state != PLAYER_ACTARRAY_ACTSTATE_BRAKED));
00376     }
00377 }
00378 
00379 // ---[ Sweep a cube
00380 void
00381     sweep (playerc_client_t *client, playerc_actarray_t *device, 
00382             int actuator, float next_pos, float speed)
00383 {
00384   // Set the speed to move with
00385   playerc_actarray_speed_config (device, actuator, speed);
00386   
00387   mvprintw (21, 0, "Sweeping. Next position is %f \n", next_pos); refresh ();
00388   playerc_actarray_position_cmd (device, actuator, DEG2RAD (next_pos));
00389 
00390 }
00391 
00392 //find the start_angle
00393 float
00394     go_to_pose (playerc_client_t *client, playerc_actarray_t *device, 
00395             int actuator, float min_angle, float max_angle)
00396 {
00397   float next_pos;
00398   int key;
00399   
00400    // Find the current position
00401   float current_pos = RAD2DEG (device->actuators_data[actuator].position);
00402   
00403   // Go to either min_angle or max_angle depending which one is closer
00404   if (current_pos < min_angle)
00405     next_pos = min_angle;
00406   
00407   if (current_pos > max_angle)
00408     next_pos = max_angle;
00409   
00410   if (fabs (current_pos - min_angle) > fabs (current_pos - max_angle))
00411     next_pos = max_angle;
00412   else
00413     next_pos = min_angle;
00414   
00415   mvprintw (21, 0, "Init sweeping to: %f (dist to min: %f, dist to max:  %f) \n", next_pos, fabs (current_pos - min_angle), fabs (current_pos - max_angle)); refresh ();
00416   
00417   playerc_actarray_position_cmd (device, actuator, DEG2RAD (next_pos));
00418   // Loop until the actuator is idle-ing or break-ed.
00419   do {
00420     playerc_client_read (client);
00421     print_data (device);
00422     current_pos = RAD2DEG (device->actuators_data[actuator].position);
00423   }     
00424   while ( (fabs (current_pos - next_pos) > EPS) || (
00425                                                     (device->actuators_data[actuator].state != PLAYER_ACTARRAY_ACTSTATE_IDLE) &&
00426                                                     (device->actuators_data[actuator].state != PLAYER_ACTARRAY_ACTSTATE_BRAKED))
00427           );
00428     
00429   if (next_pos == max_angle)
00430     next_pos = min_angle;
00431   else
00432     next_pos = max_angle;
00433   
00434   return next_pos;
00435 }
00436 
00437 // ---[ Move a cube
00438 void
00439     rotate (playerc_client_t *client, playerc_actarray_t *device, 
00440             int actuator, float angle, float speed)
00441 {
00442     float next_pos;
00443 
00444     // Set the speed to move with
00445     //playerc_actarray_speed_config (device, actuator, speed);
00446     
00447     // Find the current position
00448     float current_pos = RAD2DEG (device->actuators_data[actuator].position);
00449     next_pos = current_pos + angle;
00450     
00451     playerc_actarray_position_cmd (device, actuator, DEG2RAD (next_pos));
00452     // Loop until the actuator is idle-ing or break-ed.
00453     do {
00454         playerc_client_read (client);
00455         print_data (device);
00456     }
00457     while ((device->actuators_data[actuator].state != PLAYER_ACTARRAY_ACTSTATE_IDLE) &&
00458            (device->actuators_data[actuator].state != PLAYER_ACTARRAY_ACTSTATE_BRAKED));
00459 }
00460 
00461 //print data to stdio
00462 void
00463     print_data (playerc_actarray_t *device)
00464 {
00465     int i;
00466     for (i = 0; i < device->actuators_count; i++)
00467     {
00468       mvprintw (10+i, 0, "X%d> pos, speed, accel, cur, state  : [%f, %f, %f, %f, %d]\n", (i+1), 
00469             RAD2DEG (device->actuators_data[i].position), 
00470             device->actuators_data[i].speed, 
00471             device->actuators_data[i].acceleration, 
00472             device->actuators_data[i].current, 
00473             device->actuators_data[i].state); refresh ();
00474     }
00475 }
00476 
00477 void 
00478 laser_power_on_off(playerc_client_t *client, playerc_laser_t *device_laser, bool sw)
00479 {
00480   //turn laser power on and off
00481   player_laser_power_config_t power_rq;
00482   power_rq.state = sw;
00483   void * dummy; 
00484   playerc_client_request(client, &device_laser->info, PLAYER_LASER_REQ_POWER,
00485                          reinterpret_cast <void *>(&power_rq), 
00486                          NULL);
00487  }
00488 
00489 //print CLI usage
00490 void usage_ ()
00491  {
00492    fprintf(stderr, "Usage: %s [options]\n", g_options.program);
00493    fprintf(stderr, "  Available options\n");
00494    fprintf(stderr, "    -i, --interface <0-right|1-left>\n");
00495    fprintf(stderr, "    -s, --start_angle\n");
00496    fprintf(stderr, "    -e, --end_angle\n");
00497    fprintf(stderr, "    -j, --rot_joint <0-5>\n");
00498    fprintf(stderr, "    -v, --rot_speed <rad/s>\n");
00499    fprintf(stderr, "    -f, --log_filename \n");
00500    fprintf(stderr, "    -h, --help Print this message and exit\n");
00501    exit(0);
00502  }


player_log_actarray
Author(s): Radu Bogdan Rusu
autogenerated on Mon Oct 6 2014 09:38:35