1 #ifndef pcl_ROS_POINT_CLOUD_H_ 2 #define pcl_ROS_POINT_CLOUD_H_ 5 #include <pcl/point_cloud.h> 6 #include <pcl/pcl_config.h> 7 #if PCL_VERSION_COMPARE(>=, 1, 11, 0) 8 #include <pcl/type_traits.h> 10 #include <pcl/point_traits.h> 11 #endif // PCL_VERSION_COMPARE(>=, 1, 11, 0) 12 #include <pcl/for_each_type.h> 13 #include <pcl/conversions.h> 15 #include <sensor_msgs/PointCloud2.h> 16 #include <boost/foreach.hpp> 17 #include <boost/mpl/size.hpp> 18 #include <boost/ref.hpp> 19 #include <boost/thread/mutex.hpp> 25 template<
typename Stream,
typename Po
intT>
32 const char* name = pcl::traits::name<PointT, U>::value;
33 std::uint32_t name_length = strlen(name);
36 memcpy(
stream_.advance(name_length), name, name_length);
38 std::uint32_t offset = pcl::traits::offset<PointT, U>::value;
41 std::uint8_t
datatype = pcl::traits::datatype<PointT, U>::value;
44 std::uint32_t count = pcl::traits::datatype<PointT, U>::size;
51 template<
typename Po
intT>
58 std::uint32_t name_length = strlen(pcl::traits::name<PointT, U>::value);
59 length += name_length + 13;
69 namespace message_traits
74 static const char*
value(
const pcl::PointCloud<T>&) {
return value(); }
87 static const char*
value(
const pcl::PointCloud<T>&) {
return value(); }
93 static const char*
value(
const pcl::PointCloud<T>&) {
return value(); }
110 header_.reset(
new std_msgs::Header());
112 return &(header_->stamp);
115 header_const_.reset(
new std_msgs::Header());
117 return &(header_const_->stamp);
130 static std::string*
pointer(pcl::PointCloud<T>& m) {
return &m.header.frame_id; }
131 static std::string
const*
pointer(
const pcl::PointCloud<T>& m) {
return &m.header.frame_id; }
132 static std::string
value(
const pcl::PointCloud<T>& m) {
return m.header.frame_id; }
137 namespace serialization
142 template<
typename Stream>
143 inline static void write(
Stream& stream,
const pcl::PointCloud<T>& m)
145 stream.next(m.header);
148 uint32_t height = m.height, width = m.width;
149 if (height == 0 && width == 0) {
150 width = m.points.size();
157 typedef typename pcl::traits::fieldList<T>::type FieldList;
158 uint32_t fields_size = boost::mpl::size<FieldList>::value;
159 stream.next(fields_size);
163 uint8_t is_bigendian =
false;
164 stream.next(is_bigendian);
167 uint32_t point_step =
sizeof(T);
168 stream.next(point_step);
169 uint32_t row_step = point_step * width;
170 stream.next(row_step);
171 uint32_t data_size = row_step * height;
172 stream.next(data_size);
173 memcpy(stream.
advance(data_size), m.points.data(), data_size);
175 uint8_t is_dense = m.is_dense;
176 stream.next(is_dense);
179 template<
typename Stream>
180 inline static void read(
Stream& stream, pcl::PointCloud<T>& m)
185 stream.next(m.height);
186 stream.next(m.width);
189 std::vector<sensor_msgs::PointField> fields;
193 static pcl::MsgFieldMap mapping;
194 static boost::mutex mutex;
197 boost::mutex::scoped_lock lock(mutex);
198 pcl::createMapping<T>(fields, mapping);
201 uint8_t is_bigendian;
202 stream.next(is_bigendian);
203 uint32_t point_step, row_step;
204 stream.next(point_step);
205 stream.next(row_step);
209 stream.next(data_size);
210 assert(data_size == m.height * m.width * point_step);
211 m.points.resize(m.height * m.width);
212 uint8_t* m_data =
reinterpret_cast<uint8_t*
>(m.points.data());
214 if (mapping.size() == 1 &&
215 mapping[0].serialized_offset == 0 &&
216 mapping[0].struct_offset == 0 &&
217 point_step ==
sizeof(T))
219 uint32_t m_row_step =
sizeof(T) * m.width;
221 if (m_row_step == row_step)
223 memcpy (m_data, stream.
advance(data_size), data_size);
227 for (uint32_t i = 0; i < m.height; ++i, m_data += m_row_step)
228 memcpy (m_data, stream.
advance(row_step), m_row_step);
234 for (uint32_t row = 0; row < m.height; ++row) {
235 const uint8_t* stream_data = stream.
advance(row_step);
236 for (uint32_t col = 0; col < m.width; ++col, stream_data += point_step) {
237 BOOST_FOREACH(
const pcl::detail::FieldMapping& fm, mapping) {
238 memcpy(m_data + fm.struct_offset, stream_data + fm.serialized_offset, fm.size);
246 stream.next(is_dense);
247 m.is_dense = is_dense;
258 typedef typename pcl::traits::fieldList<T>::type FieldList;
259 pcl::for_each_type<FieldList>(boost::ref(fl));
267 length += m.points.size() *
sizeof(T);
280 #if defined(__cpp_rvalue_references) && defined(__cpp_constexpr) 281 #define ROS_POINTER_COMPATIBILITY_IMPLEMENTED 1 283 #define ROS_POINTER_COMPATIBILITY_IMPLEMENTED 0 286 #if ROS_POINTER_COMPATIBILITY_IMPLEMENTED 287 #include <type_traits> 290 #if PCL_VERSION_COMPARE(>=, 1, 11, 0) 291 #include <pcl/memory.h> 292 #elif PCL_VERSION_COMPARE(>=, 1, 10, 0) 293 #include <pcl/make_shared.h> 301 #if ROS_POINTER_COMPATIBILITY_IMPLEMENTED 302 #if PCL_VERSION_COMPARE(>=, 1, 10, 0) 304 constexpr
static bool pcl_uses_boost = std::is_same<boost::shared_ptr<T>,
305 pcl::shared_ptr<T>>::value;
308 constexpr
static bool pcl_uses_boost =
true;
311 template<
class SharedPo
inter>
struct Holder
315 Holder(
const SharedPointer &p) : p(p) {}
316 Holder(
const Holder &other) : p(other.p) {}
317 Holder(Holder &&other) : p(std::move(other.p)) {}
325 typedef Holder<std::shared_ptr<T>> H;
326 if(H *h = boost::get_deleter<H>(p))
332 return std::shared_ptr<T>(p.get(), Holder<boost::shared_ptr<T>>(p));
339 typedef Holder<boost::shared_ptr<T>> H;
340 if(H * h = std::get_deleter<H>(p))
359 #if ROS_POINTER_COMPATIBILITY_IMPLEMENTED 363 return detail::to_boost_ptr(p);
367 template <
class T,
class =
typename std::enable_if<!detail::pcl_uses_boost<T>>::type>
368 inline std::shared_ptr<T>
pcl_ptr(
const std::shared_ptr<T> &p)
373 template <
class T,
class =
typename std::enable_if<!detail::pcl_uses_boost<T>>::type>
376 return detail::to_std_ptr(p);
379 template <
class T,
class =
typename std::enable_if<detail::pcl_uses_boost<T>>::type>
382 return detail::to_boost_ptr(p);
385 template <
class T,
class =
typename std::enable_if<detail::pcl_uses_boost<T>>::type>
static ros::Time * pointer(typename pcl::PointCloud< T > &m)
static ros::Time value(const typename pcl::PointCloud< T > &m)
static void write(Stream &stream, const pcl::PointCloud< T > &m)
static boost::shared_ptr< std_msgs::Header > header_const_
sensor_msgs::PointCloud2 PointCloud
ROS_FORCE_INLINE uint8_t * advance(uint32_t len)
static const char * value(const pcl::PointCloud< T > &)
static const char * value()
static uint32_t serializedLength(const pcl::PointCloud< T > &m)
#define ROS_STATIC_ASSERT(cond)
static std::string * pointer(pcl::PointCloud< T > &m)
FieldStreamer(Stream &stream)
static const char * value()
static std::string const * pointer(const pcl::PointCloud< T > &m)
static boost::shared_ptr< std_msgs::Header > header_
void toPCL(const ros::Time &stamp, std::uint64_t &pcl_stamp)
static ros::Time const * pointer(const typename pcl::PointCloud< T > &m)
static const char * value(const pcl::PointCloud< T > &)
static std::string value(const pcl::PointCloud< T > &m)
static void read(Stream &stream, pcl::PointCloud< T > &m)
uint32_t serializationLength(const T &t)
static const char * value()
static const char * value(const pcl::PointCloud< T > &)
TFSIMD_FORCE_INLINE tfScalar length(const Quaternion &q)
void fromPCL(const std::uint64_t &pcl_stamp, ros::Time &stamp)
boost::shared_ptr< T > pcl_ptr(const boost::shared_ptr< T > &p)
boost::shared_ptr< T > ros_ptr(const boost::shared_ptr< T > &p)