WEBVTT

00:00.110 --> 00:05.930
In the second Python laboratory lesson, we will implement a subscriber node that uses the publisher

00:05.930 --> 00:12.290
subscriber communication protocol to receive and subscribe to a topic and read all the messages that

00:12.290 --> 00:13.310
pass through it.

00:14.210 --> 00:19.670
If you are interested in the plus cplusplus software development, then you can skip directly to the

00:19.670 --> 00:25.160
next lesson where we will implement the same node with the same functionalities in C plus plus.

00:25.970 --> 00:32.110
Let's start by adding this new node inside the Arduino board Pi examples package.

00:32.120 --> 00:38.000
And so within the Arduino board, Pi examples subfolder that was automatically created and where we

00:38.000 --> 00:40.880
have already created the simple publisher node.

00:40.970 --> 00:45.560
So let's add a new file and let's call this one simple

00:48.260 --> 00:50.750
subscriber dot pi here.

00:50.750 --> 01:00.170
Let's start by importing the Pi library that will allow us to use the Ros two functionalities within

01:00.170 --> 01:01.100
this script.

01:01.100 --> 01:10.880
And then still from the RCL Pi library from the node modules, let's import the node class and we can

01:10.880 --> 01:14.390
use now this class to create a Ros two node.

01:14.390 --> 01:24.860
So let's create a new class that is called Simple Subscriber that inherits from the node class that

01:24.860 --> 01:28.650
is defined in the RCL Pi library.

01:29.160 --> 01:32.760
So first let's define the constructor of this class.

01:32.760 --> 01:38.130
So the function that is automatically executed when a new object of this class is created.

01:38.160 --> 01:46.920
So let's define the init function and the first thing that we do when we initialize an object of the

01:46.920 --> 01:51.300
simple subscriber class is to call the constructor of the base class.

01:51.300 --> 01:54.720
So of the node class from which we are inheriting.

01:54.720 --> 02:04.050
So let's use, let's call the init function of the base class and let's assign a name that is simple

02:05.490 --> 02:07.230
subscriber to this node.

02:08.030 --> 02:15.560
Now that we have initialized the two node class, let's proceed to create a new subscriber object using

02:15.560 --> 02:17.630
the Create subscription function.

02:17.630 --> 02:26.930
So let's call the create subscription function that we inherited from the node class and let's save

02:27.380 --> 02:31.930
the output of this function into a new variable called soap.

02:32.710 --> 02:38.980
In this function, we need to indicate the message type that is the type of the interface to be used

02:38.980 --> 02:40.420
for the message exchange.

02:40.420 --> 02:46.720
So basically we need to specify which type of messages the subscriber object will receive within the

02:46.720 --> 02:47.390
topic.

02:47.410 --> 02:52.500
For example, let's assume again that we want to transmit string messages.

02:52.510 --> 03:03.220
So let's import from the standard messages library, from the messages, let's import the definition

03:03.220 --> 03:09.340
of the string message and let's use it inside the create subscription function.

03:09.340 --> 03:13.210
To define that, our subscriber is going to read string messages.

03:13.510 --> 03:19.240
Then let's also specify the name of the topic on which we want to listen and receive messages.

03:19.240 --> 03:22.270
And let's call this one for example chapter.

03:22.890 --> 03:30.150
When creating a subscriber to a ros2 topic, it is necessary to define a callback function, namely

03:30.150 --> 03:34.710
a function to be executed upon receiving each new message within the topic.

03:34.710 --> 03:39.960
And we will define this callback function as always within the simple publisher class.

03:39.960 --> 03:47.700
So let's call this one message callback.

03:47.970 --> 03:53.970
And furthermore, we also need to indicate the size of the queue, namely the size of the message queue

03:53.970 --> 03:55.380
that works as a buffer.

03:55.380 --> 04:00.390
If the subscriber to this topic is not receiving and processing messages fast enough.

04:00.540 --> 04:03.570
For example, let's set this 1 to 10.

04:04.470 --> 04:11.160
With this, the constructor of the simple subscriber class is completed and now we can proceed to define

04:11.160 --> 04:12.870
the message callback function.

04:12.870 --> 04:19.440
So this one here, that is the one that is called upon receiving a new message in the Ros2 topic.

04:19.890 --> 04:28.800
So let's define this function as a member of the simple subscriber class and as this is a callback function,

04:28.800 --> 04:33.930
it receives as input the content of the message that was just received on the topic.

04:33.930 --> 04:36.090
So a variable message.

04:36.940 --> 04:37.960
In this function.

04:37.960 --> 04:44.080
Every time a new message is received by the subscriber, we simply decide to print it in the terminal

04:44.080 --> 04:46.540
using the get logger function.

04:46.540 --> 04:53.050
So still, this is a function that we inherited from the base class, the node class.

04:53.320 --> 05:01.450
And from this one, let's print an informative message in the terminal that says I earth, followed

05:01.450 --> 05:04.780
by the content of the message that we want to print.

05:05.170 --> 05:13.300
So for example, let's print the data, so the content of the string that we just received.

05:14.020 --> 05:16.930
With this, The simple subscriber class is complete.

05:16.960 --> 05:21.610
We don't need to do anything else and we just need to define the main function.

05:21.610 --> 05:26.350
So basically the one that is automatically executed when the script starts.

05:32.290 --> 05:35.410
And this one, let's execute another function that is called main.

05:35.860 --> 05:40.360
And first, let's define this main function.

05:40.630 --> 05:42.790
And here let's the first step.

05:42.790 --> 05:52.240
Let's initialize the Ros two with the rcl pi init function, and then let's create a new object of the

05:52.240 --> 05:53.710
simple subscriber class.

05:53.710 --> 06:02.410
So a new instance that we call simple subscriber as an instance of the simple subscriber class.

06:02.410 --> 06:08.200
And then in order to keep this node up and running and thus keep the subscriber active so that it can

06:08.200 --> 06:17.080
continuously receive the messages that pass through the chatter topic, Let's use the RCL pi spin function

06:18.550 --> 06:21.490
to keep the simple subscriber up and running.

06:21.490 --> 06:26.980
And finally, if we terminate the execution of the node with control C, let's ensure that the simple

06:26.980 --> 06:37.180
subscriber node is properly destroyed by calling the function destroy node on the simple subscriber.

06:37.180 --> 06:43.570
And also in this case, let's shut down Ros with the shutdown function.

06:44.620 --> 06:46.660
Let's save this script.

06:46.660 --> 06:52.750
And now to execute this node, first we need to instruct the compiler on how it should build our script

06:52.750 --> 06:55.000
and make it an executable in Ros two.

06:55.510 --> 07:01.420
To do so as we did for the simple publisher, let's modify the file setup.py.

07:01.420 --> 07:08.650
And still in the entry point section where we have installed the simple publisher node, let's add a

07:08.650 --> 07:09.330
new line.

07:09.340 --> 07:14.290
So here let's add a new executable called Simple

07:16.420 --> 07:17.560
subscriber.

07:17.560 --> 07:22.030
And this is still in the Arduino, but by.

07:24.210 --> 07:29.520
Examples in the simple subscriber file.

07:29.520 --> 07:31.770
And from this one we want to start.

07:31.770 --> 07:34.140
So the entry point should be the main function.

07:34.140 --> 07:37.350
We want to start the main function when we start the node.

07:37.950 --> 07:43.410
Let's save also this script and now we can build again our workspace and launch our node.

07:43.950 --> 07:45.810
So open a terminal.

07:46.650 --> 07:53.940
Let's go to the Arduino board workspace and let's use the command called Build to build again our workspace.

07:53.940 --> 07:59.040
And so to compile the new node, once this is done, we can split the terminal.

07:59.040 --> 08:03.300
So let's open a new window and here let's source the workspace.

08:03.450 --> 08:08.880
So source the file setup dot bash that is in the install folder.

08:08.880 --> 08:18.090
And now we can proceed to run the new node so we can still use the command Ros to run to execute a node.

08:18.720 --> 08:21.930
And from the Arduino Pi examples package.

08:21.930 --> 08:27.250
Now if we press tab twice, we can see that we have two nodes, the simple publisher and the simple

08:27.250 --> 08:28.120
subscriber.

08:28.360 --> 08:31.600
So let's start with the simple subscriber node.

08:31.870 --> 08:33.700
Let's press enter.

08:33.790 --> 08:40.690
And actually we can verify that this node is running by opening another terminal and using the command

08:40.690 --> 08:43.450
Ros2 topic list.

08:43.450 --> 08:47.020
And actually we can see that the chapter topic is there.

08:47.020 --> 08:53.650
And so actually this node is listening to this topic and we can also confirm this by using the command

08:53.650 --> 09:04.450
Ros2 topic info on the chapter topic, let's add the verbose flag and we can see that there is only

09:04.450 --> 09:10.330
one node that is interacting with this topic and actually that is subscribed to this topic.

09:10.330 --> 09:13.120
And this is the simple subscriber node.

09:14.180 --> 09:20.630
Now let's try to publish a new messenger on this topic to observe that actually the node is listening

09:20.630 --> 09:24.980
on this topic and triggers an event upon receiving the message.

09:25.250 --> 09:33.890
To do so, we can use the command Ros2 topic pub followed by the name of the topic in which we want

09:33.890 --> 09:40.010
to publish the message that is the chatter topic, followed by the type of the message that is being

09:40.040 --> 09:43.200
transmitted and accepted in this topic.

09:43.220 --> 09:47.660
So in this case we can use the Ros2 Autocompletion features.

09:47.660 --> 09:54.860
So let's press tab twice and so we can see that it is automatically detected the message that is accepted

09:54.860 --> 09:55.850
in this topic.

09:56.120 --> 10:03.140
So let's use the standard message string and then we need to insert the content of this message.

10:03.140 --> 10:11.480
So let's use the double quotes and then press tab twice so we can see that here it is also present an

10:11.480 --> 10:14.420
empty prototype of the string message.

10:14.420 --> 10:17.840
So let's type data then let's press tab.

10:18.200 --> 10:21.890
And here with this we are going to publish an empty message.

10:22.040 --> 10:26.990
Let's change the content of this string to Hello Ros.

10:27.890 --> 10:34.880
So let's press enter to publish this message and as long as we do so, we can see that this is starting

10:34.880 --> 10:37.760
publishing the same message multiple times.

10:37.760 --> 10:39.950
So let's interrupt this one.

10:39.950 --> 10:46.220
But the interesting thing is that our node, so the simple subscriber node was able to receive to to

10:46.220 --> 10:51.080
listen all the messages that we were publishing inside the chatter topic.

10:51.080 --> 10:53.090
And so it is printed correctly.

10:53.090 --> 10:57.590
The message Hello Ros2 that we were publishing here.

10:58.760 --> 11:04.850
Finally, let me show you another interesting feature of two, which makes this framework a language

11:04.880 --> 11:11.210
agnostic framework, namely that it works independently, so the same way regardless of the programming

11:11.210 --> 11:12.230
language used.

11:12.410 --> 11:18.450
So in this terminal window, let's keep this subscriber node that we just developed in Python Active.

11:18.470 --> 11:26.030
So listening on the chatter topic and in the new terminal, let's still source the workspace.

11:26.270 --> 11:35.330
So the install setup batch file and here let's run the publisher node which we developed in the previous

11:35.330 --> 11:36.860
lesson in C plus plus.

11:36.860 --> 11:43.970
So using a different programming language still, let's run the node with the Ros2 run command.

11:44.390 --> 11:47.450
And from the Arduino bot CP examples.

11:47.720 --> 11:50.240
Let's start the simple publisher node.

11:50.390 --> 11:52.190
So let's press enter.

11:52.340 --> 11:58.530
Now what is happening is that in one terminal window we have a node that is developed in C plus plus.

11:58.530 --> 12:04.290
So this one that is publishing messages on the chatter topic at a frequency of one hertz.

12:04.290 --> 12:08.670
So namely it is publishing one message per second in another window.

12:08.670 --> 12:12.840
So this one above, we have our python node that we just developed.

12:12.840 --> 12:18.840
So the subscriber that is listening on the same chatter topic and that is printing all the messages

12:18.840 --> 12:19.920
that it received.

12:21.370 --> 12:25.030
Among the other things, this is one of the advantages of using Ros two.

12:25.150 --> 12:30.790
That is to enable the communication between different nodes that often perform different operations

12:30.790 --> 12:36.880
and potentially they are developed in different programming languages without any effort from the developer

12:36.880 --> 12:39.160
of these nodes for their integration.
