ROSのリリースセンサデータ(LaserScanとPointCloud)

5326 ワード

参照先:http://wiki.ros.org/cn/navigation/Tutorials/RobotSetup/Sensors
センサから取得したデータをROS上で正確に公開することは,ナビゲーション機能パッケージの安全な動作にとって重要である.ナビゲーション機能パッケージがロボットのセンサから何の情報も受信できない場合、盲目的に行動し、衝突が発生する可能性が高い.ナビゲーション機能パッケージには、レーザ、カメラ、ソナー、赤外線、衝突センサなどの情報を提供するために使用できるセンサがたくさんあります.ただし、現在のナビゲーション機能パッケージセットではsensor_の使用のみが受け入れられています.msgs/LaserScanまたはsensor_msgs/PointCloudメッセージタイプで公開されたセンサデータ.次のチュートリアルでは、典型的な設定とこの2つのタイプのメッセージを使用する例を示します.関連:TF構成
メッセージタイプ:sensor_msgs/LaserScanとsensor_msgs/PointCloudは、tfフレームおよび時間に関する情報を含む他のメッセージと同様である.これらの情報を標準化するために、メッセージタイプHeaderは、このようなメッセージのすべてのフィールドに使用される.
タイプ:Headerには、どのフィールドが含まれますか.フィールドseqは識別子に対応し、メッセージがパブリッシュされるにつれて自動的に増加します.フィールドstampは、データに関連付けられた時間情報を格納します.レーザスキャンを例にとると、stampはスキャンの開始時間ごとに対応する可能性がある.フィールドframe_idは、データに関連付けられたtfフレーム情報を格納する.レーザスキャンを例にとると、レーザデータが存在するフレームになります.
#Standard metadata for higher-level flow data types
#sequence ID: consecutively increasing ID 
uint32 seq
#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
#Frame this data is associated with
# 0: no frame
# 1: global frame
string frame_id

ロボットのレーザースキャナーに対してROS上でLaserScansを発表し、ROSはレーザー情報を格納する特殊なメッセージタイプLaserScanを提供し、パッケージsensor_msgs.LaserScanメッセージは、スキャナから取得したデータがこのタイプのメッセージにフォーマットできる限り、任意のレーザを処理するのに便利です.これらのメッセージを生成およびパブリッシュする方法について説明する前に、メッセージ自体の仕様を見てみましょう.
#
#          ,     
#       0    (  X   )
#

Header header
float32 angle_min        # scan      [  ]
float32 angle_max        # scan      [  ]
float32 angle_increment  #           [  ]
float32 time_increment   #        [ ]
float32 scan_time        #        [ ]
float32 range_min        #         [ ]
float32 range_max        #         [ ]
float32[] ranges         #         [ ] (  :   < range_min   > range_max      )
float32[] intensities    #      [device-specific units]

所望のように、上記の名前/注釈は、メッセージ内の各フィールドを明確に表している.より具体的な説明のために,彼らがどのように動作しているかを示す簡単なレーザデータパブリッシャーを書いた.ROS上でLaserScanメッセージを公開するのはかなり簡単です.
#include 
#include 

int main(int argc, char** argv){
  ros::init(argc, argv, "laser_scan_publisher");

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

  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_pub.publish(scan);
    ++count;
    r.sleep();
  }
}

ROSでポイントクラウドPointCloudsをリリース
ROSは、世界中の一連のポイントを格納し、共有するためにsensor_を提供します.msgs/PointCloudメッセージ.前述したように、このメッセージは、3次元空間内の点の配列と、1つのチャネルに保存されている任意の関連データをサポートする.例えば、「intensity」チャネルを有するPointCloudは、点群データ内の各点の強度を維持することができる.次に、ROSを使用してPointCloudをリリースし、このプロセスを探索します.
#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
ROSを使用してPointCloudをリリースするのは簡単です.次に、完全な例を示します.
#include 
#include 

int main(int argc, char** argv){
  ros::init(argc, argv, "point_cloud_publisher");

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

  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     :frame   timestamp.

    cloud.points.resize(num_points);//       .

    //     "intensity"       ,         .
    cloud.channels.resize(1);
    cloud.channels[0].name = "intensities";
    cloud.channels[0].values.resize(num_points);

    //         PointCloud   .  ,         intensity   .
    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;
    }

    cloud_pub.publish(cloud);
    ++count;
    r.sleep();
  }
}