In the second Python laboratory lesson, we will implement a subscriber node that uses the publisher
subscriber communication protocol to receive and subscribe to a topic and read all the messages that
pass through it.
If you are interested in the plus cplusplus software development, then you can skip directly to the
next lesson where we will implement the same node with the same functionalities in C plus plus.
Let's start by adding this new node inside the Arduino board Pi examples package.
And so within the Arduino board, Pi examples subfolder that was automatically created and where we
have already created the simple publisher node.
So let's add a new file and let's call this one simple
subscriber dot pi here.
Let's start by importing the Pi library that will allow us to use the Ros two functionalities within
this script.
And then still from the RCL Pi library from the node modules, let's import the node class and we can
use now this class to create a Ros two node.
So let's create a new class that is called Simple Subscriber that inherits from the node class that
is defined in the RCL Pi library.
So first let's define the constructor of this class.
So the function that is automatically executed when a new object of this class is created.
So let's define the init function and the first thing that we do when we initialize an object of the
simple subscriber class is to call the constructor of the base class.
So of the node class from which we are inheriting.
So let's use, let's call the init function of the base class and let's assign a name that is simple
subscriber to this node.
Now that we have initialized the two node class, let's proceed to create a new subscriber object using
the Create subscription function.
So let's call the create subscription function that we inherited from the node class and let's save
the output of this function into a new variable called soap.
In this function, we need to indicate the message type that is the type of the interface to be used
for the message exchange.
So basically we need to specify which type of messages the subscriber object will receive within the
topic.
For example, let's assume again that we want to transmit string messages.
So let's import from the standard messages library, from the messages, let's import the definition
of the string message and let's use it inside the create subscription function.
To define that, our subscriber is going to read string messages.
Then let's also specify the name of the topic on which we want to listen and receive messages.
And let's call this one for example chapter.
When creating a subscriber to a ros2 topic, it is necessary to define a callback function, namely
a function to be executed upon receiving each new message within the topic.
And we will define this callback function as always within the simple publisher class.
So let's call this one message callback.
And furthermore, we also need to indicate the size of the queue, namely the size of the message queue
that works as a buffer.
If the subscriber to this topic is not receiving and processing messages fast enough.
For example, let's set this 1 to 10.
With this, the constructor of the simple subscriber class is completed and now we can proceed to define
the message callback function.
So this one here, that is the one that is called upon receiving a new message in the Ros2 topic.
So let's define this function as a member of the simple subscriber class and as this is a callback function,
it receives as input the content of the message that was just received on the topic.
So a variable message.
In this function.
Every time a new message is received by the subscriber, we simply decide to print it in the terminal
using the get logger function.
So still, this is a function that we inherited from the base class, the node class.
And from this one, let's print an informative message in the terminal that says I earth, followed
by the content of the message that we want to print.
So for example, let's print the data, so the content of the string that we just received.
With this, The simple subscriber class is complete.
We don't need to do anything else and we just need to define the main function.
So basically the one that is automatically executed when the script starts.
And this one, let's execute another function that is called main.
And first, let's define this main function.
And here let's the first step.
Let's initialize the Ros two with the rcl pi init function, and then let's create a new object of the
simple subscriber class.
So a new instance that we call simple subscriber as an instance of the simple subscriber class.
And then in order to keep this node up and running and thus keep the subscriber active so that it can
continuously receive the messages that pass through the chatter topic, Let's use the RCL pi spin function
to keep the simple subscriber up and running.
And finally, if we terminate the execution of the node with control C, let's ensure that the simple
subscriber node is properly destroyed by calling the function destroy node on the simple subscriber.
And also in this case, let's shut down Ros with the shutdown function.
Let's save this script.
And now to execute this node, first we need to instruct the compiler on how it should build our script
and make it an executable in Ros two.
To do so as we did for the simple publisher, let's modify the file setup.py.
And still in the entry point section where we have installed the simple publisher node, let's add a
new line.
So here let's add a new executable called Simple
subscriber.
And this is still in the Arduino, but by.
Examples in the simple subscriber file.
And from this one we want to start.
So the entry point should be the main function.
We want to start the main function when we start the node.
Let's save also this script and now we can build again our workspace and launch our node.
So open a terminal.
Let's go to the Arduino board workspace and let's use the command called Build to build again our workspace.
And so to compile the new node, once this is done, we can split the terminal.
So let's open a new window and here let's source the workspace.
So source the file setup dot bash that is in the install folder.
And now we can proceed to run the new node so we can still use the command Ros to run to execute a node.
And from the Arduino Pi examples package.
Now if we press tab twice, we can see that we have two nodes, the simple publisher and the simple
subscriber.
So let's start with the simple subscriber node.
Let's press enter.
And actually we can verify that this node is running by opening another terminal and using the command
Ros2 topic list.
And actually we can see that the chapter topic is there.
And so actually this node is listening to this topic and we can also confirm this by using the command
Ros2 topic info on the chapter topic, let's add the verbose flag and we can see that there is only
one node that is interacting with this topic and actually that is subscribed to this topic.
And this is the simple subscriber node.
Now let's try to publish a new messenger on this topic to observe that actually the node is listening
on this topic and triggers an event upon receiving the message.
To do so, we can use the command Ros2 topic pub followed by the name of the topic in which we want
to publish the message that is the chatter topic, followed by the type of the message that is being
transmitted and accepted in this topic.
So in this case we can use the Ros2 Autocompletion features.
So let's press tab twice and so we can see that it is automatically detected the message that is accepted
in this topic.
So let's use the standard message string and then we need to insert the content of this message.
So let's use the double quotes and then press tab twice so we can see that here it is also present an
empty prototype of the string message.
So let's type data then let's press tab.
And here with this we are going to publish an empty message.
Let's change the content of this string to Hello Ros.
So let's press enter to publish this message and as long as we do so, we can see that this is starting
publishing the same message multiple times.
So let's interrupt this one.
But the interesting thing is that our node, so the simple subscriber node was able to receive to to
listen all the messages that we were publishing inside the chatter topic.
And so it is printed correctly.
The message Hello Ros2 that we were publishing here.
Finally, let me show you another interesting feature of two, which makes this framework a language
agnostic framework, namely that it works independently, so the same way regardless of the programming
language used.
So in this terminal window, let's keep this subscriber node that we just developed in Python Active.
So listening on the chatter topic and in the new terminal, let's still source the workspace.
So the install setup batch file and here let's run the publisher node which we developed in the previous
lesson in C plus plus.
So using a different programming language still, let's run the node with the Ros2 run command.
And from the Arduino bot CP examples.
Let's start the simple publisher node.
So let's press enter.
Now what is happening is that in one terminal window we have a node that is developed in C plus plus.
So this one that is publishing messages on the chatter topic at a frequency of one hertz.
So namely it is publishing one message per second in another window.
So this one above, we have our python node that we just developed.
So the subscriber that is listening on the same chatter topic and that is printing all the messages
that it received.
Among the other things, this is one of the advantages of using Ros two.
That is to enable the communication between different nodes that often perform different operations
and potentially they are developed in different programming languages without any effort from the developer
of these nodes for their integration.