sensor_filter.cpp
Go to the documentation of this file.
00001 #include "pr2_overhead_grasping/sensor_filter.h"
00002 #include <pluginlib/class_list_macros.h>
00003 #include "omp.h"
00004 PLUGINLIB_DECLARE_CLASS(collision_detection, sensor_filter, collision_detection::SensorFilter, nodelet::Nodelet)
00005 
00006 namespace collision_detection {
00007   float compGauss(float sigma, float x) {
00008     return exp(-x*x / (2 * sigma * sigma));
00009   }
00010 
00011   int mod_wrap(long x, int n) {
00012     while(x < 0)
00013       x += n;
00014     return x % n;
00015   }
00016 
00017   void SensorFilter::onInit() {
00019     // constants defined
00020     //         position   effort   accel   pressuresums pos_errors
00021     num_sensors = 7 +       7 +      3 +        4 +          7;
00022     num_scales = 8;
00023     rate = 100;
00024     // doog_diffs_1 = {1, 2, 3, 6, 13, 26, 51, 102};
00026     
00028     // create filters
00029     sigmas = new float[num_scales];
00030     float sigma_mult = 0.8;
00031     float filter_start = 2.0;
00032 
00033     filters = new float*[num_scales];
00034     // these first values don't extrapolate well
00035     filters[0] = new float[1];
00036     filters[0][0] = 1.0;
00037     sigmas[0] = sigma_mult*1;
00038     filters[1] = new float[2];
00039     filters[1][0] = 0.5;
00040     filters[1][1] = 0.5;
00041     sigmas[1] = sigma_mult*2;
00042     filters[2] = new float[4];
00043     filters[2][0] = 0.18;
00044     filters[2][1] = 0.32;
00045     filters[2][2] = 0.32;
00046     filters[2][3] = 0.18;
00047     sigmas[2] = sigma_mult*4;
00048 
00049     int filter_len = 8;
00050     for(int i=3;i<num_scales;i++) {
00051       filters[i] = new float[filter_len];
00052       float x = filter_start * filter_len;
00053       float step = 2 * x / (filter_len - 1);
00054       float sigma = sigma_mult * filter_len;
00055       sigmas[i] = sigma;
00056       x = -x;
00057 
00058       float filter_sum = 0.0;
00059       // set filter values
00060       for(int j=0;j<filter_len;j++) {
00061         filters[i][j] = compGauss(sigma, x);
00062         filter_sum += filters[i][j];
00063         x += step;
00064       }
00065       // normalize filter
00066       for(int j=0;j<filter_len;j++) {
00067         filters[i][j] /= filter_sum;
00068       }
00069 
00070       buffer_len = filter_len;
00071       filter_len *= 2;
00072     }
00074 
00076     // instantiate arrays
00077     buffer = new float*[buffer_len];
00078     for(int i=0;i<buffer_len;i++) 
00079       buffer[i] = new float[num_sensors];
00080 
00081     filtered_buffer = new float**[buffer_len];
00082     for(int i=0;i<buffer_len;i++) {
00083       filtered_buffer[i] = new float*[num_sensors];
00084       for(int j=0;j<num_sensors;j++)
00085         filtered_buffer[i][j] = new float[num_scales];
00086     }
00088 
00090     // initialize variables
00091     cur_iter = 0;
00092     js_in = false; acc_in = false; press_in = false; error_in = false;
00094 
00095     // start loop
00096     sf_thread = boost::thread(&SensorFilter::startOnline, this);
00097   }
00098 
00099   void SensorFilter::applyFilter() {
00100     //double in = ros::Time::now().toSec();
00101     for(int n=0;n<num_sensors;n++) {
00102       int filter_len = 1;
00103       for(int i=0;i<num_scales;i++) {
00104         filtered_buffer[mod_wrap(cur_iter, buffer_len)][n][i] = 0.0;
00105         for(int j=0;j<filter_len;j++) {
00106           filtered_buffer[mod_wrap(cur_iter, buffer_len)][n][i] += buffer[mod_wrap(cur_iter - j, buffer_len)][n] * filters[i][j];
00107         }
00108         filter_len *= 2;
00109       }
00110     }
00111     //double out = ros::Time::now().toSec();
00112     //NODELET_INFO("Filter time: %f", 1000000000.0 * (out-in));
00113   }
00114 
00115   const int doog_diffs_1[] = {0, 1, 1, 3, 6, 13, 25, 51};
00116   const int doog_diffs_2[] = {1, 1, 2, 3, 7, 13, 26, 51};
00117 
00118 
00119   void SensorFilter::startOnline() {
00120     ros::NodeHandle nh = getMTNodeHandle();
00121     ros::NodeHandle nh_priv = getMTPrivateNodeHandle();
00122     ros::Publisher pub;
00123     std::string pub_topic, arm_str;
00124     nh_priv.getParam("arm", arm_str);
00125     arm_ = arm_str[0];
00126 
00127     if(arm_ == 'r') {
00128       js_sub = nh.subscribe("joint_states", 1, 
00129                             &SensorFilter::jsCallback, this);
00130       acc_sub = nh.subscribe("accelerometer/r_gripper_motor", 1, 
00131                              &SensorFilter::accCallback, this);
00132       press_sub = nh.subscribe("pressure/r_gripper_motor", 1, 
00133                                &SensorFilter::pressCallback, this);
00134       error_sub = nh.subscribe("r_arm_controller/state", 1, 
00135                                &SensorFilter::errorCallback, this);
00136 
00137       pub_topic.assign("r_arm_features");
00138       pub = nh.advertise<pr2_overhead_grasping::SensorPoint>("r_arm_features", 2);
00139     } else {
00140       js_sub = nh.subscribe("joint_states", 1, 
00141                             &SensorFilter::jsCallback, this);
00142       acc_sub = nh.subscribe("accelerometer/l_gripper_motor", 1, 
00143                              &SensorFilter::accCallback, this);
00144       press_sub = nh.subscribe("pressure/l_gripper_motor", 1, 
00145                                &SensorFilter::pressCallback, this);
00146       error_sub = nh.subscribe("l_arm_controller/state", 1, 
00147                                &SensorFilter::errorCallback, this);
00148 
00149       pub_topic.assign("l_arm_features");
00150       pub = nh.advertise<pr2_overhead_grasping::SensorPoint>("l_arm_features", 2);
00151     }
00152 
00153     zeroBuffer();
00154 
00155     ros::Rate r(rate);
00156     int seq = 0;
00157     int ind, f_ind;
00158     ROS_INFO("[sensor_filter] Sensor filter is publishing on %s", pub_topic.c_str());
00159     while(ros::ok()) {
00160       // Call callbacks to get most recent data
00161       ros::spinOnce();
00162       recordData(); // saves data to buffers
00163       applyFilter(); // applys filter to buffers and saves in filtered_buffer
00164 
00165       // create SensorPoint object
00166       boost::shared_ptr<pr2_overhead_grasping::SensorPoint> sp(new pr2_overhead_grasping::SensorPoint);
00167       sp->header.seq = seq;
00168       sp->header.stamp = ros::Time::now();
00169       sp->header.frame_id = "";
00170 
00172       // Add features:
00173       // For 8 scales:
00174       // Raw: n
00175       // Gaussian: n * 28
00176       // DOOG: n * 20
00177       // DOG: n * 20
00178       // 
00179       // Total: n * 69
00180       // If n = 28 then total = 1932
00181       // Difference features start: 812
00182       // Raw 0, Gauss 28, DOOG 812, DOG 1372
00183 
00184       int st_ind = 0;
00185       ind = 0; f_ind = 0;
00186       // add raw data
00187       for(int n=0;n<num_sensors;n++)
00188         sp->raw_data.push_back(buffer[mod_wrap(cur_iter, buffer_len)][n]);
00189       /*int b_len = 1;
00190       for(int i=0;i<num_scales;i++) {
00191         sp->data[ind++] = filters[i][mod_wrap(cur_iter, b_len)];
00192         b_len *= 2;
00193       }*/
00194 
00195       //ROS_INFO("RAW FEATURES: %d, ind %d", ind - st_ind, ind);
00196       st_ind = ind;
00197 
00198       // add gaussian features
00199       // x = s - 1; x * (x + 1) / 2
00200       // s = 8; num_features = 28/n
00201       for(int n=0;n<num_sensors;n++) {
00202         int center_offset = 1;
00203         for(int i=1;i<num_scales;i++) { // offset iteration
00204           int scale_len = 1;
00205           for(int j=0;j<i;j++) { // length of half of smaller filter
00206             sp->gaussians.push_back(filtered_buffer[mod_wrap(cur_iter - center_offset + scale_len, buffer_len)][n][i]);
00207             scale_len *= 2;
00208           }
00209           center_offset *= 2;
00210         }
00211       }
00212       //ROS_INFO("GAUSS FEATURES: %d, ind %d", ind - st_ind, ind);
00213       st_ind = ind;
00214 
00216       // Simple bug to fix eventually:
00217       // These loops:
00218       // for(int j=1;j<num_scales-2;j++) { 
00219       // should go to num_scales-1
00220       // this is not a big deal, it just means that only num_scales-2 features (6)
00221       // are really being used (2 - 64) lengths
00222       // note: use better variable names in the future...
00224 
00225       // compute DOOG features
00226       // x = s - 2; x * (x + 1) / 2
00227       // s = 8; num_features = 21/n
00228       for(int n=0;n<num_sensors;n++) {
00229         int scale_len = 1; // length of half of both filters
00230         for(int j=1;j<num_scales-2;j++) { // scale iteration
00231           int center_offset = 2;
00232           for(int i=0;i<num_scales-1-j;i++) { // offset iteration
00233             sp->features.push_back(filtered_buffer[mod_wrap(cur_iter - center_offset + scale_len + doog_diffs_2[j], buffer_len)][n][j] - filtered_buffer[mod_wrap(cur_iter - center_offset  + scale_len - doog_diffs_1[j], buffer_len)][n][j]);
00234             //if(n == 0)
00235             //  ROS_INFO("center %d, scale_len %d, i %d, sum %d, sum2 %d", center_offset, scale_len, j, - center_offset + scale_len + doog_diffs_2[j], - center_offset  + scale_len - doog_diffs_1[j]);
00236             center_offset *= 2;
00237           }
00238           scale_len *= 2;
00239         }
00240         sp->split_inds1.push_back(sp->features.size());
00241         if(n+1 == 3 || n+1 == 10 || n+1 == 17 || n+1 == 21)
00242           sp->split_inds2.push_back(sp->features.size());
00243       }
00244       sp->split_inds1.pop_back();
00245       sp->split_inds3.push_back(sp->features.size());
00246       //ROS_INFO("DOOG FEATURES: %d, ind %d", ind - st_ind, ind);
00247       st_ind = ind;
00248 
00249       // compute DOG features
00250       // x = s - 2; x * (x + 1) / 2
00251       // s = 8; num_features = 21/n
00252       for(int n=0;n<num_sensors;n++) {
00253         int scale_len = 1; // length of half of smaller filter
00254         for(int j=1;j<num_scales-2;j++) { // scale iteration
00255           int center_offset = 2;
00256           for(int i=0;i<num_scales-1-j;i++) { // offset iteration
00257             sp->features.push_back(filtered_buffer[mod_wrap(cur_iter - center_offset + scale_len * 2, buffer_len)][n][j+1] - filtered_buffer[mod_wrap(cur_iter - center_offset + scale_len, buffer_len)][n][j]);
00258             ind++;
00259             center_offset *= 2;
00260           }
00261           scale_len *= 2;
00262         }
00263         sp->split_inds1.push_back(sp->features.size());
00264         if(n == 3 || n == 10 || n == 17 || n == 21)
00265           sp->split_inds2.push_back(sp->features.size());
00266       }
00267       sp->split_inds1.pop_back();
00268       sp->split_inds3.push_back(sp->features.size());
00269       //ROS_INFO("DOG FEATURES: %d, ind %d", ind - st_ind, ind);
00270       st_ind = ind;
00271 
00272       // add gaussian features for error
00273       // x = s - 1; x * (x + 1) / 2
00274       // s = 8; num_features = 28/n
00275       for(int n=21;n<num_sensors;n++) {
00276         int center_offset = 1;
00277         for(int i=1;i<num_scales-1;i++) { // offset iteration
00278           int scale_len = 1;
00279           for(int j=0;j<i;j++) { // length of half of smaller filter
00280             sp->features.push_back(filtered_buffer[mod_wrap(cur_iter - center_offset + scale_len, buffer_len)][n][i]);
00281             ind++;
00282             scale_len *= 2;
00283           }
00284           center_offset *= 2;
00285         }
00286         sp->split_inds1.push_back(sp->features.size());
00287       }
00288       sp->split_inds1.pop_back();
00289 
00290       //ROS_INFO("%d", ind);
00291       pub.publish(sp);
00292 
00293       r.sleep();
00294       cur_iter++;
00295     }
00296 
00297     ROS_INFO("[sensor_filter] Sensor filter stopping");
00298   }
00299 
00300   int JOINTSTATE_INDS_R[] = {17, 18, 16, 20, 19, 21, 22};
00301   int JOINTSTATE_INDS_L[] = {29, 30, 28, 32, 31, 33, 34};
00302 
00303   void SensorFilter::recordData() {
00304     int ind = 0;
00305     int* js_inds;
00306     if(arm_ == 'r')
00307       js_inds = JOINTSTATE_INDS_R;
00308     else
00309       js_inds = JOINTSTATE_INDS_L;
00310       
00311     // accelerometer data
00312 
00313     // average out samples
00314     float avg[3] = {0.0, 0.0, 0.0};
00315     for(uint32_t j=0;j<acc_msg->samples.size();j++) {
00316       avg[0] += acc_msg->samples[j].x;
00317       avg[1] += acc_msg->samples[j].y;
00318       avg[2] += acc_msg->samples[j].z;
00319     }
00320 
00321     for(int i=0;i<3;i++) {
00322       avg[i] /= acc_msg->samples.size();
00323       buffer[mod_wrap(cur_iter, buffer_len)][ind++] = avg[i];
00324     }
00325 
00326     // joint angles
00327     for(int i=0;i<7;i++) 
00328       buffer[mod_wrap(cur_iter, buffer_len)][ind++] = js_msg->position[js_inds[i]];
00329 
00330     // joint efforts
00331     for(int i=0;i<7;i++) 
00332       buffer[mod_wrap(cur_iter, buffer_len)][ind++] = js_msg->effort[js_inds[i]];
00333 
00334     // pressure data
00335     float r_periph_sum = 0.0, r_pad_sum = 0.0;
00336     float l_periph_sum = 0.0, l_pad_sum = 0.0;
00337     // periphery sensor sums (around the edge)
00338     for(int i=1;i<7;i++) {
00339       r_periph_sum += press_msg->r_finger_tip[i];
00340       l_periph_sum += press_msg->l_finger_tip[i];
00341     }
00342     // pad sensor sums (in the middle)
00343     for(int i=7;i<22;i++) {
00344       r_pad_sum += press_msg->r_finger_tip[i];
00345       l_pad_sum += press_msg->l_finger_tip[i];
00346     }
00347     buffer[mod_wrap(cur_iter, buffer_len)][ind++] = r_periph_sum;
00348     buffer[mod_wrap(cur_iter, buffer_len)][ind++] = l_periph_sum;
00349     buffer[mod_wrap(cur_iter, buffer_len)][ind++] = r_pad_sum;
00350     buffer[mod_wrap(cur_iter, buffer_len)][ind++] = l_pad_sum;
00351 
00352     // controller errors
00353     for(int i=0;i<7;i++) 
00354       buffer[mod_wrap(cur_iter, buffer_len)][ind++] = error_msg->error.positions[i];
00355 
00356   }
00357 
00358   void SensorFilter::zeroBuffer() {
00359     ros::Rate r(200);
00360     while(ros::ok()) {
00361       ros::spinOnce();
00362       if(js_in && acc_in && press_in && error_in)
00363         break;
00364       r.sleep();
00365     }
00366 
00367     for(int i=0;i<buffer_len;i++)
00368       for(int j=0;j<num_sensors;j++) 
00369         buffer[i][j] = buffer[cur_iter][j]; // just use initial value for right now
00370   }
00371 
00372   void SensorFilter::jsCallback(JointState::ConstPtr message) {
00373     js_in = true;
00374     js_msg = message;
00375   }
00376 
00377   void SensorFilter::accCallback(AccelerometerState::ConstPtr message) {
00378     acc_in = true;
00379     acc_msg = message;
00380   }
00381 
00382   void SensorFilter::pressCallback(PressureState::ConstPtr message) {
00383     press_in = true;
00384     press_msg = message;
00385   }
00386 
00387   void SensorFilter::errorCallback(JointTrajectoryControllerState::ConstPtr message) {
00388     error_in = true;
00389     error_msg = message;
00390   }
00391 
00392   SensorFilter::~SensorFilter() {
00393     sf_thread.interrupt();
00394   }
00395 }


kelsey_sandbox
Author(s): kelsey
autogenerated on Wed Nov 27 2013 11:52:04