文章目录

  • 自定义消息的实现过程及说明
  • 一、功能包的创建
  • 二、自定义话题消息
  • (1)创建自定义消息文件步骤
  • (2)添加编译选项步骤
  • 三、创建发布者
  • 四、创建订阅者
  • 五、添加编译选项
  • 六、编译运行
  • (1)编译
  • (2)运行


自定义一个类型为gps的消息(包括位置x,y和工作状态state信息),一个node以一定频率发布模拟的gps消息,另一个node接收并处理,算出到原点的距离。

自定义消息的实现过程及说明

ros机器人 python ROS机器人编程_ros机器人 python

一、功能包的创建

  • 1.进入src目录cd ~/工作空间名/src
cd ~/catkin_ws/src
  • 2.创建功能包
catkin_create_pkg topic_demo roscpp rospy std_msg

使用命令catkin_create_pkg 功能包名 [依赖项1] [依赖项2] ... 话题编程所依赖的依赖项有:rospyroscppstd_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