impl/point_cloud2_iterator.h
Go to the documentation of this file.
1 #include "sick_scan/sick_scan_base.h" /* Base definitions included in all header files, added by add_sick_scan_base_header.py. Do not edit this line. */
2 /*
3  * Software License Agreement (BSD License)
4  *
5  * Copyright (c) 2013, Open Source Robotics Foundation
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Open Source Robotics Foundation nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 #ifndef SENSOR_MSGS_IMPL_POINT_CLOUD_ITERATOR_H
37 #define SENSOR_MSGS_IMPL_POINT_CLOUD_ITERATOR_H
38 
40 #include <cstdarg>
41 #include <string>
42 #include <vector>
43 
49 namespace
50 {
54 inline int sizeOfPointField(int datatype)
55 {
57  return 1;
59  return 2;
62  return 4;
64  return 8;
65  else
66  {
67  std::stringstream err;
68  err << "PointField of type " << datatype << " does not exist";
69  throw std::runtime_error(err.str());
70  }
71  return -1;
72 }
73 
82 inline int addPointField(sensor_msgs::PointCloud2 &cloud_msg, const std::string &name, int count, int datatype,
83  int offset)
84 {
85  sensor_msgs::PointField point_field;
86  point_field.name = name;
87  point_field.count = count;
88  point_field.datatype = datatype;
89  point_field.offset = offset;
90  cloud_msg.fields.push_back(point_field);
91 
92  // Update the offset
93  return offset + point_field.count * sizeOfPointField(datatype);
94 }
95 }
96 
98 
99 namespace sensor_msgs
100 {
101 
102 inline PointCloud2Modifier::PointCloud2Modifier(PointCloud2& cloud_msg) : cloud_msg_(cloud_msg)
103 {
104 }
105 
106 inline size_t PointCloud2Modifier::size() const
107 {
108  return cloud_msg_.data.size() / cloud_msg_.point_step;
109 }
110 
111 inline void PointCloud2Modifier::reserve(size_t size)
112 {
113  cloud_msg_.data.reserve(size * cloud_msg_.point_step);
114 }
115 
116 inline void PointCloud2Modifier::resize(size_t size)
117 {
118  cloud_msg_.data.resize(size * cloud_msg_.point_step);
119 
120  // Update height/width
121  if (cloud_msg_.height == 1) {
122  cloud_msg_.width = size;
123  cloud_msg_.row_step = size * cloud_msg_.point_step;
124  } else
125  if (cloud_msg_.width == 1)
126  cloud_msg_.height = size;
127  else {
128  cloud_msg_.height = 1;
129  cloud_msg_.width = size;
130  cloud_msg_.row_step = size * cloud_msg_.point_step;
131  }
132 }
133 
134 inline void PointCloud2Modifier::clear()
135 {
136  cloud_msg_.data.clear();
137 
138  // Update height/width
139  if (cloud_msg_.height == 1)
140  cloud_msg_.row_step = cloud_msg_.width = 0;
141  else
142  if (cloud_msg_.width == 1)
143  cloud_msg_.height = 0;
144  else
145  cloud_msg_.row_step = cloud_msg_.width = cloud_msg_.height = 0;
146 }
147 
148 
166 inline void PointCloud2Modifier::setPointCloud2Fields(int n_fields, ...)
167 {
168  cloud_msg_.fields.clear();
169  cloud_msg_.fields.reserve(n_fields);
170  va_list vl;
171  va_start(vl, n_fields);
172  int offset = 0;
173  for (int i = 0; i < n_fields; ++i) {
174  // Create the corresponding PointField
175  std::string name(va_arg(vl, char*));
176  int count(va_arg(vl, int));
177  int datatype(va_arg(vl, int));
178  offset = addPointField(cloud_msg_, name, count, datatype, offset);
179  }
180  va_end(vl);
181 
182  // Resize the point cloud accordingly
183  cloud_msg_.point_step = offset;
184  cloud_msg_.row_step = cloud_msg_.width * cloud_msg_.point_step;
185  cloud_msg_.data.resize(cloud_msg_.height * cloud_msg_.row_step);
186 }
187 
198 inline void PointCloud2Modifier::setPointCloud2FieldsByString(int n_fields, ...)
199 {
200  cloud_msg_.fields.clear();
201  cloud_msg_.fields.reserve(n_fields);
202  va_list vl;
203  va_start(vl, n_fields);
204  int offset = 0;
205  for (int i = 0; i < n_fields; ++i) {
206  // Create the corresponding PointFields
207  std::string
208  field_name = std::string(va_arg(vl, char*));
209  if (field_name == "xyz") {
210  sensor_msgs::PointField point_field;
211  // Do x, y and z
212  offset = addPointField(cloud_msg_, "x", 1, sensor_msgs::PointField::FLOAT32, offset);
213  offset = addPointField(cloud_msg_, "y", 1, sensor_msgs::PointField::FLOAT32, offset);
214  offset = addPointField(cloud_msg_, "z", 1, sensor_msgs::PointField::FLOAT32, offset);
215  offset += sizeOfPointField(sensor_msgs::PointField::FLOAT32);
216  } else
217  if ((field_name == "rgb") || (field_name == "rgba")) {
218  offset = addPointField(cloud_msg_, field_name, 1, sensor_msgs::PointField::FLOAT32, offset);
219  offset += 3 * sizeOfPointField(sensor_msgs::PointField::FLOAT32);
220  } else
221  throw std::runtime_error("Field " + field_name + " does not exist");
222  }
223  va_end(vl);
224 
225  // Resize the point cloud accordingly
226  cloud_msg_.point_step = offset;
227  cloud_msg_.row_step = cloud_msg_.width * cloud_msg_.point_step;
228  cloud_msg_.data.resize(cloud_msg_.height * cloud_msg_.row_step);
229 }
230 
232 
233 namespace impl
234 {
235 
238 template<typename T, typename TT, typename U, typename C, template <typename> class V>
239 PointCloud2IteratorBase<T, TT, U, C, V>::PointCloud2IteratorBase() : data_char_(0), data_(0), data_end_(0)
240 {
241 }
242 
247 template<typename T, typename TT, typename U, typename C, template <typename> class V>
248 PointCloud2IteratorBase<T, TT, U, C, V>::PointCloud2IteratorBase(C &cloud_msg, const std::string &field_name)
249 {
250  int offset = set_field(cloud_msg, field_name);
251 
252  data_char_ = &(cloud_msg.data.front()) + offset;
253  data_ = reinterpret_cast<TT*>(data_char_);
254  data_end_ = reinterpret_cast<TT*>(&(cloud_msg.data.back()) + 1 + offset);
255 }
256 
261 template<typename T, typename TT, typename U, typename C, template <typename> class V>
262 V<T>& PointCloud2IteratorBase<T, TT, U, C, V>::operator =(const V<T> &iter)
263 {
264  if (this != &iter)
265  {
266  point_step_ = iter.point_step_;
267  data_char_ = iter.data_char_;
268  data_ = iter.data_;
269  data_end_ = iter.data_end_;
270  is_bigendian_ = iter.is_bigendian_;
271  }
272 
273  return *this;
274 }
275 
281 template<typename T, typename TT, typename U, typename C, template <typename> class V>
282 TT& PointCloud2IteratorBase<T, TT, U, C, V>::operator [](size_t i) const
283 {
284  return *(data_ + i);
285 }
286 
290 template<typename T, typename TT, typename U, typename C, template <typename> class V>
291 TT& PointCloud2IteratorBase<T, TT, U, C, V>::operator *() const
292 {
293  return *data_;
294 }
295 
299 template<typename T, typename TT, typename U, typename C, template <typename> class V>
300 V<T>& PointCloud2IteratorBase<T, TT, U, C, V>::operator ++()
301 {
302  data_char_ += point_step_;
303  data_ = reinterpret_cast<TT*>(data_char_);
304  return *static_cast<V<T>*>(this);
305 }
306 
311 template<typename T, typename TT, typename U, typename C, template <typename> class V>
313 {
314  V<T> res = *static_cast<V<T>*>(this);
315 
316  res.data_char_ += i*point_step_;
317  res.data_ = reinterpret_cast<TT*>(res.data_char_);
318 
319  return res;
320 }
321 
325 template<typename T, typename TT, typename U, typename C, template <typename> class V>
326 V<T>& PointCloud2IteratorBase<T, TT, U, C, V>::operator +=(int i)
327 {
328  data_char_ += i*point_step_;
329  data_ = reinterpret_cast<TT*>(data_char_);
330  return *static_cast<V<T>*>(this);
331 }
332 
336 template<typename T, typename TT, typename U, typename C, template <typename> class V>
337 bool PointCloud2IteratorBase<T, TT, U, C, V>::operator !=(const V<T>& iter) const
338 {
339  return iter.data_ != data_;
340 }
341 
345 template<typename T, typename TT, typename U, typename C, template <typename> class V>
346 V<T> PointCloud2IteratorBase<T, TT, U, C, V>::end() const
347 {
348  V<T> res = *static_cast<const V<T>*>(this);
349  res.data_ = data_end_;
350  return res;
351 }
352 
358 template<typename T, typename TT, typename U, typename C, template <typename> class V>
359 int PointCloud2IteratorBase<T, TT, U, C, V>::set_field(const sensor_msgs::PointCloud2 &cloud_msg, const std::string &field_name)
360 {
361  is_bigendian_ = cloud_msg.is_bigendian;
362  point_step_ = cloud_msg.point_step;
363  // make sure the channel is valid
364  std::vector<sensor_msgs::PointField>::const_iterator field_iter = cloud_msg.fields.begin(), field_end =
365  cloud_msg.fields.end();
366  while ((field_iter != field_end) && (field_iter->name != field_name))
367  ++field_iter;
368 
369  if (field_iter == field_end) {
370  // Handle the special case of r,g,b,a (we assume they are understood as the channels of an rgb or rgba field)
371  if ((field_name == "r") || (field_name == "g") || (field_name == "b") || (field_name == "a"))
372  {
373  // Check that rgb or rgba is present
374  field_iter = cloud_msg.fields.begin();
375  while ((field_iter != field_end) && (field_iter->name != "rgb") && (field_iter->name != "rgba"))
376  ++field_iter;
377  if (field_iter == field_end)
378  throw std::runtime_error("Field " + field_name + " does not exist");
379  if (field_name == "r")
380  {
381  if (is_bigendian_)
382  return field_iter->offset + 1;
383  else
384  return field_iter->offset + 2;
385  }
386  if (field_name == "g")
387  {
388  if (is_bigendian_)
389  return field_iter->offset + 2;
390  else
391  return field_iter->offset + 1;
392  }
393  if (field_name == "b")
394  {
395  if (is_bigendian_)
396  return field_iter->offset + 3;
397  else
398  return field_iter->offset + 0;
399  }
400  if (field_name == "a")
401  {
402  if (is_bigendian_)
403  return field_iter->offset + 0;
404  else
405  return field_iter->offset + 3;
406  }
407  } else
408  throw std::runtime_error("Field " + field_name + " does not exist");
409  }
410 
411  return field_iter->offset;
412 }
413 
414 }
415 }
416 
417 #endif// SENSOR_MSGS_IMPL_POINT_CLOUD_ITERATOR_H
sensor_msgs::PointField_::datatype
_datatype_type datatype
Definition: PointField.h:50
sensor_msgs::PointField_::UINT8
@ UINT8
Definition: PointField.h:57
sensor_msgs::PointField_::INT16
@ INT16
Definition: PointField.h:58
sensor_msgs::PointCloud2_::point_step
_point_step_type point_step
Definition: PointCloud2.h:71
roswrap::message_traits::datatype
const char * datatype()
returns DataType<M>::value();
Definition: message_traits.h:236
sensor_msgs::PointCloud2Modifier::PointCloud2Modifier
PointCloud2Modifier(PointCloud2 &cloud_msg)
Definition: impl/point_cloud2_iterator.h:102
sensor_msgs::PointCloud2
::sensor_msgs::PointCloud2_< std::allocator< void > > PointCloud2
Definition: PointCloud2.h:90
sensor_msgs::PointField_::FLOAT64
@ FLOAT64
Definition: PointField.h:63
sensor_msgs::PointCloud2_::fields
_fields_type fields
Definition: PointCloud2.h:65
operator+
TiXmlString operator+(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.cpp:81
sensor_msgs::PointField_::UINT32
@ UINT32
Definition: PointField.h:61
api.setup.name
name
Definition: python/api/setup.py:12
PointCloud2.h
sensor_msgs::PointField_::count
_count_type count
Definition: PointField.h:53
sensor_msgs::PointField_::name
_name_type name
Definition: PointField.h:44
sensor_msgs::PointField_::INT8
@ INT8
Definition: PointField.h:56
sensor_msgs::PointCloud2_::is_bigendian
_is_bigendian_type is_bigendian
Definition: PointCloud2.h:68
sensor_msgs::PointField_::offset
_offset_type offset
Definition: PointField.h:47
sensor_msgs::PointField_::FLOAT32
@ FLOAT32
Definition: PointField.h:62
sensor_msgs::PointCloud2_
Definition: PointCloud2.h:25
sensor_msgs::PointField_::INT32
@ INT32
Definition: PointField.h:60
sick_scan_base.h
sensor_msgs::PointField_
Definition: PointField.h:23
operator!=
bool operator!=(const TiXmlString &a, const TiXmlString &b)
Definition: tinystr.h:293
sensor_msgs
Tools for manipulating sensor_msgs.
sensor_msgs::PointField_::UINT16
@ UINT16
Definition: PointField.h:59


sick_scan_xd
Author(s): Michael Lehning , Jochen Sprickerhof , Martin Günther
autogenerated on Fri Oct 25 2024 02:47:09