9 from sensor_msgs.msg
import PointCloud2, PointField
17 ros_pointcloud.header = polar_pointcloud.header
18 ros_pointcloud.width = polar_pointcloud.width
19 ros_pointcloud.height = polar_pointcloud.height
20 ros_pointcloud.is_bigendian = polar_pointcloud.is_bigendian
21 ros_pointcloud.is_dense = polar_pointcloud.is_dense
23 field_offset_range = -1
24 field_offset_azimuth = -1
25 field_offset_elevation = -1
26 field_offset_intensity = -1
27 for polar_field
in polar_pointcloud.fields:
28 if polar_field.name ==
"range" and polar_field.datatype == PointField.FLOAT32:
29 field_offset_range = polar_field.offset
30 elif polar_field.name ==
"azimuth" and polar_field.datatype == PointField.FLOAT32:
31 field_offset_azimuth = polar_field.offset
32 elif polar_field.name ==
"elevation" and polar_field.datatype == PointField.FLOAT32:
33 field_offset_elevation = polar_field.offset
34 elif (polar_field.name ==
"intensity" or polar_field.name ==
"i")
and polar_field.datatype == PointField.FLOAT32:
35 field_offset_intensity = polar_field.offset
36 ros_pointcloud.fields = [ PointField(
"x", 0, PointField.FLOAT32, 1), PointField(
"y", 4, PointField.FLOAT32, 1), PointField(
"z", 8, PointField.FLOAT32, 1), PointField(
"intensity", 12, PointField.FLOAT32, 1) ]
37 ros_pointcloud.point_step = 16
38 ros_pointcloud.row_step = ros_pointcloud.point_step * ros_pointcloud.width
40 cartesian_point_cloud_buffer = np.zeros(4 * ros_pointcloud.width * ros_pointcloud.height, dtype = np.float32)
41 cartesian_point_cloud_offset = 0
42 for row_idx
in range(polar_pointcloud.height):
43 for col_idx
in range(polar_pointcloud.width):
45 polar_point_offset = row_idx * polar_pointcloud.row_step + col_idx * polar_pointcloud.point_step
46 point_range = np.frombuffer(polar_pointcloud.data, dtype = np.float32, count = 1, offset = polar_point_offset + field_offset_range)[0]
47 point_azimuth = np.frombuffer(polar_pointcloud.data, dtype = np.float32, count = 1, offset = polar_point_offset + field_offset_azimuth)[0]
48 point_elevation = np.frombuffer(polar_pointcloud.data, dtype = np.float32, count = 1, offset = polar_point_offset + field_offset_elevation)[0]
50 if field_offset_intensity >= 0:
51 point_intensity = np.frombuffer(polar_pointcloud.data, dtype = np.float32, count = 1, offset = polar_point_offset + field_offset_intensity)[0]
53 point_x = point_range * math.cos(point_elevation) * math.cos(point_azimuth)
54 point_y = point_range * math.cos(point_elevation) * math.sin(point_azimuth)
55 point_z = point_range * math.sin(point_elevation)
56 cartesian_point_cloud_buffer[cartesian_point_cloud_offset + 0] = point_x
57 cartesian_point_cloud_buffer[cartesian_point_cloud_offset + 1] = point_y
58 cartesian_point_cloud_buffer[cartesian_point_cloud_offset + 2] = point_z
59 cartesian_point_cloud_buffer[cartesian_point_cloud_offset + 3] = point_intensity
60 cartesian_point_cloud_offset = cartesian_point_cloud_offset + 4
61 ros_pointcloud.data = cartesian_point_cloud_buffer.tostring()
65 def __init__(self, subscriber_topic, publisher_topic):
67 self.
cloud_publisher = rospy.Publisher(publisher_topic, PointCloud2, queue_size=16*12*3)
72 if __name__ ==
'__main__':
73 subscriber_topic =
"/cloud_polar_unstructured_fullframe"
74 publisher_topic =
"/cloud_polar_to_cartesian"
75 arg_parser = argparse.ArgumentParser()
76 arg_parser.add_argument(
"--polar_topic", help=
"ros topic of polar pointcloud (subscriber)", default=subscriber_topic, type=str)
77 arg_parser.add_argument(
"--cartesian_topic", help=
"ros topic of cartesian pointcloud (publisher)", default=publisher_topic, type=str)
78 cli_args = arg_parser.parse_args()
79 subscriber_topic = cli_args.polar_topic
80 publisher_topic = cli_args.cartesian_topic
81 node = rospy.init_node(
"polar_to_cartesian_pointcloud")
84 while not rospy.is_shutdown():