【ROS消息包&自定义消息包&自定义消息包的使用】

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档


前言


ROS中的消息包可以分为两大类,一种是std_msgs标准消息包,另外一种是common_msgs常用消息包;

一、std_msgs标准消息包

基础类型
Byte、Bool、String、Char
Int8、Int16、Int32、Int64
UInt8、UInt16、UInt32、UInt64
Float32 Float64
Empty (不传输任何数据,只是把消息包当做一个信号使用)

数组类型
ByteMultiArray
Int8MultiArray Int16MultiArray Int32MultiArray Int64MultiArray
UInt8MultiArray UInt16MultiArray UInt32MultiArray UInt64MultiArray
Float32MultiArray Float64MultiArray
这些数组长度都是可变的,可以放置数量不确定的AD传感器数值、电机电流值、码盘值用这些数组消息包进行发送;
当需要额外增加数组的个数的时候直接调用push_back()即可,不需要修改消息的类型结构;(官方的建议是在quick prototyping快速原型开发的时候这样用)

结构体类型
这些结构体通常是把一些相互关联的数据整合在一起,然后放置到一些比较复杂的消息格式中,起到简化消息结构的作用;
ColorRGBA(包含了红、绿、蓝、透明度 四个分量的结构体,可以完整地描述一个像素)
Duration(表示相对时间,可正可负)
Time (表示绝对时间、是个无符号类型,不能为负数)
Header
(前面的数组类型的消息包都会包含如下结构体)
MultiArrayDimension用来描述数组内容的结构体
MultiArrayLayout用来描述数组内容的结构体

二、common_msgs常用消息包

包含sensor_msgs传感器消息包、geometry_msgs几何空间描述消息包、nav_msgs定位导航消息包;

几何消息包geometry_msgs

例如 Twist类型

#include <geometry_msgs/Twist.h>//引入速度消息的头文件

几何消息包里面的数据是描述一些物理几何上的信息;
加速度
Accel AccelStamped AccelWithCovariance AccelWithCovarianceStamped

惯量
Inertia InertiaStamped

空间点
Point Point32 PointStamped

多边形
Polygon PolygonStamped

空间位置
Pose Pose2D PoseArray PoseStamped PoseWithCovariance PoseWithCovarianceStamped

四元数
Quaternion QuarternionStamped

空间变换
Transform TransformStamped

空间方向
Twist TwistStamped TwistWithCovariance
TwistWithCovarianceStamped

三维矢量
Vector3 Vector3Stamped

扭矩
Wrench WrenchStamped

其中一些消息包类型带了Stamped关键词,这些消息包都是多了一个Header(时间和坐标系,将空间量和时间量进行了绑定)

传感器消息包sensor_msgs

比如:
激光雷达LaserScan类型
惯性测量单元Imu类型
需要作出以下引用:

#include <sensor_msgs/LaserScan.h>//引入雷达消息的头文件
#include <sensor_msgs/Imu.h>//引入IMU消息的头文件
#include <tf/tf.h>//引入tf转换库

常见的传感器数据包:

acttionlib_msgs行为数据包
diagnostic_msgs诊断下消息数据包
geometry_msgs几何消息数据包
nv_msgs导航消息数据包
sensor_msgs传感器数据包
shape_msgs形状数据包
stereo_msgs双目视觉消息包
trajectory_msgs运行轨迹消息包
visualization_msgs图形显示消息包(在Riz中进行线条、文字以及各种标识和符号的显示使用的即是这个包的消息类型)
以上9个消息包中最常用的是geometry_msgs几何消息数据包、sensor_msgs传感器消息包。

传感器数据包里面的消息类形都和传感器相关,比如:

激光雷达:(单线激光雷达、多线激光雷达)
LaserScan PointCloud2 LaserEcho MultiEchoLaserScan

单点测距:(超声波和红外式传感器)
Range

惯性测量:
Imu、MagneticField

彩色相机:(包含相机参数、彩色图像、区域选框信息)
CameraInfo Image CompressedImage
RegionOfInerest

立体相机:(相机参数、深度图、三维点云)
CameraInfo Image ChannelFloat32 PointCloud
PointCloud2 PointField

温度测量
Temperature

湿度测量
RelativeHumidity

照度测量:(光照强度)
Illuminance

流体压力:(液压和气压)
FluidPressure

全球定位:(通过GPS、GLONESS 北斗 GALILEO这些定位系统得到的经度和纬度数值)
NavSatFix NavSatStatus

运动关节(关节名称、关节角度、运动速度)
JointState MultiDOFJointState

控制手柄:(手柄上的遥感位置和按钮状态)
Joy JoyFeedback JoyFeedbackArray

电池状态:(电池电压、温度、充放电状态)
BatteryState

时钟源:(比如外部时钟源,用于获取更高的时间精度)
TimeReference

三、自定义消息类型

自定义数据包

cd ~/catkin_ws/src
catkin_create_pkg test_msgs roscpp rospy std_msgs std_msgs message_generation message_runtime

其中message_generation message_runtime是生存消息包和运行时所需要的依赖项;
从中可以看出,消息包也是一个普通的软件包,包名可以是任意名字,为了方便识别一般以_msgs作为结尾;

定义user消息类型(user.msg)

在vscode中打开上述创建的消息包,右键test_msgs包名创建名称为msg的文件夹;

在上述的msg文件夹中新建新的消息包类型文件user.msg
.msg消息包的定义格式:
数据类型 变量名
比如std_msgs/String.msg
string data
数据类型可以使用以下基础类型数据:
单字节类型
bool byte char
整形
int8 int16 int32 int64 uint8 uint16 uint64
浮点型
float32 float64
字符串
string
时间类
time duration
数组类型
可变长度数组array[]
固定长度数组array[n]
除此之外还可以把其他软件包定义的消息类型嵌套进来使用;

在上述user.msg文件里编写信息:
string info
int64 id
string kind

编译规则设置

给上述新的消息类型设置编译规则;
1.确保CmakeList.txt文件已经填入了message_generation和message_runtime;

find_package(catkin REQUIRED COMPONENTS
  message_generation
  message_runtime
  roscpp
  rospy
  std_msgs
  std_msgs
)

在这里插入图片描述
2.找到如下语句,取消注释;
将上述Message1.msg和Message1.msg换成前文编写的test.msg;
更改前:

# add_message_files(
#   FILES
#   Message1.msg
#   Message2.msg
# )

更改后:

add_message_files(
  FILES
  user.msg
)

3.找到generate_messages相关设置,取消注释;

## Generate added messages and services with any dependencies listed here
# generate_messages(
#   DEPENDENCIES
#   std_msgs#   std_msgs
# )

这里表示新的消息类型需要依赖的其他消息包列表;
更改后:

generate_messages(
  DEPENDENCIES
  std_msgs#   std_msgs
)

4.找到catkin_package相关设置,取消 CATKIN_DEPENDS message_generation message_runtime roscpp rospy std_msgs 的注释。(确保message_runtime在里面)
这句指令的作用是让依赖于这个新消息包的其它软件包能够在运行时使用上述自定义的test_msgs消息类型;

catkin_package(
#  INCLUDE_DIRS include
#  LIBRARIES test_msgs
 CATKIN_DEPENDS message_generation message_runtime roscpp rospy std_msgs std_msgs
#  DEPENDS system_lib
)

此为还需要对xml文件进行补全,确保message_generation和message_runtime信息完整;
在这里插入图片描述补全后应该是这样的:
在这里插入图片描述

  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>message_generation</build_depend>
  <build_depend>message_runtime</build_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <exec_depend>message_generation</exec_depend>
  <exec_depend>message_runtime</exec_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>

确保下列信息的完整性:
<build_depend>message_generation</build_depend>
<build_depend>message_runtime</build_depend>
<exec_depend>message_generation</exec_depend>
<exec_depend>message_runtime</exec_depend>

编译运行

cd catkin_ws/
catkin_make

1.查看新的消息类型是否已进入ROS的消息列表
rosmsg show 消息包的名称/消息包的类型
rosmsg show test_msgs/user
在这里插入图片描述这里查询到test_msgs消息包中的user类型的定义如下:
/user
string info
int64 id
string kind
由此可以上述步骤创建了一个新的消息类型

四、自定义消息格式类型在节点中的应用

ssr_pkg包中DHT11_node节点作为发布者
atr_pkg包中的motor_node节点作为订阅者

修改发布者节点

记得将自定义消息包test_msgs和自定义消息类型user添加进头文件

#include <ros/ros.h>
#include <std_msgs/String.h>
#include <test_msgs/user.h>

int main(int argc,char *argv[])
{
    
    
    ros::init(argc,argv,"DHT11_node");
    printf("This is DHT11_node\n");
    ros::NodeHandle nh;
    ros::Rate loop_rate(10); 
    ros::Publisher pub = nh.advertise<test_msgs::user>("sensor_topic",10);
    while(ros::ok())
    {
    
    
        printf("DHT11_node is working!\n");
        test_msgs::user msg;//生成一个消息包 
        msg.info = "DHT11 sensor data";
        msg.id = 123456;
        msg.kind = "sensor data";
        pub.publish(msg);
        loop_rate.sleep();
    }
    return 0;
}

订阅者节点编译规则设置

添加消息类型的依赖项
在这里插入图片描述追加test_msgs消息包,防止编译出现消息未定义的错误

find_package(catkin REQUIRED COMPONENTS
  roscpp
  rospy
  std_msgs
  test_msgs
)

添加add_dependencies(DHT11_node test_msgs_generate_messages_cpp)指令
表示先让test_msgs创建好新的消息类型再编译该节点

add_executable(DHT11_node src/DHT11_node.cpp)

target_link_libraries(DHT11_node
  ${
    
    catkin_LIBRARIES}
)
add_dependencies(DHT11_node test_msgs_generate_messages_cpp)

修改订阅者的.xml文件

原文件缺少新添加的消息包test_msgs
在这里插入图片描述
修改结果如下:
在这里插入图片描述编译
cd catkin_ws/
catkin_make

修改订阅者节点

记得将自定义消息包test_msgs和自定义消息类型user添加进头文件
其余部分只需要修改回调函数,修改其中订阅的消息与打印显示的内容

void motor_callback(test_msgs::user msg)
{
    
    
    ROS_WARN("Received message: %s", msg.info.c_str());
    ROS_INFO("ID: %d, Kind: %s", msg.id, msg.kind.c_str());
}

修改订阅者节点的编译规则

添加依赖项

add_executable(motor_node src/motor_node.cpp)

target_link_libraries(motor_node
  ${
    
    catkin_LIBRARIES}
)
add_dependencies(motor_node test_msgs_generate_messages_cpp)

修改订阅者节点的.xml文件

添加test_msgs依赖与执行项

  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_depend>test_msgs</build_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend>
  <exec_depend>test_msgs</exec_depend>

测试环节

编译
cd catkin_ws/
catkin_make

roscore
rosrun ssr_pkg DHT11_node
rosrun atr_pkg motor_node
rqt_graph
rostopic list
rostopic echo /senor_topic
运行框图如下:

在这里插入图片描述查看话题内容
在这里插入图片描述

节点间的通信关系如图所示:
在这里插入图片描述


总结

简述了ros中的消息类型,构建了自定义消息包并使用简单案例演示了自定义消息包的使用,下期内容再见。

猜你喜欢

转载自blog.csdn.net/weixin_46187287/article/details/143299927