laser2cloud.cpp 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #include <ros/ros.h>
  2. #include <sensor_msgs/PointCloud2.h>
  3. #include <sensor_msgs/LaserScan.h>
  4. #include <pcl_conversions/pcl_conversions.h>
  5. #include <pcl/point_cloud.h>
  6. #include <pcl/point_types.h>
  7. class PointCloudToLaserScan
  8. {
  9. public:
  10. PointCloudToLaserScan()
  11. {
  12. // 创建订阅者和发布者
  13. pointcloud_sub_ = nh_.subscribe("/velodyne_points", 1, &PointCloudToLaserScan::pointCloudCallback, this);
  14. laser_scan_pub_ = nh_.advertise<sensor_msgs::LaserScan>("/scan", 1);
  15. }
  16. private:
  17. ros::NodeHandle nh_;
  18. ros::Subscriber pointcloud_sub_;
  19. ros::Publisher laser_scan_pub_;
  20. void pointCloudCallback(const sensor_msgs::PointCloud2ConstPtr& cloud_msg)
  21. {
  22. // 转换 PointCloud2 消息到 pcl::PointCloud
  23. pcl::PointCloud<pcl::PointXYZ> cloud;
  24. pcl::fromROSMsg(*cloud_msg, cloud);
  25. // 创建 LaserScan 消息
  26. sensor_msgs::LaserScan laser_scan;
  27. laser_scan.header = cloud_msg->header; // 保持相同的时间戳和坐标系
  28. laser_scan.angle_min = -M_PI / 2; // 设置最小角度
  29. laser_scan.angle_max = M_PI / 2; // 设置最大角度
  30. laser_scan.angle_increment = M_PI / 180; // 每个激光束之间的角度增量
  31. laser_scan.range_min = 0.0; // 最小范围
  32. laser_scan.range_max = 100.0; // 最大范围
  33. // 计算 LaserScan 数据
  34. int num_readings = static_cast<int>((laser_scan.angle_max - laser_scan.angle_min) / laser_scan.angle_increment);
  35. laser_scan.ranges.resize(num_readings);
  36. // 遍历点云,将其转换为激光扫描范围
  37. for (int i = 0; i < num_readings; ++i)
  38. {
  39. float angle = laser_scan.angle_min + i * laser_scan.angle_increment;
  40. // 找到与当前角度最接近的点
  41. float min_range = laser_scan.range_max;
  42. for (const auto& point : cloud.points)
  43. {
  44. float point_angle = atan2(point.y, point.x);
  45. if (fabs(point_angle - angle) < laser_scan.angle_increment / 2)
  46. {
  47. float range = sqrt(point.x * point.x + point.y * point.y);
  48. if (range < min_range)
  49. {
  50. min_range = range;
  51. }
  52. }
  53. }
  54. laser_scan.ranges[i] = min_range;
  55. }
  56. // 发布 LaserScan 消息
  57. laser_scan_pub_.publish(laser_scan);
  58. }
  59. };
  60. int main(int argc, char** argv)
  61. {
  62. ros::init(argc, argv, "pointcloud_to_laserscan");
  63. PointCloudToLaserScan pcl_to_laser;
  64. ros::spin();
  65. return 0;
  66. }