LaserScan.cpp
Go to the documentation of this file.
1 /*
2 Copyright (c) 2010-2016, Mathieu Labbe - IntRoLab - Universite de Sherbrooke
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the Universite de Sherbrooke nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 
28 #include <rtabmap/core/LaserScan.h>
31 
32 namespace rtabmap {
33 
34 std::string LaserScan::formatName(const Format & format)
35 {
36  std::string name;
37  switch (format) {
38  case kXY:
39  name = "XY";
40  break;
41  case kXYZ:
42  name = "XYZ";
43  break;
44  case kXYI:
45  name = "XYI";
46  break;
47  case kXYZI:
48  name = "XYZI";
49  break;
50  case kXYZRGB:
51  name = "XYZRGB";
52  break;
53  case kXYNormal:
54  name = "XYNormal";
55  break;
56  case kXYZNormal:
57  name = "XYZNormal";
58  break;
59  case kXYINormal:
60  name = "XYINormal";
61  break;
62  case kXYZINormal:
63  name = "XYZINormal";
64  break;
65  case kXYZRGBNormal:
66  name = "XYZRGBNormal";
67  break;
68  default:
69  name = "Unknown";
70  break;
71  }
72  return name;
73 }
74 
76 {
77  int channels=0;
78  switch (format) {
79  case kXY:
80  channels = 2;
81  break;
82  case kXYZ:
83  case kXYI:
84  channels = 3;
85  break;
86  case kXYZI:
87  case kXYZRGB:
88  channels = 4;
89  break;
90  case kXYNormal:
91  channels = 5;
92  break;
93  case kXYZNormal:
94  case kXYINormal:
95  channels = 6;
96  break;
97  case kXYZINormal:
98  case kXYZRGBNormal:
99  channels = 7;
100  break;
101  default:
102  UFATAL("Unhandled type %d!", (int)format);
103  break;
104  }
105  return channels;
106 }
107 
109 {
110  return format==kXY || format==kXYI || format == kXYNormal || format == kXYINormal;
111 }
113 {
114  return format==kXYZNormal || format==kXYZINormal || format==kXYZRGBNormal || format == kXYNormal || format == kXYINormal;
115 }
117 {
118  return format==kXYZRGB || format==kXYZRGBNormal;
119 }
121 {
122  return format==kXYZI || format==kXYZINormal || format == kXYI || format == kXYINormal;
123 }
124 
126  const cv::Mat & oldScanFormat,
127  int maxPoints,
128  int maxRange,
129  const Transform & localTransform)
130 {
131  if(!oldScanFormat.empty())
132  {
133  if(oldScanFormat.channels() == 2)
134  {
135  return LaserScan(oldScanFormat, maxPoints, maxRange, kXY, localTransform);
136  }
137  else if(oldScanFormat.channels() == 3)
138  {
139  return LaserScan(oldScanFormat, maxPoints, maxRange, kXYZ, localTransform);
140  }
141  else if(oldScanFormat.channels() == 4)
142  {
143  return LaserScan(oldScanFormat, maxPoints, maxRange, kXYZRGB, localTransform);
144  }
145  else if(oldScanFormat.channels() == 5)
146  {
147  return LaserScan(oldScanFormat, maxPoints, maxRange, kXYNormal, localTransform);
148  }
149  else if(oldScanFormat.channels() == 6)
150  {
151  return LaserScan(oldScanFormat, maxPoints, maxRange, kXYZNormal, localTransform);
152  }
153  else if(oldScanFormat.channels() == 7)
154  {
155  return LaserScan(oldScanFormat, maxPoints, maxRange, kXYZRGBNormal, localTransform);
156  }
157  }
158  return LaserScan();
159 }
160 
162  const cv::Mat & oldScanFormat,
163  float minRange,
164  float maxRange,
165  float angleMin,
166  float angleMax,
167  float angleInc,
168  const Transform & localTransform)
169 {
170  if(!oldScanFormat.empty())
171  {
172  if(oldScanFormat.channels() == 2)
173  {
174  return LaserScan(oldScanFormat, kXY, minRange, maxRange, angleMin, angleMax, angleInc, localTransform);
175  }
176  else if(oldScanFormat.channels() == 3)
177  {
178  return LaserScan(oldScanFormat, kXYZ, minRange, maxRange, angleMin, angleMax, angleInc, localTransform);
179  }
180  else if(oldScanFormat.channels() == 4)
181  {
182  return LaserScan(oldScanFormat, kXYZRGB, minRange, maxRange, angleMin, angleMax, angleInc, localTransform);
183  }
184  else if(oldScanFormat.channels() == 5)
185  {
186  return LaserScan(oldScanFormat, kXYNormal, minRange, maxRange, angleMin, angleMax, angleInc, localTransform);
187  }
188  else if(oldScanFormat.channels() == 6)
189  {
190  return LaserScan(oldScanFormat, kXYZNormal, minRange, maxRange, angleMin, angleMax, angleInc, localTransform);
191  }
192  else if(oldScanFormat.channels() == 7)
193  {
194  return LaserScan(oldScanFormat, kXYZRGBNormal, minRange, maxRange, angleMin, angleMax, angleInc, localTransform);
195  }
196  }
197  return LaserScan();
198 }
199 
201  format_(kUnknown),
202  maxPoints_(0),
203  rangeMin_(0),
204  rangeMax_(0),
205  angleMin_(0),
206  angleMax_(0),
207  angleIncrement_(0),
208  localTransform_(Transform::getIdentity())
209 {
210 }
211 
213  const LaserScan & scan,
214  int maxPoints,
215  float maxRange,
216  const Transform & localTransform)
217 {
218  UASSERT(scan.empty() || scan.format() != kUnknown);
219  init(scan.data(), scan.format(), 0, maxRange, 0, 0, 0, maxPoints, localTransform);
220 }
221 
223  const LaserScan & scan,
224  int maxPoints,
225  float maxRange,
226  Format format,
227  const Transform & localTransform)
228 {
229  init(scan.data(), format, 0, maxRange, 0, 0, 0, maxPoints, localTransform);
230 }
231 
233  const cv::Mat & data,
234  int maxPoints,
235  float maxRange,
236  Format format,
237  const Transform & localTransform)
238 {
239  init(data, format, 0, maxRange, 0, 0, 0, maxPoints, localTransform);
240 }
241 
243  const LaserScan & scan,
244  float minRange,
245  float maxRange,
246  float angleMin,
247  float angleMax,
248  float angleIncrement,
249  const Transform & localTransform)
250 {
251  UASSERT(scan.empty() || scan.format() != kUnknown);
252  init(scan.data(), scan.format(), minRange, maxRange, angleMin, angleMax, angleIncrement, 0, localTransform);
253 }
254 
256  const LaserScan & scan,
257  Format format,
258  float minRange,
259  float maxRange,
260  float angleMin,
261  float angleMax,
262  float angleIncrement,
263  const Transform & localTransform)
264 {
265  init(scan.data(), format, minRange, maxRange, angleMin, angleMax, angleIncrement, 0, localTransform);
266 }
267 
269  const cv::Mat & data,
270  Format format,
271  float minRange,
272  float maxRange,
273  float angleMin,
274  float angleMax,
275  float angleIncrement,
276  const Transform & localTransform)
277 {
278  init(data, format, minRange, maxRange, angleMin, angleMax, angleIncrement, 0, localTransform);
279 }
280 
282  const cv::Mat & data,
283  Format format,
284  float rangeMin,
285  float rangeMax,
286  float angleMin,
287  float angleMax,
288  float angleIncrement,
289  int maxPoints,
290  const Transform & localTransform)
291 {
292  UASSERT(data.empty() || data.rows == 1);
293  UASSERT(data.empty() || data.type() == CV_8UC1 || data.type() == CV_32FC2 || data.type() == CV_32FC3 || data.type() == CV_32FC(4) || data.type() == CV_32FC(5) || data.type() == CV_32FC(6) || data.type() == CV_32FC(7));
294  UASSERT(!localTransform.isNull());
295 
296  bool is2D = false;
297  if(angleIncrement != 0.0f)
298  {
299  // 2D scan
300  is2D = true;
301  UASSERT(rangeMax>rangeMin);
302  UASSERT((angleIncrement>0 && angleMax>angleMin) || (angleIncrement<0 && angleMax<angleMin));
303  maxPoints_ = std::ceil((angleMax - angleMin) / angleIncrement)+1;
304  }
305  else
306  {
307  // 3D scan
308  UASSERT(rangeMax>=rangeMin);
310  }
311 
312  data_ = data;
313  format_ = format;
320 
321  if(!data.empty() && !isCompressed())
322  {
323  if(is2D && data_.cols > maxPoints_)
324  {
325  UWARN("The number of points (%d) in the scan is over the maximum "
326  "points (%d) defined by angle settings (min=%f max=%f inc=%f). "
327  "The scan info may be wrong!",
329  }
330  else if(!is2D && maxPoints_>0 && data_.cols > maxPoints_)
331  {
332  UDEBUG("The number of points (%d) in the scan is over the maximum "
333  "points (%d) defined by max points setting.",
334  data_.cols, maxPoints_);
335  }
336 
337  if(format == kUnknown)
338  {
339  if(angleIncrement_ != 0)
340  {
342  }
343  else
344  {
346  }
347  }
348  else // verify that format corresponds to expected number of channels
349  {
350  UASSERT_MSG(data.channels() != 2 || (data.channels() == 2 && format == kXY), uFormat("format=%s", LaserScan::formatName(format).c_str()).c_str());
351  UASSERT_MSG(data.channels() != 3 || (data.channels() == 3 && (format == kXYZ || format == kXYI)), uFormat("format=%s", LaserScan::formatName(format).c_str()).c_str());
352  UASSERT_MSG(data.channels() != 4 || (data.channels() == 4 && (format == kXYZI || format == kXYZRGB)), uFormat("format=%s", LaserScan::formatName(format).c_str()).c_str());
353  UASSERT_MSG(data.channels() != 5 || (data.channels() == 5 && (format == kXYNormal)), uFormat("format=%s", LaserScan::formatName(format).c_str()).c_str());
354  UASSERT_MSG(data.channels() != 6 || (data.channels() == 6 && (format == kXYINormal || format == kXYZNormal)), uFormat("format=%s", LaserScan::formatName(format).c_str()).c_str());
355  UASSERT_MSG(data.channels() != 7 || (data.channels() == 7 && (format == kXYZRGBNormal || format == kXYZINormal)), uFormat("format=%s", LaserScan::formatName(format).c_str()).c_str());
356  }
357  }
358 }
359 
361 {
362  if(angleIncrement_ > 0.0f)
363  {
365  }
367 }
368 
369 float & LaserScan::field(unsigned int pointIndex, unsigned int channelOffset)
370 {
371  UASSERT(pointIndex < (unsigned int)data_.cols);
372  UASSERT(channelOffset < (unsigned int)data_.channels());
373  return data_.ptr<float>(0, pointIndex)[channelOffset];
374 }
375 
377 {
378  *this = *this+scan;
379  return *this;
380 }
381 
383 {
384  UASSERT(this->empty() || scan.empty() || this->format() == scan.format());
385  LaserScan dest;
386  if(!scan.empty())
387  {
388  if(this->empty())
389  {
390  dest = scan.clone();
391  }
392  else
393  {
394  cv::Mat destData(1, data_.cols + scan.data().cols, data_.type());
395  data_.copyTo(destData(cv::Range::all(), cv::Range(0,data_.cols)));
396  scan.data().copyTo(destData(cv::Range::all(), cv::Range(data_.cols, data_.cols+scan.data().cols)));
397  dest = LaserScan(destData, 0, 0, this->format());
398  }
399  }
400  else
401  {
402  dest = this->clone();
403  }
404  return dest;
405 }
406 
407 }
int maxPoints() const
Definition: LaserScan.h:116
int channels() const
Definition: LaserScan.h:115
f
float angleMin() const
Definition: LaserScan.h:119
GLM_FUNC_DECL bool all(vecType< bool, P > const &v)
const cv::Mat & data() const
Definition: LaserScan.h:112
Format format() const
Definition: LaserScan.h:113
Some conversion functions.
#define UFATAL(...)
static bool isScanHasNormals(const Format &format)
Definition: LaserScan.cpp:112
float rangeMax() const
Definition: LaserScan.h:118
float & field(unsigned int pointIndex, unsigned int channelOffset)
Definition: LaserScan.cpp:369
#define UASSERT(condition)
void init(const cv::Mat &data, Format format, float minRange, float maxRange, float angleMin, float angleMax, float angleIncrement, int maxPoints, const Transform &localTransform=Transform::getIdentity())
Definition: LaserScan.cpp:281
#define UASSERT_MSG(condition, msg_str)
Definition: ULogger.h:67
string name
static bool isScanHasRGB(const Format &format)
Definition: LaserScan.cpp:116
bool empty() const
Definition: LaserScan.h:124
float rangeMin() const
Definition: LaserScan.h:117
bool isNull() const
Definition: Transform.cpp:107
float angleMax() const
Definition: LaserScan.h:120
LaserScan & operator+=(const LaserScan &)
Definition: LaserScan.cpp:376
#define UDEBUG(...)
LaserScan operator+(const LaserScan &)
Definition: LaserScan.cpp:382
bool isCompressed() const
Definition: LaserScan.h:132
ULogger class and convenient macros.
static bool isScan2d(const Format &format)
Definition: LaserScan.cpp:108
#define UWARN(...)
Transform localTransform_
Definition: LaserScan.h:172
const char char * dest
Definition: lz4hc.h:181
float angleIncrement() const
Definition: LaserScan.h:121
std::string formatName() const
Definition: LaserScan.h:114
static bool isScanHasIntensity(const Format &format)
Definition: LaserScan.cpp:120
std::string UTILITE_EXP uFormat(const char *fmt,...)
static LaserScan backwardCompatibility(const cv::Mat &oldScanFormat, int maxPoints=0, int maxRange=0, const Transform &localTransform=Transform::getIdentity())
Definition: LaserScan.cpp:125
Transform clone() const
Definition: Transform.cpp:102
GLM_FUNC_DECL genType ceil(genType const &x)
Transform localTransform() const
Definition: LaserScan.h:122
LaserScan clone() const
Definition: LaserScan.cpp:360


rtabmap
Author(s): Mathieu Labbe
autogenerated on Mon Jan 23 2023 03:37:28