ROS的C++发布器publisher和订阅器subscriber

参考https://www.cnblogs.com/yrm1160029237/p/9991014.html,对原有博客进行了改进。ROS菜鸟,如有不对望指正。

注:一个源码编译的CMakeLists.txt对应一个package。(个人理解)

1、编写发布器publisher

  • 初始化ROS系统;
  • 在ROS网络内广播将要在chatter话题上发布std_msgs::Strring类型的消息;
  • 以每秒10次的频率在chatter上发布消息。
    ros_test目录下创建test/src/talker.cpp文件:
mkdir ~/ros_test/test/src
cd ~/ros_test/test/src
gedit talker.cpp

将下面的源码复制到talker.cpp

#include <ros/ros.h>
#include <std_msgs/String.h>

#include <sstream>

int main(int argc, char **argv)
{
    /**
     * 初始化ROS可指定节点的名称。节点的名称必须唯一(名称内不能包含/等符号)
     */ 
    ros::init(argc, argv, "talker");
    
    /**
     * 为这个进程的节点创建一个句柄。
     * 第一个创建的NodeHandle会为节点进行初始化,
     * 最后一个销毁的NodeHandle则会释放该节点所占用的所有资源
     */ 
    ros::NodeHandle n;
    
    /**
     * 告诉ROS我们将在chatter(话题名)上发布std_msgs::String消息类型的消息。
     * 如果发布的消息的频率太高,缓冲区中的消息在大于1000个的时候就会开始丢失先前发布的消息。
     * advertise返回一个ros::Publisher对象,它有两个作用:
     * 1、它有一个publish()成员函数可以让你在topic上发布消息;
     * 2、如果消息类型不对,它会拒绝发布。
     */ 
    ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);

    /**
     * 设置每秒10次的频率
     */ 
    ros::Rate loop_rate(10);

    int count = 0;

    while (ros::ok())
    {
        std_msgs::String msg;

        std::stringstream ss;
        ss << "hello world " << count;
        msg.data = ss.str();

        /**
         * 可以用printf/cout等函数代替
         */ 
        ROS_INFO("%s", msg.data.c_str());

        /**
         * 向所有订阅chatter话题的节点发布消息
         */ 
        chatter_pub.publish(msg);

        /**
         * 没有这一句,则你的回调函数就永远也不会被调用
         */ 
        ros::spinOnce();

        /**
         * 调用ros::Rate对象来休眠一段时间以使得发布频率为10Hz
         */ 
        loop_rate.sleep();
        ++count;
    }
    return 0;
}

2、编写订阅器subscriber

  • 初始化ROS系统;
  • 订阅chatter话题;
  • 进入自循环,等待消息的到达;
  • 当消息到达,调用chatterCallback()函数;
    ros_test目录下创建test/src/listener.cpp文件:
#include <ros/ros.h>
#include <std_msgs/String.h>

void chatterCallback(const std_msgs::String::ConstPtr &msg)
{
    ROS_INFO("I heard: [%s]", msg->data.c_str());
}

void chatterCallback(const std_msgs::String::ConstPtr &msg, std::string p, int s)
{
    ROS_INFO("I heard: [%s], %s, %d", msg->data.c_str(), p.c_str(), s);
}

int main(int argc, char **argv)
{
    ros::init(argc, argv, "listener");

    ros::NodeHandle n;

    /**
     * 告诉ROS我们要订阅chatter话题上的消息。
     * 当有消息发布到这个话题上时,ROS就会调用chatterCallback()函数。
     * 第二个参数上消息队列大小,以防我们处理消息的速度不够快,
     * 当缓冲到达1000条消息后,再有新的消息到来就将开始丢弃先前接收的消息。
     */ 
    ros::Subscriber sub = n.subscribe("chatter", 1000, &chatterCallback);
    
    /**
     * 当回调函数有多个参数时,可以采用boost::bing()函数作为传递参数。
     * 在使用过程中需注意,subscribe的模板函数,在传入boost::function类型时,需要传入模板参数。
     * 即chatterCallback()的第一个参数类型,std_msgs::String::ConstPtr,
     * 因此传入模板参数是std_msgs::String。
     * 如果在类里实现,则需要输入this,如下:
     * boost::bind(&chatterCallback, this, _1, p, s)
     */
    std::string p = "10";
    int s = 10;
    //ros::Subscriber sub = n.subscribe<std_msgs::String>("chatter", 1000, boost::bind(&chatterCallback, _1, p, s));
    
    /**
     * 进入自循环,可以尽可能快的调用消息回调函数。
     */ 
    ros::spin();
    return 0;
}

3、编写CMakeLists.txt
在在ros_test目录下创建test/CMakeLists.txt文件:

cmake_minimum_required(VERSION 2.8.3)
project(ros_test)

find_package(catkin REQUIRED COMPONENTS roscpp rospy std_msgs genmsg)

#add_message_files(DIRECTORY msg FILES Num.msg)
#add_service_files(DIRECTORY srv FILES AddTwoInts.srv)

#generate_messages(DEPENDENCIES std_msgs)

catkin_package()

include_directories(include ${catkin_INCLUDE_DIRS})

add_executable(talker src/talker.cpp)
target_link_libraries(talker ${catkin_LIBRARIES})
#add_dependencies(talker beginner_tutorials_generate_messages_cpp)

add_executable(listener src/listener.cpp)
target_link_libraries(listener ${catkin_LIBRARIES})
#add_dependencies(listener beginner_tutorials_generate_messages_cpp)

4、编写package.xml
ros_test目录下创建test/package.xml

<?xml version="1.0"?>
<package format="2">
  <name>ros_test</name>
  <version>0.0.0</version>
  <description>The ros_test package</description>

  <!-- One maintainer tag required, multiple allowed, one person per tag -->
  <!-- Example:  -->
  <!-- <maintainer email="jane.doe@example.com">Jane Doe</maintainer> -->
  <maintainer email="wdh@todo.todo">wdh</maintainer>


  <!-- One license tag required, multiple allowed, one license per tag -->
  <!-- Commonly used license strings: -->
  <!--   BSD, MIT, Boost Software License, GPLv2, GPLv3, LGPLv2.1, LGPLv3 -->
  <license>TODO</license>


  <!-- Url tags are optional, but multiple are allowed, one per tag -->
  <!-- Optional attribute type can be: website, bugtracker, or repository -->
  <!-- Example: -->
  <!-- <url type="website">http://wiki.ros.org/pcl_test</url> -->


  <!-- Author tags are optional, multiple are allowed, one per tag -->
  <!-- Authors do not have to be maintainers, but could be -->
  <!-- Example: -->
  <!-- <author email="jane.doe@example.com">Jane Doe</author> -->


  <!-- The *depend tags are used to specify dependencies -->
  <!-- Dependencies can be catkin packages or system dependencies -->
  <!-- Examples: -->
  <!-- Use depend as a shortcut for packages that are both build and exec dependencies -->
  <!--   <depend>roscpp</depend> -->
  <!--   Note that this is equivalent to the following: -->
  <!--   <build_depend>roscpp</build_depend> -->
  <!--   <exec_depend>roscpp</exec_depend> -->
  <!-- Use build_depend for packages you need at compile time: -->
  <!--   <build_depend>message_generation</build_depend> -->
  <!-- Use build_export_depend for packages you need in order to build against this package: -->
  <!--   <build_export_depend>message_generation</build_export_depend> -->
  <!-- Use buildtool_depend for build tool packages: -->
  <!--   <buildtool_depend>catkin</buildtool_depend> -->
  <!-- Use exec_depend for packages you need at runtime: -->
  <!--   <exec_depend>message_runtime</exec_depend> -->
  <!-- Use test_depend for packages you need only for testing: -->
  <!--   <test_depend>gtest</test_depend> -->
  <!-- Use doc_depend for packages you need only for building documentation: -->
  <!--   <doc_depend>doxygen</doc_depend> -->
  <buildtool_depend>catkin</buildtool_depend>
  <build_depend>pcl_ros</build_depend>
  <build_depend>roscpp</build_depend>
  <build_depend>sensor_msgs</build_depend>
  <build_export_depend>pcl_ros</build_export_depend>
  <build_export_depend>roscpp</build_export_depend>
  <build_export_depend>sensor_msgs</build_export_depend>
  <exec_depend>pcl_ros</exec_depend>
  <exec_depend>roscpp</exec_depend>
  <exec_depend>sensor_msgs</exec_depend>


  <!-- The export tag contains other, unspecified, tags -->
  <export>
    <!-- Other tools can request additional information be placed here -->

  </export>
</package>

5、编译与运行
编译有两种方式:
1、采用camke的方式:

# 编译
mkdir ~/ros_test/test/build
cd ~/ros_test/test/build
cmake ..
make

# 运行
# 打开第一个终端,输入如下命令
roscore
# 打开第二个终端,输入如下命令
cd ~/ros_test/test/build
./devel/lib/ros_test/listener
# 打开第三个终端,输入如下命令
cd ~/ros_test/test/build
./devel/lib/ros_test/talker

执行完以上命令,就可以在第二个和第三个终端看到消息输出。

2、采用catkin_make的方式:

# 编译
cd ~/ros_test
catkin_make

#运行
打开第一个终端,输入如下命令
roscore
打开第二个终端,输入如下命令
cd ~/ros_test
./devel/lib/ros_test/listener
打开第二个终端,输入如下命令
cd ~/ros_test
./devel/lib/ros_test/talker

执行完以上命令,就可以在第二个和第三个终端看到消息输出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值