ROS2中模拟生成地面点云

#include "rclcpp/rclcpp.hpp"
#include "sensor_msgs/msg/point_cloud2.hpp"
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/conversions.h>
#include <pcl_conversions/pcl_conversions.h> 
#include <iostream>
#include <pcl/point_types.h>
#include <pcl/visualization/pcl_visualizer.h>
#include <pcl/common/common.h>
#include <pcl/common/time.h>

class GroundPointCloudPublisher : public rclcpp::Node
{
public:
  GroundPointCloudPublisher() : Node("ground_point_cloud_publisher")
  {
    // 创建PointCloud2消息
    auto msg = std::make_shared<sensor_msgs::msg::PointCloud2>();
    // 创建点云发布者
    point_cloud_publisher_ = this->create_publisher<sensor_msgs::msg::PointCloud2>("ground_point_cloud", 10);


    // 初始化点云消息
    msg->header.stamp = now();
    msg->header.frame_id = "base_link";

    // 模拟生成地面点云
    pcl::PointCloud<pcl::PointXYZI>::Ptr cloud(new pcl::PointCloud<pcl::PointXYZI>);
    cloud->width = 100;
    uint32_t ground_length = 10; // 地面长度
    uint32_t ground_height = 1 ;// 地面高度

    cloud->height = 10;
    cloud->points.resize(cloud->width * cloud->height);

    // 填充点云数据
    for (uint32_t i = 0; i < cloud-> width / ground_length ; i ++)
    {
        for(uint32_t j = 0; j < ground_length; j ++){
            cloud->points[i * ground_length + j].x = i; // x坐标
            cloud->points[i * ground_length + j].y = j; // y坐标
            cloud->points[i * ground_length + j].z = ground_height;     // z坐标
        }
      
    }

    // 定义旋转角度(弧度)
    double rotation_angle_x = M_PI / 4; // X轴旋转45度
    double rotation_angle_y = M_PI / 6; // Y轴旋转45度

    // 创建旋转矩阵
    Eigen::AngleAxisd rotation_x(rotation_angle_x, Eigen::Vector3d::UnitX());
    Eigen::AngleAxisd rotation_y(rotation_angle_y, Eigen::Vector3d::UnitY());
    Eigen::Matrix3d rotation_matrix = (rotation_y * rotation_x).matrix();

    // 应用旋转变换
    for (auto &point : cloud->points)
    {
      Eigen::Vector3d point_vector(point.x, point.y, point.z);
      point_vector = rotation_matrix * point_vector;
      point.x = point_vector(0);
      point.y = point_vector(1);
      point.z = point_vector(2);
    }

    // 定时发布点云
    this->declare_parameter("publish_rate", 1.0);
    auto publish_rate = this->get_parameter("publish_rate").as_double();
    timer_ = this->create_wall_timer(
      std::chrono::duration<double>(1.0 / publish_rate),
      [cloud, this]() {
        // 将PCL点云转换为ROS 2消息
        sensor_msgs::msg::PointCloud2 ros_cloud;
        pcl::toROSMsg(*cloud, ros_cloud);
        ros_cloud.header.stamp = this->now();
        ros_cloud.header.frame_id = "base_link";

        // 发布点云
        point_cloud_publisher_->publish(ros_cloud);
      });


    // 创建可视化窗口对象
    pcl::visualization::PCLVisualizer::Ptr viewer(new pcl::visualization::PCLVisualizer("Point Cloud Viewer"));

    // 设置点云颜色为 intensity 值
    pcl::visualization::PointCloudColorHandlerGenericField<pcl::PointXYZI> fildColor(cloud, "intensity");
    
    // 将点云添加到可视化窗口中
    viewer->addPointCloud<pcl::PointXYZI>(cloud, fildColor, "cloud");

    // 设置点云大小
    viewer->setPointCloudRenderingProperties(pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 2, "cloud");

    // 显示可视化窗口,直到用户关闭窗口为止
    while (!viewer->wasStopped())
    {
        viewer->spinOnce(1000);  // 每隔100毫秒渲染一次
    }

  }

private:
  rclcpp::Publisher<sensor_msgs::msg::PointCloud2>::SharedPtr publisher_;
  rclcpp::TimerBase::SharedPtr timer_;
  rclcpp::Time now() const { return rclcpp::Clock().now(); }
};

int main(int argc, char **argv)
{
  rclcpp::init(argc, argv);
  rclcpp::spin(std::make_shared<GroundPointCloudPublisher>());
  rclcpp::shutdown();
  return 0;
}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
ROS2处理点云数据可以使用PCL库和ROS2的点云消息。 1. 使用PCL库: - 导入PCL库:在你的代码导入PCL库,例如 `import pcl`。 - 创建点云对象:使用PCL库提供的函数和类创建点云对象,例如 `cloud = pcl.PointCloud()`。 - 加载点云数据:使用PCL库提供的函数加载点云数据,例如 `pcl.loadPCDFile("point_cloud.pcd", cloud)`。 - 对点云进行操作:使用PCL库提供的函数和类进行点云的滤波、分割、配准、特征提取等操作,例如 `filter = cloud.make_statistical_outlier_filter(),filter.set_mean_k(50),filter.set_std_dev_mul_thresh(1.0),filter.filter()` - 保存点云数据:使用PCL库提供的函数保存点云数据,例如 `pcl.savePCDFile("filtered_point_cloud.pcd", cloud)`。 2. 使用ROS2的点云消息: - 导入ROS2的相关包:在你的代码导入ROS2的相关包,例如 `from sensor_msgs.msg import PointCloud2`。 - 创建订阅器和发布器:使用ROS2的API创建订阅器和发布器来接收和发布点云消息,例如 `subscriber = node.create_subscription(PointCloud2, "/point_cloud_topic", callback)`。 - 编写回调函数:编写一个回调函数来处理接收到的点云消息,在回调函数可以对点云数据进行操作,例如 `def callback(msg: PointCloud2):`。 - 通过ROS2节点发送点云消息:使用ROS2的API将处理后的点云消息发送出去,例如 `publisher.publish(filtered_msg)`。 这些是在ROS2处理点云数据的基本步骤。你可以根据具体的需求使用PCL库或ROS2的点云消息进行点云数据的处理和传输。如果有任何问题,请随时向我提问!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值