WEBVTT

00:00.050 --> 00:03.680
In this lesson you will write a C plus plus publisher.

00:03.680 --> 00:08.660
We will do the same thing as we did for the Python publisher, but just this time in C plus plus.

00:08.660 --> 00:13.940
So you will be able to compare the code for the same functionalities in the two languages.

00:13.940 --> 00:18.740
Let's go to our workspace again in the source repository.

00:18.740 --> 00:21.290
And then we have our two packages.

00:21.290 --> 00:23.990
I'm going to go to the C plus plus one this time.

00:24.440 --> 00:29.210
And I'm going to go to the source folder of the C plus plus package where we already have.

00:29.240 --> 00:33.560
You can see the first node and also the template for the node.

00:33.560 --> 00:42.590
Let's create a new file named Robot News Station dot CP, which is going to be the node where we have

00:42.590 --> 00:45.380
the publisher and nothing else to do here.

00:45.380 --> 00:51.590
I'm just going to open VSCode and here, so I'm going to close my Python package.

00:51.590 --> 00:53.090
I don't need that anymore.

00:53.090 --> 01:01.020
And let's go to the C plus plus package inside my so Robot news station dot CP I'm going to use the

01:01.020 --> 01:02.040
template.

01:02.610 --> 01:07.260
So I'm just going to take the code from the template and put it there.

01:07.440 --> 01:07.890
Okay.

01:07.920 --> 01:12.300
And as you can see you might have an error just because you need to save the file.

01:12.300 --> 01:13.650
So I'm saving the file.

01:13.650 --> 01:17.220
And after a few seconds you see.

01:17.220 --> 01:20.040
So I had to wait about five 10s.

01:20.490 --> 01:22.890
Then the include is working.

01:22.920 --> 01:23.100
Okay.

01:23.130 --> 01:25.230
So don't worry too much if you have an error.

01:25.260 --> 01:28.770
First save the file first and then let's rename that.

01:28.770 --> 01:34.680
So it's going to be Robot News Station node.

01:34.920 --> 01:35.130
Okay.

01:35.130 --> 01:38.640
So I'm just going to use the same names as I did for Python.

01:38.760 --> 01:42.840
And we also need to modify it here and there.

01:43.950 --> 01:44.160
Okay.

01:44.190 --> 01:48.180
So class name is going to be in three places.

01:48.180 --> 01:54.840
And the node name is going to be here Robot News Station I'm going to use the same.

01:54.840 --> 01:56.820
Let's remove those comments.

01:57.870 --> 02:00.210
And now the node is set up.

02:00.210 --> 02:02.770
So we have to include Lclc-rp.

02:02.920 --> 02:04.150
We create the node.

02:04.150 --> 02:06.850
We have the constructor where we initialize the node.

02:06.850 --> 02:10.330
And then in the main function we start Rosta communications.

02:10.330 --> 02:15.790
We create a shared pointer of the object for robot new station node.

02:15.790 --> 02:18.100
And then we make the node spin and we shut down.

02:18.100 --> 02:20.500
So let's create our publisher.

02:20.500 --> 02:26.800
And in Cplusplus, as you might already know, the syntax is going to be a bit more complicated than

02:26.800 --> 02:27.520
in Python.

02:27.520 --> 02:30.760
There's a bit more stuff to write, but that's just how it is.

02:30.760 --> 02:35.950
So the first thing actually I'm going to do is not to create the publisher, but is to import.

02:35.950 --> 02:38.710
So to include the interface, okay.

02:38.740 --> 02:42.040
And the interface, that's the same one we've used with Python.

02:42.040 --> 02:46.000
So I'm going to use include and I'm going to use the string.

02:46.510 --> 03:00.100
So if I go back here I can do Ros to interface show example interfaces MSG and string okay.

03:00.130 --> 03:03.370
That's the interface I'm going to use, and I can use this in Python.

03:03.370 --> 03:06.010
I can also use this in C plus plus.

03:06.010 --> 03:11.020
And you see this string message has a data field of type string.

03:11.740 --> 03:19.540
So how to include this in C plus plus you will start with example interfaces slash.

03:19.540 --> 03:24.040
And you can see we also have the Autocompletion MSG slash.

03:24.040 --> 03:26.230
And that's going to be string.

03:26.230 --> 03:28.810
So here the string is lowercase okay.

03:28.840 --> 03:32.110
Quite important dot h p p.

03:32.500 --> 03:34.750
We're going to try to import HTTP files.

03:34.750 --> 03:38.440
If you have an error like this you just save the file.

03:39.790 --> 03:42.100
And after a few seconds it's going to be found.

03:42.130 --> 03:45.460
Now because we are using you see we are using our clcp.

03:45.880 --> 03:47.590
So that's one package.

03:47.590 --> 03:50.140
But we are also using example interfaces.

03:50.140 --> 03:52.210
That's a second package.

03:52.210 --> 03:59.890
So we will need to add the dependencies here in the my CPP package I go to the package dot XML.

03:59.890 --> 04:02.650
You see we have a deep end tag with Lclc-rp.

04:02.980 --> 04:07.690
I'm going to add another one depend example.

04:09.700 --> 04:13.960
Interfaces and I close the depend tag.

04:13.990 --> 04:14.380
All right.

04:14.380 --> 04:16.960
So that's the same thing as we did for Python.

04:16.960 --> 04:22.750
But now in Cplusplus there is an additional thing you need to do because you're going to compile the

04:22.750 --> 04:23.740
file okay.

04:23.770 --> 04:25.390
And you need the dependency.

04:25.390 --> 04:28.390
When you compile you need to link the dependencies.

04:28.390 --> 04:31.540
So we need to add something in the CMake list.txt.

04:31.570 --> 04:33.040
Here we find the dependencies.

04:33.040 --> 04:37.000
You see we have first element cmake and we have lclc-rp.

04:37.180 --> 04:46.630
You're going to add another find package with example interfaces.

04:46.630 --> 04:50.710
And we've also required okay.

04:50.740 --> 04:57.340
And then we're going to use that also when we link the dependencies here with the executable.

04:57.370 --> 04:57.700
All right.

04:57.700 --> 05:04.740
So if you add a new package cage inside the file, you add it to the package dot XML and also to the

05:04.740 --> 05:06.420
Cmakelists.txt.

05:07.260 --> 05:07.560
Great.

05:07.590 --> 05:10.500
Now we have included the interface.

05:10.500 --> 05:12.450
Let's create the publisher.

05:12.450 --> 05:15.330
We are going to create a private attribute.

05:15.330 --> 05:17.490
So we have the public and the private.

05:17.490 --> 05:23.790
In the private attribute I'm going to create a publisher and the publisher is going to be RCL, cpp

05:24.960 --> 05:30.630
and inside RCL cpp we have a publisher class okay.

05:30.660 --> 05:33.510
And this publisher class we need to give.

05:33.510 --> 05:35.850
So this is going to be a template.

05:35.850 --> 05:38.520
We need to give the interface.

05:38.520 --> 05:48.900
So the interface is example interfaces and then MSG and then string just like that okay.

05:48.930 --> 05:54.240
So when you create a publisher here when you declare a publisher you have to provide also the type in

05:54.240 --> 05:56.790
C plus plus here using those brackets.

05:56.790 --> 05:57.900
So that's a template.

05:57.900 --> 06:04.920
And we are not actually going to create just a publisher, we are going to create a shared pointer to

06:04.950 --> 06:05.820
a publisher.

06:05.850 --> 06:06.120
Okay.

06:06.150 --> 06:11.520
So once again we use shared pointer for everything in C plus plus in rust.

06:11.520 --> 06:14.460
And this shared pointer here this sharedptr.

06:14.490 --> 06:19.680
As you can see this is going to create an STD shared pointer here.

06:19.710 --> 06:19.980
Okay.

06:20.010 --> 06:23.400
So that's something you can use to simplify your code.

06:23.460 --> 06:26.640
And let's call it publisher.

06:27.720 --> 06:27.900
Okay.

06:27.930 --> 06:34.410
So that's the name we give it with an underscore here just to say that that's an attribute of the class.

06:34.440 --> 06:34.860
Great.

06:34.860 --> 06:40.110
So now that I have declared it here I can initialize it in my constructor.

06:40.110 --> 06:46.200
So publisher publisher like that is equal to.

06:46.320 --> 06:48.390
And then I'm going to use this.

06:48.420 --> 06:48.570
Okay.

06:48.600 --> 06:55.230
It's not mandatory but it's just to explicitly say that I'm using the node functionality.

06:55.230 --> 06:56.220
So you don't need to do that.

06:56.220 --> 07:02.670
But as I told you before, I'm going to do this in this course and create a publisher.

07:02.670 --> 07:06.990
So you have a create publisher method here to create a publisher.

07:07.020 --> 07:09.840
And that's going to return a shared pointer to a publisher.

07:09.840 --> 07:12.540
You need to give the interface once again.

07:12.540 --> 07:18.960
So example interfaces msg and then string.

07:18.960 --> 07:21.120
And then you're going to open the parentheses.

07:21.120 --> 07:25.140
And you need to give the name of the topic.

07:25.140 --> 07:27.480
So we've already provided the interface.

07:27.480 --> 07:29.820
So the data type like this.

07:29.820 --> 07:31.290
Then we need to give the name.

07:31.290 --> 07:35.220
Let's also name it Robot News okay.

07:35.220 --> 07:41.280
And also in those parentheses we are going to provide the queue size of ten okay.

07:41.280 --> 07:47.970
So this I already explained with Python it's just a buffer in case you have too many messages are too

07:47.970 --> 07:54.600
big or it's a lossy network, then that's going to add messages to a buffer up to ten messages okay.

07:54.630 --> 07:56.580
And with that we have created the publisher.

07:56.610 --> 07:59.850
Now let's create a method to publish.

07:59.870 --> 08:04.070
So I'm going to add a method in private here void.

08:04.070 --> 08:05.780
We don't return anything.

08:05.780 --> 08:08.090
Publish news okay.

08:08.090 --> 08:09.530
Let's call it publish news.

08:10.040 --> 08:12.800
And I'm going to put this function as private.

08:12.800 --> 08:15.920
Because this is not something we call from outside of the class.

08:15.920 --> 08:18.590
We're just going to use it from a timer okay.

08:18.620 --> 08:20.150
And the timer is inside the class.

08:20.150 --> 08:22.490
So that's why I put it here in private.

08:22.490 --> 08:23.480
And let's create.

08:23.510 --> 08:27.590
We need to create a message I'm going to use the auto type.

08:27.710 --> 08:35.270
So auto MSG and the message is example interfaces msg string.

08:35.270 --> 08:41.270
You can really see here the powerfulness of the auto completion okay I really don't recommend you to

08:41.300 --> 08:45.260
write C plus plus code for Ros2 without auto completion okay.

08:45.290 --> 08:47.210
Because that's going to become a nightmare.

08:47.300 --> 08:50.780
So you create here a string object.

08:50.780 --> 08:52.940
And actually here is kind of an exception.

08:52.940 --> 08:54.770
It's not going to be a shared pointer.

08:54.770 --> 08:57.860
It's just going to be the object directly okay.

08:57.860 --> 09:00.470
So then we can do MSG dot.

09:00.470 --> 09:05.630
And here we have a field named data that can be high.

09:05.930 --> 09:08.360
This is okay.

09:08.360 --> 09:11.630
And let's directly do the string construction.

09:11.660 --> 09:14.210
Let's create a robot name.

09:14.210 --> 09:25.280
So I'm going to do this here STD string robot name like that.

09:25.640 --> 09:28.880
And let's initialize the robot name here.

09:30.020 --> 09:36.710
Robot name to um, let's name it this time R2d2.

09:37.190 --> 09:38.000
All right.

09:38.000 --> 09:41.720
And I'm going to concatenate that robot name.

09:41.720 --> 09:45.020
And actually just in case we get some errors.

09:45.020 --> 09:49.130
So this is an STD string that is not an STD string.

09:49.130 --> 10:01.190
So I'm going to do STD string of this text plus this string plus.

10:01.310 --> 10:05.480
STD string of that text.

10:05.480 --> 10:13.310
So hi, this is robot name from the robot news station.

10:14.270 --> 10:15.650
Um, STD here.

10:16.820 --> 10:20.930
Okay, so we create the object for the message.

10:20.930 --> 10:25.790
We here we add a data field because we have a data inside the interface.

10:25.790 --> 10:27.260
And then we just need to publish.

10:27.260 --> 10:28.430
So we have the publisher.

10:28.430 --> 10:30.320
We do simply publisher.

10:31.160 --> 10:34.670
So publisher the publisher is a shared pointer.

10:34.670 --> 10:38.240
So that's an arrow publish.

10:38.420 --> 10:39.710
And what do we publish.

10:39.710 --> 10:43.970
We publish the message as simple as that.

10:43.970 --> 10:50.330
And now that we have a publisher and a method to publish, well we need to actually call that method.

10:50.330 --> 10:52.520
And we want to publish twice per second.

10:52.520 --> 10:54.710
So I'm going to add a timer.

10:54.710 --> 10:56.360
So I'm going to create a timer here.

10:56.360 --> 11:03.070
For example here our Clcp Timer base.

11:03.700 --> 11:08.350
And also no surprise, still a shared pointer.

11:09.430 --> 11:13.690
Okay, so this we've done it already in the section on nodes for this course.

11:13.690 --> 11:17.530
And after the publisher I'm going to initialize my timer.

11:18.820 --> 11:21.670
Timer is equal to this.

11:22.240 --> 11:30.250
So once again this is not mandatory just for me to explicitly say I'm using the node class create wall

11:30.280 --> 11:30.790
timer.

11:30.790 --> 11:33.100
So in C plus plus it's called wall timer.

11:33.100 --> 11:35.830
And we need to give a duration.

11:35.830 --> 11:43.300
So what I'm going to do here instead of doing STD Chrono and duration I'm gonna make things a bit simpler.

11:43.300 --> 11:52.150
I'm going to do using namespace std chrono literals.

11:52.150 --> 11:58.480
So by doing using namespace std chrono literals at the beginning, then I can just give a literal for

11:58.480 --> 12:03.730
example 0.5 s for second and that's going to be recognized.

12:03.760 --> 12:03.970
Okay.

12:04.000 --> 12:07.720
We don't need to write the whole STD, Chrono etc..

12:07.750 --> 12:12.400
So I have first the period in in second here.

12:12.400 --> 12:14.860
And then I need to provide the callback.

12:14.860 --> 12:19.120
So to provide the callback I need to do std bind.

12:19.420 --> 12:24.580
And we will first provide the reference to.

12:24.670 --> 12:28.750
So to this which is robot new station publish news.

12:28.750 --> 12:38.020
So robot news station node publish news with no parentheses.

12:38.020 --> 12:48.400
And then comma this specify that is this object we are binding to and a semicolon here.

12:48.430 --> 12:49.060
All right.

12:49.060 --> 12:54.220
So if this syntax is still complicated for you well don't worry because as I told you before it's always

12:54.220 --> 12:55.150
going to be the same thing.

12:55.150 --> 12:58.030
So after a few repetitions you will get used to it.

12:58.390 --> 12:59.500
And that's going to be it.

12:59.500 --> 13:05.060
I'm going to add a log here just to finish the constructor as Clcp info.

13:05.090 --> 13:09.650
With this get logger.

13:10.640 --> 13:18.950
And just to say the robot news station has been started.

13:19.130 --> 13:19.340
Okay.

13:19.340 --> 13:23.210
Just a log to finish the constructor.

13:23.240 --> 13:24.020
Okay.

13:24.020 --> 13:26.930
And now we can so we can save the file.

13:26.960 --> 13:28.370
Make sure you save the file.

13:28.370 --> 13:32.690
And let's go to the Cmakelists.txt to create an executable.

13:32.720 --> 13:34.460
We have the first one here.

13:34.460 --> 13:36.890
So let's add a new line here.

13:36.890 --> 13:39.500
Add executable.

13:39.650 --> 13:40.970
What's going to be the name.

13:40.970 --> 13:44.900
Let's name it Robot News Station.

13:44.900 --> 13:52.220
So once again I use the same name for the executable for the file name and for the node name.

13:53.360 --> 13:56.570
So robot new station where is the file.

13:56.570 --> 14:02.970
The file is in src Slash and then robot news station WKRP.

14:03.000 --> 14:06.330
Robot news station dot CPP.

14:07.170 --> 14:09.180
After that, I will do payment.

14:09.720 --> 14:17.190
Target dependencies I will first provide the name of the executable, which is Robot News Station.

14:17.190 --> 14:19.410
That's the name here I've provided here.

14:19.440 --> 14:25.260
You see, this is where you should start not to make confusions because that's the name of the executable.

14:25.290 --> 14:28.860
Here was obvious cpp node was that name.

14:28.860 --> 14:32.370
It's not the name of the file, it's not the name of the node inside the file.

14:32.370 --> 14:35.940
This is the name of the executable you write here.

14:35.970 --> 14:38.100
Okay so not to be confused.

14:38.130 --> 14:41.130
And then we need to provide all the dependencies.

14:41.130 --> 14:42.750
We need to link to that.

14:42.750 --> 14:45.240
So we have our clcp of course.

14:46.620 --> 14:49.200
But then if we look at the file we have our clcp.

14:49.200 --> 14:52.680
And we also have example interfaces.

14:52.680 --> 15:02.430
So I'm going to write example interfaces that we have also Uh, added here we find package.

15:02.460 --> 15:02.970
Okay.

15:03.000 --> 15:06.900
So important that you add this line and that you add the dependency here.

15:06.990 --> 15:09.540
Then this is going to create an executable.

15:09.540 --> 15:11.460
But we also need to install it.

15:11.460 --> 15:14.880
So I'm going to add simply one more line here.

15:15.210 --> 15:17.370
Robot news station.

15:17.790 --> 15:18.060
Okay.

15:18.090 --> 15:20.100
So one executable per line.

15:20.100 --> 15:22.080
And you don't need to change this structure.

15:22.080 --> 15:22.860
And that's it.

15:22.860 --> 15:28.770
So you can see after you've created your first executable adding another one is not going to take that

15:28.770 --> 15:29.460
much time.

15:29.460 --> 15:34.110
Let's save the file and we should be able to compile.

15:34.110 --> 15:40.650
So let's go back to the terminal I go to my roster workspace and I do call on build.

15:41.820 --> 15:44.460
I'm just going to build the package.

15:44.460 --> 15:48.960
So the C plus plus one with packages select.

15:50.760 --> 15:53.130
So my CP pkg.

15:56.400 --> 15:56.940
Okay.

15:56.940 --> 16:05.490
So it has been built and now I could so I could source, install, setup bash, run it from here.

16:05.670 --> 16:09.960
I can also just open a new terminal is going to be the same.

16:10.200 --> 16:17.790
So let's do that and let's run Ros to run my CP pg with.

16:17.820 --> 16:19.920
So just in case I press tab twice.

16:20.040 --> 16:23.160
And you see I have my new executable here.

16:23.190 --> 16:25.440
Robot news station.

16:26.790 --> 16:29.100
And we have the robot new station has been started.

16:29.100 --> 16:30.240
So we have the log.

16:30.630 --> 16:32.730
And you see the node is hanging.

16:32.730 --> 16:34.710
So the node is spinning.

16:34.710 --> 16:39.150
And we can also do Ros to node list.

16:39.720 --> 16:40.350
Okay.

16:40.380 --> 16:45.000
Ros to node info with that name.

16:46.530 --> 16:46.830
Okay.

16:46.860 --> 16:54.060
We see we have a publisher which is Robot News and the type is string from example interfaces package.

16:54.060 --> 16:56.610
So we can find all this information again.

16:56.610 --> 17:02.300
And we can also do Ros two to topic eco robot news.

17:06.470 --> 17:10.940
And you see how this is out to the two from the robot news station.

17:10.940 --> 17:18.200
And this is actually something else we can do is we can start the subscriber node from.

17:18.200 --> 17:24.830
So Rostron my Python package with a smartphone okay.

17:24.860 --> 17:27.680
So we are running the C plus plus publisher.

17:27.680 --> 17:33.320
And here I'm going to try to run the subscriber I have created with Python for the exact same topic.

17:33.320 --> 17:36.770
So with the same name and same data type let's see what happens.

17:38.540 --> 17:40.100
And it correctly works.

17:40.100 --> 17:45.980
You see we receive the data from the C plus plus publisher.

17:45.980 --> 17:51.050
And so with this example you can clearly see that Ros two is language agnostic.

17:51.080 --> 17:55.520
You can create one node in C plus plus and one other node in Python.

17:55.520 --> 17:59.990
And both nodes can communicate using for example, topics.
