如何在分离的节点 ros pcl 中发送集群

How to send cluster in separated node ros pcl

嗨,我是点云库的新手。我试图在 rviz 或 pcl 查看器上显示聚类结果点,然后什么都不显示。我意识到当我订阅和计算时,我的数据也什么也没有显示。希望能解决我的问题,谢谢

这是我的集群和发送节点的代码

void cloudReceive(const sensor_msgs::PointCloud2ConstPtr& inputMsg){
mutex_lock.lock();
pcl::fromROSMsg(*inputMsg, *inputCloud);
cout<<inputCloud<<endl;
pcl::search::KdTree<pcl::PointXYZRGB>::Ptr tree (new pcl::search::KdTree<pcl::PointXYZRGB>);
tree->setInputCloud(inputCloud);

std::vector<pcl::PointIndices> cluster_indices;
pcl::EuclideanClusterExtraction<pcl::PointXYZRGB> ec;

ec.setClusterTolerance(0.03);//2cm
ec.setMinClusterSize(200);//min points
ec.setMaxClusterSize(1000);//max points
ec.setSearchMethod(tree);
ec.setInputCloud(inputCloud);
ec.extract(cluster_indices);

if(cluster_indices.size() > 0){
    std::vector<pcl::PointIndices>::const_iterator it;

    int i = 0;

    for (it = cluster_indices.begin(); it != cluster_indices.end(); ++it){
        if(i >= 10)
            break;

        cloud_cluster[i]->points.clear();
        std::vector<int>::const_iterator idx_it;

        for (idx_it = it->indices.begin(); idx_it != it->indices.end(); idx_it++)
            cloud_cluster[i]->points.push_back(inputCloud->points[*idx_it]);

        cloud_cluster[i]->width = cloud_cluster[i]->points.size();
        // cloud_cluster[i]->height = 1;
        // cloud_cluster[i]->is_dense = true;

        cout<<"PointCloud representing the Cluster: " << cloud_cluster[i]->points.size() << " data points"<<endl;
        std::stringstream ss;
        ss<<"cobaa_pipecom2_cluster_"<< i << ".pcd";
        writer.write<pcl::PointXYZRGB> (ss.str(), *cloud_cluster[i], false);

        pcl::toROSMsg(*cloud_cluster[i], outputMsg);
        // cout<<"data = "<< outputMsg <<endl;
        cloud_cluster[i]->header.frame_id = FRAME_ID;
        pclpub[i++].publish(outputMsg);

        // i++;
    }
}
else
   ROS_INFO_STREAM("0 clusters extracted\n");

}

而这个是主要的

int main(int argc, char** argv){

for (int z = 0; z < 10; z++) {
    // std::cout << " - clustering/" << z << std::endl;

    cloud_cluster[z] = pcl::PointCloud<pcl::PointXYZRGB>::Ptr(new pcl::PointCloud<pcl::PointXYZRGB>);
    cloud_cluster[z]->height = 1;
    cloud_cluster[z]->is_dense = true;
    // cloud_cluster[z]->header.frame_id = FRAME_ID;
}

ros::init(argc,argv,"clustering");
ros::NodeHandlePtr nh(new ros::NodeHandle());
pclsub = nh->subscribe("/pclsegmen",1,cloudReceive);

std::string pub_str("clustering/0");

for (int z = 0; z < 10; z++) {
    pub_str[11] = z + 48;//48=0(ASCII)
    // z++;
    pclpub[z] = nh->advertise <sensor_msgs::PointCloud2> (pub_str, 1);
}

// pclpub = nh->advertise<sensor_msgs::PointCloud2>("/pclcluster",1);
ros::spin();

}

这不是一个确切的答案,但我认为它解决了您的问题并且可以简化您的调试。 RViz 可以直接订阅已发布的点云,我假设您正试图在 cloud_receive 回调中看到这一点。如果您将框架设置为发布它的任何框架,并从可用主题中添加它,您应该会看到这些点。 (比尝试将其重新广播为不同的主题更容易)。

此外,我建议查看 rostopic 命令行工具。您可以 rostopic list 检查它是否正在发布,rostopic bw 查看它是否真的发布了预期的数据量(例如字节、千字节和兆字节),rostopic hz 查看发布频率(如果有的话)它正在发布,并且(简短地)rostopic echo 查看数据本身。 (这是我根据你的问题假设更多的是数据进入你的节点的问题)。

如果您遇到问题,不是数据进入节点,也不是一般点云数据的可视化,而是应该从节点出来的转换数据,我会检查聚类有效,并将您的代码减少到仅让 1 个发布者发布内容。你可能正在做一些奇怪的事情。就像弄乱你的指针一样。您还可以使用 -Wall -Wextra -Werror 为您的节点打开更强的编译警告,或者逐步执行它 via gdb (launch-prefix="xterm -e gdb --args").

解决办法是,我把ASCII码改成lexical_cast。感谢您的回复,我希望这可以帮助其他人

    for (int z = 0; z < CLOUD_QTD; z++) {
    // pub_str[11] = z + 48;
    std::string topicName = "/pclcluster/" + boost::lexical_cast<std::string>(z);
    global::pub[z] = n.advertise <sensor_msgs::PointCloud2> (topicName, 1);
}