1.std_msgs
消息类型如下:
来源:std_msgs Msg/Srv Documentation
std_msgs的消息类型大致可以分为:基础类型,如Bool
数组类型,如Float32MultiArray
结构体类型。如Header
我们可以在ROS Index这里查到各种类型的消息包。std_msgs相对比较常用,包含各种基本的消息类型,我们在构建自定义消息类型时可以用到。
2.common_msgs
该消息包和std_msgs不同,它是由几个消息包组合而成。
例:geometry_msgs中的Twist消息包:主要用于表示机器人的线速度和角速度,这两部分速度通常用三维矢量(x,y,z)表示,读者可自行尝试去ros wiki查看。
3.自定义消息类型
首先在工作目录的src目录下创建一个test_msgs包,依赖项除了roscpp rospy std_msgs以外,还有message_generation message_runtime,这两个是消息包生成的依赖项。
然后在test_msgs下创建一msg文件夹。
假设我们要描述的对象是一个worker,我们需要在msg文件夹下创建一个消息类型文件,在该文件中定义我们自定义的消息结构,格式如下:(数据类型+变量名),数据类型也可以用其他包的数据类型。
然后我们需要给这个自定义消息类型设置编译规则,在创建好的包中找到CMakeList.txt文件,先确保message_generation和message_runtime在find_package内:
然后找到如下语句:
将其取消注释,并将里面的msg文件换成我们定义好的worker.msg
如果定义了其他的消息类型,也需要写在这里。
然后再将generate_messages也取消注释
里面的内容是我们自定义消息需要依赖的软件包,按需求填写即可
再找到catkin_package,将CATKIN_DEPENDS取消注释,目的是让依赖我们定义的消息包的其他软件包能够使用自定义的消息类型。
至此,CMakeList.txt全部修改完成。
然后在创建的包中找到package.xml文件,找到最下面的依赖关系部分,确保message_generation和message_runtime包含在内,缺失的话就把他们补全:
然后就可以在工作空间编译了。
4.自定义消息类型的使用
(1)发布者节点
确保创建好的test_msgs仍在工作空间中。
创建一个节点,内容如下:
#include<ros/ros.h>
#include<std_msgs/String.h>
#include<test_msgs/worker_msgs.h>
int main(int argc, char *argv[])
{
ros::init(argc,argv,"worker_talk_node");
printf("这里是walkTalkNode节点,用于发布worker类型的消息\n");
ros::NodeHandle n;
ros::Publisher pub = n.advertise<test_msgs::worker_msgs>("workerTopic",10);
ros::Rate loop_rate(10);
while(ros::ok())
{
test_msgs::worker_msgs msg;
msg.name="Li Hua";
msg.department="project";
msg.age=30;
msg.salary=10000;
pub.publish(msg);
loop_rate.sleep();
}
return 0;
}
然后需要在编译规则里添加消息包的依赖,让编译器先去编译test_msgs消息包,再编译该节点。
打开节点的软件包的CMakeList文件,找到find_package(其功能是设置依赖项),将test_msgs加入其中:
再在文件末尾添加如下内容:
add_executable(worker_talk_node src/worker_talk_node.cpp)
add_dependencies(worker_talk_node test_msgs_generate_messages_cpp)
#CMake指令,确保在构建workerTalk_node之前,test_msgs_generate_messages_cpp已经构建完成
target_link_libraries(worker_talk_node
${catkin_LIBRARIES}
)
然后找到package.xml文件,将worker_msgs加入到build_depend和exec_depend中
<buildtool_depend>catkin</buildtool_depend>
<build_depend>roscpp</build_depend>
<build_depend>rospy</build_depend>
<build_depend>std_msgs</build_depend>
<build_depend>worker_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>worker_msgs</exec_depend>
到这里,发布者节点的编写就完成了。回到工作空间编译一下这个过程没有出错。
(2)订阅者节点
代码如下:
#include<ros/ros.h>
#include<std_msgs/String.h>
#include<test_msgs/worker_msgs.h>
void worker_callback(test_msgs::worker_msgs msg)
{
printf(msg.name.c_str());
printf(msg.department.c_str());
printf("age:%ld\n",msg.age);
printf("salary:%ld\n",msg.salary);
}
int main(int argc, char *argv[])
{
ros::init(argc,argv,"worker_subscriber_node");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("workerTopic",10,worker_callback);
while(ros::ok())
{
ros::spinOnce();
}
return 0;
}
修改编译规则:
CMakeList文件:
确保定义好的消息文件所在的软件包在find_package内。
然后就是文件结尾了,这里我把两个节点放在了同一软件包内。
编译并运行。
订阅者结果如下:
这里我没有换行,如果要让他看的更清楚一点可以改成这种格式:printf("%s\n",msg.name.c_str());
标签:std,ros,自定义,msgs,worker,msg,消息,类型,ROS From: https://blog.csdn.net/m0_74409155/article/details/145246291