ROS Navigation - Publishing Sensor Stream
9485 ワード
Publishing Sensor Streams over ROSナビゲーションワークステーションの安全な動作を確保するためには、ROS環境においてセンサ値を正確に発行することが重要である.ナビゲーションスタックがセンサから情報を受信できない場合は、正常に動作しにくい.
Navigation Stackに情報を提供できるセンサは多いが、現在のナビゲーションスタックではsensor msgs/Laserscanメッセージタイプまたはsensor msgs/PointCloudメッセージタイプを介して発行されるセンサデータしか受け入れられない.
ROS Message Headersセンサmsgs/LaserScanおよびセンサmsgs/PointCloudメッセージタイプは、他のROSメッセージタイプと同様にtfフレームおよび時間に関する情報を有する.
これらの情報の伝達方法を規範化するために,Headerメッセージタイプを上記メッセージのドメインとして用いた.
Headerタイプの3つのフィールドを以下に示します.
seqフィールドは、所与のpublisherからメッセージが伝達されるたびに、その値が増加する識別子ロールを自動的に実行するフィールドである.
stampfieldは、メッセージ内のデータに関連付けなければならない時間情報を持つフィールドです.レーザスキャンを例にとると、stampはスキャン発生時の時刻に相当する.
frame idフィールドは、メッセージ内のデータに関連付けなければならないtf frame情報を有するフィールドである.レーザスキャンの場合、frame idはスキャンが発生したフレームに相当する.
Publishing LaserScans over ROS
The LaserScan Message ROSは、LaserScanと呼ばれる特殊なメッセージタイプを提供する.sensor msgs packageに存在し、scanから取得した情報を保存できます.
スキャナで得られたデータをメッセージにフォーマットできる限り、LaserScanメッセージは、ほとんどのレーザセンサを既存のコードに関連付けて使用することができる.
これらのメッセージを生成してパブリッシュする前に、メッセージ自体を見てみましょう. のほとんどのフィールドは、名前だけで何のフィールドかを感じることができます. 簡単な例により をさらに理解する.
Writing Code to Publish a LaserScan Message ROS環境でLaserScanメッセージを公開するのはかなり直感的です.
次は コードです
Publishing PointClouds over ROS
The PointCloud Message
ROSは、現実世界の複数のポイントに関する情報を保存および共有するためにsensor msgs/PointCloudメッセージを提供する.
この情報は,3次元世界の点からなる配列とchannelのように保存された関連情報をサポートするために作成された.
[強度](Strength)チャネルを使用してPointCloudを転送する例を次に示します.このチャネルは、クラウドの各ポイントの強度値を有します.
#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
seqフィールドは、所与のpublisherからメッセージが伝達されるたびに、その値が増加する識別子ロールを自動的に実行するフィールドである.
stampfieldは、メッセージ内のデータに関連付けなければならない時間情報を持つフィールドです.レーザスキャンを例にとると、stampはスキャン発生時の時刻に相当する.
frame idフィールドは、メッセージ内のデータに関連付けなければならないtf frame情報を有するフィールドである.レーザスキャンの場合、frame idはスキャンが発生したフレームに相当する.
The LaserScan Message
#
# 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]
Writing Code to Publish a LaserScan Message
次は
#include <ros/ros.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);
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();
}
}
ひとつひとつ見る#include <sensor_msgs/LaserScan.h>
送信するメッセージを含むsensor msgs/LaserScanros::Publisher scan_pub = n.advertise<sensor_msgs::LaserScan>("scan", 50);
このコードはros::Publisherを生成するコードです.これは、後でROS環境でLaserScanメッセージを送信するために使用されます. unsigned int num_readings = 100;
double laser_frequency = 40;
double ranges[num_readings];
double intensities[num_readings];
Scanのデータの山を埋めます.実際には、ロボットに適用する場合、レーザドライバからこれらのデータ値を抽出する必要がある場合があります. //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();
増加したヒープ・データを1秒あたり埋め込む //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];
}
スキャンmsgs::LaserScanメッセージを生成し、上で生成したデータを埋め込む scan_pub.publish(scan);
最後に、ROSを通じてこのメッセージを発表します.Publishing PointClouds over ROS
The PointCloud Message
ROSは、現実世界の複数のポイントに関する情報を保存および共有するためにsensor msgs/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
Writing Code to Publish a PointCloud Message#include <ros/ros.h>
#include <sensor_msgs/PointCloud.h>
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);
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";
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);
//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;
}
cloud_pub.publish(cloud);
++count;
r.sleep();
}
}
コードを1つずつ表示すると、#include <sensor_msgs/PointCloud.h>
sensor msgs/PointCloudメッセージが含まれます.ros::Publisher cloud_pub = n.advertise<sensor_msgs::PointCloud>("cloud", 50);
PointCloudメッセージを送信するros::Publisherを生成 sensor_msgs::PointCloud cloud;
cloud.header.stamp = ros::Time::now();
cloud.header.frame_id = "sensor_frame";
フレーム情報とタイムスタンプ情報を使用してPointCloudメッセージヘッダを埋めます. cloud.points.resize(num_points);
スタックデータを埋め込むpointcloudの個数を決定する //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);
強さ(Strength)という名前のチャネルを追加し、クラウドで作成するポイントの数にサイズを変更します. //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;
}
スタックされたデータを使用してPointCloudメッセージと強度チャネルを埋め込む cloud_pub.publish(cloud);
最後に、ROS環境でPointCloudをリリースReference
この問題について(ROS Navigation - Publishing Sensor Stream), 我々は、より多くの情報をここで見つけました https://velog.io/@richard7714/ROS-Navigation-Publishing-Sensor-Streamテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol