Let's now create a subscriber to listen to the publisher we have just created in the previous lesson.
So we will create a node for a smartphone here and inside it create a topic subscriber.
As you can guess, a node which is handling a smartphone can have many features such as reading and
publishing the battery state, sending a text message to a contact, increase or decrease the speaker
volume, etc., etc. the subscriber that we create here is one part is just one part of this node.
So let's go back to our workspace source.
And then in the Python package again.
And there we have the robot new station I will create.
So I will create a smartphone dot Pi and make it executable okay for the Simulink install to work.
Also if you have a you see if you have a Pi cache folder like that, you might want to remove it.
Okay.
We don't really need that.
All right.
So now we have our file here and we can open VSCode again.
So it was already open here.
Let's go to smartphone Dot Pi.
And let's use the template again in smartphone dot Pi.
Okay.
So we have my custom node that's going to become smartphone node which inherits from node and then smartphone
node here again.
And let's keep things simple.
Let's name the node smartphone.
And maybe I've said that already.
Maybe not.
But don't name your nodes for example smartphone node okay.
Because it's already a node name okay.
So you don't say it's the smartphone node node.
You say it's the smartphone node okay.
So don't add underscore node or something like that.
You might see this in existing packages okay.
But that's basically not a good practice.
All right, let's modify.
Let's remove the modify commands.
And we are done with the node structure.
So you can see once we use the template it's very easy.
Just make sure you correctly understand this template.
Of course now we are going to create a Python subscriber.
Where do we create the subscriber.
Well we are also going to create it here in the constructor.
And of course after the super.
So let's do self dot subscriber I'm going to save it as an attribute of the class.
And we do self dot.
And once again we're going to use the functionalities of the node class create sub.
And you see we have create subscription.
So it's not create subscriber it's create subscription.
Then I open the parentheses and you see the first thing again that we need to provide is the message
type.
So message type that's going to be the same as the one we have on the publisher okay.
If you want a publisher and a subscriber to be able to communicate, then you need to use the exact
same message type.
And in the previous lesson I've already explained to you what is this example interfaces message with
the string.
So we're going to use the exact same here.
So from example interfaces dot msg import string okay.
Just make sure that it's the exact same here between the publisher and the subscriber.
And then as we use the example interfaces we make sure that in package dot XML we have the dependency
which I already set that because I wrote the publisher before.
Great.
So now I can provide string.
Then I need to give the topic name.
And here again it is very important that you use the same topic name for the publisher and the subscriber,
because if you use the wrong name, then this is going to publish to one topic.
This is going to to try to receive data from another topic and then the communication will not work.
So make sure here I'm just going to copy robot News and paste it here to make sure it's the same name.
All right.
And then after that you see we need to provide a callback because, well, a publisher, when you have
a publisher you decide when to publish.
So in this case you create a publisher.
And when you want to publish, you do publisher dot publish, but a subscriber doesn't know when it's
going to receive messages, okay.
It's going to receive messages when the publisher is publishing it.
But on the subscriber side, we have no control over that.
So that's why we're going to provide a callback function that's going to be called whenever we receive
a message.
And so let's create a function here a method inside the class.
And let's name it Callback robot news with self.
And we are going to receive a message.
I can also use a colon here And type string.
Okay, that's not mandatory.
That's optional with Python.
But this way you make the type a bit more explicit, which is, I would say, never a bad thing.
And so you see I named this function.
You can name it as you want, but usually for subscriber callbacks I will start with callback and then
the name of the topic.
Okay.
First callback.
Because then it's a good way not to make mistakes in the future because you don't want to call this
function by yourself from the class.
Okay.
This is something that's going to be called automatically.
And then this is to recognize the topic.
So when we receive a message what do we do with that message.
Well you can do whatever you want here.
We are just going to print it.
So self dot get logger and then info message.
And actually we don't just print the message.
The message is an object.
We're going to print the message dot data.
And you see I have the auto completion here because I have provided the type string and message dot
data once again, because in you see in the string object we have a data field.
So that's why it's data.
So we just print it.
But for example I don't know let's say you have let's say this is a temperature sensor that's going
to publish the temperature of whatever in your robot.
Then this could be a node that monitors the temperature of several sensors.
And then if the temperature is too high, maybe you need to take some actions.
So in this case in this callback you could monitor the temperature.
And if it's too high then you could well you could do whatever you want and take some actions here from
that node.
Great.
So we have the callback.
You can see just one line here.
We need to provide the callback here in the create subscription.
So I'm going to do self dot callback robot news.
And finally we have one last parameter here which is the queue size.
So exact same thing as for the publisher.
We have a queue size just in case.
Well, there are too many messages.
Messages are too big.
The network is lossy, so you have kind of a buffer and make sure that the messages can arrive.
All right.
So we have here the data type the name the callback and the queue size.
Now this line is quite long I'm just going to do this okay.
To make it a bit more readable.
And that's it for the code for the subscriber.
So what's going to happen is that once again you initialize rows to communications.
Then you create the node.
When you create the node you're going to create a subscriber.
When you create a subscriber, you see we register a callback and then you make the node spin.
So the node is spinning.
We stop the execution here.
The node is still alive and it can process any callbacks.
So this callback is going to be processed when we receive a message from a publisher somewhere else.
So whenever a publisher.
So for example that one is publishing a message on the robot news topic with the string data type,
then this callback is going to be called.
And we receive the message and we can process it inside the node, and this is going to last as long
as the node is alive.
So until we press Ctrl C let's save.
And then let's go back to the terminal and let's go back to.
So let's go back to the roster workspace.
And even though we used Simulink install before, the thing is here this is a new file.
This is going to be a new executable.
So we need to build it anyway.
And actually to build it it's going to be better if we add the instruction to build it.
So here I'm going to add another comma.
And then let's call it smartphone.
That's going to be the name of the executable is equal.
My pi pkg dot.
Uh the name is smartphone dot pi.
So smartphone.
And then the main function as always I'm going to save that.
Go back to the terminal and then run call build with packages Select I select my package so my pi pkg
and then Simulink install.
Okay it was built and now I'm just going to open once again new terminals so that everything is correctly
sourced.
That's probably the easiest way to make sure everything is working fine.
And let's run um let's run it here.
Ros, to run my Pi pkg, if I press tab twice, you can see that.
Now we should have also a smartphone executable.
So let's run smartphone and you can see we have okay.
We don't have any log.
I'm just going to go back and add a log at the end of the constructor.
Self dot get logger info.
Smartphone has been started.
It's not very important but just I like it when you can see that the node has been started and we have
reached the end of the constructor.
So let's run again.
You can see the smartphone has been started and well, nothing happens because well, we have a callback
that's going to print some messages, but we are not publishing any messages.
So now let's start the publisher Ros2 run my pi pkg with Robot News Station.
And as soon as I start you should see we receive messages here on that terminal.
You see, if I stop the publisher, then the subscriber is still running.
But we don't receive any more messages.
I start the publisher again.
You see, we continue to receive messages and congratulations.
You now have two nodes which are communicating with a topic.
As you can see, once you understand how topics work, creating a topic, publisher or subscriber inside
the node is not that hard and it's going to be always the same thing.