Skip to content

Commit

Permalink
Add static message field mapping to Serializer class
Browse files Browse the repository at this point in the history
Currently, Serializer caches computed message field mapping in a
protected field [1] of pcl::PointCloud<T> class. This commit adds a
static field to the Serializer class and stores the mapping there
instead.

Motivation: as a part of boost::shared_ptr -> std::shared_ptr migration
in PCL [2] we have changed the type of the aforementioned protected
field. Later on we were informed that this broke pcl_ros. This was
unexpected since the field and the associated accessor function are not
a public API. After some investigation we came to conclusion that
pcl_ros is probably the only user of that field. With this in mind, we'd
like to get rid of it altogether. Therefore, this commit serves two
purposes: unbreak pcl_ros for PCL master and get rid of the dependency
on non-public API that is going to be deprecated/removed soon.

References:
[1] https://github.com/taketwo/pcl/blob/0a6508ab6c18b5adff3aaf6ef1d2884647f9acba/common/include/pcl/point_cloud.h#L606
[2] PointCloudLibrary/pcl#2792
  • Loading branch information
taketwo committed Dec 29, 2019
1 parent 49545ac commit 7ccb486
Showing 1 changed file with 17 additions and 13 deletions.
30 changes: 17 additions & 13 deletions pcl_ros/include/pcl_ros/point_cloud.h
Original file line number Diff line number Diff line change
Expand Up @@ -206,15 +206,7 @@ namespace ros
stream.next(fields);

// Construct field mapping if deserializing for the first time
boost::shared_ptr<pcl::MsgFieldMap>& mapping_ptr = pcl::detail::getMapping(m);
if (!mapping_ptr)
{
// This normally should get allocated by DefaultMessageCreator, but just in case
mapping_ptr = boost::make_shared<pcl::MsgFieldMap>();
}
pcl::MsgFieldMap& mapping = *mapping_ptr;
if (mapping.empty())
pcl::createMapping<T> (fields, mapping);
createMapping(fields);

uint8_t is_bigendian;
stream.next(is_bigendian); // ignoring...
Expand All @@ -229,9 +221,9 @@ namespace ros
m.points.resize(m.height * m.width);
uint8_t* m_data = reinterpret_cast<uint8_t*>(&m.points[0]);
// If the data layouts match, can copy a whole row in one memcpy
if (mapping.size() == 1 &&
mapping[0].serialized_offset == 0 &&
mapping[0].struct_offset == 0 &&
if (mapping_.size() == 1 &&
mapping_[0].serialized_offset == 0 &&
mapping_[0].struct_offset == 0 &&
point_step == sizeof(T))
{
uint32_t m_row_step = sizeof(T) * m.width;
Expand All @@ -252,7 +244,7 @@ namespace ros
for (uint32_t row = 0; row < m.height; ++row) {
const uint8_t* stream_data = stream.advance(row_step);
for (uint32_t col = 0; col < m.width; ++col, stream_data += point_step) {
BOOST_FOREACH(const pcl::detail::FieldMapping& fm, mapping) {
BOOST_FOREACH(const pcl::detail::FieldMapping& fm, mapping_) {
memcpy(m_data + fm.struct_offset, stream_data + fm.serialized_offset, fm.size);
}
m_data += sizeof(T);
Expand Down Expand Up @@ -287,6 +279,18 @@ namespace ros

return length;
}

static void createMapping(const std::vector<sensor_msgs::PointField>& msg_fields)
{
if (mapping_.empty())
{
boost::mutex::scoped_lock lock(mutex_);
pcl::createMapping<T>(msg_fields, mapping_);
}
}

static pcl::MsgFieldMap mapping_;
static boost::mutex mutex_;
};
} // namespace ros::serialization

Expand Down

0 comments on commit 7ccb486

Please sign in to comment.