1. 在功能包下新增msg 文件夹
在功能包的下面新建 msg 文件夹,如下图所示
2. 新增Person.msg 消息实体
右键打开命令框,输入 touch Person.msg
就会在msg 目录下新增 Person.msg 文件
在Person.msg中输入如下内容完成.msg文件的创建,msg文件是ROS独有的格式
string name
uint8 sex
uint8 ageuint8 unknown = 0
uint8 male = 1
uint8 female = 2
3 修改package.xml文件
需要加入编译依赖和执行依赖,编译和执行均需要相关依赖功能包,在package.xml文件中添加以下内容
<build_depend>message_generation</build_depend> //编译的支持项
<exec_depend>message_runtime</exec_depend> //生成可执行文件的支持项
4 修改CMakeLists.txt文件
//在功能包的CMakeList.txt文件夹下添加message_generation库,这一块主要是编译会用到的支持包
find_package(catkin REQUIRED COMPONENTSroscpprospystd_msgsmessage_generation
)//在声明ROS消息时需要加入以下内容
add_message_files(FILES Person.msg)
generate_messages(DEPENDENCIES std_msgs)//取消对编译选项的注释,在原本的内容下加入message_runtime,此处为生成可执行文件所需依赖包
catkin_package(
# INCLUDE_DIRS include
# LIBRARIES package1CATKIN_DEPENDS roscpp rospy std_msgs message_runtime
# DEPENDS system_lib
)// 添加编译及链接文件,增加add_dependencies表明优先编译消息头文件,避免后续使用时候编译程序报错
回到catkin_ws 再编译
cd ~/catkin_wscatkin_make
5 新增Publisher 发布消息代码cpp
#include "ros/ros.h"
//功能包名下的类
#include "learning_topic/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<package1::Person>("/person_info",10); //设置循环频率(HZ),与loop_rate.sleep()函数关联,如果下一帧信息不满足频率要求则系统延时ros::Rate loop_rate(1); while(ros::ok()){ //初始化learning_topic::Person类型的消息,并赋值learning_topic::Person person_msg;person_msg.name = "Bob";person_msg.age = 6;person_msg.sex = package1::Person::male;//发布消息person_info_pub.publish(person_msg);ROS_INFO("Publish Person Info: name:%s age:%d sex:%d ",person_msg.name.c_str(),person_msg.age,person_msg.sex);//按照循环频率延时loop_rate.sleep();}return 0;
}
6 新增监听类Subscriber
#include <ros/ros.h>
#include "learning_topic/Person.h"void personInfoCallback(const learning_topic::Person::ConstPtr& msg)
{//将接收到的消息打印出来,注意在这里需要使用->指针,因为传进来的参数也是指针,当前对象还没有.属性ROS_INFO("Subscribe Person Info: name:%s age:%d sex:%d ",msg->name.c_str(),msg->age,msg->sex);
}int main(int argc,char **argv)
{//ROS节点初始化ros::init(argc,argv,"person_subscriber"); //创建句柄ros::NodeHandle n; //创建一个Publisher,发布名为/person_info的话题,消息类型为learning_topic::Person,队列长度为10 ros::Subscriber person_info_sub = n.subscribe("/person_info",10,personInfoCallback); ros::spin();return 0;
}
目录结构如下图
7 再次修改CMakeLists.txt文件
// 添加编译及链接文件,增加add_dependencies表明优先编译消息头文件,避免后续使用时候编译程序报错
add_executable(person_publishersrc/person_publisher.cpp)
target_link_libraries(person_publisher${catkin_LIBRARIES})
add_dependencies(person_publisher${PROJECT_NAME}_generate_messages_cpp)add_executable(person_subscribersrc/person_subscriber.cpp)
target_link_libraries(person_subscriber${catkin_LIBRARIES})
add_dependencies(person_subscriber${PROJECT_NAME}_generate_messages_cpp)
如图:
8 再次编译
cd ~/catkin_ws
catkin_make
source devel/setup.bash
编译成功如下图
9.测试
先启动监听端
rosrun learning_topic person_subscriber
启动发布者
rosrun learning_topic person_publisher
效果如下图所示:
这样自定义topic 的发布和订阅就已经完成了,有问题评论区见