对于话题的解释和学习,笔者在这里推荐古月的21讲水平:古月21讲
话题通信是ROS系统工作中最为基础,同时也是最为重要的通信方式,笔者本篇文章主要记录如何配置话题通信而不是原理的讲解,具体原理可在古月居博客中进行了解!
本文主要讲述如何使用自定义的msg文件及如何配置CmakeLists
一、建立自定义msg文件
1.在功能包中新建msg文件夹,在文件夹中创建Person.msg文件:
string name
uint8 sex
uint8 age
注:如uint8这样的数据类型,ROS系统都是在std_msgs中定义的!!!
.msg文件不属于任何一种编程语言,但其样式很好记!!!
其中的数据类型最好不要使用int,笔者试过,报错了!!!
创建完文件后要对cmakelists和package进行配置,然后再编译才能让系统知道有着一个数据类型,若不配置直接进行编译系统中不会产生该数据类型
2.配置package.xml:
在export上方添加:
<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>
注:
1.在kinetic版本中所有的exec_depend都改为run_depend
2.所有的依赖都在package.xml有所体现,所以想添加依赖时要在package.xml中进行相应添加
3.在CMakeLists中:
3.1:在find_package中添加message_generation
注:find_package中也是添加依赖的地方,在package.xml和find_package中都添加后依赖也就添加完成了
3.2:在
################################################
## Declare ROS dynamic reconfigure parameters ##
################################################
的上方添加:
add_message_files(
FILES
Person.msg
)
generate_messages(
DEPENDENCIES
std_msgs
)
其中:add_message_files中的第二个参数填的是刚刚新建的msg名称,本语句是告知编译器用哪个msg文件进行编译
generate_messages是用来写msg中的数据使用了哪些依赖,如uint8就使用了 std_msgs的依赖,且本句无论是有依赖都要写
3.3在catkin_package第三行前的#号去掉,并在末尾添加message_runtime
3.4:编译
编译完成后会在devel /include/learning_pub文件夹中生成Person.h文件,意味着编译完成,这里的头文件也是后面用来调用的
可使用rosmsg list
查看,消息数据会以功能包名/数据名
的样式呈现,笔者使用的功能包learning_pub,数据名为Person
到这里能看到就说明已经生成成功了,上述配置只在生成时使用,在调用中就不需要上述配置了。
也可以使用指令rosmsg show learning_pub/Person
来查看消息类型
二、在其他包中使用自定义msg文件
笔者建议大家用一个专门的功能包放自定义msg文件,然后在其他功能包中引用
在其他包中引用该数据类型时,主要是添加使用的msg文件所在功能包依赖!!!
**1.**新建功能包catkin_create_pkg learning_publisher std_msgs roscpp rospy learning_pub
其中 std_msgs roscpp rospy 为每个功能包都应该添加的依赖, learning_pub为使用到的msg的包名的依赖
**2.**编写代码:注意包含msg所在的头文件
/**
* 该例程将发布/Person话题,自定义消息类型learning_pub::Person
*/
#include <ros/ros.h>
#include "learning_pub/Person.h"//---------》此处为包含的头文件
int main(int argc, char **argv)
{
// ROS节点初始化
ros::init(argc, argv, "person_publisher");
// 创建节点句柄
ros::NodeHandle n;
// 创建一个Publisher,发布名为/person_info的topic,消息类型为learning_topic::Person,队列长度10
ros::Publisher person_info_pub = n.advertise<learning_pub::Person>("/Person", 10);
// 设置循环的频率
ros::Rate loop_rate(1);
int count = 0;
while (ros::ok())
{
// 初始化learning_topic::Person类型的消息
learning_pub::Person person_msg;
person_msg.age = 18;
// 发布消息
person_info_pub.publish(person_msg);
ROS_INFO("sending...");
// 按照循环频率延时
loop_rate.sleep();
}
return 0;
}
**3.**在Cmakelists的
###########
## Build ##
###########
下添加
add_executable(publisher src/publisher.cpp)
target_link_libraries(publisher ${catkin_LIBRARIES} )
add_dependencies(publisher ${catkin_EXPORTED_TARGETS} )
三个语句的第一个参数都是生成的节点名,第一和第二个语句是生成节点必备的,第三个语句是使用自定义msg才添加的!!!
**4.**编译运行:
总结下:调用其他包msg最主要的就是添加依赖和add_dependencies这一语句