Now that you understand what a ros2 topic is, let's create a publisher with Python.
So what we are going to do here is we are first going to create a node.
And in this node we're going to add a publisher that's going to publish some text twice per second on
a topic.
And how to get started.
Well as I told you, we need to create a node because the publisher is going to be inside the node.
And where do we create nodes?
Well, we are going to go back to our roster workspace in the source folder.
And then we already have a Python package.
So I'm just going to use that one okay.
For the examples we do in this course I'm going to go to my Python package.
And inside this package I also have another folder with the same name okay.
And you can simply see that we already have my first node.py.
I've also added the template okay, that you could download from the section three.
And we are going to create a new file.
So I'm going to name it Robot News station dot p y.
So the ID here is just to imagine we are creating a news station that's going to publish some text on
a topic.
Okay.
Very simple example.
So I create the file and I'm going to make it executable chmod plus x.
That's because for the symlink install to work if you're going to use symlink install for installing
your Python package you have to have the file executable.
Great.
So now we can go back here I'm going to open VSCode once again.
I open it from the source folder of the workspace.
And from there we can edit that file.
So let's open the new file here the robot news station.
And we have a blank page.
But from now on we're going to use this template.
So this is a template we have written in the section on nodes.
So we can just take that template here and put it there.
Okay.
And the only thing we need to do is to modify the names.
So the name of the class here and also the name of the node.
So here my custom node is going to be let's name it Robot News Station node okay.
And that's going to be the same here.
And then I need to give a name to the node.
So let's simply name it Robot News Station.
And as you can see here already I'm using the same name for the file name here.
And for the node name that's something that's quite common okay.
Those are two different things.
Once again this is the file name and this is the node name.
But you can use the same if you want.
Let's just remove those comments that are not needed.
All right.
And let's save the file.
Great.
And now we can start from this.
So we have the imports here we have our class where we can write everything that's related to the node.
And then we have the main function where we initialize ros2 communications.
We start the node.
We make the node spin and then shut down.
And how to create a publisher and also where to create it.
Well we're going to do that in the constructor of the class.
Okay.
So we have the class robot new station node here after the super.
So the super is going to be the first line okay.
After this I can create a publisher.
So let's also do self dot publisher okay.
We're going to save it as an attribute of the class and how to create a publisher.
I'm going to do self dot create publisher.
And as you can see I have the auto completion here okay.
So I use the create publisher method from the node class.
And if you remember from the previous video for a topic, we need two things.
We need a name and we also need a data type.
So what type are we going to use.
Because you see we have to provide the type here as the first argument.
And well here to get started I'm going to give you directly the type we're going to use.
So there are already some data types for messages for topics that are existing and already installed
for you to use.
And then we will be able to also create our own types.
But this is going to be the focus on one full section just a bit later in this course.
So I'm just going to show you I'm going to go back to the terminal and I'm just going to show you,
let's just clear that we have a comment.
It's called Ross to Interface show.
Okay.
So still a rose to command line.
And then interface show to display an interface that you can use and that's already installed.
And you can type Example interfaces.
You can press tab, you see, and you should have the auto completion and then MSG slash and then string
with an S uppercase okay.
If you type this and you press enter you see we have here.
So it's found we have an interface.
So we have an interface.
We have a message called string which contains that.
So we have a few commented lines you see.
So you don't need to worry about those lines.
And then we have string data.
This means that we have a field named data inside this message and of type string.
And this is exactly what we want for this topic.
We want to publish a string on a topic.
So we're going to use that message.
So you see the example interface package.
So that's a package.
And that's an interface inside the package okay.
So this package is quite useful for you to get started.
So we can use all kinds of basic data types without having to create messages by ourselves, which is
going to be the focus later in this course.
So let's import that one inside our code and how to import that.
Well we will need to do here from example interfaces.
And as you can see it's also found because of the Ross extension.
So from example interfaces dot msg.
Okay we have an MSG folder that's for topics import and then string you see as uppercase.
And it should be found.
So now what I can do in my create publisher I can provide the message type which is string.
Okay.
That's the class here that I'm using.
Now before we go further here, as you can see we have a new import.
And the first import was RCL pipe.
Okay.
With rcl p we already had if I go to package XML.
We already had a depend tag for this package for this dependency, but now we are using a new one.
We are using the package named example interfaces.
So because we are depending on a new package, I'm going to add the dependency to the package dot XML.
So I'm going to add depend example interfaces just like that.
Okay.
So that will specify that this package Mypy pkg depends on the example interfaces.
So I'm going to save and go back here.
And that's basically it for the package dot XML.
Okay.
So whenever you import a new package here make sure you also add the depend tag on the package dot XML.
Great.
And now let's finish this publisher.
So to create a publisher we have a data type.
And we have a name okay.
So what name do we use.
Well here we can create a name Because we create a publisher, we can publish to whatever name we want.
And as a reminder, you need to start the name with a letter.
Then you can use some numbers, some underscores, etc..
Here I'm going to name it Robot News just like that.
And there is one more thing actually you need to add for the publisher.
Otherwise you might get an error.
You need to add a queue size.
So I'm just going to put ten.
So very basically that can be useful if you are going to publish let's say big messages like images
that are very big or if you're going to publish very fast in a network, in a Wi-Fi network that's not
very stable, maybe publishers and subscribers can't keep up with the messages.
So this is going to create kind of a buffer so that the publisher can have a buffer of up to ten messages
to send.
Okay.
So you can choose for example, one you could put ten 1000.
Well it doesn't really matter at this point.
Okay.
As I told you, maybe if you have a lousy network or big messages, you're going to have to tweak this.
But for everything we do in this course and most things you will do anyway with roster, you don't need
to worry about that.
So I'm just going to keep ten.
Okay.
For everything we do in this course.
All right.
And now we have our publisher.
So create publisher with a data type and a name.
The thing is this publisher is not going to do anything because we create the node.
We have a publisher.
Great.
But it's not doing anything.
I'm going to add another method in the class here.
I'm going to call it for example publish news.
And I need to put self because we are in a Python class and how to publish a message on that topic.
Well, we need to do two things.
First, we need to create the message and then we need to publish it.
So let's create a message.
We are going to use the string here.
The string class and create a string object.
Then inside this string I can do msg dot.
We have you see msg dot data.
Why data?
Because if you remember in the interface we have a field named data which is of type string.
So I will use a string here and let's just say hello.
So I have created a message I have filled all the the fields of the message.
So it's just one here.
And then I can publish it using the publisher.
So I will do self dot publisher dot publish.
Okay.
So it's quite simple.
You publish and you publish what the message that you have just created.
And that's how you publish a message on a topic.
Now once again this code is not going to do anything because well we have a publisher, we have a function,
but we don't call the function.
So how to call the function?
Let's say we want to call the function twice per second.
Well, if you remember what we did previously when we created the first node we added a timer.
So I'm going to add a timer here as well.
Let's do self timer.
So let's save it as also an attribute of the class.
And we can do self dot create timer.
As you can see I also created that in the constructor.
And I will create it also after the publisher.
So the author doesn't necessarily matter in this case okay.
But you see I create a publisher and then I create a timer in the constructor.
So self dot create timer.
The first thing I need to provide is the timer period in second.
So if I want to publish twice per second it means every 0.5 second.
And then what is the function?
What is the method that I need to call back for this timer that one.
So self dot publish news with no parentheses.
Okay.
It's just the reference of the function.
And with this code then that function is going to be called because.
So we initialize Ros to communications.
Then we create the node that's going to create the publisher and the timer.
And then when the node is spinning the node is going to be kept alive.
Okay.
The program is going to be stuck here.
So the node is kept alive.
And we can execute all the callbacks for that node.
And because we have a timer, then we will have a callback that will be triggered every 0.5 second.
So that function will be executed every 0.5 seconds.
That's it for the code.
But there is one thing I like to do is after I finish the constructor here, you see there is no log.
So when we start the node we will not see anything printed on the terminal.
So what I like to do usually is to add a log.
So self get logger info.
And just to say that the node has been started.
So let's say robot news station has been started okay.
It could be just uh okay or whatever message, but I like to have a message at the end.
So log at the end of the constructor.
Great.
And now it seems that the code is complete.
What I will do is I will now install this executable.
And to do that I will go to setup.py.
And here you can see at the end we already have in the console script we have our first node.
So I'm going to add a comma.
That's very important here.
Make sure you add a comma and then go back to a new line.
And I will create a new executable.
Now what name to give to the executable.
Well I can name it for example Robot News Station.
So here, as you can see, I'm going to use the same name for the executable, for the file name and
for the node name.
Okay.
That's completely valid.
Once again those are three different things.
But I can use the same name.
So robot new station is equal to what's the folder name.
My pi pkg dot.
What's the file name.
Robot.
New station use station without the extension.
And then what is the function we want to call?
Well it's always going to be main because I'm always going to use the the main with the node template.
So we want to execute the main function.
All right.
As simple as that.
And for every new executable you just add a comma and you create a new one here.
It's not complicated if you ever make a mistake.
For example, if you forgot the comma and then it's going to build something, but it's going to be
weird and you're going to have some errors.
Okay.
In this case I recommend that.
So you go to your workspace and if you have built something that is wrong I recommend that you remove
those build install and log.
Okay.
So our m r build install log.
So in case you mess up with something and you build it, then you can always remove everything that's
going to be a bit cleaner.
Okay.
But now we don't have any mistakes.
So let's save all the files.
Let's make sure we have saved all the files.
You see, we should have crosses here on VSCode.
And let's go back.
And once again, let's go back to our roster workspace and let's do a call on build with I'm going to
do packages select with my pi pkg.
And I'm also going to use the symlink install so that I don't need to compile This anymore.
So I need to use I need to compile it first once.
At least with the Simulink install option.
But then if I modify this file here, I should be able to run it without installing it again.
Great.
So it has been built.
What I'm going to do is I'm going to open a new terminal so that I have everything correctly sourced.
Let's just split that for example, and let's run our publisher.
So let's run the node which contains a publisher Ros to run my Pi PG.
And if I press tab twice, you see that.
Now I have two executables.
I have the first one that I've created and Robot New Station.
So I can start robot new station using the auto completion.
And you see so we have this log robot news station has been started.
Now I can use the rose two command line tools that we have seen previously.
For example Ros two Not least I see I have my robot news station Ros2 node info with robot news station.
Don't forget the slash and well, we have a bunch of stuff, but you can see on the publishers we have
robot news.
Okay, you can see there is added slash okay.
There is no slash in the code.
Okay.
You don't need to provide a slash.
If you don't it's going to add automatically a slash for you.
And so you see we have the robot news topic with the string interface from the example interfaces package.
Now to be able to see what we published we need a subscriber.
So we will need to write a subscriber.
But before we do that I'm going to show you there is another command line.
And I'm going to come back to this also in a dedicated lesson in this section.
So we have Ros2 topic list.
If you do Ros2 topic list, you can see we have the robot news topic and if I do rose to topic equal
with the name of the topic here with slash robot News, then I can basically create a subscriber and
I can display what we receive on that topic directly in the terminal.
So make sure that the publisher is running here.
And then you should see that we receive data.
Hello.
Every 0.5 seconds okay.
And well it's still receiving.
Now if I kill the publisher.
You see now we don't receive any more data.
So we can see that what we receive here was directly published by that node right here.
And I'm just going to finish with a slight improvement.
So let's say we want to say hi this is and then a name.
So for example C-3po from the Robot News.
station.
And let's also say that instead of hard coding this, I'm going to use a variable.
So I'm going to do this self dot robot name is equal to C-3po.
And then I can use.
So I can use this plus self robot name plus.
All right.
So I construct a string and I put this attribute here.
So that also later on we will see ways to modify that.
Let's save.
And because I have built the workspace with Simulink install.
So this package with Simulink install I should be able to run again.
And we should see you see.
Hi, this is C-3po from the robot news station.
Okay, so now we have the new data.
Great.
And you have created your first Python publisher in Ros two.