confusion about constructing pointcloud2 messages
foxy on ubuntu 20.04, C++, new to ROS2 and ROS generally
I would like to publish a pointcloud2 message based on periodic laser profiles (a rudimentary driver if you will).
I considered using a laser scan message, but since the data come as Cartesian co-ordinates (not polar), going right to point cloud seemed more appropriate. My data consist of X co-ordinates and Z co-ordinates.
from the PointCloud2.msg file:
The point cloud data may be organized 2d (image-like) or 1d (unordered). Point clouds organized as 2d images may be produced by camera depth sensors such as stereo or time-of-flight... 2D structure of the point cloud. If the cloud is unordered, height is 1 and width is the length of the point cloud.
I am not clear on how to choose these dimensions. My data is not exactly image-like, but it is not unordered (or at least need not be) either.
Are the height and width defined in terms of bytes, co-ordinates, or points (sets of two co-ordinates)?
From the PointField.msg file:
Common PointField names are x, y, z, intensity, rgb, rgba
So... if the field name is RGB, does that imply a "point" is an amalgamation of 3 values? Why would one choose to do that? Why wouldn't one do that with xyz? Is a "point" a single co-ordinate or a set of co-ordinates whose number of elements is equal to the dimensionality of the space (in my case two)?
No idea what offset means here... (first reference to "struct"?)
The actual values (in real units) are real numbers (some negative) with 2 degrees of precision. I have already unpacked the data from the sensor into arrays of floats (it arrived as two byte values). Is FLOAT32 therefore the right choice?
how many elements are there in the field? One X one Z - so two? Or one X in one field and one Z in another field?
point_step? same irreconcilability...
row_step? When did we start talking about rows?
I understand the actual co-ordinates need to be stored in a binary blob (technically a std::vector<unsigned char="">). How should I do that starting from floats? Or should I not even bother with trans-coding into floats in the first place? If not, how should I handle scaling the values to real units? Where are the units specified?
Any reference on this subject is welcomed. Any examples of anything similar?
Thanks in advance!
[UPDATE]
I am grateful (and still clueless and frustrated). I am now able to build a pcl::PointCloud<pcl::pointxyz>
object (I think).
I believe I have the recommended package installed:
$ apt-cache policy ros-foxy-pcl-conversions
ros-foxy-pcl-conversions: Installed: 2.2.0-1focal.20201103.153038
I've updated my CMakeLists.txt file to:
cmake_minimum_required(VERSION 3.5)
project(leuze_lps_36_driver)
find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)
find_package(sensor_msgs REQUIRED)
find_package(PCL 1.3 REQUIRED COMPONENTS common io conversions)
include_directories(${PCL_INCLUDE_DIRS})
link_directories(${PCL_LIBRARY_DIRS}) add_definitions(${PCL_DEFINITIONS})
add_executable(profile_publisher src/profile_publisher.cpp)
ament_target_dependencies(profile_publisher rclcpp std_msgs sensor_msgs)
target_include_directories(profile_publisher PUBLIC $<build_interface:${cmake_current_source_dir ...
Taking a step back:
you normally don't create
sensor_msgs/PointCloud2
messages by hand, but create a PCL cloud object and then convert that using pcl_ros et al. The conversion takes care of almost all the details you now have questions about.Don't confuse a message (ie: the serialised form of a data structure) with the object (in this case the PCL cloud object). You create objects, then convert them to messages and publish those.
The sensor is a Leuze LPS 36HI/EN.10. I did look, but could not find anything. Thanks for the tip about object/message confusion - no doubt I have it. I did come across pcl_ros, but did not investigate deeply b/c it has not been ported to ROS2 (AFAIK).
The
pcl_conversions
package has been ported to ROS2, and that's the specific one you'll need to convert between PCL cloud objects and ROS2sensor_msgs/PointCloud2
messages. You should be able to install it throughros-foxy-pcl-conversions
. I would definitely recommend using the functions in that package (in particular,pcl::toROSMsg()
) instead of manually populating the fields in the PointCloud2 message.where do you actually
find_package(pcl_conversions REQUIRED)
and passpcl_conversions
toament_target_dependencies
?I don't see that in the
CMakeLists.txt
you show.You also shouldn't need to manually
find_package(PCL ..)
, as I believepcl_conversions
already brings in that dependency, but it probably doesn't hurt. I wouldn't uselink_directories(..)
any more though.That certainly helped :) I did still have to pull in PCL independently... Thanks ton! Now to see if I can actually get toROSMsg() to work! Will update with a synopsis when I get it.