Main MRPT website > C++ reference for MRPT 1.9.9
CColouredPointsMap.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +------------------------------------------------------------------------+ */
9 
10 #include "maps-precomp.h" // Precomp header
11 
15 #include <mrpt/utils/color_maps.h>
16 #include <mrpt/system/os.h>
18 #include <mrpt/utils/CStream.h>
19 
20 #include "CPointsMap_crtp_common.h"
21 
22 using namespace std;
23 using namespace mrpt;
24 using namespace mrpt::maps;
25 using namespace mrpt::obs;
26 using namespace mrpt::utils;
27 using namespace mrpt::poses;
28 using namespace mrpt::system;
29 using namespace mrpt::math;
30 
31 // =========== Begin of Map definition ============
33  "CColouredPointsMap,colourPointsMap", mrpt::maps::CColouredPointsMap)
34 
36 void CColouredPointsMap::TMapDefinition::loadFromConfigFile_map_specific(
38  const std::string& sectionNamePrefix)
39 {
40  insertionOpts.loadFromConfigFile(
41  source, sectionNamePrefix + string("_insertOpts"));
42  likelihoodOpts.loadFromConfigFile(
43  source, sectionNamePrefix + string("_likelihoodOpts"));
44  colourOpts.loadFromConfigFile(
45  source, sectionNamePrefix + string("_colorOpts"));
46 }
47 
48 void CColouredPointsMap::TMapDefinition::dumpToTextStream_map_specific(
49  mrpt::utils::CStream& out) const
50 {
51  this->insertionOpts.dumpToTextStream(out);
52  this->likelihoodOpts.dumpToTextStream(out);
53  this->colourOpts.dumpToTextStream(out);
54 }
55 
56 mrpt::maps::CMetricMap* CColouredPointsMap::internal_CreateFromMapDefinition(
58 {
60  *dynamic_cast<const CColouredPointsMap::TMapDefinition*>(&_def);
62  obj->insertionOptions = def.insertionOpts;
63  obj->likelihoodOptions = def.likelihoodOpts;
64  obj->colorScheme = def.colourOpts;
65  return obj;
66 }
67 // =========== End of Map definition Block =========
68 
70 
71 #if MRPT_HAS_PCL
72 #include <pcl/io/pcd_io.h>
73 #include <pcl/point_types.h>
74 //# include <pcl/registration/icp.h>
75 #endif
76 
77 /*---------------------------------------------------------------
78  Constructor
79  ---------------------------------------------------------------*/
80 CColouredPointsMap::CColouredPointsMap() {}
81 /*---------------------------------------------------------------
82  Destructor
83  ---------------------------------------------------------------*/
84 CColouredPointsMap::~CColouredPointsMap() {}
85 /*---------------------------------------------------------------
86  reserve & resize methods
87  ---------------------------------------------------------------*/
88 void CColouredPointsMap::reserve(size_t newLength)
89 {
90  newLength = mrpt::utils::length2length4N(newLength);
91 
92  x.reserve(newLength);
93  y.reserve(newLength);
94  z.reserve(newLength);
95  m_color_R.reserve(newLength);
96  m_color_G.reserve(newLength);
97  m_color_B.reserve(newLength);
98 }
99 
100 // Resizes all point buffers so they can hold the given number of points: newly
101 // created points are set to default values,
102 // and old contents are not changed.
103 void CColouredPointsMap::resize(size_t newLength)
104 {
105  this->reserve(newLength); // to ensure 4N capacity
106 
107  x.resize(newLength, 0);
108  y.resize(newLength, 0);
109  z.resize(newLength, 0);
110  m_color_R.resize(newLength, 1);
111  m_color_G.resize(newLength, 1);
112  m_color_B.resize(newLength, 1);
113  mark_as_modified();
114 }
115 
116 // Resizes all point buffers so they can hold the given number of points,
117 // *erasing* all previous contents
118 // and leaving all points to default values.
119 void CColouredPointsMap::setSize(size_t newLength)
120 {
121  this->reserve(newLength); // to ensure 4N capacity
122 
123  x.assign(newLength, 0);
124  y.assign(newLength, 0);
125  z.assign(newLength, 0);
126  m_color_R.assign(newLength, 1);
127  m_color_G.assign(newLength, 1);
128  m_color_B.assign(newLength, 1);
129  mark_as_modified();
130 }
131 
132 /*---------------------------------------------------------------
133  Copy constructor
134  ---------------------------------------------------------------*/
135 void CColouredPointsMap::copyFrom(const CPointsMap& obj)
136 {
137  CPointsMap::base_copyFrom(
138  obj); // This also does a ::resize(N) of all data fields.
139 
140  const CColouredPointsMap* pCol =
141  dynamic_cast<const CColouredPointsMap*>(&obj);
142  if (pCol)
143  {
144  m_color_R = pCol->m_color_R;
145  m_color_G = pCol->m_color_G;
146  m_color_B = pCol->m_color_B;
147  // m_min_dist = pCol->m_min_dist;
148  }
149 }
150 
151 /*---------------------------------------------------------------
152  writeToStream
153  Implements the writing to a CStream capability of
154  CSerializable objects
155  ---------------------------------------------------------------*/
156 void CColouredPointsMap::writeToStream(
157  mrpt::utils::CStream& out, int* version) const
158 {
159  if (version)
160  *version = 9;
161  else
162  {
163  uint32_t n = x.size();
164 
165  // First, write the number of points:
166  out << n;
167 
168  if (n > 0)
169  {
170  out.WriteBufferFixEndianness(&x[0], n);
171  out.WriteBufferFixEndianness(&y[0], n);
172  out.WriteBufferFixEndianness(&z[0], n);
173  }
174  out << m_color_R << m_color_G << m_color_B; // added in v4
175 
176  out << genericMapParams; // v9
177  insertionOptions.writeToStream(
178  out); // version 9?: insert options are saved with its own method
179  likelihoodOptions.writeToStream(out); // Added in version 5
180  }
181 }
182 
183 /*---------------------------------------------------------------
184  readFromStream
185  Implements the reading from a CStream capability of
186  CSerializable objects
187  ---------------------------------------------------------------*/
188 void CColouredPointsMap::readFromStream(mrpt::utils::CStream& in, int version)
189 {
190  switch (version)
191  {
192  case 8:
193  case 9:
194  {
195  mark_as_modified();
196 
197  // Read the number of points:
198  uint32_t n;
199  in >> n;
200 
201  this->resize(n);
202 
203  if (n > 0)
204  {
205  in.ReadBufferFixEndianness(&x[0], n);
206  in.ReadBufferFixEndianness(&y[0], n);
207  in.ReadBufferFixEndianness(&z[0], n);
208  }
209  in >> m_color_R >> m_color_G >> m_color_B;
210 
211  if (version >= 9)
212  in >> genericMapParams;
213  else
214  {
215  bool disableSaveAs3DObject;
216  in >> disableSaveAs3DObject;
217  genericMapParams.enableSaveAs3DObject = !disableSaveAs3DObject;
218  }
219  insertionOptions.readFromStream(in);
220  likelihoodOptions.readFromStream(in);
221  }
222  break;
223 
224  case 0:
225  case 1:
226  case 2:
227  case 3:
228  case 4:
229  case 5:
230  case 6:
231  case 7:
232  {
233  mark_as_modified();
234 
235  // Read the number of points:
236  uint32_t n;
237  in >> n;
238 
239  this->resize(n);
240 
241  if (n > 0)
242  {
243  in.ReadBufferFixEndianness(&x[0], n);
244  in.ReadBufferFixEndianness(&y[0], n);
245  in.ReadBufferFixEndianness(&z[0], n);
246 
247  // Version 1: weights are also stored:
248  // Version 4: Type becomes long int -> uint32_t for
249  // portability!!
250  if (version >= 1)
251  {
252  if (version >= 4)
253  {
254  if (version >= 7)
255  {
256  // Weights were removed from this class in v7 (MRPT
257  // 0.9.5),
258  // so nothing else to do.
259  }
260  else
261  {
262  // Go on with old serialization format, but discard
263  // weights:
264  std::vector<uint32_t> dummy_pointWeight(n);
265  in.ReadBufferFixEndianness(
266  &dummy_pointWeight[0], n);
267  }
268  }
269  else
270  {
271  std::vector<uint32_t> dummy_pointWeight(n);
272  in.ReadBufferFixEndianness(&dummy_pointWeight[0], n);
273  }
274  }
275  }
276 
277  if (version >= 2)
278  {
279  // version 2: options saved too
280  in >> insertionOptions.minDistBetweenLaserPoints >>
281  insertionOptions.addToExistingPointsMap >>
282  insertionOptions.also_interpolate >>
283  insertionOptions.disableDeletion >>
284  insertionOptions.fuseWithExisting >>
285  insertionOptions.isPlanarMap;
286 
287  if (version < 6)
288  {
289  bool old_matchStaticPointsOnly;
290  in >> old_matchStaticPointsOnly;
291  }
292 
293  in >> insertionOptions.maxDistForInterpolatePoints;
294  {
295  bool disableSaveAs3DObject;
296  in >> disableSaveAs3DObject;
297  genericMapParams.enableSaveAs3DObject =
298  !disableSaveAs3DObject;
299  }
300  }
301 
302  if (version >= 3)
303  {
304  in >> insertionOptions.horizontalTolerance;
305  }
306 
307  if (version >= 4) // Color data
308  {
309  in >> m_color_R >> m_color_G >> m_color_B;
310  if (version >= 7)
311  {
312  // Removed: in >> m_min_dist;
313  }
314  else
315  {
316  std::vector<float> dummy_dist;
317  in >> dummy_dist;
318  }
319  }
320  else
321  {
322  m_color_R.assign(x.size(), 1.0f);
323  m_color_G.assign(x.size(), 1.0f);
324  m_color_B.assign(x.size(), 1.0f);
325  // m_min_dist.assign(x.size(),2000.0f);
326  }
327 
328  if (version >= 5) // version 5: added likelihoodOptions
329  likelihoodOptions.readFromStream(in);
330 
331  if (version >= 8) // version 8: added insertInvalidPoints
332  in >> insertionOptions.insertInvalidPoints;
333  }
334  break;
335  default:
337  };
338 }
339 
340 /*---------------------------------------------------------------
341  Clear
342  ---------------------------------------------------------------*/
343 void CColouredPointsMap::internal_clear()
344 {
345  // This swap() thing is the only way to really deallocate the memory.
349 
350  vector_strong_clear(m_color_R);
351  vector_strong_clear(m_color_G);
352  vector_strong_clear(m_color_B);
353 
354  mark_as_modified();
355 }
356 
357 /** Changes a given point from map. First index is 0.
358  * \exception Throws std::exception on index out of bound.
359  */
360 void CColouredPointsMap::setPoint(
361  size_t index, float x, float y, float z, float R, float G, float B)
362 {
363  if (index >= this->x.size()) THROW_EXCEPTION("Index out of bounds");
364  this->x[index] = x;
365  this->y[index] = y;
366  this->z[index] = z;
367  this->m_color_R[index] = R;
368  this->m_color_G[index] = G;
369  this->m_color_B[index] = B;
370  mark_as_modified();
371 }
372 
373 /** Changes just the color of a given point from the map. First index is 0.
374  * \exception Throws std::exception on index out of bound.
375  */
376 void CColouredPointsMap::setPointColor(size_t index, float R, float G, float B)
377 {
378  if (index >= this->x.size()) THROW_EXCEPTION("Index out of bounds");
379  this->m_color_R[index] = R;
380  this->m_color_G[index] = G;
381  this->m_color_B[index] = B;
382  // mark_as_modified(); // No need to rebuild KD-trees, etc...
383 }
384 
385 void CColouredPointsMap::insertPointFast(float x, float y, float z)
386 {
387  this->x.push_back(x);
388  this->y.push_back(y);
389  this->z.push_back(z);
390  m_color_R.push_back(1);
391  m_color_G.push_back(1);
392  m_color_B.push_back(1);
393 
394  // mark_as_modified(); -> Fast
395 }
396 
397 void CColouredPointsMap::insertPoint(
398  float x, float y, float z, float R, float G, float B)
399 {
400  this->x.push_back(x);
401  this->y.push_back(y);
402  this->z.push_back(z);
403  m_color_R.push_back(R);
404  m_color_G.push_back(G);
405  m_color_B.push_back(B);
406 
407  mark_as_modified();
408 }
409 
410 /*---------------------------------------------------------------
411  getAs3DObject
412  ---------------------------------------------------------------*/
413 void CColouredPointsMap::getAs3DObject(
414  mrpt::opengl::CSetOfObjects::Ptr& outObj) const
415 {
416  ASSERT_(outObj);
417 
418  if (!genericMapParams.enableSaveAs3DObject) return;
419 
421  mrpt::make_aligned_shared<opengl::CPointCloudColoured>();
422 
423  obj->loadFromPointsMap(this);
424  obj->setColor(1, 1, 1, 1.0);
425 
427 
428  outObj->insert(obj);
429 }
430 
431 /*---------------------------------------------------------------
432  TColourOptions
433  ---------------------------------------------------------------*/
434 CColouredPointsMap::TColourOptions::TColourOptions()
435  : scheme(cmFromHeightRelativeToSensor), z_min(-10), z_max(10), d_max(5)
436 {
437 }
438 
440  const mrpt::utils::CConfigFileBase& source, const std::string& section)
441 {
442  scheme = source.read_enum(section, "scheme", scheme);
443  MRPT_LOAD_CONFIG_VAR(z_min, float, source, section)
444  MRPT_LOAD_CONFIG_VAR(z_max, float, source, section)
445  MRPT_LOAD_CONFIG_VAR(d_max, float, source, section)
446 }
447 
449  mrpt::utils::CStream& out) const
450 {
451  out.printf(
452  "\n----------- [CColouredPointsMap::TColourOptions] ------------ \n\n");
453 
454  out.printf(
455  "scheme = %u\n", (unsigned)scheme);
456  out.printf("z_min = %f\n", z_min);
457  out.printf("z_max = %f\n", z_max);
458  out.printf("d_max = %f\n", d_max);
459 }
460 
461 /*---------------------------------------------------------------
462  getPoint
463  ---------------------------------------------------------------*/
465  size_t index, float& x, float& y, float& z) const
466 {
467  if (index >= this->x.size()) THROW_EXCEPTION("Index out of bounds");
468 
469  x = this->x[index];
470  y = this->y[index];
471  z = this->z[index];
472 
473  return 1; // Weight
474 }
475 
476 /*---------------------------------------------------------------
477  getPoint
478  ---------------------------------------------------------------*/
480  size_t index, float& x, float& y, float& z, float& R, float& G,
481  float& B) const
482 {
483  if (index >= this->x.size()) THROW_EXCEPTION("Index out of bounds");
484 
485  x = this->x[index];
486  y = this->y[index];
487  z = this->z[index];
488 
489  R = m_color_R[index];
490  G = m_color_G[index];
491  B = m_color_B[index];
492 }
493 
494 /** Retrieves a point color (colors range is [0,1])
495  */
497  size_t index, float& R, float& G, float& B) const
498 {
499  if (index >= this->x.size()) THROW_EXCEPTION("Index out of bounds");
500 
501  R = m_color_R[index];
502  G = m_color_G[index];
503  B = m_color_B[index];
504 }
505 
506 // This function is duplicated from
507 // "mrpt::vision::pinhole::projectPoint_with_distortion", to avoid
508 // a dependency on mrpt-vision.
511  mrpt::utils::TPixelCoordf& pixel, bool accept_points_behind)
512 {
513  MRPT_UNUSED_PARAM(accept_points_behind);
514  // Pinhole model:
515  const double x = P.x / P.z;
516  const double y = P.y / P.z;
517 
518  // Radial distortion:
519  const double r2 = square(x) + square(y);
520  const double r4 = square(r2);
521  const double r6 = r2 * r4;
522 
523  pixel.x = params.cx() +
524  params.fx() * (x * (1 + params.dist[0] * r2 +
525  params.dist[1] * r4 + params.dist[4] * r6) +
526  2 * params.dist[2] * x * y +
527  params.dist[3] * (r2 + 2 * square(x)));
528  pixel.y = params.cy() +
529  params.fy() * (y * (1 + params.dist[0] * r2 +
530  params.dist[1] * r4 + params.dist[4] * r6) +
531  2 * params.dist[3] * x * y +
532  params.dist[2] * (r2 + 2 * square(y)));
533 }
534 
535 /*---------------------------------------------------------------
536  getPoint
537  ---------------------------------------------------------------*/
539  const CObservationImage& obs, const CPose3D& robotPose)
540 {
541  // Check if image is not grayscale
542  ASSERT_(obs.image.isColor());
543 
544  CPose3D cameraPoseR; // Get Camera Pose on the Robot(B) (CPose3D)
545  CPose3D cameraPoseW; // World Camera Pose
546 
547  obs.getSensorPose(cameraPoseR);
548  cameraPoseW = robotPose + cameraPoseR; // Camera Global Coordinates
549 
550  // Image Information
551  unsigned int imgW = obs.image.getWidth();
552  unsigned int imgH = obs.image.getHeight();
553 
554  // Projection related variables
555  std::vector<TPixelCoordf>
556  projectedPoints; // The set of projected points in the image
558  itProPoints; // Iterator for projectedPoints
559  std::vector<size_t> p_idx;
560  std::vector<float> p_dist;
561  std::vector<unsigned int> p_proj;
562 
563  // Get the N closest points
565  cameraPoseW.x(), cameraPoseW.y(), // query point
566  200000, // number of points to search
567  p_idx, p_dist); // indexes and distances of the returned points
568 
569  // Fill p3D vector
570  for (size_t k = 0; k < p_idx.size(); k++)
571  {
572  float d = sqrt(p_dist[k]);
573  size_t idx = p_idx[k];
574  if (d < colorScheme.d_max) // && d < m_min_dist[idx] )
575  {
576  TPixelCoordf px;
578  TPoint3D(x[idx], y[idx], z[idx]), obs.cameraParams, px, true);
579  projectedPoints.push_back(px);
580  p_proj.push_back(k);
581  } // end if
582  } // end for
583 
584  // Get channel order
585  unsigned int chR, chG, chB;
586  if (obs.image.getChannelsOrder()[0] == 'B')
587  {
588  chR = 2;
589  chG = 1;
590  chB = 0;
591  }
592  else
593  {
594  chR = 0;
595  chG = 1;
596  chB = 2;
597  }
598 
599  unsigned int n_proj = 0;
600  const float factor = 1.0f / 255; // Normalize pixels:
601 
602  // Get the colour of the projected points
603  size_t k;
604  for (itProPoints = projectedPoints.begin(), k = 0;
605  itProPoints != projectedPoints.end(); ++itProPoints, ++k)
606  {
607  // Only get the points projected inside the image
608  if (itProPoints->x >= 0 && itProPoints->x < imgW &&
609  itProPoints->y > 0 && itProPoints->y < imgH)
610  {
611  unsigned int ii = p_idx[p_proj[k]];
612  uint8_t* p = obs.image(
613  (unsigned int)itProPoints->x, (unsigned int)itProPoints->y);
614 
615  m_color_R[ii] = p[chR] * factor; // R
616  m_color_G[ii] = p[chG] * factor; // G
617  m_color_B[ii] = p[chB] * factor; // B
618  // m_min_dist[ii] = p_dist[p_proj[k]];
619 
620  n_proj++;
621  }
622  } // end for
623 
624  return true;
625 } // end colourFromObservation
626 
628 {
629  MRPT_UNUSED_PARAM(defValue);
630  // m_min_dist.assign(x.size(),defValue);
631 }
632 
634  const std::string& file) const
635 {
636  FILE* f = os::fopen(file.c_str(), "wt");
637  if (!f) return false;
638 
639  for (unsigned int i = 0; i < x.size(); i++)
640  os::fprintf(
641  f, "%f %f %f %d %d %d\n", x[i], y[i], z[i],
642  (uint8_t)(255 * m_color_R[i]), (uint8_t)(255 * m_color_G[i]),
643  (uint8_t)(255 * m_color_B[i]));
644  // os::fprintf(f,"%f %f %f %f %f %f
645  //%f\n",x[i],y[i],z[i],m_color_R[i],m_color_G[i],m_color_B[i],m_min_dist[i]);
646 
647  os::fclose(f);
648  return true;
649 }
650 
651 // ================================ PLY files import & export virtual methods
652 // ================================
653 
654 /** In a base class, reserve memory to prepare subsequent calls to
655  * PLY_import_set_vertex */
657 {
658  this->setSize(N);
659 }
660 
661 /** In a base class, will be called after PLY_import_set_vertex_count() once for
662  * each loaded point.
663  * \param pt_color Will be nullptr if the loaded file does not provide color
664  * info.
665  */
667  const size_t idx, const mrpt::math::TPoint3Df& pt,
668  const mrpt::utils::TColorf* pt_color)
669 {
670  if (pt_color)
671  this->setPoint(
672  idx, pt.x, pt.y, pt.z, pt_color->R, pt_color->G, pt_color->B);
673  else
674  this->setPoint(idx, pt.x, pt.y, pt.z);
675 }
676 
677 /** In a base class, will be called after PLY_export_get_vertex_count() once for
678  * each exported point.
679  * \param pt_color Will be nullptr if the loaded file does not provide color
680  * info.
681  */
683  const size_t idx, mrpt::math::TPoint3Df& pt, bool& pt_has_color,
684  mrpt::utils::TColorf& pt_color) const
685 {
686  pt_has_color = true;
687 
688  pt.x = x[idx];
689  pt.y = y[idx];
690  pt.z = z[idx];
691 
692  pt_color.R = m_color_R[idx];
693  pt_color.G = m_color_G[idx];
694  pt_color.B = m_color_B[idx];
695 }
696 
697 /*---------------------------------------------------------------
698  addFrom_classSpecific
699  ---------------------------------------------------------------*/
701  const CPointsMap& anotherMap, const size_t nPreviousPoints)
702 {
703  const size_t nOther = anotherMap.size();
704 
705  // Specific data for this class:
706  const CColouredPointsMap* anotheMap_col =
707  dynamic_cast<const CColouredPointsMap*>(&anotherMap);
708 
709  if (anotheMap_col)
710  {
711  for (size_t i = 0, j = nPreviousPoints; i < nOther; i++, j++)
712  {
713  m_color_R[j] = anotheMap_col->m_color_R[i];
714  m_color_G[j] = anotheMap_col->m_color_G[i];
715  m_color_B[j] = anotheMap_col->m_color_B[i];
716  }
717  }
718 }
719 
720 /** Save the point cloud as a PCL PCD file, in either ASCII or binary format
721  * \return false on any error */
723  const std::string& filename, bool save_as_binary) const
724 {
725 #if MRPT_HAS_PCL
726  pcl::PointCloud<pcl::PointXYZRGB> cloud;
727 
728  const size_t nThis = this->size();
729 
730  // Fill in the cloud data
731  cloud.width = nThis;
732  cloud.height = 1;
733  cloud.is_dense = false;
734  cloud.points.resize(cloud.width * cloud.height);
735 
736  const float f = 255.f;
737 
738  union myaux_t {
739  uint8_t rgb[4];
740  float f;
741  } aux_val;
742 
743  for (size_t i = 0; i < nThis; ++i)
744  {
745  cloud.points[i].x = this->x[i];
746  cloud.points[i].y = this->y[i];
747  cloud.points[i].z = this->z[i];
748 
749  aux_val.rgb[0] = static_cast<uint8_t>(this->m_color_B[i] * f);
750  aux_val.rgb[1] = static_cast<uint8_t>(this->m_color_G[i] * f);
751  aux_val.rgb[2] = static_cast<uint8_t>(this->m_color_R[i] * f);
752 
753  cloud.points[i].rgb = aux_val.f;
754  }
755 
756  return 0 == pcl::io::savePCDFile(filename, cloud, save_as_binary);
757 
758 #else
759  MRPT_UNUSED_PARAM(filename);
760  MRPT_UNUSED_PARAM(save_as_binary);
761  THROW_EXCEPTION("Operation not available: MRPT was built without PCL")
762 #endif
763 }
764 
765 namespace mrpt
766 {
767 namespace maps
768 {
769 namespace detail
770 {
772 
773 template <>
775 {
776  /** Helper method fot the generic implementation of
777  * CPointsMap::loadFromRangeScan(), to be called only once before inserting
778  * points - this is the place to reserve memory in lric for extra working
779  * variables. */
781  CColouredPointsMap& me,
783  {
784  // Vars:
785  // [0] -> pR
786  // [1] -> pG
787  // [2] -> pB
788  // [3] -> Az_1_color
789  lric.fVars.resize(4);
790 
792  lric.fVars[3] = 1.0 / (me.colorScheme.z_max - me.colorScheme.z_min);
793  }
794 
795  /** Helper method fot the generic implementation of
796  * CPointsMap::loadFromRangeScan(), to be called once per range data */
798  CColouredPointsMap& me, const float gx, const float gy, const float gz,
800  {
801  MRPT_UNUSED_PARAM(gx);
802  MRPT_UNUSED_PARAM(gy);
803  // Relative height of the point wrt the sensor:
804  const float rel_z = gz - lric.HM.get_unsafe(2, 3); // m23;
805 
806  // Variable renaming:
807  float& pR = lric.fVars[0];
808  float& pG = lric.fVars[1];
809  float& pB = lric.fVars[2];
810  const float& Az_1_color = lric.fVars[3];
811 
812  // Compute color:
813  switch (me.colorScheme.scheme)
814  {
815  // case cmFromHeightRelativeToSensor:
818  {
819  float q = (rel_z - me.colorScheme.z_min) * Az_1_color;
820  if (q < 0)
821  q = 0;
822  else if (q > 1)
823  q = 1;
824 
825  if (me.colorScheme.scheme ==
827  {
828  pR = pG = pB = q;
829  }
830  else
831  {
832  mrpt::utils::jet2rgb(q, pR, pG, pB);
833  }
834  }
835  break;
837  {
838  // In 2D scans we don't have this channel.
839  pR = pG = pB = 1.0;
840  }
841  break;
842  default:
843  THROW_EXCEPTION("Unknown color scheme");
844  }
845  }
846  /** Helper method fot the generic implementation of
847  * CPointsMap::loadFromRangeScan(), to be called after each
848  * "{x,y,z}.push_back(...);" */
850  CColouredPointsMap& me,
852  {
853  float& pR = lric.fVars[0];
854  float& pG = lric.fVars[1];
855  float& pB = lric.fVars[2];
856  me.m_color_R.push_back(pR);
857  me.m_color_G.push_back(pG);
858  me.m_color_B.push_back(pB);
859  // m_min_dist.push_back(1e4);
860  }
861 
862  /** Helper method fot the generic implementation of
863  * CPointsMap::loadFromRangeScan(), to be called only once before inserting
864  * points - this is the place to reserve memory in lric for extra working
865  * variables. */
867  CColouredPointsMap& me,
869  {
870  // Vars:
871  // [0] -> pR
872  // [1] -> pG
873  // [2] -> pB
874  // [3] -> Az_1_color
875  // [4] -> K_8u
876  // [5] -> cx
877  // [6] -> cy
878  // [7] -> fx
879  // [8] -> fy
880  lric.fVars.resize(9);
881  float& cx = lric.fVars[5];
882  float& cy = lric.fVars[6];
883  float& fx = lric.fVars[7];
884  float& fy = lric.fVars[8];
885 
886  // unsigned int vars:
887  // [0] -> imgW
888  // [1] -> imgH
889  // [2] -> img_idx_x
890  // [3] -> img_idx_y
891  lric.uVars.resize(4);
892  unsigned int& imgW = lric.uVars[0];
893  unsigned int& imgH = lric.uVars[1];
894  unsigned int& img_idx_x = lric.uVars[2];
895  unsigned int& img_idx_y = lric.uVars[3];
896 
897  // bool vars:
898  // [0] -> hasValidIntensityImage
899  // [1] -> hasColorIntensityImg
900  // [2] -> simple_3d_to_color_relation
901  lric.bVars.resize(3);
902  uint8_t& hasValidIntensityImage = lric.bVars[0];
903  uint8_t& hasColorIntensityImg = lric.bVars[1];
904  uint8_t& simple_3d_to_color_relation = lric.bVars[2];
905 
907  lric.fVars[3] = 1.0 / (me.colorScheme.z_max -
908  me.colorScheme.z_min); // Az_1_color = ...
909  lric.fVars[4] = 1.0f / 255; // K_8u
910 
911  hasValidIntensityImage = false;
912  imgW = 0;
913  imgH = 0;
914 
915  if (lric.rangeScan.hasIntensityImage)
916  {
917  // assure the size matches:
918  if (lric.rangeScan.points3D_x.size() ==
921  {
922  hasValidIntensityImage = true;
923  imgW = lric.rangeScan.intensityImage.getWidth();
924  imgH = lric.rangeScan.intensityImage.getHeight();
925  }
926  }
927 
928  hasColorIntensityImg =
929  hasValidIntensityImage && lric.rangeScan.intensityImage.isColor();
930 
931  // running indices for the image pixels for the gray levels:
932  // If both range & intensity images coincide (e.g. SwissRanger), then we
933  // can just
934  // assign 3D points to image pixels one-to-one, but that's not the case
935  // if
936  //
937  simple_3d_to_color_relation =
938  (std::abs(lric.rangeScan.relativePoseIntensityWRTDepth.norm()) <
939  1e-5);
940  img_idx_x = 0;
941  img_idx_y = 0;
942 
943  // Will be used just if simple_3d_to_color_relation=false
944  cx = lric.rangeScan.cameraParamsIntensity.cx();
945  cy = lric.rangeScan.cameraParamsIntensity.cy();
946  fx = lric.rangeScan.cameraParamsIntensity.fx();
947  fy = lric.rangeScan.cameraParamsIntensity.fy();
948  }
949 
950  /** Helper method fot the generic implementation of
951  * CPointsMap::loadFromRangeScan(), to be called once per range data */
953  CColouredPointsMap& me, const float gx, const float gy, const float gz,
955  {
956  MRPT_UNUSED_PARAM(gx);
957  MRPT_UNUSED_PARAM(gy);
958  // Rename variables:
959  float& pR = lric.fVars[0];
960  float& pG = lric.fVars[1];
961  float& pB = lric.fVars[2];
962  float& Az_1_color = lric.fVars[3];
963  float& K_8u = lric.fVars[4];
964  float& cx = lric.fVars[5];
965  float& cy = lric.fVars[6];
966  float& fx = lric.fVars[7];
967  float& fy = lric.fVars[8];
968 
969  unsigned int& imgW = lric.uVars[0];
970  unsigned int& imgH = lric.uVars[1];
971  unsigned int& img_idx_x = lric.uVars[2];
972  unsigned int& img_idx_y = lric.uVars[3];
973 
974  const uint8_t& hasValidIntensityImage = lric.bVars[0];
975  const uint8_t& hasColorIntensityImg = lric.bVars[1];
976  const uint8_t& simple_3d_to_color_relation = lric.bVars[2];
977 
978  // Relative height of the point wrt the sensor:
979  const float rel_z = gz - lric.HM.get_unsafe(2, 3); // m23;
980 
981  // Compute color:
982  switch (me.colorScheme.scheme)
983  {
984  // case cmFromHeightRelativeToSensor:
987  {
988  float q = (rel_z - me.colorScheme.z_min) * Az_1_color;
989  if (q < 0)
990  q = 0;
991  else if (q > 1)
992  q = 1;
993 
994  if (me.colorScheme.scheme ==
996  {
997  pR = pG = pB = q;
998  }
999  else
1000  {
1001  mrpt::utils::jet2rgb(q, pR, pG, pB);
1002  }
1003  }
1004  break;
1006  {
1007  // Do we have to project the 3D point into the image plane??
1008  bool hasValidColor = false;
1009  if (simple_3d_to_color_relation)
1010  {
1011  hasValidColor = true;
1012  }
1013  else
1014  {
1015  // Do projection:
1016  TPoint3D pt; // pt_wrt_colorcam;
1019  lric.scan_x, lric.scan_y, lric.scan_z, pt.x, pt.y,
1020  pt.z);
1021 
1022  // Project to image plane:
1023  if (pt.z)
1024  {
1025  img_idx_x = cx + fx * pt.x / pt.z;
1026  img_idx_y = cy + fy * pt.y / pt.z;
1027 
1028  hasValidColor = img_idx_x < imgW && // img_idx_x>=0
1029  // isn't needed for
1030  // unsigned.
1031  img_idx_y < imgH;
1032  }
1033  }
1034 
1035  if (hasValidColor && hasColorIntensityImg)
1036  {
1038  img_idx_x, img_idx_y, 0);
1039  pR = c[2] * K_8u;
1040  pG = c[1] * K_8u;
1041  pB = c[0] * K_8u;
1042  }
1043  else if (hasValidColor && hasValidIntensityImage)
1044  {
1046  img_idx_x, img_idx_y, 0);
1047  pR = pG = pB = c * K_8u;
1048  }
1049  else
1050  {
1051  pR = pG = pB = 1.0;
1052  }
1053  }
1054  break;
1055  default:
1056  THROW_EXCEPTION("Unknown color scheme");
1057  }
1058  }
1059 
1060  /** Helper method fot the generic implementation of
1061  * CPointsMap::loadFromRangeScan(), to be called after each
1062  * "{x,y,z}.push_back(...);" */
1064  CColouredPointsMap& me,
1066  {
1067  float& pR = lric.fVars[0];
1068  float& pG = lric.fVars[1];
1069  float& pB = lric.fVars[2];
1070 
1071  me.m_color_R.push_back(pR);
1072  me.m_color_G.push_back(pG);
1073  me.m_color_B.push_back(pB);
1074 
1075  // m_min_dist.push_back(1e4);
1076  }
1077 
1078  /** Helper method fot the generic implementation of
1079  * CPointsMap::loadFromRangeScan(), to be called once per range data, at the
1080  * end */
1082  CColouredPointsMap& me,
1084  {
1085  MRPT_UNUSED_PARAM(me);
1086  unsigned int& imgW = lric.uVars[0];
1087  unsigned int& img_idx_x = lric.uVars[2];
1088  unsigned int& img_idx_y = lric.uVars[3];
1089 
1090  const uint8_t& hasValidIntensityImage = lric.bVars[0];
1091  const uint8_t& simple_3d_to_color_relation = lric.bVars[2];
1092 
1093  // Advance the color pointer (just for simple cases, e.g. SwissRanger,
1094  // not for Kinect)
1095  if (simple_3d_to_color_relation && hasValidIntensityImage)
1096  {
1097  if (++img_idx_x >= imgW)
1098  {
1099  img_idx_y++;
1100  img_idx_x = 0;
1101  }
1102  }
1103  }
1104 };
1105 }
1106 }
1107 }
1108 
1109 /** See CPointsMap::loadFromRangeScan() */
1111  const CObservation2DRangeScan& rangeScan, const CPose3D* robotPose)
1112 {
1114  templ_loadFromRangeScan(*this, rangeScan, robotPose);
1115 }
1116 
1117 /** See CPointsMap::loadFromRangeScan() */
1119  const CObservation3DRangeScan& rangeScan, const CPose3D* robotPose)
1120 {
1122  templ_loadFromRangeScan(*this, rangeScan, robotPose);
1123 }
virtual void getPoint(size_t index, float &x, float &y, float &z, float &R, float &G, float &B) const override
Retrieves a point and its color (colors range is [0,1])
static void internal_loadFromRangeScan3D_prepareOneRange(CColouredPointsMap &me, const float gx, const float gy, const float gz, mrpt::maps::CPointsMap::TLaserRange3DInsertContext &lric)
Helper method fot the generic implementation of CPointsMap::loadFromRangeScan(), to be called once pe...
virtual void setSize(size_t newLength) override
Resizes all point buffers so they can hold the given number of points, erasing all previous contents ...
A pair (x,y) of pixel coordinates (subpixel resolution).
Definition: TPixelCoord.h:21
double x() const
Common members of all points & poses classes.
Definition: CPoseOrPoint.h:135
virtual void addFrom_classSpecific(const CPointsMap &anotherMap, const size_t nPreviousPoints) override
Auxiliary method called from within addFrom() automatically, to finish the copying of class-specific ...
Virtual base for specifying the kind and parameters of one map (normally, to be inserted into mrpt::m...
Declares a class derived from "CObservation" that encapsules an image from a camera, whose relative pose to robot is also stored.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
GLdouble GLdouble z
Definition: glext.h:3872
bool save3D_and_colour_to_text_file(const std::string &file) const
Save to a text file.
This namespace provides a OS-independent interface to many useful functions: filenames manipulation...
Definition: math_frwds.h:30
const mrpt::obs::CObservation3DRangeScan & rangeScan
Definition: CPointsMap.h:102
mrpt::utils::TCamera cameraParamsIntensity
Projection parameters of the intensity (graylevel or RGB) camera.
int void fclose(FILE *f)
An OS-independent version of fclose.
Definition: os.cpp:272
void aux_projectPoint_with_distortion(const mrpt::math::TPoint3D &P, const mrpt::utils::TCamera &params, mrpt::utils::TPixelCoordf &pixel, bool accept_points_behind)
mrpt::utils::TCamera cameraParams
Intrinsic and distortion parameters of the camera.
#define IMPLEMENTS_SERIALIZABLE(class_name, base, NameSpace)
This must be inserted in all CSerializable classes implementation files.
#define THROW_EXCEPTION(msg)
GLdouble GLdouble GLdouble GLdouble q
Definition: glext.h:3721
GLenum GLsizei n
Definition: glext.h:5074
double cy() const
Get the value of the principal point y-coordinate (in pixels).
Definition: TCamera.h:176
const char * getChannelsOrder() const
Returns a string of the form "BGR","RGB" or "GRAY" indicating the channels ordering.
Definition: CImage.cpp:1188
Scalar * iterator
Definition: eigen_plugins.h:26
Declares a class derived from "CObservation" that encapsules a 3D range scan measurement, as from a time-of-flight range camera or any other RGBD sensor.
STL namespace.
void kdTreeNClosestPoint2DIdx(float x0, float y0, size_t knn, std::vector< size_t > &out_idx, std::vector< float > &out_dist_sqr) const
KD Tree-based search for the N closest point to some given 2D coordinates and returns their indexes...
GLsizei GLsizei GLuint * obj
Definition: glext.h:4070
static void internal_loadFromRangeScan2D_prepareOneRange(CColouredPointsMap &me, const float gx, const float gy, const float gz, mrpt::maps::CPointsMap::TLaserRange2DInsertContext &lric)
Helper method fot the generic implementation of CPointsMap::loadFromRangeScan(), to be called once pe...
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string &section) override
This method load the options from a ".ini"-like file or memory-stored string list.
TColourOptions colorScheme
The options employed when inserting laser scans in the map.
This class allows loading and storing values and vectors of different types from a configuration text...
T square(const T x)
Inline function for the square of a number.
Definition: bits.h:55
unsigned char uint8_t
Definition: rptypes.h:41
mrpt::maps::CPointsMap::TLikelihoodOptions likelihoodOpts
double fx() const
Get the value of the focal length x-value (in pixels).
Definition: TCamera.h:178
void WriteBufferFixEndianness(const T *ptr, size_t ElementCount)
Writes a sequence of elemental datatypes, taking care of reordering their bytes from the running arch...
Definition: CStream.h:159
double fy() const
Get the value of the focal length y-value (in pixels).
Definition: TCamera.h:180
This base class is used to provide a unified interface to files,memory buffers,..Please see the deriv...
Definition: CStream.h:41
A cloud of points in 2D or 3D, which can be built from a sequence of laser scans or other sensors...
Definition: CPointsMap.h:63
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
size_t getWidth() const override
Returns the width of the image in pixels.
Definition: CImage.cpp:869
mrpt::poses::CPose3D relativePoseIntensityWRTDepth
Relative pose of the intensity camera wrt the depth camera (which is the coordinates origin for this ...
void dumpToTextStream(mrpt::utils::CStream &out) const override
This method should clearly display all the contents of the structure in textual form, sending it to a CStream.
Lightweight 3D point (float version).
T length2length4N(T len)
Returns the smaller number >=len such that it&#39;s a multiple of 4.
Definition: bits.h:273
#define MRPT_UNUSED_PARAM(a)
Can be used to avoid "not used parameters" warnings from the compiler.
double norm() const
Returns the euclidean norm of vector: .
Definition: CPoseOrPoint.h:252
GLuint index
Definition: glext.h:4054
const GLubyte * c
Definition: glext.h:6313
#define MRPT_THROW_UNKNOWN_SERIALIZATION_VERSION(__V)
For use in CSerializable implementations.
mrpt::math::CMatrixDouble44 HM
Homog matrix of the local sensor pose within the robot.
Definition: CPointsMap.h:101
virtual void PLY_import_set_vertex(const size_t idx, const mrpt::math::TPoint3Df &pt, const mrpt::utils::TColorf *pt_color=nullptr) override
In a base class, will be called after PLY_import_set_vertex_count() once for each loaded point...
size_t getHeight() const override
Returns the height of the image in pixels.
Definition: CImage.cpp:897
float scan_x
In internal_loadFromRangeScan3D_prepareOneRange, these are the local coordinates of the scan points b...
Definition: CPointsMap.h:105
void PLY_export_get_vertex(const size_t idx, mrpt::math::TPoint3Df &pt, bool &pt_has_color, mrpt::utils::TColorf &pt_color) const override
In a base class, will be called after PLY_export_get_vertex_count() once for each exported point...
std::shared_ptr< CSetOfObjects > Ptr
Definition: CSetOfObjects.h:32
static void internal_loadFromRangeScan2D_init(CColouredPointsMap &me, mrpt::maps::CPointsMap::TLaserRange2DInsertContext &lric)
Helper method fot the generic implementation of CPointsMap::loadFromRangeScan(), to be called only on...
This namespace contains representation of robot actions and observations.
EIGEN_STRONG_INLINE void setSize(size_t row, size_t col)
Changes the size of matrix, maintaining its previous content as possible and padding with zeros where...
virtual void PLY_import_set_vertex_count(const size_t N) override
In a base class, reserve memory to prepare subsequent calls to PLY_import_set_vertex.
std::vector< float > fVars
Extra variables to be used as desired by the derived class.
Definition: CPointsMap.h:86
double x
X,Y,Z coordinates.
static void templ_loadFromRangeScan(Derived &obj, const mrpt::obs::CObservation2DRangeScan &rangeScan, const mrpt::poses::CPose3D *robotPose)
mrpt::maps::CColouredPointsMap::TColourOptions colourOpts
virtual bool savePCDFile(const std::string &filename, bool save_as_binary) const override
Save the point cloud as a PCL PCD file, in either ASCII or binary format.
static void internal_loadFromRangeScan3D_postPushBack(CColouredPointsMap &me, mrpt::maps::CPointsMap::TLaserRange3DInsertContext &lric)
Helper method fot the generic implementation of CPointsMap::loadFromRangeScan(), to be called after e...
A map of 2D/3D points with individual colours (RGB).
mrpt::maps::CPointsMap::TInsertionOptions insertionOpts
GLsizei const GLchar ** string
Definition: glext.h:4101
double cx() const
Get the value of the principal point x-coordinate (in pixels).
Definition: TCamera.h:174
Classes for 2D/3D geometry representation, both of single values and probability density distribution...
Definition: CPoint.h:17
std::vector< float > fVars
Extra variables to be used as desired by the derived class.
Definition: CPointsMap.h:107
void loadFromConfigFile(const mrpt::utils::CConfigFileBase &source, const std::string &sectionNamePrefix) override
Load all params from a config file/source.
int fprintf(FILE *fil, const char *format,...) noexcept MRPT_printf_format_check(2
An OS-independent version of fprintf.
Definition: os.cpp:405
void vector_strong_clear(VECTOR_T &v)
Like calling a std::vector<>&#39;s clear() method, but really forcing deallocating the memory...
Definition: bits.h:265
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
#define MAP_DEFINITION_REGISTER(_CLASSNAME_STRINGS, _CLASSNAME_WITH_NS)
Registers one map class into TMetricMapInitializer factory.
A "CObservation"-derived class that represents a 2D range scan measurement (typically from a laser sc...
#define ASSERT_NOT_EQUAL_(__A, __B)
void POINTSMAPS_3DOBJECT_POINTSIZE(float value)
The size of points when exporting with getAs3DObject() (default=3.0) Affects to:
Definition: CPointsMap.cpp:55
Declares a virtual base class for all metric maps storage classes.
Definition: CMetricMap.h:55
const float R
virtual void setPoint(size_t index, float x, float y, float z, float R, float G, float B) override
Changes a given point from map.
A class used to store a 3D pose (a 3D translation + a rotation in 3D).
Definition: CPose3D.h:88
void resetPointsMinDist(float defValue=2000.0f)
Reset the minimum-observed-distance buffer for all the points to a predefined value.
virtual void loadFromRangeScan(const mrpt::obs::CObservation2DRangeScan &rangeScan, const mrpt::poses::CPose3D *robotPose=nullptr) override
See CPointsMap::loadFromRangeScan()
bool hasIntensityImage
true means the field intensityImage contains valid data
void jet2rgb(const float color_index, float &r, float &g, float &b)
Computes the RGB color components (range [0,1]) for the corresponding color index in the range [0...
Definition: color_maps.cpp:140
GLuint in
Definition: glext.h:7274
std::vector< float > points3D_x
If hasPoints3D=true, the (X,Y,Z) coordinates of the 3D point cloud detected by the camera...
GLsizei GLsizei GLchar * source
Definition: glext.h:4082
#define ASSERT_(f)
A RGB color - floats in the range [0,1].
Definition: TColor.h:78
mrpt::utils::CImage image
The image captured by the camera, that is, the main piece of information of this observation.
Helper struct used for internal_loadFromRangeScan3D_prepareOneRange()
Definition: CPointsMap.h:93
GLenum GLint GLint y
Definition: glext.h:3538
std::vector< float > m_color_R
The color data.
FILE * fopen(const char *fileName, const char *mode) noexcept
An OS-independent version of fopen.
Definition: os.cpp:254
void getSensorPose(mrpt::poses::CPose3D &out_sensorPose) const override
A general method to retrieve the sensor pose on the robot.
bool isColor() const
Returns true if the image is RGB, false if it is grayscale.
Definition: CImage.cpp:911
unsigned char * get_unsafe(unsigned int col, unsigned int row, unsigned int channel=0) const
Access to pixels without checking boundaries - Use normally the () operator better, which checks the coordinates.
Definition: CImage.cpp:496
static void internal_loadFromRangeScan2D_postPushBack(CColouredPointsMap &me, mrpt::maps::CPointsMap::TLaserRange2DInsertContext &lric)
Helper method fot the generic implementation of CPointsMap::loadFromRangeScan(), to be called after e...
#define MRPT_LOAD_CONFIG_VAR( variableName, variableType, configFileObject, sectionNameStr)
An useful macro for loading variables stored in a INI-like file under a key with the same name that t...
GLenum GLint x
Definition: glext.h:3538
Lightweight 3D point.
mrpt::utils::CImage intensityImage
If hasIntensityImage=true, a color or gray-level intensity image of the same size than "rangeImage"...
mrpt::math::CMatrixDouble44 HM
Homog matrix of the local sensor pose within the robot.
Definition: CPointsMap.h:83
unsigned __int32 uint32_t
Definition: rptypes.h:47
bool colourFromObservation(const mrpt::obs::CObservationImage &obs, const mrpt::poses::CPose3D &robotPose)
Colour a set of points from a CObservationImage and the global pose of the robot. ...
size_t size() const
Returns the number of stored points in the map.
Definition: CPointsMap.h:385
std::shared_ptr< CPointCloudColoured > Ptr
GLfloat GLfloat p
Definition: glext.h:6305
GLenum const GLfloat * params
Definition: glext.h:3534
void getPointColor(size_t index, float &R, float &G, float &B) const
Retrieves a point color (colors range is [0,1])
static void internal_loadFromRangeScan3D_postOneRange(CColouredPointsMap &me, mrpt::maps::CPointsMap::TLaserRange3DInsertContext &lric)
Helper method fot the generic implementation of CPointsMap::loadFromRangeScan(), to be called once pe...
Helper struct used for internal_loadFromRangeScan2D_prepareOneRange()
Definition: CPointsMap.h:75
static void internal_loadFromRangeScan3D_init(CColouredPointsMap &me, mrpt::maps::CPointsMap::TLaserRange3DInsertContext &lric)
Helper method fot the generic implementation of CPointsMap::loadFromRangeScan(), to be called only on...
virtual int printf(const char *fmt,...) MRPT_printf_format_check(2
Writes a string to the stream in a textual form.
Definition: CStream.cpp:597
Structure to hold the parameters of a pinhole camera model.
Definition: TCamera.h:32
void inverseComposePoint(const double gx, const double gy, const double gz, double &lx, double &ly, double &lz, mrpt::math::CMatrixFixedNumeric< double, 3, 3 > *out_jacobian_df_dpoint=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dpose=nullptr, mrpt::math::CMatrixFixedNumeric< double, 3, 6 > *out_jacobian_df_dse3=nullptr) const
Computes the 3D point L such as .
Definition: CPose3D.cpp:723



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: ae4571287 Thu Nov 23 00:06:53 2017 +0100 at dom oct 27 23:51:55 CET 2019