WEBVTT

00:00.050 --> 00:04.040
In this lesson you will learn how to create a Cplusplus node.

00:04.040 --> 00:08.990
You will write the node, compile it and run it, and we're going to follow the same structure.

00:08.990 --> 00:12.620
As for the Python node, we're going to first write a very minimal code.

00:12.620 --> 00:17.660
And then in the next lesson you will have the object oriented programming way of writing the code,

00:17.690 --> 00:22.670
plus the full template that you can use for any future node that you create.

00:22.670 --> 00:24.260
And let's get started.

00:24.260 --> 00:32.900
So we are going to go first inside our roster workspace and then the source directory and then the my

00:32.930 --> 00:34.670
CPP package.

00:34.670 --> 00:39.410
So inside this package we have a include and a source folder.

00:39.410 --> 00:43.100
We are going to go inside the source folder of that package.

00:43.100 --> 00:44.930
And here we have nothing.

00:44.930 --> 00:46.550
So let's create a file.

00:46.580 --> 00:51.680
Touch my first node dot cpp.

00:51.680 --> 00:54.260
So we use the CPP extension.

00:54.290 --> 00:54.710
All right.

00:54.740 --> 01:01.310
So that's where you will create your cplusplus files inside the source folder of the package.

01:01.310 --> 01:04.050
And now let's edit that with VSCode.

01:04.050 --> 01:11.700
So I'm going to go back again here to the source folder of the workspace called Dot.

01:12.780 --> 01:21.450
And let's find the file which is going to be right here in the my CP package.

01:21.450 --> 01:23.850
And you see I have my first node CP.

01:23.850 --> 01:26.130
So let's start with the includes.

01:26.130 --> 01:28.470
And we only have one include here.

01:28.470 --> 01:38.970
So we're going to do include and then RCL CP slash RCL CP dot HP.

01:38.970 --> 01:43.140
And you can see here again I have the auto completion.

01:43.140 --> 01:47.190
If you don't have the auto completion you need to go back to the extensions here.

01:47.190 --> 01:53.430
Make sure you have installed the Ros extension by Microsoft and then maybe start the VSCode again.

01:53.970 --> 01:59.190
Okay, so include RCL, CP and then RCL, cp, HP.

01:59.340 --> 02:03.170
At this point I would also suggest to already save the file.

02:04.310 --> 02:09.920
Okay, you see, we have an error and then it's recognized again.

02:09.920 --> 02:16.010
So save the file because then if you use the clcp functionalities later, if you haven't saved the file

02:16.010 --> 02:18.890
maybe you will have some issues with the autocompletion.

02:18.890 --> 02:22.250
So save the file after you include something in Cplusplus.

02:22.250 --> 02:23.660
I would recommend to do that.

02:23.660 --> 02:26.810
And then well, what do we need to do in a Cplusplus program?

02:26.810 --> 02:29.990
We need to create a main function.

02:29.990 --> 02:33.320
So let's just create one with arg c.

02:33.350 --> 02:39.080
So number of arguments and then this for the arguments okay.

02:39.080 --> 02:40.640
So there's nothing special here.

02:40.640 --> 02:43.760
It's just a standard main structure for C plus plus.

02:43.760 --> 02:46.280
And what do we do inside the Ros2 program.

02:46.280 --> 02:55.490
Well first we initialize ros2 communication with our clcp then colon colon init okay.

02:55.520 --> 03:01.670
So inside the clcp library we have the init function just like we had in Python.

03:02.120 --> 03:04.850
And here we can pass the arguments of the main.

03:04.850 --> 03:07.400
So argc and argv.

03:08.450 --> 03:14.000
So that's the first thing we will do every time we initialize ros2 communications.

03:14.000 --> 03:16.340
Then we're going to do some stuff.

03:16.340 --> 03:21.680
And the last thing we will do is our clcp shut down.

03:22.040 --> 03:22.520
Okay.

03:22.520 --> 03:24.500
Just like we did in Python.

03:24.500 --> 03:27.860
But of course with the C plus plus syntax and after shutdown.

03:27.860 --> 03:30.110
Well because you see it's a int.

03:30.110 --> 03:32.060
So we need to return an integer.

03:32.210 --> 03:33.980
Let's return zero.

03:34.010 --> 03:34.520
Okay.

03:34.520 --> 03:37.310
So that's the first thing you will do in a C plus plus program.

03:37.310 --> 03:40.310
And that's the last thing you will do in the middle.

03:40.310 --> 03:42.470
We can create nodes and do all sorts of stuff.

03:42.470 --> 03:44.360
But first you initialize Ros2.

03:44.390 --> 03:47.330
And then at the end you shut down Ros2 and you return.

03:47.360 --> 03:49.640
Now let's create a node.

03:49.640 --> 03:51.770
So what type we will give.

03:51.800 --> 03:54.500
Let's just use the auto type.

03:54.830 --> 03:57.380
So auto node is equal to.

03:57.410 --> 04:00.350
And we are not just going to create a node.

04:00.350 --> 04:03.680
We are going to actually create a pointer to a node.

04:03.680 --> 04:08.870
and in Ros2 you will see that we use pointers for everything and actually not just pointers.

04:08.870 --> 04:13.580
We're going to use smart pointers and in this case a shared pointer.

04:13.580 --> 04:18.320
And if you don't know anything about smart pointers, well maybe just find a quick tutorial online to

04:18.350 --> 04:19.580
get a few explanations.

04:19.580 --> 04:20.750
But it's not that hard.

04:20.750 --> 04:25.610
It's just going to take care of allocating memory and destroying the memory for you, so you don't need

04:25.610 --> 04:27.080
to worry about that.

04:27.080 --> 04:29.870
And in Ros two everything is using those pointers.

04:29.870 --> 04:35.660
So at the beginning it might be a bit complicated to understand, but as you get used to it it's always

04:35.660 --> 04:36.440
the same thing.

04:36.440 --> 04:46.700
So let's do STD make shared to create a pointer of an object and what is going to be the object rcl

04:46.730 --> 04:49.310
cpp node.

04:49.340 --> 04:55.400
Okay, so we get the node class from rcl cpp directly okay.

04:55.430 --> 04:59.660
So here with this we open and close the parentheses.

04:59.690 --> 05:03.410
With this we create a node object.

05:03.410 --> 05:07.180
And actually here we create a shared pointer to a node object.

05:07.180 --> 05:15.640
So you can see now the auto is actually a shared pointer of an lclc-rp node.

05:15.670 --> 05:15.970
Okay.

05:16.000 --> 05:19.720
So that's how you create a node in Ros2 with C plus plus.

05:19.720 --> 05:23.080
And then well we can do the same thing as we did with Python.

05:23.080 --> 05:28.090
We can also make the node print something because this is the minimum code.

05:28.090 --> 05:30.100
But well it's not going to do anything.

05:30.100 --> 05:31.540
So let's do node.

05:31.540 --> 05:35.230
And because this is a pointer we need to use an arrow.

05:35.410 --> 05:35.830
Okay.

05:35.860 --> 05:39.970
If you just use a dot you're going to interact with the shared pointer.

05:40.000 --> 05:44.470
If you use an arrow you interact with the object inside the shared pointer.

05:44.470 --> 05:49.720
And we have a get logger functionality and actually to print something.

05:49.720 --> 05:56.380
So to use a log we are going to use the RCL cpp info like that.

05:56.380 --> 06:01.990
And then we're going to put node get logger as the first argument.

06:01.990 --> 06:06.460
And then the second argument is going to be the log itself.

06:06.490 --> 06:07.660
So hello, world.

06:07.750 --> 06:11.680
And you can construct a string here just like that.

06:11.680 --> 06:13.510
Let's not forget the semicolon.

06:13.540 --> 06:14.050
All right.

06:14.050 --> 06:17.380
So lclc-rp underscore info all uppercase.

06:17.380 --> 06:19.030
And then you do node.

06:19.030 --> 06:21.520
So the node you've created getlogger.

06:21.670 --> 06:26.110
And then the log you want to print okay let's save that.

06:26.110 --> 06:27.400
And now how to test it.

06:27.400 --> 06:33.790
So with Python we could already test it by just making the file executable and running the file as Python

06:33.790 --> 06:35.890
was an interpreted language.

06:35.890 --> 06:37.930
But C plus plus you cannot do that.

06:37.930 --> 06:40.840
You need to build the code anyway.

06:40.840 --> 06:42.070
And how to build the code.

06:42.070 --> 06:43.780
How to create an executable.

06:43.780 --> 06:50.050
Well, this time here we will go to the Cmakelists.txt and well I don't want this.

06:50.050 --> 06:53.170
And you see I have already the syntax highlighting.

06:53.170 --> 06:58.780
If you don't have this, make sure you have the CMake extension here by Twx.

06:58.810 --> 06:58.990
Okay.

06:58.990 --> 07:01.270
That's the one that I'm using here for this course.

07:02.530 --> 07:04.900
So let's go back to Cmakelists.txt.

07:05.380 --> 07:09.790
And we're going to write here the rules to create executables for Cplusplus.

07:09.790 --> 07:12.610
But first let's do a bit of cleanup.

07:12.610 --> 07:17.050
So you see we have here the minimum required version for CMake.

07:17.050 --> 07:18.550
Some stuff for the compiler.

07:18.550 --> 07:20.740
We find some dependencies okay.

07:20.740 --> 07:26.050
So we have a CMake that's going to be well because this is a C plus plus package.

07:26.050 --> 07:29.110
And then we have RCL cpp you see.

07:29.140 --> 07:35.260
So if you add a new dependency in a C plus plus package you will have to add the dependency here.

07:35.560 --> 07:35.950
Okay.

07:35.980 --> 07:40.840
But if you need the dependency to compile some stuff, you will also need to find the package here.

07:41.350 --> 07:42.490
And then we have this.

07:42.520 --> 07:48.250
If build testing with some testing stuff that we actually don't need right now.

07:48.250 --> 07:52.390
So usually if I don't need that I'm just removing it okay.

07:52.420 --> 07:53.560
It's a bit cleaner.

07:53.560 --> 07:59.320
And we finish the CMake list.txt with payment package.

07:59.320 --> 08:00.910
So that should be the last line.

08:00.910 --> 08:02.680
So make sure you don't remove that one.

08:02.680 --> 08:04.600
And now how to add an executable.

08:04.600 --> 08:10.600
Well after you find the dependencies parentheses and before the event package line we will add.

08:10.600 --> 08:16.570
So add executable and you need to choose a name for your executable.

08:16.570 --> 08:19.870
So for example cpp node.

08:19.900 --> 08:22.870
Okay this is whatever you want.

08:22.900 --> 08:27.010
Then we need to provide the path to the file.

08:27.040 --> 08:27.460
Okay.

08:27.460 --> 08:31.780
So here from from there the path is to go to the source folder.

08:31.780 --> 08:33.850
And then my first node cpp.

08:34.360 --> 08:41.620
So we write src my first node dot cpp.

08:42.070 --> 08:44.980
So with this we create an executable.

08:44.980 --> 08:55.360
But we also need to add the dependencies for that executable with the payment target dependencies.

08:55.780 --> 08:58.390
Dependencies like that.

08:58.420 --> 08:58.870
Okay.

08:58.870 --> 09:05.800
So add executable is a command cmake function but that's specific to A-mount and Ros2 okay.

09:05.830 --> 09:08.320
So aim and target dependencies.

09:08.350 --> 09:12.130
The first argument is going to be the executable name.

09:12.130 --> 09:14.440
So cpp node.

09:14.440 --> 09:18.130
And then you will add all the dependencies that you need to link.

09:18.130 --> 09:24.040
So in this case you see in our code we are using rcl cpp.

09:24.280 --> 09:32.350
So I'm going to add Lclc-rp which is also found here we find package rcl cpp.

09:32.440 --> 09:38.950
If you don't add this then you will get an error at compilation saying that Lclc-rp is not found okay

09:38.980 --> 09:43.030
because you haven't used the payment target dependencies.

09:43.090 --> 09:43.630
Great.

09:43.630 --> 09:47.410
And this is going to create an executable, but it's not going to install it.

09:47.410 --> 09:51.550
So we need to add an install block okay.

09:51.580 --> 09:53.920
And in this you can write for example here.

09:53.920 --> 09:58.750
So let's write target like that uppercase.

09:59.440 --> 10:04.780
And then we're going to add I'm just adding two spaces here cpp node.

10:04.780 --> 10:06.580
That's the executable name.

10:06.580 --> 10:07.720
Same here.

10:08.080 --> 10:10.270
And then destination.

10:12.310 --> 10:13.390
All uppercase.

10:13.390 --> 10:15.730
We're going to use lib slash.

10:16.360 --> 10:20.920
And then you use dollar sign curly brackets like that.

10:20.920 --> 10:25.180
And project underscore name.

10:25.180 --> 10:27.430
And make sure you don't make any typo here.

10:27.430 --> 10:31.270
It's dollar sign curly brackets project name okay.

10:31.300 --> 10:33.400
Because I see lots of people making typos here.

10:33.400 --> 10:36.610
And then it doesn't work well because there is a typo okay.

10:36.640 --> 10:40.210
So this is going to create an executable with the dependencies.

10:40.210 --> 10:45.550
And this is going to install the executable in somewhere in the lib folder.

10:45.550 --> 10:48.460
So that's going to be in the install folder of the workspace.

10:48.460 --> 10:50.950
Somewhere in the package there's going to be a lib folder.

10:50.950 --> 10:54.250
And that's where we install the C plus plus executables.

10:54.250 --> 11:00.790
And note that this you just need to do it once because then for any new executable that you want to

11:00.820 --> 11:05.380
add from this package, you basically need to duplicate those two lines.

11:05.380 --> 11:11.620
And then you just need to add the new executable name in a new line just here.

11:11.650 --> 11:14.620
Okay, so let's save that.

11:14.650 --> 11:16.420
Make sure you save everything.

11:16.420 --> 11:17.650
All the files.

11:17.980 --> 11:19.750
Let's go back to the terminal.

11:19.780 --> 11:24.760
Let's go back to the Ros2 workspace once again.

11:24.790 --> 11:29.500
It's super important that you build from that folder and not anywhere else.

11:29.500 --> 11:31.510
And let's do a quick build.

11:32.050 --> 11:36.100
So we could build both packages because we have two packages.

11:36.130 --> 11:41.080
If you want you can just build with packages select.

11:41.170 --> 11:48.970
We can just build my CP pkg and let's use Autocompletion for everything because that makes it faster.

11:48.970 --> 11:52.450
And we don't have errors when we type stuff.

11:54.430 --> 11:54.730
All right.

11:54.730 --> 11:59.800
And you can see well if you have an cplusplus error that's what it's going to look like.

11:59.800 --> 12:02.890
So sometimes it can be explicit or not.

12:02.890 --> 12:05.140
But I need to go back to my file.

12:05.140 --> 12:10.740
And you see well actually I need to give a name here.

12:10.920 --> 12:13.890
So let's do CP test.

12:14.220 --> 12:14.760
All right.

12:14.760 --> 12:18.210
So you can see this kind of error is what you're going to get.

12:18.210 --> 12:25.950
So this is a here this is a typical classic C plus plus error that you see that when you build the package

12:25.950 --> 12:26.880
that's going to build the file.

12:26.880 --> 12:28.950
And that's when you have errors.

12:28.980 --> 12:29.400
Okay.

12:29.430 --> 12:32.340
So in this case we go back to the file here.

12:32.340 --> 12:36.990
When I create a node I need to pass the node name of course as a parameter.

12:36.990 --> 12:42.300
So I save again and then I build again.

12:44.970 --> 12:47.610
And you can see now successful.

12:47.610 --> 12:50.820
So you see this time here we have finished.

12:50.850 --> 12:53.100
Last time we had failed okay.

12:53.130 --> 12:55.770
So that's how you know that the package has been built.

12:55.770 --> 12:57.690
You see this finished line.

12:57.690 --> 12:58.200
Great.

12:58.200 --> 12:59.730
So what happened.

12:59.730 --> 13:05.100
What happened is that we have this file that is used here to create an executable.

13:05.400 --> 13:13.620
This executable is named CP node and is going to be installed somewhere inside the install folder of

13:13.620 --> 13:17.670
our workspace, so you can try to browse inside and find the file if you want.

13:17.670 --> 13:21.780
But it doesn't really matter because we are going to use Ros2 right now.

13:21.780 --> 13:24.330
So let's source the workspace.

13:24.360 --> 13:30.930
Let's do source install setup bash to make sure that we source the workspace, because we have added

13:30.930 --> 13:33.600
something in the terminal that's already open.

13:33.960 --> 13:39.300
And then let's do Ros2 so we can do it from here, from the home directory from anywhere.

13:39.510 --> 13:48.750
So let's do clear and Ros2 run my CP, let's press tab cp package.

13:48.750 --> 13:54.720
And then what was the name CP just in case you press tab is going to be found.

13:54.960 --> 13:57.450
Okay CP node let's press enter.

13:57.450 --> 13:59.730
And you see we have hello world.

13:59.730 --> 14:01.170
So we have the info log.

14:01.170 --> 14:02.430
We have the timestamp.

14:02.460 --> 14:05.190
That's the name of the node okay.

14:05.220 --> 14:06.270
And then the log.

14:06.900 --> 14:08.850
And once again here you see we have.

14:08.850 --> 14:12.630
So the name of the file is my first node DHCP.

14:13.890 --> 14:15.840
Okay, that's one thing.

14:15.870 --> 14:18.510
The second thing is the name of the node here.

14:18.510 --> 14:20.040
It's CP test.

14:20.040 --> 14:24.690
And the third thing is the name of the executable which is CP node.

14:24.690 --> 14:30.990
So you see those are three different things that sometimes you're going to use the same for all three.

14:30.990 --> 14:33.780
But they are three different things.

14:33.780 --> 14:35.430
And you can see it here.

14:35.460 --> 14:43.350
When we do raster run we actually use the executable name that we have created in the Cmakelists.txt.

14:43.350 --> 14:50.280
And then we see CP test in the log, because that corresponds to the node name that is defined from

14:50.280 --> 14:51.690
within the code.

14:51.780 --> 14:52.410
All right.

14:52.410 --> 15:00.420
And now well let's just finish this with a spin because you see once again I run this and that's it.

15:00.450 --> 15:05.130
It's going to start print something and then shut down.

15:05.340 --> 15:07.590
That's exactly what we asked it to do.

15:07.590 --> 15:10.380
But now let's say we want to keep the node alive okay.

15:10.410 --> 15:17.700
So the node can stay alive as long as we want until we press Ctrl C so we can do this right here just

15:17.700 --> 15:18.480
before shutdown.

15:18.480 --> 15:24.930
We do lclc-rp and then spin and we pass the node.

15:24.930 --> 15:28.200
You see, we need to give a shared pointer to a node.

15:28.200 --> 15:30.450
So we pass the node as a parameter.

15:30.450 --> 15:31.830
And that's basically it.

15:31.860 --> 15:36.600
So now I save and I need to build again okay.

15:36.600 --> 15:40.650
So I go back to my Ros2 workspace.

15:40.650 --> 15:46.680
And then you need to remember that every time that we change the code we're going to do build source

15:46.680 --> 15:47.610
and run.

15:47.610 --> 15:50.040
So let's find the command to build.

15:50.070 --> 15:51.210
It's here.

15:53.580 --> 16:03.240
So I have built now I will source and then I will run okay.

16:03.240 --> 16:08.250
And this time you see that we are hanging here because the node is spinning.

16:08.250 --> 16:12.930
Now I press Ctrl C and you see the node is shut down.
