point_cloud_conversion.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) 2010, Willow Garage, Inc.
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 Willow Garage, Inc. 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  * $Id$
36  *
37  */
38 
39 #ifndef SENSOR_MSGS_POINT_CLOUD_CONVERSION_H
40 #define SENSOR_MSGS_POINT_CLOUD_CONVERSION_H
41 
42 #include <sensor_msgs/PointCloud.h>
44 #include <sensor_msgs/point_field_conversion.h>
45 
50 namespace sensor_msgs
51 {
53 
57 static inline int getPointCloud2FieldIndex (const sensor_msgs::PointCloud2 &cloud, const std::string &field_name)
58 {
59  // Get the index we need
60  for (size_t d = 0; d < cloud.fields.size (); ++d)
61  if (cloud.fields[d].name == field_name)
62  return (d);
63  return (-1);
64 }
65 
67 
72 {
73  output.header = input.header;
74  output.width = input.points.size ();
75  output.height = 1;
76  output.fields.resize (3 + input.channels.size ());
77  // Convert x/y/z to fields
78  output.fields[0].name = "x"; output.fields[1].name = "y"; output.fields[2].name = "z";
79  int offset = 0;
80  // All offsets are *4, as all field data types are float32
81  for (size_t d = 0; d < output.fields.size (); ++d, offset += 4)
82  {
83  output.fields[d].offset = offset;
84  output.fields[d].datatype = sensor_msgs::PointField::FLOAT32;
85  output.fields[d].count = 1;
86  }
87  output.point_step = offset;
88  output.row_step = output.point_step * output.width;
89  // Convert the remaining of the channels to fields
90  for (size_t d = 0; d < input.channels.size (); ++d)
91  output.fields[3 + d].name = input.channels[d].name;
92  output.data.resize (input.points.size () * output.point_step);
93  output.is_bigendian = false; // @todo ?
94  output.is_dense = false;
95 
96  // Copy the data points
97  for (size_t cp = 0; cp < input.points.size (); ++cp)
98  {
99  memcpy (&output.data[cp * output.point_step + output.fields[0].offset], &input.points[cp].x, sizeof (float));
100  memcpy (&output.data[cp * output.point_step + output.fields[1].offset], &input.points[cp].y, sizeof (float));
101  memcpy (&output.data[cp * output.point_step + output.fields[2].offset], &input.points[cp].z, sizeof (float));
102  for (size_t d = 0; d < input.channels.size (); ++d)
103  {
104  if (input.channels[d].values.size() == input.points.size())
105  {
106  memcpy (&output.data[cp * output.point_step + output.fields[3 + d].offset], &input.channels[d].values[cp], sizeof (float));
107  }
108  }
109  }
110  return (true);
111 }
112 
114 
119 {
120 
121  output.header = input.header;
122  output.points.resize (input.width * input.height);
123  output.channels.resize (input.fields.size () - 3);
124  // Get the x/y/z field offsets
125  int x_idx = getPointCloud2FieldIndex (input, "x");
126  int y_idx = getPointCloud2FieldIndex (input, "y");
127  int z_idx = getPointCloud2FieldIndex (input, "z");
128  if (x_idx == -1 || y_idx == -1 || z_idx == -1)
129  {
130  std::cerr << "x/y/z coordinates not found! Cannot convert to sensor_msgs::PointCloud!" << std::endl;
131  return (false);
132  }
133  int x_offset = input.fields[x_idx].offset;
134  int y_offset = input.fields[y_idx].offset;
135  int z_offset = input.fields[z_idx].offset;
136  uint8_t x_datatype = input.fields[x_idx].datatype;
137  uint8_t y_datatype = input.fields[y_idx].datatype;
138  uint8_t z_datatype = input.fields[z_idx].datatype;
139 
140  // Convert the fields to channels
141  int cur_c = 0;
142  for (size_t d = 0; d < input.fields.size (); ++d)
143  {
144  if ((int)input.fields[d].offset == x_offset || (int)input.fields[d].offset == y_offset || (int)input.fields[d].offset == z_offset)
145  continue;
146  output.channels[cur_c].name = input.fields[d].name;
147  output.channels[cur_c].values.resize (output.points.size ());
148  cur_c++;
149  }
150 
151  // Copy the data points
152  for (size_t cp = 0; cp < output.points.size (); ++cp)
153  {
154  // Copy x/y/z
155  output.points[cp].x = sensor_msgs::readPointCloud2BufferValue<float>(&input.data[cp * input.point_step + x_offset], x_datatype);
156  output.points[cp].y = sensor_msgs::readPointCloud2BufferValue<float>(&input.data[cp * input.point_step + y_offset], y_datatype);
157  output.points[cp].z = sensor_msgs::readPointCloud2BufferValue<float>(&input.data[cp * input.point_step + z_offset], z_datatype);
158  // Copy the rest of the data
159  int cur_c = 0;
160  for (size_t d = 0; d < input.fields.size (); ++d)
161  {
162  if ((int)input.fields[d].offset == x_offset || (int)input.fields[d].offset == y_offset || (int)input.fields[d].offset == z_offset)
163  continue;
164  output.channels[cur_c++].values[cp] = sensor_msgs::readPointCloud2BufferValue<float>(&input.data[cp * input.point_step + input.fields[d].offset], input.fields[d].datatype);
165  }
166  }
167  return (true);
168 }
169 }
170 #endif// SENSOR_MSGS_POINT_CLOUD_CONVERSION_H
sensor_msgs::PointCloud2_::row_step
_row_step_type row_step
Definition: PointCloud2.h:74
sensor_msgs::PointCloud_
Definition: PointCloud.h:26
sensor_msgs::PointCloud2_::width
_width_type width
Definition: PointCloud2.h:62
sensor_msgs::getPointCloud2FieldIndex
static int getPointCloud2FieldIndex(const sensor_msgs::PointCloud2 &cloud, const std::string &field_name)
sensor_msgs::PointCloud2_::point_step
_point_step_type point_step
Definition: PointCloud2.h:71
sensor_msgs::PointCloud_::points
_points_type points
Definition: PointCloud.h:48
sensor_msgs::PointCloud2_::fields
_fields_type fields
Definition: PointCloud2.h:65
sensor_msgs::PointCloud2_::height
_height_type height
Definition: PointCloud2.h:59
sensor_msgs::PointCloud2_::data
_data_type data
Definition: PointCloud2.h:77
PointCloud2.h
d
d
sensor_msgs::PointCloud2_::is_bigendian
_is_bigendian_type is_bigendian
Definition: PointCloud2.h:68
sensor_msgs::PointCloud_::header
_header_type header
Definition: PointCloud.h:45
sensor_msgs::PointField_::FLOAT32
@ FLOAT32
Definition: PointField.h:62
sensor_msgs::PointCloud2_
Definition: PointCloud2.h:25
PointCloud.h
sick_scan_base.h
sensor_msgs::PointCloud2_::header
_header_type header
Definition: PointCloud2.h:56
sensor_msgs::PointCloud_::channels
_channels_type channels
Definition: PointCloud.h:51
sensor_msgs::convertPointCloud2ToPointCloud
static bool convertPointCloud2ToPointCloud(const sensor_msgs::PointCloud2 &input, sensor_msgs::PointCloud &output)
sensor_msgs
Tools for manipulating sensor_msgs.
sensor_msgs::PointCloud2_::is_dense
_is_dense_type is_dense
Definition: PointCloud2.h:80
sensor_msgs::convertPointCloudToPointCloud2
static bool convertPointCloudToPointCloud2(const sensor_msgs::PointCloud &input, sensor_msgs::PointCloud2 &output)


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