Introduction

ROS nodes are the building blocks of ROS systems. They are individual processes that perform a specific task, such as sensing, control, or communication. In this article, we will cover the basics of creating and running ROS nodes.

The structure of a ROS node is simple. It consists of a main function that initializes the node and sets up any necessary communication mechanisms, such as publishers or subscribers. The main function then enters a loop that processes incoming data and performs any necessary computation or control.

Creating a ROS Publisher Node

Let's start by creating a simple publisher node that publishes a string message to a topic. First, create a new package with the following command:

cd ~/blog_ws/src
catkin_create_pkg my_publisher std_msgs roscpp

This command creates a new package called "my_publisher" and depends on the "std_msgs" and "roscpp" packages.

Next, create a new C++ file called "talker.cpp" in the "src" folder of the package. In this file, we will implement the main function of the node. Here is an example of a simple publisher node:

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

int main(int argc, char **argv)
{
    // Initialize the node
    ros::init(argc, argv, "talker");
    // Create a node handle
    ros::NodeHandle n;
    // Create a publisher
    ros::Publisher chatter_pub = n.advertise<std_msgs::String>("chatter", 1000);
    // Set the loop rate
    ros::Rate loop_rate(10);

    int count = 0;
    while (ros::ok())
    {
        // Create a message
        std_msgs::String msg;
        std::stringstream ss;
        ss << "hello world " << count;
        msg.data = ss.str();
        // Publish the message
        chatter_pub.publish(msg);
        // Log the message
        ROS_INFO("I said: [%s]", msg.data.c_str());
        // Sleep for the loop rate
        loop_rate.sleep();
        count++;
    }
    return 0;
}

In this example, we first initialize the node using the "ros::init()" function and create a node handle using "ros::NodeHandle n;". We then create a publisher that publishes to the "chatter" topic of type "std_msgs::String". In the main loop, we create a message, set its data, and publish it. We also log the message using "ROS_INFO()" and sleep for the loop rate.

To build and run the node, navigate to the root of your catkin workspace and run the following commands:

cd ~/blog_ws
catkin_make
source /opt/ros/noetic/setup.bash
source devel/setup.bash
rosrun my_publisher talker

The second command builds the package, the third and fourth source the setup file, and the fifth runs the node. You should see the node output "I said: [hello world 0]" in the terminal. To see the messages being published, you can use the "rostopic echo /chatter" command to print the messages being published on a topic.

Publisher output

This is a very basic example of a publisher node, but it demonstrates the basic structure and functionality of a ROS node.

Creating a ROS Subscriber Node

You can also create subscriber nodes that listen to topics and process incoming messages, using the "ros::Subscriber" class.

To create a subscriber node, you will need to create a new C++ file and implement the main function similar to the publisher node, but instead of creating a publisher, you will create a subscriber. Here is an example of a simple subscriber node that subscribes to the "chatter" topic and prints the incoming messages:

#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());
}

int main(int argc, char **argv)
{
    // Initialize the node
    ros::init(argc, argv, "listener");
    // Create a node handle
    ros::NodeHandle n;
    // Create a subscriber
    ros::Subscriber sub = n.subscribe("chatter", 1000, chatterCallback);
    // Spin
    ros::spin();
    return 0;
}

In this example, we first initialize the node, create a node handle, and create a subscriber that subscribes to the "chatter" topic and calls the "chatterCallback" function when a message is received. The "spin()" function is used to keep the node running and process incoming messages.

To build and run the node, navigate to the root of your catkin workspace and run the following command:

cd ~/blog_ws
catkin_make
source /opt/ros/noetic/setup.bash
source devel/setup.bash
rosrun my_publisher listener

You can run the publisher and subscriber nodes in different terminals and see the messages being printed in both terminals.

Subscriber output

Conclusion

In conclusion, ROS nodes are individual processes that perform specific tasks and communicate with each other using topics, services, and other communication mechanisms. By understanding the basics of creating and using ROS nodes, you can start building your own ROS systems and harness the power of ROS.

Conclusion

Check out my next article about setting up the bashrc file to automatically source necessary setup files HERE.