本文介绍了RVIZ:显示自己的点云的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用高斯分布构建自己的点云.rviz 的可视化不起作用.

这是我创建点云的方法

int sizeOfCloud = 1000;keypoints.points.resize(sizeOfCloud);getRandomPointCloud(keypoints, 100, 100, sizeOfCloud);keypoints.header.frame_id = "base_link";keypoints.header.stamp = ros::Time::now();keypoints_publisher.publish(keypoints);

这里是函数 getRandomPointCloud:

void getRandomPointCloud(sensor_msgs::PointCloud& pc, int centerX, int centerY, int& sizeOfCloud) {std::random_device rd;std::mt19937 gen(rd());std::normal_distribution<>distX(centerX, 10);std::normal_distribution<>距离(中心Y,10);for (int i = 0; i 

正如我所说,它无法在rviz中显示.我确实按主题选择,选择正确的主题,然后屏幕上没有任何内容.主题是正确的,如果我将网格设置为 base_link,那么该主题的所有内容都可以.也许我必须在 rviz 中设置一个特殊的属性,或者我没有正确构建我的点云.

这是rviz的截图

现在我认为问题更多是关于无法解决的base_link"tf主题.如果我尝试映射我的 tf 树,则没有条目.如何在我的 tf 树中设置 base_link.或者我的目的还有另一种可能性吗?

解决方案

消息

这是对我有用的代码

#include #include #include #include void getRandomPointCloud(sensor_msgs::PointCloud& pc,双中心X,双中心Y,内部&sizeOfCloud) {std::random_device rd;std::mt19937 gen(rd());std::normal_distribution<>distX(centerX, 2.);std::normal_distribution<>distY(centerY, 2.);for (int i = 0; i ("point_cloud", 10);ros::率率(30);而 (ros::ok()) {keypoints.header.stamp = ros::Time::now();keypoints_publisher.publish(keypoints);ros::spinOnce();率.sleep();}返回0;}

I try to build my own point cloud with a gaussian distribution. The visualization with rviz doesn't work.

Here is how I create the pointcloud

int sizeOfCloud = 1000;
keypoints.points.resize(sizeOfCloud);
getRandomPointCloud(keypoints, 100, 100, sizeOfCloud);

keypoints.header.frame_id = "base_link";
keypoints.header.stamp = ros::Time::now();
keypoints_publisher.publish(keypoints);

and here is the function getRandomPointCloud:

void getRandomPointCloud(sensor_msgs::PointCloud& pc, int centerX, int centerY, int& sizeOfCloud) {
    std::random_device rd;
    std::mt19937 gen(rd());
    std::normal_distribution<> distX(centerX, 10);
    std::normal_distribution<> distY(centerY, 10);


    for (int i = 0; i < pc.points.size(); i++) {
        double xValue = distX(gen);
        double yValue = distY(gen);
        std::cout << std::round(xValue) << std::endl;
        pc.points[i].x = std::round(xValue);
        pc.points[i].y = std::round(yValue);
    }
    std::cout << "done" << std::endl;
}

As I said, it can't be displayed in rviz. I do select by topic, select the proper topic and then there is nothing on the screen. Topic is correct and if I set the grid to base_link then everything with the topic is okay. Maybe I have to set a special attribute in rviz or I don't build my pointcloud correctly.

Edit:

Here is a screenshot from rviz

Now I think the problem is more about the "base_link" tf topic which can't get resolved. If I try to map my tf tree then there is no entry. How do I set the base_link in my tf tree. Or is there another possibility for my purpose?

解决方案

The message sensor_msgs::PointCloud pc has an array of Point32 which in turn has x, y and z values. You are setting the x and y values of each point but you are missing the z value.

I'm not sure if the rviz visualizer also requires channel information. If the point cloud is still not visible despite the z value, then set the channel information. The channel is an array in sensor_msgs::PointCloud called channels which is of type ChannelFloat32. If you have depth information you can use a single channel:

sensor_msgs::ChannelFloat32 depth_channel;
depth_channel.name = "distance";
for (int i = 0; i < pc.points.size(); i++) {
  depth_channel.values.push_back(0.43242); // or set to a random value if you like
}
// add channel to point cloud
pc.channels.push_back(depth_channel);

It is also important to publish the message more than once in order to see it in rviz and often when dealing with TF you need to update the time stamp in the header.

Btw you are spreading the points around the point 100meter/10meter thats way out!

Here is my example.

Here is the code that works for me

#include <ros/ros.h>
#include <sensor_msgs/PointCloud.h>
#include <string>
#include <random>

void getRandomPointCloud(sensor_msgs::PointCloud& pc,
                         double centerX,
                         double centerY,
                         int& sizeOfCloud) {
  std::random_device rd;
  std::mt19937 gen(rd());
  std::normal_distribution<> distX(centerX, 2.);
  std::normal_distribution<> distY(centerY, 2.);

  for (int i = 0; i < pc.points.size(); i++) {
    double xValue = distX(gen);
    double yValue = distY(gen);
    pc.points[i].x = xValue;
    pc.points[i].y = yValue;
    pc.points[i].z =
        std::exp(-((xValue * xValue) + (yValue * yValue)) / 4.);
  }
  sensor_msgs::ChannelFloat32 depth_channel;
  depth_channel.name = "distance";
  for (int i = 0; i < pc.points.size(); i++) {
    depth_channel.values.push_back(pc.points[i].z); // or set to a random value if you like
  }
  // add channel to point cloud
  pc.channels.push_back(depth_channel);
}

int main(int argc, char** argv) {
  ros::init(argc, argv, "point_cloud_test");
  auto nh = ros::NodeHandle();

  int sizeOfCloud = 100000;
  sensor_msgs::PointCloud keypoints;
  keypoints.points.resize(sizeOfCloud);
  getRandomPointCloud(keypoints, 0.5, 0.5, sizeOfCloud);

  keypoints.header.frame_id = "base_link";
  keypoints.header.stamp = ros::Time::now();

  auto keypoints_publisher =
      nh.advertise<sensor_msgs::PointCloud>("point_cloud", 10);
  ros::Rate rate(30);
  while (ros::ok()) {
    keypoints.header.stamp = ros::Time::now();
    keypoints_publisher.publish(keypoints);
    ros::spinOnce();
    rate.sleep();
  }

  return 0;
}

这篇关于RVIZ:显示自己的点云的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-01 22:56