TEST(sensor_msgs, PointCloud2Iterator) { // Create a dummy PointCloud2 size_t n_points = 4; sensor_msgs::msg::PointCloud2 cloud_msg_1, cloud_msg_2; cloud_msg_1.height = static_cast<uint32_t>(n_points); cloud_msg_1.width = 1; sensor_msgs::PointCloud2Modifier modifier(cloud_msg_1); modifier.setPointCloud2FieldsByString(2, "xyz", "rgb"); cloud_msg_2 = cloud_msg_1; // Fill 1 by hand float point_data_raw[] = {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0}; std::vector<float> point_data(point_data_raw, point_data_raw + 3 * n_points); // colors in RGB order uint8_t color_data_raw[] = {40, 80, 120, 160, 200, 240, 20, 40, 60, 80, 100, 120}; std::vector<uint8_t> color_data(color_data_raw, color_data_raw + 3 * n_points); float * data = reinterpret_cast<float *>(&cloud_msg_1.data.front()); for (size_t n = 0, i = 0; n < n_points; ++n) { for (; i < 3 * (n + 1); ++i) { *(data++) = point_data[i]; } // Add an extra float of padding ++data; uint8_t * bgr = reinterpret_cast<uint8_t *>(data++); // add the colors in order BGRA like PCL size_t j_max = 2; for (size_t j = 0; j <= j_max; ++j) { *(bgr++) = color_data[3 * n + (j_max - j)]; } // Add 3 extra floats of padding data += 3; } // Fill 2 using an iterator sensor_msgs::PointCloud2Iterator<float> iter_x(cloud_msg_2, "x"); sensor_msgs::PointCloud2Iterator<uint8_t> iter_r(cloud_msg_2, "r"); sensor_msgs::PointCloud2Iterator<uint8_t> iter_g(cloud_msg_2, "g"); sensor_msgs::PointCloud2Iterator<uint8_t> iter_b(cloud_msg_2, "b"); for (size_t i = 0; i < n_points; ++i, ++iter_x, ++iter_r, ++iter_g, ++iter_b) { for (size_t j = 0; j < 3; ++j) { iter_x[j] = point_data[j + 3 * i]; } *iter_r = color_data[3 * i]; *iter_g = color_data[3 * i + 1]; *iter_b = color_data[3 * i + 2]; } // Check the values using an iterator sensor_msgs::PointCloud2ConstIterator<float> iter_const_1_x(cloud_msg_1, "x"), iter_const_2_x( cloud_msg_2, "x"); sensor_msgs::PointCloud2ConstIterator<float> iter_const_1_y(cloud_msg_1, "y"), iter_const_2_y( cloud_msg_2, "y"); sensor_msgs::PointCloud2ConstIterator<float> iter_const_1_z(cloud_msg_1, "z"), iter_const_2_z( cloud_msg_2, "z"); sensor_msgs::PointCloud2ConstIterator<uint8_t> iter_const_1_r(cloud_msg_1, "r"), iter_const_2_r( cloud_msg_2, "r"); sensor_msgs::PointCloud2ConstIterator<uint8_t> iter_const_1_g(cloud_msg_1, "g"), iter_const_2_g( cloud_msg_2, "g"); sensor_msgs::PointCloud2ConstIterator<uint8_t> iter_const_1_b(cloud_msg_1, "b"), iter_const_2_b( cloud_msg_2, "b"); size_t i = 0; for (; iter_const_1_x != iter_const_1_x.end(); ++i, ++iter_const_1_x, ++iter_const_2_x, ++iter_const_1_y, ++iter_const_2_y, ++iter_const_1_z, ++iter_const_2_z, ++iter_const_1_r, ++iter_const_1_g, ++iter_const_1_b) { EXPECT_EQ(*iter_const_1_x, *iter_const_2_x); EXPECT_EQ(*iter_const_1_x, point_data[0 + 3 * i]); EXPECT_EQ(*iter_const_1_y, *iter_const_2_y); EXPECT_EQ(*iter_const_1_y, point_data[1 + 3 * i]); EXPECT_EQ(*iter_const_1_z, *iter_const_2_z); EXPECT_EQ(*iter_const_1_z, point_data[2 + 3 * i]); EXPECT_EQ(*iter_const_1_r, *iter_const_2_r); EXPECT_EQ(*iter_const_1_r, color_data[3 * i + 0]); EXPECT_EQ(*iter_const_1_g, *iter_const_2_g); EXPECT_EQ(*iter_const_1_g, color_data[3 * i + 1]); EXPECT_EQ(*iter_const_1_b, *iter_const_2_b); EXPECT_EQ(*iter_const_1_b, color_data[3 * i + 2]); // This is to test the different operators ++iter_const_2_r; iter_const_2_g += 1; iter_const_2_b = iter_const_2_b + 1; } EXPECT_EQ(i, n_points); }
/** fill the point cloud with the 3D points */ void LinemodPointcloud::fill(const std::vector<cv::Vec3f> & pts, const cv::Vec3b &color) { int size_old = modifier->size(); modifier->resize(size_old + pts.size()); sensor_msgs::PointCloud2Iterator<float> iter_x(pc_msg, "x"); sensor_msgs::PointCloud2Iterator<float> iter_y(pc_msg, "y"); sensor_msgs::PointCloud2Iterator<float> iter_z(pc_msg, "z"); sensor_msgs::PointCloud2Iterator<uint8_t> iter_r(pc_msg, "r"); sensor_msgs::PointCloud2Iterator<uint8_t> iter_g(pc_msg, "g"); sensor_msgs::PointCloud2Iterator<uint8_t> iter_b(pc_msg, "b"); iter_x += size_old; iter_y += size_old; iter_z += size_old; iter_r += size_old; iter_g += size_old; iter_b += size_old; std::vector<cv::Vec3f>::const_iterator it_data = pts.begin(); for(; it_data != pts.end(); ++it_data, ++iter_x, ++iter_y, ++iter_z, ++iter_r, ++iter_g, ++iter_b) { *iter_x = (*it_data)(0); *iter_y = (*it_data)(1); *iter_z = (*it_data)(2); *iter_r = color(0); *iter_g = color(1); *iter_b = color(2); } }