ROS study notes 10- to write a simple subscribers and publishers (C ++ version)

This document comes from: http://wiki.ros.org/ROS/Tutorials/WritingPublisherSubscriber%28c%2B%2B%29

  1. Write publisher node
    as described above, the network node is connected to the ROS in an executable program, in this example, a node named Talker write, the node continues outside release message.

    Go to first package path:
    roscd begginner_tutorials

     Create a src directory for storing source code:

    mkdir -p src
    

    Then create a talker.cpp source file and paste the contents of which are as follows (see the code in which the Chinese interpret the comment).

     

    /*
     * Copyright (C) 2008, Morgan Quigley and Willow Garage, Inc.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *   * Redistributions of source code must retain the above copyright notice,
     *     this list of conditions and the following disclaimer.
     *   * Redistributions in binary form must reproduce the above copyright
     *     notice, this list of conditions and the following disclaimer in the
     *     documentation and/or other materials provided with the distribution.
     *   * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its
     *     contributors may be used to endorse or promote products derived from
     *     this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     INTERRUPTION *) HOWEVER CAUSED the ON the AND THEORY the ANY. OF LIABILITY, WHETHER the IN 
    {
     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     The IN the ANY WAY ARISING OUT * OF THE the USE OF THIS SOFTWARE, the EVEN IF ADVISED OF THE 
     * POSSIBILITY OF SUCH DAMAGE. 
     * / 
    //% Tag (FULLTEXT)% 
    //% Tag (ROS_HEADER)% 
    // the Comment by Spy: ROS / ros.h required for the basic functions of ros system header files 
    #include "ros / ros.h" 
    //% EndTag (ROS_HEADER)% 
    //% Tag (MSG_HEADER)% 
    // the Comment by Spy: std_msgs / String.h to std_msgs a message packet header file generated by the file String.msg 
    #include "std_msgs / String.h" 
    //% EndTag (MSG_HEADER)% 
    
    #include <sstream> 
    
    / ** 
     * This Tutorial Demonstrates Simple the sending of messages over System ROS. 
     * / 
    int main (int argc, char ** argv) 
      / ** 
       * at The ROS :: the init () function Needs to See argc and argv SO IT CAN that the perform 
       * Remapping the any of ROS name and arguments that were Provided The AT Command Line. 
       * CAN you use the For Programmatic remappings Different Version A of the init () Which Takes 
       * Directly remappings, MOST But for Command-Line Programs, and passing the argv argc IS 
       * The Easiest Way to do IT. THIRD of The argument to the init () The name of IS The Node. 
       * 
       * Call by You MUST One of ROS :: The versions of the init () before the using the any OTHER 
       * Part of The System of ROS. 
       * / 
    //% Tag (INIT)% 
    // initialize ROS, which allows us to rename the command line, we also specified that a node name, the name requires a unique (not the same name) in the ROS system below 
    / / name can not contain the slash (/). 
      :: the init ROS (argc, the argv, "Talker"); 
    // EndTag% (the INIT)% 
    
      / **
       NodeHandle IS at The main Access * Point to Communications with at The ROS System. 
       * Constructed by Will at The First Fully NodeHandle the initialize the this the Node, and at The Last 
       * NodeHandle destructed by Will at The use Close Down the Node. 
       * / 
    //% Tag (NODEHANDLE)% 
    // create handle a node, the node is initialized in fact, will release resources when the last destructor when the handle as the node process, first created. 
      :: NodeHandle n-ROS; 
    //% EndTag (NODEHANDLE)% 
    
      / ** 
       * advertise of The () function of ROS IS Tell How you that you want to 
       . * publish ON A GIVEN This Topic name of ROS The Invokes A Call to 
       * Master Node , Which keeps IS A Publishing and WHO Registry of WHO  
       * IS subscribing. advertise the After the this () Call IS Made, The Master
       * Will Notify the anyone Node WHO IS Trying to Subscribe to the this Topic name,
       * and they will in turn negotiate a peer-to-peer connection with this
       * node.  advertise() returns a Publisher object which allows you to
       * publish messages on that topic through a call to publish().  Once
       * all copies of the returned Publisher object are destroyed, the topic
       * will be automatically unadvertised.
       *
       * The second parameter to advertise() is the size of the message queue
       * used for publishing messages.  If messages are published more quickly
       * than we can send them, the number here specifies how many messages to
       * buffer up before throwing some away.
       */
    //% Tag (PUBLISHER)%
    // 3. The rest of the program calls ros :: shutdown ().
    // 该句告诉master主控节点,我们将在chatter主题中发布std_msgs的String消息,在我们发布消息时,
    // After the master node will inform all subscribe to that topic node, the message queue size is 1000, that is more than 1000 messages in the queue, the message will be discarded before the old 
      ros :: Publisher chatter_pub = n.advertise <std_msgs String ::> ( "Chatter", 1000); 
    //% EndTag (PUBLISHER)% 
    
    //% Tag (LOOP_RATE)% 
    // specified operating frequency of 10hz, will run before calling Rate :: sleep (). 
      Rate loop_rate :: ROS (10); 
    //% EndTag (LOOP_RATE)% 
    
      / ** 
       . * A How MANY of COUNT messages have have Sent This WE IS Used to Create 
       . * A UNIQUE for each Message String 
       * / 
    // the Tag% (ROS_OK)% 
      int COUNT = 0; 
    // returns true in ros :: ok when run continuously, returns false when the interrupt returns false in the following situations: 
    // 1. receives an interrupt signal, SIGINT, keyboard enter Ctrl + C will trigger an interrupt signal. 
    @ 2 is kicked from the network node of the same name. 
      the while (ROS :: OK ()) 
      {
    // 4. All ros :: NodeHandles be destroyed.  
         * The IS of The type of Message Object. this object must agree with the type
    % EndTag // (ROS_OK)% 
        / ** 
         * This IS A Message Object. By You with Stuff Data IT, IT and the then publish. 
         * / 
    //% the Tag (FILL_MESSAGE)% 
    // filled using a standard message string. 
        :: String msg std_msgs; 
    
        std :: stringstream SS; 
        SS << "the Hello world" << COUNT; 
        msg.data = ss.str (); 
    //% EndTag (FILL_MESSAGE)% 
    
    //% Tag (ROSCONSOLE)% 
    / in the output statement / ROS, std :: cout instead of the standard output. Ros information see the section level. 
        ROS_INFO ( "% S", msg.data.c_str ()); 
    //% EndTag (ROSCONSOLE)% 
    
        / ** 
         . * Of The publish () function How you IS Send messages of The Parameter 
         * Parameter Template A GIVEN AS to advertise The <> () Call, AS WAS DONE 
         * in at The constructor above.
         * / 
    //% Tag (PUBLISH)% 
    // announced 
        chatter_pub.publish (msg); 
    //% EndTag (PUBLISH)% 
    // When you add a subscription, ros :: spinOnce () will make sure that you can trigger a callback function (callback), if not the statement is not triggered. 
    % Tag // (SPINONCE)% 
        ROS :: spinOnce (); 
    //% EndTag (SPINONCE)% 
    
    //% Tag (RATE_SLEEP)% 
    // sleep to ensure 10hz run. 
        loop_rate.sleep (); 
    //% EndTag (RATE_SLEEP)% 
        ++ COUNT; 
      } 
    
    
      return 0; 
    } 
    //% EndTag (FULLTEXT)%
    

     

     The document can also be found in the following path github: https://raw.github.com/ros/ros_tutorials/kinetic-devel/roscpp_tutorials/talker/talker.cpp
    the steps outlined below:

    1.  Ros system initialization:
      ros::init(argc, argv, "talker");
      
    2.    Creation of the handle and publisher:
      ros::NodeHandle n;
      ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
      

       

    3. Specified frequency transmission cycle.

  2. Writing a subscriber
    Similarly, created in the package a listener.cpp, and paste the following code (see the code to explain the code of Chinese comments):
    /*
     * Copyright (C) 2008, Morgan Quigley and Willow Garage, Inc.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *   * Redistributions of source code must retain the above copyright notice,
     *     this list of conditions and the following disclaimer.
     *   * Redistributions in binary form must reproduce the above copyright
     *     notice, this list of conditions and the following disclaimer in the
     *     documentation and/or other materials provided with the distribution.
     *   * Neither the names of Stanford University or Willow Garage, Inc. nor the names of its
     *     contributors may be used to endorse or promote products derived from
     *     this software without specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     * POSSIBILITY OF SUCH DAMAGE.
     */
    
    // %Tag(FULLTEXT)%
    #include "ros/ros.h"
    #include "std_msgs/String.h"
    
    /**
     * This tutorial demonstrates simple receipt of messages over the ROS system.
     */
    // %Tag(CALLBACK)%
    // 接收到主题消息时的回调函数
    void chatterCallback(const std_msgs::String::ConstPtr& msg)
    {
      ROS_INFO("I heard: [%s]", msg->data.c_str());
    }
    // %EndTag(CALLBACK)%
    
    int main(int argc, char **argv)
    {
      /**
       * The ros::init() function needs to see argc and argv so that it can perform
       * any ROS arguments and name remapping that were provided at the command line.
       * For programmatic remappings you can use a different version of init() which takes
       * remappings directly, but for most command-line programs, passing argc and argv is
       * the easiest way to do it.  The third argument to init() is the name of the node.
       *
       * You must call one of the versions of ros::init() before using any other
       * part of the ROS system.
       */
    // 初始化:指定节点名称。
      ros::init(argc, argv, "listener");
    
      /**
       * NodeHandle is the main access point to communications with the ROS system.
       * The first NodeHandle constructed will fully initialize this node, and the last
       * NodeHandle destructed will close down the node.
       */
    // 创建节点句柄
      ros::NodeHandle n;
    
      /**
       * The subscribe() call is how you tell ROS that you want to receive messages
       * on a given topic.  This invokes a call to the ROS
       * master node, which keeps a registry of who is publishing and who
       * is subscribing.  Messages are passed to a callback function, here
       * called chatterCallback.  subscribe() returns a Subscriber object that you
       * must hold on to until you want to unsubscribe.  When all copies of the Subscriber
       * object go out of scope, this callback will automatically be unsubscribed from
       * this topic.
       *
       * At The SECOND, the Parameter to at The the Subscribe () function IS at The size of at The the Message 
       * Queue. The If messages are Arriving Faster Within last They are being Processed, the this 
       * IS at The Number The of messages that by Will BE buffered up the before Beginning to the throw 
       * Away at The oldest ones. 
       * / 
    //% Tag (SUBSCRIBER)% 
    // subscribed to the specified topic, and specify a callback function, the queue size is 1000, when we are too late to process the messages stored in the queue, if the queue element is greater than 1000, it will discard the old message 
      ROS for Subscriber Sub :: = n.subscribe ( "Chatter", 1000, chatterCallback); 
    //% EndTag (a SUBSCRIBER)% 
    
      / ** 
       * :: Spin ROS () Will Enter a Loop, pumping With the callbacks. Version the this, All 
       * the callbacks from the WITHIN the this by Will BE Called the Thread (at The main One). ROS :: Spin () 
       * Will IS Exit When pressed the Ctrl-C, or The the IS by the shutdown Master node. 
       * / 
    //% the Tag (SPIN)% 
    when // spin cycle will enter, and process messages when a message arrives, Ctrl + C will end the cycle master node or close the node also It will end the cycle. 
      ros :: spin ();
    // %EndTag(SPIN)%
    
      return 0;
    }
    // %EndTag(FULLTEXT)%
    
  3. Compiling nodes
    add the following code in CMakeLists.txt:
    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)
    

    These codes will be added to the above-described two nodes compiled as executable programs, and specify the required libraries and dependencies.
    Then execute catkin_make, code is as follows:

    # In your catkin workspace
    $ cd ~/catkin_ws
    $ catkin_make  
    

     Compile successfully shown below:

    Base path: /home/shao/catkin_ws
    Source space: /home/shao/catkin_ws/src
    Build space: /home/shao/catkin_ws/build
    Devel space: /home/shao/catkin_ws/devel
    Install space: /home/shao/catkin_ws/install
    ####
    #### Running command: "make cmake_check_build_system" in "/home/shao/catkin_ws/build"
    ####
    ####
    #### Running command: "make -j8 -l8" in "/home/shao/catkin_ws/build"
    ####
    [  0%] Built target std_msgs_generate_messages_eus
    [  0%] Built target std_msgs_generate_messages_lisp
    [  0%] Built target std_msgs_generate_messages_nodejs
    [  0%] Built target std_msgs_generate_messages_py
    [  0%] Built target std_msgs_generate_messages_cpp
    [  0%] Built target _begginner_tutorials_generate_messages_check_deps_AddTwoInts
    [  0%] Built target _begginner_tutorials_generate_messages_check_deps_Num
    [  5%] Generating EusLisp code from begginner_tutorials/Num.msg
    [ 11%] Generating EusLisp manifest code for begginner_tutorials
    [ 17%] Generating EusLisp code from begginner_tutorials/AddTwoInts.srv
    [ 23%] Generating Javascript code from begginner_tutorials/Num.msg
    [ 29%] Generating C++ code from begginner_tutorials/AddTwoInts.srv
    [ 35%] Generating C++ code from begginner_tutorials/Num.msg
    [ 41%] Generating Python from MSG begginner_tutorials/Num
    [ 47%] Generating Lisp code from begginner_tutorials/Num.msg
    [ 52%] Generating Javascript code from begginner_tutorials/AddTwoInts.srv
    [ 58%] Generating Lisp code from begginner_tutorials/AddTwoInts.srv
    [ 64%] Generating Python code from SRV begginner_tutorials/AddTwoInts
    [ 64%] Built target begginner_tutorials_generate_messages_nodejs
    [ 64%] Built target begginner_tutorials_generate_messages_lisp
    [ 70%] Generating Python msg __init__.py for begginner_tutorials
    [ 76%] Generating Python srv __init__.py for begginner_tutorials
    [ 76%] Built target begginner_tutorials_generate_messages_cpp
    [ 88%] Building CXX object begginner_tutorials/CMakeFiles/talker.dir/src/talker.cpp.o
    [ 88%] Building CXX object begginner_tutorials/CMakeFiles/listener.dir/src/listener.cpp.o
    [ 88%] Built target begginner_tutorials_generate_messages_py
    [ 88%] Built target begginner_tutorials_generate_messages_eus
    [ 88%] Built target begginner_tutorials_generate_messages
    [ 94%] Linking CXX executable /home/shao/catkin_ws/devel/lib/begginner_tutorials/talker
    [ 94%] Built target talker
    [100%] Linking CXX executable /home/shao/catkin_ws/devel/lib/begginner_tutorials/listener
    [100%] Built target listener
     
  4. Run node
    to open a new terminal:
    roscore
    

    Then run talker node:

    rosrun beginner_tutorials talker 
    

     Ads appear:

     

     Run listener node:

    rosrun beginner_tutorials listener 
    

    Receiving interface appears:

     

     Run successfully. Long time no see, hello world.

Guess you like

Origin www.cnblogs.com/spyplus/p/11564266.html
Recommended