4、ROS话题通信实战,代码逐行解析

在前面小节已经实现了ROS工作空间的创建,这里开始功能包的开发实战了。
首先创建功能包:

cd ~/ROS/src
#创建功能包topic,指定依赖roscpp和std_msgs包
catkin_create_pkg topic roscpp std_msgs

执行完上述步奏,会在topic功能包里面生成一下文件和文件夹
在这里插入图片描述
其中include存放头文件,src存放源文件,接下来开始撸代码:
进入src目录,创建发布话题的节点源码

#进入src目录
cd topic/src
#创建publisher_node.cpp、subscriber_node.cpp文件
touch publisher_node.cpp subscriber_node.cpp

编辑publisher_node.cpp代码如下

//开发ROS节点必须包含的头文件
#include "ros/ros.h" 
//包含ROS提供的标准消息类型
#include "std_msgs/String.h"
//C++标准库
#include <sstream> 

//进入main函数
int main (int argc, char **argv)
{
    //初始化一个叫“publish_node”的节点
    ros::init(argc,argv,"publish_node");
    //实例化节点句柄
    ros::NodeHandle nh; 

    //创建一个Publisher,发布名为ssj_chatter的topic,消息类型为 chatter_example::Persion,队列长度为100
    ros::Publisher ssj_pub = nh.advertise<chatter_example::Person>("ssj_chatter",1000);
    //设置自循环频率,需要搭配该类的sleep方法使用,100代表频率(100HZ)
    ros::Rate loop_rate(100);
    int count = 0;

    while(ros::ok())
    {
        //实例化String,取名为msg
        std_msgs::String msg;
        //实例化标准字符串流
        std::stringstream ss;
        //初始化字符串流
        ss << "hello" << count;
        msg.data = ss.str();
        //ROS_INFO打印信息到终端
        ROS_INFO("%s",msg.data.c_str());
        //发布消息
        ssj_pub.publish(msg);
        //让回调函数有机会被执行的声明
        ros::spinOnce();
        //休眠实现延时
        loop_rate.sleep();
        ++count;
    }
    return 0;
}

编辑subscribe_node.cpp代码如下:

#include "ros/ros.h"
#include "std_msgs/String.h"

//回调函数
void topicCallback(const std_msg::String::ConstPtr& msg)
{
    //将接收到的信息打印到终端
    ROS_INFO(" [%s] ", msg->data.c_str());
}

int main(int argc,char **argv)
{
    //初始化节点
    ros::init(argc,argv,"subscribe_node");
    //实例化一个节点句柄
    ros::NodeHandle nh;
    //订阅话题ssj_chatter中的消息
    ros::Subscriber ssj_sub = nh.subscribe("ssj_chatter",1000,topicCallback);
   //程序进入自循环挂起状态
    ros::spin();
    return 0;
}

修改CMakeLists.txt,至于CMakeLists.txt是什么在此不再解释,可以另行学习cmake的知识。
打开topic目录下的CMakeLists.txt,作如下修改

#指定编译该功能包所需要依赖的包
find_package(catkin REQUIRED COMPONENTS
  roscpp
  std_msgs
  message_generation
)

#要编译的文件,和可执行文件名
 add_executable(publish_node src/publish_node.cpp)
 #指定要链接的库
 target_link_libraries(publish_node ${catkin_LIBRARIES})
 
 add_executable(subscribe_node src/subscribe_node.cpp)
 target_link_libraries(subscribe_node ${catkin_LIBRARIES})

打开topic目录下的package.xml 文件,添加下列内容:

#编译依赖的工具,是catkin 必不可少的
  <buildtool_depend>catkin</buildtool_depend>

#编译依赖项
  <build_depend>roscpp</build_depend>
  <build_depend>rospy</build_depend>
  <build_depend>std_msgs</build_depend>
  <build_depend>gometry_msgs</build_depend>
  <build_depend>message_generation</build_depend>
  
#编译导出依赖项
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>rospy</build_export_depend>
  <build_export_depend>std_msgs</build_export_depend>
  <build_export_depend>gometry_msgs</build_export_depend>
  
   #执行依赖项
  <exec_depend>roscpp</exec_depend>
  <exec_depend>rospy</exec_depend>
  <exec_depend>std_msgs</exec_depend> 
  <exec_depend>message_runtime</exec_depend>  
  <exec_depend>gometry_msgs</exec_depend>

修改CMakeLists.txt 和 package.xml之后进入,工作空间执行编译指令

catkin_make

待编译完成之后:

#运行ros的核心服务
roscore
#运行topic功能包的publish_node节点
rosrun topic publish_node
#运行topic功能包的subscribe_node节点
rosrun topic subscribe_node

扩展内容: package.xml与CMakeList的关系

CMakeList.txt文件并不知道package.xml文件的存在。

1:首先最重要的一点:CMakeList.txt文件并不知道package.xml文件的存在。但是catkin(编译系统)是知道package.xml文件存在的。而且在编译的时候读取CMakeList.txt文件时在查找依赖的package时,会有到ros的rospack(后面马上会解释),这也就是为什么CMakeList.txt文件明明不知道package.xml文件的存在为什么我们不写package.xml文件有时还是编译不过去的原因。
2:package.xml文件主要是提供给ROS文件系统的,ROS会读取每一个包的package.xml文件来维护各个包的位置与依赖关系,package.xml也是一个文件可以称为package所必须的文件,在我们使用rospack查找一个package时,ros是读取各个package.xml文件来确定package的位置。
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值