ROS Writes the First Subscriber

In the last article, we implemented the first ROS program, publisher. However, at the end of the last article, we also noticed that although our program is very small, it occupies a lot of CPU resources.

This is because the necessary sleep operation is not performed in the while loop of the publisher, so that the publisher runs at the highest rate and occupies CPU for a long time.

This article is divided into the following two parts:

  1. Add sleep call to the publisher to stabilize the frequency of the publisher at 1Hz
  2. Implementing a Subscriber

1. Publisher joins sleep

In fact, all we need to do is create a ros::Rate object and call the. sleep() function of that object in the while loop.

The revised complete code is as follows:

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

int main(int argc, char **argv) {
    ros::init(argc, argv, "minimal_publisher"); // Initialize Node Name
    ros::NodeHandle n; //
    
    // ++++
    ros::Rate s_timer(1.0); // Parametric 1.0 represents the release frequency of 1.0Hz
    // ++++
    
    ros::Publisher my_publisher_object = n.advertise<std_msgs::Float64>("topic1", 1); // Create a publisher that calls advertise to notify ROS Master of the topic name and type
    //topic1 is the topic name
    // The parameter "1" is queue_size, representing the buffer size
    
    std_msgs::Float64 input_float; // Create a message variable to be used by a publisher
    // The message is defined in: / opt/ros/indigo/share/std_msgs
    // Messages published in ROS should be defined in advance so that subscribers can interpret messages when they receive them.
    // Float64 message is defined as follows, which contains a data field data:
    // float64 data
    
    input_float.data = 0.0; // Setting Data Fields
    
    
    // The work done by the program will be completed in the following loop
    while (ros::ok()) 
    {
        // This loop has no sleep, so it will always be running and consuming CPU resources.
        input_float.data = input_float.data + 0.001; //Once per cycle + 0.01
        my_publisher_object.publish(input_float); // Publish messages to corresponding topics
        // ++++
        s_timer.sleep(); // Calling the sleep function here allows the program to be here
        // Stop for a period of time to meet the required release frequency
        // ++++
    }
}

Re-compile the modified publisher and run it in the same order as the previous article:

roscore

Open another terminal and run it.

rosrun my_minimal_node my_minimal_publisher # Start the publisher

Check release frequency, run

rostopic hz /topic1

You can see that the release frequency of the publisher has basically stabilized at 1Hz. Then check the status of the system monitor:

It can also be seen that the CPU occupancy has dropped at this time.

2. Implementing a Subscriber

First, we copy the subscriber code that we modified in advance to the src directory, the code is as follows:

#include<ros/ros.h> 
#include<std_msgs/Float64.h> 
void myCallback(const std_msgs::Float64& message_holder) 
{ 
  // Print out the values we receive
  ROS_INFO("received value is: %f",message_holder.data); 
} 

int main(int argc, char **argv) 
{ 
  ros::init(argc,argv,"minimal_subscriber"); //Initialization node
  // Node name is defined as minimal_subscriber
  ros::NodeHandle n; // Node handle for creating subscribers
  // Subscribe to topic'topic1'
  // mycallback in subscribe is a callback function, which whenever new data arrives
  // It will be called.
  // The actual work is done in the callback function.
  
  ros::Subscriber my_subscriber_object=
      n.subscribe("topic1",1,myCallback); 

  ros::spin(); // Similar to the `while(1)'statement, the callback function is called when a new message arrives.

  return 0; 
} 

Then, as in the previous article, in order to compile the subscriber we just wrote, we also need to modify the CMakeLists. TXT file so that the compiler knows that we should compile our new files. By analogy with the publisher of the previous article, we added the following two lines to the CMakeLists.txt file:

add_executable(my_minimal_subscriber src/minimal_subscriber .cpp) # The first parameter is the second parameter of the generated executable file name.
# Is the path name of the source file
target_link_libraries(my_minimal_subscriber  ${catkin_LIBRARIES}) # Link library

Open the terminal, navigate to ~/catkin_ws in the workspace directory, and execute the command

catkin_make

After the compilation is completed, the commands are executed sequentially (these commands are typed in different terminals)

roscore
rosrun my_minimal_node my_minimal_publisher
rosrun my_minimal_node my_minimal_subscriber

Then you can see the output at the end of the subscriber.

Run the command rosnode list to check the node

Finally, you can run commands

rqt_graph

To display a graphical node-topic graph:

As can be seen from the intuitive display above, messages flow from the publisher to topic topic1 and then to the subscriber.

video

ROS Writes the First Subscriber Program

All of the above processes I recorded a video, in the process of browsing articles, if you encounter problems, you can look at the video to see how I do.

Keywords: Linux

Added by adammo on Sat, 05 Oct 2019 01:59:50 +0300