point_cloud_publisher_tutorial

描述:提供发送两种类型的传感器流,sensor_msgs/LaserScan消息和sensor_msgs/PointCloud message

  1. ROS 上发送传感器流

ROS中正确的从传感器发送数据对于导航堆栈(navigation stack)安全执行时很重要的。如果导航堆栈从机器人传感器上不获得信息,它将很盲目的运行。有许多传感器可以提供导航堆栈所用的信息,如激光,相机,雷达,红外线,碰撞传感器等。然而当前导航堆栈只接受发布的传感器数据使用sensor_msgs/laser_scan与sensor_msgs/PointCloud消息类型。接下来我们介绍安装和使用这两种消息类型的例子。

  1. ROS message header

sensor_msgs/LaserScan and sensor_msgs/PointCloud消息类型包含 tf frame与 time dependent information,为了标准化发送信息,Header 消息类型被这种message使用作为a filed

三种Header 类型

#Standard metadata for higher-level flow data types

#sequence ID: consecutively increasing ID

uint32 seq              //seq字段对应一个标识符,自动增加的消息被发送给publisher

#Two-integer timestamp that is expressed as:

# * stamp.secs: seconds (stamp_secs) since epoch

# * stamp.nsecs: nanoseconds since stamp_secs

# time-handling sugar is provided by the client library

time stamp                       //stamp字段存储时间信息,与数据关联的时间信息

#Frame this data is associated with

# 0: no frame

# 1: global frame

string frame_id                  // frame_id字段存储与message里的data相关联的tf帧信息

 

  1. ROS中发布LaserScans

3.1 Laserscan消息

#

# Laser scans angles are measured counter clockwise, with 0 facing forward

# (along the x-axis) of the device frame

#

 

Header header

float32 angle_min        # start angle of the scan [rad]

float32 angle_max        # end angle of the scan [rad]

float32 angle_increment  # angular distance between measurements [rad]

float32 time_increment   # time between measurements [seconds]

float32 scan_time        # time between scans [seconds]

float32 range_min        # minimum range value [m]

float32 range_max        # maximum range value [m]

float32[] ranges         # range data [m] (Note: values < range_min or > range_max should be discarded)

float32[] intensities    # intensity data [device-specific units]

编写一个简单的激光扫描publisher展示它们是如何工作的。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

对于配备激光扫描器的机器人,ROS在sensor_msgs包中提供一个特殊的消息类型为LaserScan,来保持给定扫描的信息,LaserScan方便代码来处理任何从扫描器出来的激光数据,可以格式化适合的消息。之前我们谈论如何生成和发布这些消息,让我们来看看message本身规

范:                                                               

3.2    编写代码发布LaserScan 消息

ROS中编写LaserScan消息相当直接,下面示例代码:

#include <ros/ros.h>

#include <sensor_msgs/LaserScan.h>   include sensor_msgs/LaserScan.h消息,我们希望在这条线上发送。

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

  ros::init(argc, argv, "laser_scan_publisher");

 

  ros::NodeHandle n;

  ros::Publisher scan_pub = n.advertise<sensor_msgs::LaserScan>("scan", 50);

//我们创建ros::Publisher后面被用来发送LaserScan message

  unsigned int num_readings = 100;

  double laser_frequency = 40;

  double ranges[num_readings];

  double intensities[num_readings];

//这里我们只是设置存储的虚拟数据我们将使用填充扫描。一个真正的应用程序将把这个数据从他们的激光驱动器。

  int count = 0;

  ros::Rate r(1.0);

  while(n.ok()){

    //generate some fake data for our laser scan

    for(unsigned int i = 0; i < num_readings; ++i){

      ranges[i] = count;

      intensities[i] = 100 + count;

    }

ros::Time scan_time = ros::Time::now();

//每秒钟填充虚拟激光数据

 

 

    //populate the LaserScan message

    sensor_msgs::LaserScan scan;

    scan.header.stamp = scan_time;

    scan.header.frame_id = "laser_frame";

    scan.angle_min = -1.57;

    scan.angle_max = 1.57;

    scan.angle_increment = 3.14 / num_readings;

    scan.time_increment = (1 / laser_frequency) / (num_readings);

    scan.range_min = 0.0;

    scan.range_max = 100.0;

 

    scan.ranges.resize(num_readings);

    scan.intensities.resize(num_readings);

    for(unsigned int i = 0; i < num_readings; ++i){

      scan.ranges[i] = ranges[i];

      scan.intensities[i] = intensities[i];

    }

//创造一个scan_msgs::Laser消息,使用我们准备发送的生成数据来填充

 

 

    scan_pub.publish(scan);      //ROS上发布消息

    ++count;

    r.sleep();

  }

}

 

  1. ROS中发布点云数据

1.1   点云消息

#This message holds a collection of 3d points, plus optional additional information about each point.

#Each Point32 should be interpreted as a 3d point in the frame given in the header

 

Header header

geometry_msgs/Point32[] points  #Array of 3d points

ChannelFloat32[] channels       #Each channel should have the same number of elements as points array, and the data in each channel should correspond 1:1 with each point

用于存储和share世界坐标系上大量的数据点,ROS 提供sensor_msgs / PointCloud消息。这条消息,如下所示,是为了支持数组的点在三维空间以及任何相关的数据存储为一个通道。例如,PointCloud可以通过线程发送的“intensify”channel保持 信息云中的每个点的强度值。我们将探讨的一个示例发送PointCloud使用ROS在下一节。

1.2   写代码来发送点云信息

#include <ros/ros.h>

#include <sensor_msgs/PointCloud.h>

//包含sensor_msgs/PointCloud消息

 

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

  ros::init(argc, argv, "point_cloud_publisher");

 

  ros::NodeHandle n;

  ros::Publisher cloud_pub = n.advertise<sensor_msgs::PointCloud>("cloud", 50);

//创造 ros::Publisher t来发送 PointCloud messages out over the wire.

 

  unsigned int num_points = 100;

 

  int count = 0;

  ros::Rate r(1.0);

  while(n.ok()){

    sensor_msgs::PointCloud cloud;

    cloud.header.stamp = ros::Time::now();

    cloud.header.frame_id = "sensor_frame";

//在PointCloud消息的头,我们发送相关帧和时间戳信息

 

    cloud.points.resize(num_points);

//设置点云中点数,以便我们可以用伪数据填充它们

 

    //we'll also add an intensity channel to the cloud

    cloud.channels.resize(1);

    cloud.channels[0].name = "intensities";

    cloud.channels[0].values.resize(num_points);

//在点云中添加一个名为“intensity”的通道,并将其大小设置为与云中的点数相匹配。

 

 

    //generate some fake data for our point cloud

    for(unsigned int i = 0; i < num_points; ++i){

      cloud.points[i].x = 1 + count;

      cloud.points[i].y = 2 + count;

      cloud.points[i].z = 3 + count;

      cloud.channels[0].values[i] = 100 + count;

    }

//使用伪数据填充点云和intensity通道

 

    cloud_pub.publish(cloud);   //使用ROS发布点云

    ++count;

    r.sleep();

  }

}

 

摘自:http://wiki.ros.org/navigation/Tutorials/RobotSetup/Sensors

主要作用:发布两种传感器信息流的方法,以及message的消息类型

Source: git https://github.com/ros-planning/navigation_tutorials.git (branch: indigo-devel)

 

posted on 2017-02-20 21:03  _青桐  阅读(158)  评论(0)    收藏  举报

导航