在ROS上发布传感器流。
在ros上正确地从传感器上发布数据对导航堆栈的安全运行非常重要。如果导航堆栈是没有从机器人的传感器接收到信息,那么便没法完成导航的工作。有很多传感器能够用导航堆栈提供信息:激光、相机、声呐、红外、碰撞传感器等。但是,当前导航堆栈仅接收传感器/激光扫描消息类型或传感器信息/点云消息类型。
ros消息头
消息类型包含TF帧和时间相关信息。seq字段对应于一个标识符,该标识符在从给定发布者发送消息时自动增加。stamp字段存储着与消息信息相关的时间信息,如在激光扫描当中,stamp字段就会和扫描时间相对应。frame_id字段存储tf帧信息,这应该与消息中的数据信息相关联。
uint32 seq
time stamp
string frame_id
对于激光扫描传感器,ROS在sensor_msgs包中提供了一种名为LaserScan的特殊消息类型,用于保存关于给定扫描的信息。 LaserScan Messages使得只要从扫描器返回的数据可以被标准格式化以适合于消息,就可以让代码轻松地与几乎任何激光器一起工作。下面是消息规范:
#激光扫描角度是逆时针测量的,0面朝前
#沿x轴
Header header
float32 angle_min #扫描起始角
float32 angle_max #扫描结束角
float32 angle_increment #测量间隔角度
float32 time_increment #测量间隔时间
float32 scan_time #扫描间隔时间
float32 range_min #最小量程值
float32 range_max #最大量程值
float32[ ] ranges #数据范围[m](注意:值< range_min或> range_max应丢弃)
float32[ ] intensities #光照强度
下面是一段激光扫描示例代码:
以激光为例:
#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节点通信的接入点
ros::Publisher scan_pub = n.advertise<sensor_msgs::LaserScan>("Scan", 50); //创建一个publisher使用ros发布激光扫描消息的消息
//advertising()函数是告诉ROS要在给定的主题名称上发布的方法
unsigned int num_readings = 100;
double laser_frequency = 40;
double ranges[num_readings];
double intensities[num_readings];
int cout = 0;
ros::Rate r(1.0);
while (n.ok()) {
//这里我们只是为我们要用来填充扫描的虚拟数据建立存储。一个真正的应用程序将从他们的激光驱动程序中提取这些数据。
for (unsigned int i = 0; i < num_reading; i++) {
ranges[i] = count;
intensities[i] = 100 + count;
}
ros::Time scan_time = ros::Time::now();
sensor_msgs::LaserScan scan; //创建一个消息对象。你用数据填充它,然后发布它。
scan.header.stamp = scan_time;
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();
}
}