Creating nodes

In this section, we are going to learn how to create two nodes: one to publish data and the other to receive this data. This is the basic way of communicating between two nodes, that is, to handle data and do something with this data.

Navigate to the chapter2_tutorials/src/ folder using the following command:

    $ roscd chapter2_tutorials/src/  

Create two files with the names example1_a.cpp and example1_b.cpp. The example1_a.cpp file will send the data with the node name, and the example1_b.cpp file will show the data in the shell. Copy the following code inside the example1_a.cpp file or download it from the repository:

#include "ros/ros.h" 
#include "std_msgs/String.h" 
#include <sstream> 
 
int main(int argc, char **argv) 
{ 
  ros::init(argc, argv, "example1_a"); 
  ros::NodeHandle n; 
  ros::Publisher chatter_pub = 
n.advertise<std_msgs::String>("message", 1000); ros::Rate loop_rate(10); while (ros::ok()) { std_msgs::String msg; std::stringstream ss; ss<< " I am the example1_a node "; msg.data = ss.str(); //ROS_INFO("%s", msg.data.c_str()); chatter_pub.publish(msg); ros::spinOnce(); loop_rate.sleep(); } return 0; }

Here is a further explanation of the preceding code. The headers to be included are ros/ros.h, std_msgs/String.h, and sstream. Here, ros/ros.h includes all the files necessary for using the node with ROS, and std_msgs/String.h includes the header that denotes the type of message that we are going to use:

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

At this point, we initialize the node and set the name; remember that the name must be unique:

ros::init(argc, argv, "example1_a"); 

This is the handler of our process; it allows us to interact with the environment:

ros::NodeHandle n; 

We instantiate a publisher and tell the master the name of the topic and the type. The name is message, and the second parameter is the buffer size. If the topic is publishing data quickly, the buffer will keep at least 1000 messages:

ros::Publisher chatter_pub = 
n.advertise<std_msgs::String>("message", 1000);

The next step is to set the data sending frequency, which in this case is 10 Hz:

ros::Rate loop_rate(10); 

The ros::ok() line stops the node if Ctrl + C is pressed or if ROS stops all the nodes:

while (ros::ok()) 
{ 

In this part, we create a variable for the message with the correct type to send the data:

std_msgs::String msg; 
std::stringstream ss; 
ss<< " I am the example1_a node "; 
msg.data = ss.str(); 

We continue by sending the message, in this case, the semantic is to publish a message, using the previously defined publisher:

chatter_pub.publish(msg); 

The spinOnce function takes care of handling all of ROS's internal events and actions, such as reading from subscribed topics; spinOnce performs one iteration in the main loop of ROS in order to allow the user to perform actions between iterations, in contrast with the spin function, which runs the main loop without interruption:

ros::spinOnce(); 

Finally, we sleep for the required time to get a 10 Hz frequency:

loop_rate.sleep(); 

Now we will create the other node. Copy the following code inside the example1_b.cpp file or download it from the repository:

#include "ros/ros.h" 
#include "std_msgs/String.h" 
 
void chatterCallback(const std_msgs::String::ConstPtr&amp; msg) 
{ 
  ROS_INFO("I heard: [%s]", msg->data.c_str()); 
} 
 
int main(int argc, char **argv) 
{ 
  ros::init(argc, argv, "example1_b"); 
  ros::NodeHandle n; 
  ros::Subscriber sub = n.subscribe("message", 1000, 
chatterCallback); ros::spin(); return 0; }

Let's explain the code. Include the headers and the type of message to use for the topic:

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

The following type of function is a callback and happens in response to an action, which in this case is the reception of a String message. This function allows us to do something with the data; in this case, we display it in the terminal:

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

We create a subscriber and start to listen to the topic with the name message. The buffer will be of 1000, and the function to handle the message will be messageCallback:

ros::Subscriber sub = n.subscribe("message", 1000, 
messageCallback);

The ros::spin() line is the main loop where the node starts to read the topic and when a message arrives, messageCallback is called. When the user presses Ctrl + C, the node exits the loop and ends:

ros::spin(); 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.190.156.80