ROS Resources: Documentation | Support | Discussion Forum | Index | Service Status | ros @ Robotics Stack Exchange
Ask Your Question

tracsat's profile - activity

2022-10-12 04:41:11 -0500 marked best answer How to Initialize a 2D MultiArray?

Hello,

I am using a Raspberry Pi with Lubuntu 16.04, ros Kinetic, a Sick tim 561 and the package sick_scan to get data from the tim561. Currently my goal is to extract the x and y data from the sick_scan package which is published to the topic cloud as a PointCloud2. I can do this but not exactly in the way that I want. I have coded a subsriber to the cloud topic which then publishes out whatever by following a tutorial. So right now I create a Float32MultiArray and store the distance values that I get (so I do sqrt(x^2 + y^2)) and can successfully publish this.

This works fine, and the code below is what I am using. However, I would prefer to be publishing the x and y data. Unfortunately, I am rather unfamiliar with Float32MultiArray, and I am unsure as how to create a 2D array using this data type. It would also be ideal if I could give it a set size for memory allocation purposes.

I am more used to standard arrays, so what I am looking to do is float array[2][length] where length is the number of data points I am receiving (output.data.size() / 16). Is there any way to do this with a 2D Float32MultiArray?

Thanks!

Code:

#include <ros/ros.h>
// PCL specific includes
#include <sensor_msgs/PointCloud2.h>
#include <pcl_conversions/pcl_conversions.h>
#include <pcl/point_cloud.h>
#include <pcl/point_types.h>
#include <pcl/filters/voxel_grid.h>

#include <iostream>
#include <cmath>
#include <std_msgs/MultiArrayLayout.h>
#include <std_msgs/MultiArrayDimension.h>
#include <std_msgs/Float32MultiArray.h>

ros::Publisher pub;
typedef unsigned char uchar;


float bytesToFloat(uchar b0, uchar b1, uchar b2, uchar b3)
{
  float f;
  uchar b[] = {b0, b1, b2, b3};
  memcpy(&f, &b, sizeof(f));
  return f;
}

void 
cloud_cb (const sensor_msgs::PointCloud2ConstPtr& input)
{
  //Create container for data
  sensor_msgs::PointCloud2 output;

  //Data Processing
  output = *input;

  std_msgs::Float32MultiArray arr;
  arr.data.clear();

  for (int i = 0; i < output.data.size(); i += 16)
  {
      arr.data.push_back(sqrt(pow(bytesToFloat(output.data[i], output.data[i + 1], output.data[i + 2], output.data[i + 3]), 2) +  pow(bytesToFloat(output.data[i + 4], output.data[i + 5], output.data[i + 6], output.data[i + 7$
  }

  //Publish data
  pub.publish(arr);
}

int
main (int argc, char** argv)
{
  // Initialize ROS
  ros::init (argc, argv, "my_pcl_tutorial");
  ros::NodeHandle nh;

  // Create a ROS subscriber for the input point cloud
  ros::Subscriber sub = nh.subscribe<sensor_msgs::PointCloud2> ("input", 1, cloud_cb);

  // Create a ROS publisher for the output point cloud
  pub = nh.advertise<std_msgs::Float32MultiArray> ("arr", 1);

  // Spin
  ros::spin ();
}
2019-09-23 14:34:44 -0500 received badge  Famous Question (source)
2019-06-12 13:21:02 -0500 received badge  Student (source)
2019-06-12 13:12:11 -0500 received badge  Notable Question (source)
2019-03-27 19:53:47 -0500 received badge  Famous Question (source)
2019-03-25 20:29:31 -0500 received badge  Popular Question (source)
2019-03-25 14:05:27 -0500 asked a question How to Initialize a 2D MultiArray?

How to Initialize a 2D MultiArray? Hello, I am using a Raspberry Pi with Lubuntu 16.04, ros Kinetic, a Sick tim 561 and

2019-03-25 02:09:50 -0500 received badge  Notable Question (source)
2019-03-24 21:57:40 -0500 commented answer Help with PointCloud2 Data

Thanks that makes a lot of sense. I was not aware that uchar was a fundamental type.

2019-03-24 21:44:47 -0500 marked best answer Help with PointCloud2 Data

Hello,

I am using a Raspberry Pi with Lubuntu 16.04, ROS Kinetic, a tim 561 and a package called sick_scan to get data from the LIDAR. I can use sick_scan to publish PointCloud2 data to the topic /cloud and I can visualize data with rviz. The end goal for my LIDAR is to be able to get distance data from it. So I want it to tell me what the distance to the things around it is. I am having some issues with this though as I am not really sure where to start. Would I be able to extract distance data from directly from the PointCloud2 data and if so how, or would there be some intermediary steps?

I have successfully followed this tutorial to convert PointCloud2 to PointCloud<t> but I'm not really sure if this is the right direction to go in. I'm also not really sure what the difference between the PointCloud2 and PointCloud<t> is. I noticed though that the data looks very different, is this by design or my mistake? (I will post a comparison below).

I also found this tutorial that changes a PointCloud to a rangeImage, would this be helpful?

I would also like to add that I am beginner and PointCloud2 is by far the most complex data type I have worked with. I am used to the simpler data types, so any help would be truly appreciated as I am sure that I am missing some key understanding about this data type.

Thanks!

/output data after converting to PointCloud<t>:

header: 
  seq: 895
  stamp: 
    secs: 1553455523
    nsecs: 598997000
  frame_id: "cloud"
values: [-0.0, -0.0, 1.0, -0.0]
---
header: 
  seq: 896
  stamp: 
    secs: 1553455523
    nsecs: 665580000
  frame_id: "cloud"
values: [-0.0, -0.0, 1.0, -0.0]

/cloud data of type PointCloud2:

header: 
  seq: 296
  stamp: 
    secs: 1553456947
    nsecs: 421859979
  frame_id: "cloud"
height: 1
width: 811
fields: 
  - 
    name: "x"
    offset: 0
    datatype: 7
    count: 1
  - 
    name: "y"
    offset: 4
    datatype: 7
    count: 1
  - 
    name: "z"
    offset: 8
    datatype: 7
    count: 1
  - 
    name: "intensity"
    offset: 12
    datatype: 7
    count: 1
is_bigendian: False
point_step: 16
row_step: 12976
data: [108, 171, 8, 191, 107, 171, 8, 191, 0, 0, 0, 0, 0, 0, 113, 70, 167, 197, 8, 191, 103, 95, 10, 191, 0, 0, 0, 0, 0, 240, 115, 70, 99, 101, 9, 191, 127, 161, 12, 191, 0, 0, 0, 0, 0, 200, 106, 70, 99, 50, 5, 191, 202, 237, 9, 191, 0, 0, 0, 0, 0, 76, 82, 70, 200, 22, 235, 190, 200, 74, 246, 190, 0, 0, 0, 0, 0, 132, 52, 70, 186, 111, 255, 190, 99, 95, 7, 191, 0, 0, 0, 0, 0, 24, 60, 70, 227, 1, 8, 191, 89, 217, 17, 191, 0, 0, 0, 0, 0, 64, 93, 70, 216, 183, 8, 191, 245, 84, 20, 191, 0, 0, 0, 0, 0, 236, 112, 70, 195, 94, 8, 191, 64, 177, 21, 191, 0, 0, 0, 0 ...
(more)
2019-03-24 21:44:47 -0500 received badge  Scholar (source)
2019-03-24 21:38:52 -0500 received badge  Popular Question (source)
2019-03-24 21:37:53 -0500 commented answer Help with PointCloud2 Data

Ok that makes a lot of sense thank you! I just have one more thing if you don't mind. I noticed that the solution uses a

2019-03-24 20:36:01 -0500 commented answer Help with PointCloud2 Data

Ah ok this makes a lot of sense thank you! I had come to a similar conclusion after reading through a bunch of blog post

2019-03-24 20:29:10 -0500 received badge  Supporter (source)
2019-03-24 16:19:12 -0500 edited question Help with PointCloud2 Data

Help with PointCloud2 Data Hello, I am using a Raspberry Pi with Lubuntu 16.04, ROS Kinetic, a tim 561 and a package ca

2019-03-24 15:57:26 -0500 asked a question Help with PointCloud2 Data

Help with PointCloud2 Data Hello, I am using a Raspberry Pi with Lubuntu 16.04, ROS Kinetic, a tim 561 and a package ca