文章目录
- 自定义消息的实现过程及说明
- 一、功能包的创建
- 二、自定义话题消息
- (1)创建自定义消息文件步骤
- (2)添加编译选项步骤
- 三、创建发布者
- 四、创建订阅者
- 五、添加编译选项
- 六、编译运行
- (1)编译
- (2)运行
自定义一个类型为gps的消息(包括位置x,y和工作状态state信息),一个node以一定频率发布模拟的gps消息,另一个node接收并处理,算出到原点的距离。
自定义消息的实现过程及说明
一、功能包的创建
- 1.进入src目录
cd ~/工作空间名/src
cd ~/catkin_ws/src
- 2.创建功能包
catkin_create_pkg topic_demo roscpp rospy std_msg
使用命令
catkin_create_pkg 功能包名 [依赖项1] [依赖项2] ...
话题编程所依赖的依赖项有:rospy
、roscpp
、std_msgs
。
二、自定义话题消息
(1)创建自定义消息文件步骤
- 1.进入功能包目录
cd ~/工作空间名/功能包名
cd ~/catkin_ws/topic_demo
- 2.创建msg文件夹用来存放msg文件
mkdir msg
- 3.创建msg文件
vi gps.msg
- 4.编辑msg文件
- msg文件内容:
string state #工作状态
float32 x #x坐标
float32 y #y坐标
- msg数据类型类似于结构体
在程序中对一个gps消息进行创建修改的方法和对结构体的操作一样。
struct gps
{
string state;
float32 x;
float32 y;
}
(2)添加编译选项步骤
- 1.编辑
CMakeLists.txt
- (1)在
find_package
中添加message_generation
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
message_generation #需要添加的地方
)
- (2)添加文件夹生成命令
add_message_files(FILES gps.msg)
#catkin在cmake之上新增的命令,指定从哪个消息文件生成
- (3)添加生成消息的命令
generate_messages(DEPENDENCIES std_msgs)
#catkin新增的命令,用于生成消息
#DEPENDENCIES后面指定生成msg需要依赖其他什么消息,由于gps.msg用到了flaot32这种ROS标准消息,因此需要再把std_msgs作为依赖
- 2.编辑
package.xml
- 添加:
<build_depend>message_generation</build_depend>
<run_depend>message_runtime</run_depend>
- 3.编译后产生gps.h头文件,在include目录下
三、创建发布者
- topic_demo/src/talker.cpp
#include <ros/ros.h>
#include <topic_demo/gps.h> //自定义msg产生的头文件
int main(int argc, char **argv)
{
ros::init(argc, argv, "talker"); //用于解析ROS参数,第三个参数为本节点名
ros::NodeHandle nh; //实例化句柄,初始化node
topic_demo::gps msg; //自定义gps消息并初始化
...
ros::Publisher pub = nh.advertise<topic_demo::gps>("gps_info", 1); //创建publisher,往"gps_info"话题上发布消息
ros::Rate loop_rate(1.0); //定义发布的频率,1HZ
while (ros::ok()) //循环发布msg
{
... //处理msg
pub.publish(msg);//以1Hz的频率发布msg
loop_rate.sleep();//根据前面的定义的loop_rate,设置1s的暂停
}
return 0;
}
四、创建订阅者
- topic_demo/src/listener.cpp
#include <ros/ros.h>
#include <topic_demo/gps.h>
#include <std_msgs/Float32.h>
void gpsCallback(const topic_demo::gps::ConstPtr &msg)
{
std_msgs::Float32 distance; //计算离原点(0,0)的距离
distance.data = sqrt(pow(msg->x,2)+pow(msg->y,2));
ROS_INFO("Listener: Distance to origin = %f, state: %s",distance.data,msg->state.c_str()); //输出
}
int main(int argc, char **argv)
{
ros::init(argc, argv, "listener");
ros::NodeHandle n;
ros::Subscriber sub = n.subscribe("gps_info", 1, gpsCallback); //设置回调函数gpsCallback
ros::spin(); //ros::spin()用于调用所有可触发的回调函数,将进入循环,不会返回,类似于在循环里反复调用spinOnce()
//而ros::spinOnce()只会去触发一次
return 0;
}
五、添加编译选项
CMakeLists.txt
的修改
add_executable(talker src/talker.cpp) #生成可执行文件talker
add_dependencies(talker topic_demo_generate_messages_cpp)
#表明在编译talker前,必须先生编译完成自定义消息
#必须添加add_dependencies,否则找不到自定义的msg产生的头文件
#表明在编译talker前,必须先生编译完成自定义消息
target_link_libraries(talker ${catkin_LIBRARIES}) #链接
add_executable(listener src/listener.cpp ) #声称可执行文件listener
add_dependencies(listener topic_demo_generate_messages_cpp)
target_link_libraries(listener ${catkin_LIBRARIES})#链接
六、编译运行
(1)编译
- 进入工作空间
cd ~/catkin_ws
- 编译
catkin_make
(2)运行
- 运行发布者
rosrun topic_demo talker
- 运行订阅者
rosrun topic_demo listener