我尝试用高斯分布构建自己的点云。使用rviz进行可视化不起作用。
以下是我创建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);
这是函数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;
}
正如我所说,它无法在rviz中显示。我按主题选择,选择正确的主题,然后屏幕上没有任何内容。主题是正确的,如果我将网格设置为base_link,那么主题的所有内容都可以。也许我必须在rviz中设置一个特殊属性,或者我没有正确构建我的pointcloud。
编辑:
现在我认为问题更多的是关于无法解决的“base_link”tf主题。如果我尝试映射我的tf树,那么就没有条目。如何在我的tf树中设置base_link。或者我的目的还有另一种可能性吗?
答案 0 :(得分:1)
消息sensor_msgs::PointCloud pc有一个Point32数组,后者又有x,y和z值。您正在设置每个点的x和y值,但是您缺少z值。
我不确定rviz visualizer是否还需要频道信息。如果尽管z值仍然看不到点云,则设置频道信息。该频道是sensor_msgs::PointCloud中名为channels
的数组,其类型为ChannelFloat32。如果您有深度信息,可以使用单个频道:
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);
为了在rviz中查看消息而多次发布消息也很重要,并且通常在处理TF时需要更新标题中的时间戳。
顺便说一句,你在100米/ 10米的点周围分散点!
以下是适用于我的代码
#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;
}
答案 1 :(得分:0)