#include <ros/ros.h>
#include <sensor_msgs/LaserScan.h>
#include <sensor_msgs/PointCloud2.h>
#include <laser_geometry/laser_geometry.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/conversions.h>
#include <tf/transform_listener.h>
#include <iostream>
#include <pcl_ros/point_cloud.h>
#include <vector>
class My_Filter {
public:
My_Filter();
private:
void scanCallback_2(const sensor_msgs::LaserScan::ConstPtr& scan);
void pclCloudCallback(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr& cloud);
void publishAllPoints(const ros::TimerEvent& event);
ros::NodeHandle node_;
ros::Subscriber scan_sub_;
ros::Subscriber pclCloud_sub_;
ros::Publisher point_cloud_publisher_;
laser_geometry::LaserProjection projector_;
tf::TransformListener tfListener_;
std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr> all_points_; // 使用数组形式记录点云数据
ros::Timer timer_;
};
My_Filter::My_Filter() {
scan_sub_ = node_.subscribe<sensor_msgs::LaserScan>("/scan", 100, &My_Filter::scanCallback_2, this);
point_cloud_publisher_ = node_.advertise<sensor_msgs::PointCloud2>("/cloud2", 100, false);
tfListener_.setExtrapolationLimit(ros::Duration(0.1));
pclCloud_sub_ = node_.subscribe<pcl::PointCloud<pcl::PointXYZ>>("/cloud2", 10, &My_Filter::pclCloudCallback, this);
timer_ = node_.createTimer(ros::Duration(0.1), &My_Filter::publishAllPoints, this);
}
void My_Filter::scanCallback_2(const sensor_msgs::LaserScan::ConstPtr& scan) {
sensor_msgs::PointCloud2 cloud;
projector_.transformLaserScanToPointCloud("odom_combined", *scan, cloud, tfListener_);
pcl::PointCloud<pcl::PointXYZ>::Ptr rawCloud(new pcl::PointCloud<pcl::PointXYZ>);
pcl::fromROSMsg(cloud, *rawCloud);
// 将当前点云添加到数组中
all_points_.push_back(rawCloud);
for (size_t i = 0; i < rawCloud->points.size(); i++) {
std::cout << rawCloud->points[i].x << "\t" << rawCloud->points[i].y << "\t" << rawCloud->points[i].z << std::endl;
}
point_cloud_publisher_.publish(cloud);
}
void My_Filter::pclCloudCallback(const pcl::PointCloud<pcl::PointXYZ>::ConstPtr& cloud) {
pcl::PointCloud<pcl::PointXYZ>::Ptr newCloud(new pcl::PointCloud<pcl::PointXYZ>(*cloud));
all_points_.push_back(newCloud);
for (size_t i = 0; i < cloud->points.size(); i++) {
std::cout << "direct_trans: " << cloud->points[i].x << "\t" << cloud->points[i].y << "\t" << cloud->points[i].z << std::endl;
}
}
void My_Filter::publishAllPoints(const ros::TimerEvent& event) {
sensor_msgs::PointCloud2 output;
pcl::PointCloud<pcl::PointXYZ>::Ptr combinedCloud(new pcl::PointCloud<pcl::PointXYZ>);
// 将所有点云合并到一个新的点云中
for (const auto& cloud : all_points_) {
*combinedCloud += *cloud;
}
pcl::toROSMsg(*combinedCloud, output);
output.header.frame_id = "odom_combined";
output.header.stamp = ros::Time::now();
point_cloud_publisher_.publish(output);
}
int main(int argc, char** argv) {
ros::init(argc, argv, "my_filter_node");
My_Filter my_filter;
ros::spin();
return 0;
}
这段代码功能只是能够定时发布每一刻的点云数据,不能将之前的点云数据保存
我的目的是通过点云数据来构建点云地图
如何修改这段代码,能够保存点云数据从发布到结束时的所有数据,并将所有数据实时的显示到rviz里