Visual Servoing Platform  version 3.6.1 under development (2024-07-27)
ClassUsingPclViewer.cpp
1 #include "ClassUsingPclViewer.h"
3 
4 #if defined(VISP_HAVE_PCL) && defined(VISP_HAVE_PCL_IO)
5 // PCL
6 #include <pcl/io/pcd_io.h>
7 
8 // Visp
9 #include <visp3/core/vpTime.h>
10 #include <visp3/core/vpGaussRand.h>
11 #include <visp3/core/vpRobust.h>
12 #include <visp3/gui/vpColorBlindFriendlyPalette.h>
13 #include <visp3/io/vpKeyboard.h>
14 
15 #ifdef ENABLE_VISP_NAMESPACE
16 using namespace VISP_NAMESPACE_NAME;
17 #endif
18 
20 double zFunction(const double &x, const double &y, const unsigned int order)
21 {
22  const double offset(0.5);
23  double z(0.);
24 
25  for (unsigned int n = 0; n <= order; n++) {
26  for (unsigned int k = 0; k <= order - n; k++) {
27  if (k + n > 0) {
28  z += std::pow(x, n) * std::pow(y, k);
29  }
30  else {
31  z += offset;
32  }
33  }
34  }
35 
36  return z;
37 }
39 
41 ClassUsingPclViewer::ClassUsingPclViewer(std::pair<double, double> xlimits, std::pair<double, double> ylimits, std::pair<unsigned int, unsigned int> nbPoints)
42  : m_t(0.1, 0.1, 0.1)
43  , m_R(M_PI_4, M_PI_4, M_PI_4)
44  , m_cMo(m_t, m_R)
45  , m_minX(xlimits.first)
46  , m_maxX(xlimits.second)
47  , m_n(nbPoints.first)
48  , m_minY(ylimits.first)
49  , m_maxY(ylimits.second)
50  , m_m(nbPoints.second)
51  , m_visualizer("Grid of points with / without robust")
52 {
53  m_dX = (m_maxX - m_minX) / (static_cast<double>(m_n) - 1.);
54  m_dY = (m_maxY - m_minY) / (static_cast<double>(m_m) - 1.);
55 }
57 
59 {
60 
61 }
62 
64 std::pair<vpPclViewer::pclPointCloudPointXYZRGBPtr, vpPclViewer::pclPointCloudPointXYZRGBPtr> ClassUsingPclViewer::generateControlPoints(const double &addedNoise, const unsigned int &order, vpColVector &confidenceWeights)
65 {
66  std::pair<vpPclViewer::pclPointCloudPointXYZRGBPtr, vpPclViewer::pclPointCloudPointXYZRGBPtr> result;
67 
68  // Create control points
71 
72  // Initializing confindence weights
73  confidenceWeights.resize(m_m * m_n);
74 
75  // Noise generator for the observed points
76  // We deriberately choose to set the standard deviation to be twice the tolerated value to observe rejected points
77  vpGaussRand r;
78  r.setSigmaMean(addedNoise * 2., 0.);
80 
81  // Residual vector to compute the confidence weights
82  vpColVector residuals(m_m * m_n);
83 
84  for (unsigned int j = 0; j < m_m; j++) {
85  for (unsigned int i = 0; i < m_n; i++) {
86  // Creating model, expressed in the object frame
87  double oX = m_minX + (double)i * m_dX;
88  double oY = m_minY + (double)j * m_dY;
89  double oZ = zFunction(oX, oY, order);
90 
91  // Setting the point coordinates of the first point cloud in
92  // the object frame
93  std::vector<double> point = { oX, oY, oZ,1. };
94  vpColVector oCoords = vpColVector(point);
95  (*unrotatedControlPoints)(i, j).x = oCoords[0];
96  (*unrotatedControlPoints)(i, j).y = oCoords[1];
97  (*unrotatedControlPoints)(i, j).z = oCoords[2];
98 
99  // Moving the point into another coordinate frame
100  vpColVector cCoords = m_cMo * oCoords;
101  (*rotatedControlPoints)(i, j).x = cCoords[0];
102  (*rotatedControlPoints)(i, j).y = cCoords[1];
103 
104  // Potentially adding some noise if the user asked to
105  double noise = r();
106  (*rotatedControlPoints)(i, j).z = cCoords[2] + noise;
107 
108  // Filling the confidence weights with default value of 1.
109  confidenceWeights[j * m_n + i] = 1.;
110 
111  // Indicating the residual, here it corresponds to the difference
112  // between the theoretical position of the point and the actual one
113  residuals[j * m_n + i] = noise;
114  }
115  }
116 
117  if (std::abs(addedNoise) > 0.) {
118  // Estimating the confidence weights to remove points suffering too much noise
119  // See vpRobust documentation for more information.
120  vpRobust robust;
121  robust.setMinMedianAbsoluteDeviation(addedNoise);
122  robust.MEstimator(vpRobust::TUKEY, residuals, confidenceWeights);
123  }
124 
125  result.first = unrotatedControlPoints;
126  result.second = rotatedControlPoints;
127  return result;
128 }
130 
131 void ClassUsingPclViewer::blockingMode(const double &addedNoise, const unsigned int &order)
132 {
133  // Confidence weights, that would be obtained thanks to vpRobust for instance
134  vpColVector confWeights;
135 
137  std::pair<vpPclViewer::pclPointCloudPointXYZRGBPtr, vpPclViewer::pclPointCloudPointXYZRGBPtr> grids = generateControlPoints(addedNoise, order, confWeights);
139 
141  // Adding a point cloud for which we don't chose the color
142  unsigned int id_ctrlPts = m_visualizer.addSurface(grids.first, "Standard");
144 
146  // Adding a point cloud for which we chose the color
148  unsigned int id_robust = m_visualizer.addSurface(grids.second, confWeights, "RotatedWithRobust", color.to_RGB());
150 
151  std::cout << "Press \"q\" while selecting the viewer window to stop the program." << std::endl;
153  m_visualizer.display();
155 
156  (void)id_ctrlPts;
157  (void)id_robust;
158 }
159 
160 void ClassUsingPclViewer::threadedMode(const double &addedNoise, const unsigned int &order)
161 {
162  // Confidence weights, that would be obtained thanks to vpRobust for instance
163  vpColVector confWeights;
164 
165  // Create control points
166  std::pair<vpPclViewer::pclPointCloudPointXYZRGBPtr, vpPclViewer::pclPointCloudPointXYZRGBPtr> grids = generateControlPoints(addedNoise, order, confWeights);
167 
168  // Adding a point cloud for which we don't chose the color
169  unsigned int id_ctrlPts = m_visualizer.addSurface(grids.first, "Standard");
170 
171  // Adding a point cloud for which we chose the color
173  unsigned int id_robust = m_visualizer.addSurface(grids.second, confWeights, "RotatedWithRobust", color.to_RGB());
174 
176  m_visualizer.launchThread();
178 
179  m_visualizer.updateSurface(grids.first, id_ctrlPts);
180  m_visualizer.updateSurface(grids.second, id_robust, confWeights);
181 
182  vpKeyboard keyboard;
183  bool wantToStop = false;
184  double t;
185 
186  std::cout << "Press any key in the console to stop the program." << std::endl;
187  while (!wantToStop) {
188  t = vpTime::measureTimeMs();
189  grids = generateControlPoints(addedNoise, order, confWeights);
190 
192  m_visualizer.updateSurface(grids.first, id_ctrlPts);
193  m_visualizer.updateSurface(grids.second, id_robust, confWeights);
195 
196  if (keyboard.kbhit()) {
197  wantToStop = true;
198  }
199  vpTime::wait(t, 40);
200  }
201 
202 }
203 #else
204 void dummy_class_using_pcl_visualizer()
205 { }
206 #endif
void threadedMode(const double &addedNoise, const unsigned int &order)
Demonstration on how to use a vpPclViewer in threaded mode.
~ClassUsingPclViewer()
[Constructor]
ClassUsingPclViewer(std::pair< double, double > xlimits={ -2.5, 2.5 }, std::pair< double, double > ylimits={ -2.5, 2.5 }, std::pair< unsigned int, unsigned int > nbPoints={ 50, 50 })
Construct a new object.
void blockingMode(const double &addedNoise, const unsigned int &order)
Demonstration on how to use a vpPclViewer in blocking mode, i.e. we expect an input from the user aft...
Implementation of column vector and the associated operations.
Definition: vpColVector.h:191
void resize(unsigned int i, bool flagNullify=true)
Definition: vpColVector.h:1143
Class that furnishes a set of colors that color blind people should be able to distinguish one from a...
std::vector< unsigned char > to_RGB() const
Cast a vpColorBlindFriendlyPalette in a vector {R, G, B}. A vpColorBlindFriendlyPalette::Palette::COU...
Class for generating random number with normal probability density.
Definition: vpGaussRand.h:117
void setSigmaMean(double sigma_val, double mean_val)
Definition: vpGaussRand.h:141
void seed(long seed_val)
Definition: vpGaussRand.h:152
Keyboard management under unix (Linux or OSX). This class is not available under windows.
Definition: vpKeyboard.h:83
int kbhit()
Definition: vpKeyboard.cpp:93
void display()
Blocking-mode display of the viewer.
pcl::PointCloud< pclPointXYZRGB > pclPointCloudPointXYZRGB
Definition: vpPclViewer.h:72
void launchThread()
Start the drawing thread that permits to have a non-blocking display.
pclPointCloudPointXYZRGB::Ptr pclPointCloudPointXYZRGBPtr
Definition: vpPclViewer.h:73
void updateSurface(const pclPointCloudPointXYZRGB::Ptr &surface, const unsigned int &id, const bool &hasToKeepColor=false)
Update the surface known by id by the viewer.
unsigned int addSurface(const pclPointCloudPointXYZRGB::Ptr &surface, const std::string &name="", const std::vector< unsigned char > &v_color=std::vector< unsigned char >())
Add a surface to the list of point clouds known by the viewer.
Contains an M-estimator and various influence function.
Definition: vpRobust.h:84
@ TUKEY
Tukey influence function.
Definition: vpRobust.h:89
void MEstimator(const vpRobustEstimatorType method, const vpColVector &residues, vpColVector &weights)
Definition: vpRobust.cpp:130
void setMinMedianAbsoluteDeviation(double mad_min)
Definition: vpRobust.h:136
VISP_EXPORT int wait(double t0, double t)
VISP_EXPORT double measureTimeMicros()
VISP_EXPORT double measureTimeMs()