sampling.cpp
Go to the documentation of this file.
00001 #include "handle_detector/sampling.h"
00002 
00003 // sampling methods
00004 const int SUM = 1;
00005 const int MAX = 2;
00006 
00007 const int Sampling::NUM_ITERATIONS = 10;
00008 const int Sampling::NUM_SAMPLES = 100;
00009 const int Sampling::NUM_INIT_SAMPLES = 100;
00010 const double Sampling::PROB_RAND_SAMPLES = 0.2;
00011 const bool Sampling::VISUALIZE_STEPS = false;
00012 const int Sampling::METHOD = SUM;
00013 
00014 void Sampling::illustrate(const PointCloud::Ptr &cloud, const PointCloudRGB::Ptr &cloudrgb, double target_radius)
00015 {
00016   // parameters
00017   int num_samples = 200;
00018   int num_init_samples = 1000;
00019   double sigma = 2.0 * target_radius;
00020 
00021   // find initial affordances
00022   std::vector<int> indices = this->affordances.createRandomIndices(cloud, num_init_samples);
00023   std::vector<CylindricalShell> all_shells = this->affordances.searchAffordances(cloud, indices);
00024 
00025   double term = 1.0 / sqrt(pow(2.0 * M_PI, 3.0) * pow(sigma, 3.0));
00026 
00027   // create random generator for normal distribution
00028   boost::mt19937 *rng = new boost::mt19937();
00029   rng->seed(time(NULL));
00030   boost::normal_distribution<> distribution(0.0, 1.0);
00031   boost::variate_generator<boost::mt19937, boost::normal_distribution<> > generator(*rng, distribution);
00032 
00033   // sum of Gaussians
00034   Eigen::MatrixXd samples_sum(3, num_samples);
00035   for (int j = 0; j < num_samples; j++)
00036   {
00037     int idx = rand() % all_shells.size();
00038     samples_sum(0, j) = all_shells[idx].getCentroid()(0) + generator() * sigma;
00039     samples_sum(1, j) = all_shells[idx].getCentroid()(1) + generator() * sigma;
00040     samples_sum(2, j) = all_shells[idx].getCentroid()(2) + generator() * sigma;
00041   }
00042 
00043   // max of Gaussians
00044   Eigen::MatrixXd samples_max(3, num_samples);
00045   int j = 0;
00046   int count[all_shells.size()];
00047   for (std::size_t k = 0; k < all_shells.size(); k++)
00048     count[k] = 0;
00049   while (j < num_samples) // draw samples using rejection sampling
00050   {
00051     // draw from sum of Gaussians
00052     int idx = rand() % all_shells.size();
00053     Eigen::Vector3d x;
00054     x(0) = all_shells[idx].getCentroid()(0) + generator() * sigma;
00055     x(1) = all_shells[idx].getCentroid()(1) + generator() * sigma;
00056     x(2) = all_shells[idx].getCentroid()(2) + generator() * sigma;
00057 
00058     double maxp = 0;
00059     for (std::size_t k = 0; k < all_shells.size(); k++)
00060     {
00061       double p = (x - all_shells[k].getCentroid()).transpose() * (x - all_shells[k].getCentroid());
00062       p = term * exp((-1.0 / (2.0 * sigma)) * p);
00063       if (p > maxp)
00064         maxp = p;
00065     }
00066 
00067     double p = (x - all_shells[idx].getCentroid()).transpose() * (x - all_shells[idx].getCentroid());
00068     p = term * exp((-1.0 / (2.0 * sigma)) * p);
00069     if (p >= maxp)
00070     {
00071       samples_max.col(j) = x;
00072       count[idx]++;
00073       j++;
00074     }
00075   }
00076 
00077   SamplingVisualizer sum_visualizer;
00078   sum_visualizer.createViewerRGB(cloudrgb, all_shells, samples_sum, target_radius);
00079   sum_visualizer.getViewer()->setSize(800, 600);
00080   sum_visualizer.getViewer()->setCameraPosition(0.255106, -0.903705, -0.538521, 0.255053, -0.902864, -0.537242,
00081                                                 -0.0206334, -0.835517, 0.549076);
00082   sum_visualizer.getViewer()->addText("Samples drawn from sum of Gaussians", 10, 20, 16, 1.0, 1.0, 1.0);
00083   while (!sum_visualizer.getViewer()->wasStopped())
00084   {
00085     sum_visualizer.getViewer()->spinOnce(100);
00086     boost::this_thread::sleep(boost::posix_time::microseconds(100000));
00087   }
00088 
00089   SamplingVisualizer max_visualizer;
00090   max_visualizer.createViewerRGB(cloudrgb, all_shells, samples_max, target_radius);
00091   max_visualizer.getViewer()->setSize(800, 600);
00092   max_visualizer.getViewer()->setCameraPosition(0.255106, -0.903705, -0.538521, 0.255053, -0.902864, -0.537242,
00093                                                 -0.0206334, -0.835517, 0.549076);
00094   max_visualizer.getViewer()->addText("Samples drawn from sum of Gaussians", 10, 20, 16, 1.0, 1.0, 1.0);
00095   while (!max_visualizer.getViewer()->wasStopped())
00096   {
00097     max_visualizer.getViewer()->spinOnce(100);
00098     boost::this_thread::sleep(boost::posix_time::microseconds(100000));
00099   }
00100 }
00101 
00102 std::vector<CylindricalShell> Sampling::searchAffordances(const PointCloud::Ptr &cloud,
00103                                                           const PointCloudRGB::Ptr &cloudrgb, double target_radius)
00104 {
00105   double start_time = omp_get_wtime();
00106   double sigma = 2.0 * target_radius;
00107 
00108   // find initial affordances
00109   std::vector<int> indices = this->affordances.createRandomIndices(cloud, num_init_samples);
00110   std::vector<CylindricalShell> all_shells = this->affordances.searchAffordances(cloud, indices);
00111 
00112   // visualize
00113   if (this->is_visualized)
00114   {
00115     Eigen::MatrixXd init_samples(3, num_init_samples);
00116     for (std::size_t i = 0; i < num_init_samples; i++)
00117     {
00118       init_samples(0, i) = cloudrgb->points[indices[i]].x;
00119       init_samples(1, i) = cloudrgb->points[indices[i]].y;
00120       init_samples(2, i) = cloudrgb->points[indices[i]].z;
00121     }
00122     std::vector<CylindricalShell> no_shells;
00123     no_shells.resize(0);
00124 
00125     SamplingVisualizer visualizer;
00126     visualizer.createViewerRGB(cloudrgb, no_shells, init_samples, target_radius);
00127     visualizer.getViewer()->setSize(800, 600);
00128     visualizer.getViewer()->setCameraPosition(0.255106, -0.903705, -0.538521, 0.255053, -0.902864, -0.537242,
00129                                               -0.0206334, -0.835517, 0.549076);
00130 
00131     while (!visualizer.getViewer()->wasStopped())
00132     {
00133       visualizer.getViewer()->spinOnce(100);
00134       boost::this_thread::sleep(boost::posix_time::microseconds(100000));
00135     }
00136   }
00137 
00138   int num_rand_samples = prob_rand_samples * num_samples;
00139   int num_gauss_samples = num_samples - num_rand_samples;
00140 
00141   Eigen::Matrix3d diag_sigma = Eigen::Matrix3d::Zero();
00142   diag_sigma.diagonal() << sigma, sigma, sigma;
00143   Eigen::Matrix3d inv_sigma = diag_sigma.inverse();
00144   double term = 1.0 / sqrt(pow(2.0 * M_PI, 3.0) * pow(sigma, 3.0));
00145 
00146   // create random generator for normal distribution
00147   boost::mt19937 *rng = new boost::mt19937();
00148   rng->seed(time(NULL));
00149   boost::normal_distribution<> distribution(0.0, 1.0);
00150   boost::variate_generator<boost::mt19937, boost::normal_distribution<> > generator(*rng, distribution);
00151   Eigen::MatrixXd samples(3, num_samples);
00152 
00153   // find affordances using importance sampling
00154   for (std::size_t i = 0; i < num_iterations; i++)
00155   {
00156     double iteration_start_time = omp_get_wtime();
00157 
00158     // draw samples close to affordances (importance sampling)
00159     if (this->method == SUM) // sum of Gaussians
00160     {
00161       for (std::size_t j = 0; j < num_gauss_samples; j++)
00162       {
00163         int idx = rand() % all_shells.size();
00164         samples(0, j) = all_shells[idx].getCentroid()(0) + generator() * sigma;
00165         samples(1, j) = all_shells[idx].getCentroid()(1) + generator() * sigma;
00166         samples(2, j) = all_shells[idx].getCentroid()(2) + generator() * sigma;
00167       }
00168     }
00169     else // max of Gaussians
00170     {
00171       int j = 0;
00172       while (j < num_gauss_samples) // draw samples using rejection sampling
00173       {
00174         // draw from sum of Gaussians
00175         int idx = rand() % all_shells.size();
00176         Eigen::Vector3d x;
00177         x(0) = all_shells[idx].getCentroid()(0) + generator() * sigma;
00178         x(1) = all_shells[idx].getCentroid()(1) + generator() * sigma;
00179         x(2) = all_shells[idx].getCentroid()(2) + generator() * sigma;
00180 
00181         double maxp = 0;
00182         for (std::size_t k = 0; k < all_shells.size(); k++)
00183         {
00184           double p = (x - all_shells[k].getCentroid()).transpose() * (x - all_shells[k].getCentroid());
00185           p = term * exp((-1.0 / (2.0 * sigma)) * p);
00186           if (p > maxp)
00187             maxp = p;
00188         }
00189 
00190         double p = (x - all_shells[idx].getCentroid()).transpose() * (x - all_shells[idx].getCentroid());
00191         p = term * exp((-1.0 / (2.0 * sigma)) * p);
00192         if (p >= maxp)
00193         {
00194           samples.col(j) = x;
00195           j++;
00196         }
00197       }
00198     }
00199 
00200     // draw random samples
00201     for (int j = num_samples - num_rand_samples; j < num_samples; j++)
00202     {
00203       int r = std::rand() % cloud->points.size();
00204       while (!pcl::isFinite((*cloud)[r])
00205           || !this->affordances.isPointInWorkspace(cloud->points[r].x, cloud->points[r].y, cloud->points[r].z))
00206         r = std::rand() % cloud->points.size();
00207       samples.col(j) = cloud->points[r].getVector3fMap().cast<double>();
00208     }
00209 
00210     // visualize
00211     if (is_visualized)
00212     {
00213       SamplingVisualizer visualizer;
00214 //      visualizer.createViewer(cloud, all_shells, samples, target_radius);
00215       visualizer.createViewerRGB(cloudrgb, all_shells, samples.block(0, 0, 3, num_gauss_samples), target_radius);
00216       visualizer.getViewer()->setSize(800, 600);
00217       visualizer.getViewer()->setCameraPosition(0.255106, -0.903705, -0.538521, 0.255053, -0.902864, -0.537242,
00218                                                 -0.0206334, -0.835517, 0.549076);
00219       visualizer.getViewer()->addText(
00220           "Iteration " + boost::lexical_cast < std::string > (i) + ", shells: " + boost::lexical_cast < std::string
00221               > (all_shells.size()) + ", num_gauss_samples: " + boost::lexical_cast < std::string
00222               > (num_gauss_samples) + ", num_rand_samples: " + boost::lexical_cast < std::string > (num_rand_samples),
00223           10, 20, 16, 1.0, 1.0, 1.0);
00224 
00225       while (!visualizer.getViewer()->wasStopped())
00226       {
00227         visualizer.getViewer()->spinOnce(100);
00228         boost::this_thread::sleep(boost::posix_time::microseconds(100000));
00229       }
00230     }
00231 
00232     // find affordances
00233     std::vector<CylindricalShell> shells = this->affordances.searchAffordancesTaubin(cloud, samples);
00234     all_shells.insert(all_shells.end(), shells.begin(), shells.end());
00235     printf("ELAPSED TIME (ITERATION %i): %.3f\n", (int)i, omp_get_wtime() - iteration_start_time);
00236   }
00237 
00238   printf("elapsed time (affordance search): %.3f sec, total # of affordances found: %i\n", omp_get_wtime() - start_time,
00239          (int)all_shells.size());
00240   return all_shells;
00241 }
00242 
00243 void Sampling::initParams(const ros::NodeHandle& node)
00244 {
00245   node.param("num_iterations", this->num_iterations, this->NUM_ITERATIONS);
00246   node.param("num_samples", this->num_samples, this->NUM_SAMPLES);
00247   node.param("num_init_samples", this->num_init_samples, this->NUM_INIT_SAMPLES);
00248   node.param("prob_rand_samples", this->prob_rand_samples, this->PROB_RAND_SAMPLES);
00249   node.param("visualize_steps", this->is_visualized, this->VISUALIZE_STEPS);
00250   node.param("sampling_method", this->method, this->METHOD);
00251 }


handle_detector
Author(s):
autogenerated on Fri Aug 28 2015 10:59:15