本文聚焦于ROS(Robot Operating System,机器人操作系统)中的常用消息类型,为机器人开发者提供了深入理解ROS消息机制的重要参考。博客首先介绍了ROS消息的基本概念,包括其定义、作用以及在机器人通信中的核心地位。随后,详细列举了ROS中常用的几种消息类型,如传感器数据、控制指令、状态信息等,并针对每种消息类型给出了具体的应用场景和实例。此外,博客还探讨了如何根据实际需求创建和使用自定义消息类型,为开发者提供了实用的指导。通过阅读本文,读者将能够更全面地掌握ROS消息的使用技巧,为机器人开发和应用奠定坚实基础。
1. sensor_msgs
sensor_msgs是存储传感器常用消息数据message的包,提供各种消息数据message的转换方法并定义了常用传感器使用的消息类型message,如相机、激光扫描测距仪等;
1.1. sensor_msgs/ChannelFloat32.msg
PointCloud消息用此消息保存与点云中每个点相关的数据;数组values的长度应与点云中点的数组长度相同;values中每个值与点云中一个点相对应。
目前常见的通道名称包括
"u", "v":图像的行列
"rgb":uint8(R, G, B),共24bits;
"intensity":激光或者像素密度
"distance":距离
通道名称应该给出通道具体的语义,如 "intensity密度" 而不是 "value值".
成员名称name和values固定,可以改变其值;
string name
float32[] values
具体实例参考:
sensor_msgs::ChannelFloat32 velocity_x_of_point;
//特征点沿x向速度;names
sensor_msgs::ChannelFloat32 velocity_y_of_point;
//特征点沿y向速度;names
for (unsigned int j = 0; j < ids.size(); j++) {
//向values添加值;
velocity_x_of_point.values.push_back(pts_velocity[j].x);
velocity_y_of_point.values.push_back(pts_velocity[j].y);
}
1.2. sensor_msgs/PointCloud.msg
sensor_msgs/PointCloudPtr.msg指针类型,调用成员用->
sensor_msgs/PointCloud.msg点云类型,调用成员用.
该消息用于存储3d点,及其它相关信息
存储传感器获取数据的时间、相关坐标系ID、序号
std_msgs/Header header
3d点数组,每个Point是header指定坐标系下的3d点
geometry_msgs/Point[] points
每个通道都有和点的数组相同数量的元素;
每个通道的数据和点一一对应的;
常见通道名称已经列于ChannelFloat32.msg中
sensor_msgs/ChannelFloat32[] channels
示例
sensor_msgs::PointCloudPtr feature_points(new sensor_msgs::PointCloud);
//初始化点云消息
feature_points->header = img_msg->header;
//采集图像的时间
feature_points->header.frame_id = "world";
//坐标系id
# 添加header
geometry_msgs::Point32 p;
p.x = un_pts[j].x;
p.y = un_pts[j].y;
p.z = 1;
feature_points->points.push_back(p);
# 添加points
sensor_msgs::ChannelFloat32 id_of_point;
sensor_msgs::ChannelFloat32 u_of_point;
sensor_msgs::ChannelFloat32 v_of_point;
//省略3个ChannelFloat32的values处理;
feature_points->channels.push_back(id_of_point);
feature_points->channels.push_back(u_of_point);
feature_points->channels.push_back(v_of_point);
# 添加channels
1.3. sensor_msgs/Image.msg
sensor_msgs/Image.msg图像对象,调用成员用.
sensor_msgs/ImagePtr.msg图像指针对象,调用成员->
该消息包含未压缩的图像
(0, 0)是图像的左上角
Header timestamp:图像采集时间
Header frame_id:相机坐标系代号
坐标系原点应该是相机的光心
+x指向图像右边
+y指向图像下侧
+z 指向图像平面
std_msgs/Header header
uint32 height # 图像高度,或行数
uint32 width # 图像宽度,或列数
图像编码方式 is this data bigendian?
step:以bytes记,行长度
data:实际矩阵数据,大小是(step * rows)
string encoding
uint8 is_bigendian
uint32 step
uint8[] data
示例
sensor_msgs::Image img;
img.header = img_msg->header;
img.height = img_msg->height;
img.width = img_msg->width;
img.is_bigendian = img_msg->is_bigendian;
img.step = img_msg->step;
img.data = img_msg->data;
img.encoding = "mono8";
1.4. sensor_msgs/Imu.msg
该消息存储来自IMU惯导的数据
加速度单位是m/s²,旋转速度单位是rad/s
如果测量的协方差一致,那应该将其填入矩阵对角线
全是0的协防矩阵被视作协方差未知,可使用假设的或其他
数据源
std_msgs/Header header
geometry_msgs/Quaternion orientation
# 旋转方向
float64[9] orientation_covariance
# 行排序,分别关于x/y/轴
geometry_msgs/Vector3 angular_velocity
# 旋转速度
float64[9] angular_velocity_covariance
# 行排序,分别关于x/y/轴
geometry_msgs/Vector3 linear_acceleration
# 加速度
float64[9] linear_acceleration_covariance
# 行排序,分别关于x/y/轴
2. geometry_msgs
geometry_msgs提供关于常见几何元素的消息,例如点、向量、位姿等;这些元素可进一步设计为常见的数据类型;
2.1. geometry_msgs/Accel.msg
表示自由空间速度,可分解为两部分线速度和角速度
线速度
Vector3 linear
角速度
Vector3 angular
2.2. geometry_msgs/AccelStamped.msg
关联有参考坐标系和时间戳的Accel.msg
Header header
Accel accel
2.3. geometry_msgs/Point.msg
该消息包含自由空间中的点坐标,64bits
float64 x
float64 y
float64 z
2.4. geometry_msgs/Point32.msg
该消息包含自由空间中点的位置,具有32bits;.
推荐使用Point.msg而不是Point32.msg
这种推荐有助于提升互操作性
ros中大多数函数的接口是用64位定义的
但是当需要发布的点的数量较大时可以采用point32
方式定义点,可以减少所需的内存空间
float32 x
float32 y
float32 z
2.5. geometry_msgs/Quaternion.msg
这个消息表示以四元数表示的自由空间的旋转方向
float64 x
float64 y
float64 z
float64 w
2.6. geometry_msgs/Vector3.msg
该消息表示自由空间的向量;
这意味着仅能表示方向,因此对它应用平移没有意义
例如当你对御用Vector3做刚体运动时,tf2仅能表示旋转;
如果你想让你的数据平移,
请使用geometry_msgs/Point.msg
float64 x
float64 y
float64 z
2.7. geometry_msgs/PointStamped.msg
该消息存储点包含有参考坐标系和时间戳;
Header header
Point point
2.8. geometry_msgs/Pose.msg
自由空间位姿的表示方法,由位置和方向构成
Point position
# 位置
Quaternion orientation
# 方向
2.9. geometry_msgs/PoseStamped.msg
关联有参考坐标系和时间戳的Pose.msg
Header header
Pose pose
2.10. geometry_msgs/Transform.msg
该消息表示自由空间中两个坐标系间的变换
Vector3 translation
# 平移
Quaternion rotation
# 旋转
2.11. geometry_msgs/TransformStamped.msg
该消息表示从坐标系header.frame_id到
坐标系child_frame_id的变换
该消息一般用于tf包;
更多消息请参考tf包
Header header
string child_frame_id # child_frame_id
Transform transform
2.12. geometry_msgs/QuaternionStamped.msg
该消息表示关联参考坐标系在某时间戳下的方向;
Header header
Quaternion quaternion
3. std_msgs
std_msgs是一种标准消息类型包,包含了一些常用的基本数据类型的消息定义。
3.1 基本类别
std_msgs/Bool:表示布尔值(True或False)
std_msgs/Int8、Int16、Int32、Int64:表示有符号的8、16、32和64位整数
std_msgs/UInt8、UInt16、UInt32、UInt64:表示无符号的8、16、32和64位整数
std_msgs/Float32、Float64:表示单精度和双精度浮点数
std_msgs/String:表示字符串
std_msgs还包括其他类型的消息,例如:
std_msgs/Time:表示ROS的时间戳
std_msgs/Duration:表示时间段
std_msgs/Header:表示ROS消息头,其中包括时间戳、坐标系和序列号等信息。
3.2. 使用模板
#include "ros/ros.h"
#include "std_msgs/String.h"
#include "std_msgs/Int32.h"
void callback_string(const std_msgs::String::ConstPtr& msg)
{
ROS_INFO("Received string: %s", msg->data.c_str());
// 创建一个新的std_msgs::String类型消息
std_msgs::String output_msg;
output_msg.data = "Received string: " + msg->data;
// 发布新消息
pub.publish(output_msg);
}
void callback_int(const std_msgs::Int32::ConstPtr& msg)
{
ROS_INFO("Received integer: %d", msg->data);
// 创建一个新的std_msgs::String类型消息
std_msgs::String output_msg;
output_msg.data = "Received integer: " + std::to_string(msg->data);
// 发布新消息
pub.publish(output_msg);
}
int main(int argc, char **argv)
{
// 初始化ROS节点
ros::init(argc, argv, "listener_and_talker");
// 创建ROS节点句柄和两个订阅节点对象,以及一个发布者对象
ros::NodeHandle nh;
ros::Subscriber sub_string = nh.subscribe("my_topic_string", 10, callback_string);
ros::Subscriber sub_int = nh.subscribe("my_topic_int", 10, callback_int);
ros::Publisher pub = nh.advertise<std_msgs::String>("my_topic_output", 10);
// 运行ROS节点
ros::spin();
return 0;
}