WEBVTT

00:00.080 --> 00:06.500
Now that we know how the life cycle nodes work, let's see how to use them to create the interface.

00:06.530 --> 00:09.500
The driver that connects our robot.

00:09.500 --> 00:13.790
And so the Arduino and the servo motors to the Ros two environment.

00:14.150 --> 00:19.760
To do this, we are going to use the Ros two Control library and we are going to develop an Arduino

00:19.790 --> 00:26.300
interface to control the real robot and the real motors so that all the other applications that use

00:26.300 --> 00:32.150
the Ros to control, to move the simulated robot, like, for example, move it can continue using the

00:32.150 --> 00:39.290
same logic and the same files to move the real robot in the same way as they were actuating on the simulated

00:39.290 --> 00:39.980
robot.

00:41.220 --> 00:48.090
At the time of creating this lesson in Ros2, it is possible to develop an hardware interface and integrate

00:48.090 --> 00:52.380
it with the Ros2 Control library only with C plus plus.

00:52.620 --> 00:58.590
Therefore, there won't be a similar lesson for the creation of the hardware interface in Python.

00:58.860 --> 01:04.920
Anyway, as soon as this functionality becomes available also in Python I will take care of extending

01:04.920 --> 01:06.600
this lesson in Python as well.

01:07.420 --> 01:13.230
And since we are about to create the hardware interface for controlling the robot, let's add this functionality

01:13.230 --> 01:16.080
within the Arduino bot controller package.

01:16.200 --> 01:23.190
And here, let's start by creating a new script, a new header file within the include folder and within

01:23.190 --> 01:25.560
the Arduino bot controller sub folder.

01:25.710 --> 01:33.060
And let's call this file Arduino bot interface dot PHP.

01:34.140 --> 01:37.890
If this is the first time you encounter a file of this type.

01:37.890 --> 01:45.960
So with extension h p, you just need to know that this is a cplusplus header file used to separate

01:45.960 --> 01:52.050
the declaration of a class and so to declaration of its methods and attributes from its definition.

01:52.050 --> 01:59.190
So where the logic is, the separation is very useful, especially in large projects, and improves

01:59.190 --> 02:02.640
the code readability and the reusability of the code.

02:03.400 --> 02:04.510
In this other file.

02:04.510 --> 02:07.540
Let's start by importing the CPP library.

02:08.950 --> 02:11.830
So the CPP.

02:14.290 --> 02:20.320
And then let's also import the system interface module from the hardware interface library.

02:20.740 --> 02:29.260
So let's include from the hardware interface, the system interface module.

02:29.350 --> 02:34.150
And we are going to use it to create a new hardware interface for our robot.

02:34.150 --> 02:46.030
So for our manipulator, let's create a new class called Arduino Bot Interface, which inherits from

02:46.030 --> 02:50.590
the system interface class that is defined in the Arduino interface.

02:50.590 --> 02:53.290
And so from the system interface class.

02:53.990 --> 03:00.130
And this indicates that the Arduino bot interface class that we have just created implements an hardware

03:00.140 --> 03:02.650
interface of the Ros2 Control library.

03:02.660 --> 03:05.720
So to integrate it with the Ros to control library.

03:06.860 --> 03:09.170
Now let's continue defining this class.

03:09.380 --> 03:14.960
And before declaring this class, let's first use the Cplusplus include guards.

03:15.080 --> 03:33.700
So if is not defined the Arduino bot interface H let's define this one and at the end of the file.

03:33.710 --> 03:37.580
So here let's just put and if.

03:38.310 --> 03:44.490
This include guards, prevent this class from being redefined multiple times in the same project or

03:44.490 --> 03:45.720
in the same application.

03:45.720 --> 03:53.970
If, for example, several different cplusplus scripts include this header file in their in their definition.

03:54.150 --> 03:57.120
Let's also place the declaration of this class.

03:57.120 --> 04:07.740
So if the Arduino board interface class within a namespace and let's call this one Arduino board controller.

04:07.740 --> 04:15.600
So let's define these namespace and let's define the Arduino board interface class within this namespace.

04:15.990 --> 04:20.790
Now let's start by adding functionalities to the Arduino board interface class.

04:21.300 --> 04:25.410
Let's start by clearing the public attributes of this class.

04:25.410 --> 04:27.750
And so let's start with this constructor.

04:27.930 --> 04:35.940
So with the Arduino board interface class and then also let's declare the virtual destructor of this

04:35.940 --> 04:36.570
class.

04:36.810 --> 04:40.590
So still Arduino board interface.

04:41.630 --> 04:48.650
And then since this node is inheriting from the system interface class, from the interface library

04:48.650 --> 04:50.120
and since this class.

04:50.120 --> 04:57.320
So the system interface class implements a lifecycle node, we need to redefine the behavior of some

04:57.320 --> 05:02.330
functions that are the on activate and on the activate functions.

05:02.480 --> 05:08.000
So still here, let's redefine the behavior on the on.

05:10.540 --> 05:11.920
Activate function.

05:13.070 --> 05:19.300
So let's use the override to say that we are redefining the behavior respect to the one that was defined

05:19.330 --> 05:26.140
here and also the on the activate function.

05:27.100 --> 05:29.080
Let's override also this here.

05:29.760 --> 05:37.120
The return type of this function is callback return that is defined in the CPP lifecycle library.

05:37.140 --> 05:39.630
So first we need to import this library.

05:40.230 --> 05:51.450
So let's include CPP lifecycle and from this one from the node interfaces, let's import the lifecycle

05:51.450 --> 05:52.800
node interface.

05:52.810 --> 06:00.060
And now here within the namespace, instead of retyping every time the type callback return.

06:00.060 --> 06:07.740
So as we did for example here, as we did in the simple lifecycle node, instead of retyping every time

06:07.740 --> 06:12.120
all of these return type, we can use an using statement.

06:12.120 --> 06:30.030
So using callback return and so let's use just this one instead of using the CPP lifecycle node interfaces.

06:30.030 --> 06:33.570
And then from this one, the lifecycle node interface.

06:33.570 --> 06:35.580
And from this one the callback return.

06:35.730 --> 06:42.690
So from now on, instead of rewriting all of this here, we can just refer to it just as callback return.

06:43.200 --> 06:51.720
And so this one is the return type that now we can use on the on activate function and on the on the

06:51.720 --> 06:54.990
activate function about the input of this function.

06:54.990 --> 06:59.310
So we can see that still there is an error since the input is not correct.

06:59.310 --> 07:06.600
And so about the input they receive an object of type state from the CPP interface package.

07:06.600 --> 07:08.730
So let's include this class.

07:09.030 --> 07:15.090
So include still from the CPP lifecycle.

07:15.480 --> 07:21.420
Let's take the definition of the state class and now let's use this class that we have imported.

07:21.420 --> 07:29.760
So the state class to define that the on activate function receive as input an object of type rql cpp

07:31.590 --> 07:41.400
lifecycle of type state and let's call this one for example, previous state.

07:42.230 --> 07:48.170
And also the on the activate function receives the same input.

07:48.200 --> 07:55.130
With this, we have redefined only the two functions that we need to configure and start the behavior

07:55.130 --> 07:56.750
of the life cycle node.

07:57.170 --> 08:04.160
Now we need to redefine some other functions that belongs to the system Interface class of the hardware

08:04.160 --> 08:06.950
interface library from which we are inheriting.

08:07.600 --> 08:13.960
Redefining the behavior of this function will allow us to configure the drivers behavior and the communication

08:13.960 --> 08:15.970
with the Arduino and the motors.

08:16.480 --> 08:22.930
Among these, we need to redefine the function that is called on init.

08:22.930 --> 08:27.280
So let's override the behavior of this function.

08:27.550 --> 08:37.060
And also this one returns an object of type callback return and instead it receives as input an object

08:37.060 --> 08:37.870
of type.

08:41.320 --> 08:47.650
Hardware info and let's call this one hardware info.

08:48.130 --> 08:59.350
Next, we need to redefine another function that is the export state interface and the return type of

08:59.350 --> 09:00.860
this function is a vector.

09:00.880 --> 09:11.620
So let's import the vector module from the C plus plus standard library and let's use it to declare

09:11.620 --> 09:24.790
that here the return type of this function is a vector of type hardware interface and of type state

09:24.940 --> 09:26.140
interface.

09:26.830 --> 09:37.870
Let's redefine one more function, and this is the export command interface.

09:37.870 --> 09:40.070
This time.

09:41.180 --> 09:53.690
So let's override this function and it also returns a vector this time of type hardware interface command

09:53.720 --> 09:54.800
interface.

09:55.400 --> 09:58.990
Finally, we need to redefine two more functions.

09:59.000 --> 10:02.480
So here and these are the read function.

10:07.130 --> 10:08.990
And the write function.

10:11.910 --> 10:18.360
And also these two functions are inherited from the system interface class.

10:18.720 --> 10:26.940
Both of them return an object of type hardware interface return type.

10:27.330 --> 10:36.150
So this is the return type of both these functions and both receive as input an object of type time

10:36.150 --> 10:38.250
from the CPP library.

10:38.550 --> 10:47.820
So from the CPP they both receive an object of type time and let's call this variable time.

10:48.840 --> 10:55.170
And this works for the read and also for the write function.

10:55.680 --> 11:00.060
And also they receive another input, both of them.

11:00.750 --> 11:07.360
That is another object of type rql CPP duration.

11:07.380 --> 11:10.560
And let's call this one period.

11:11.400 --> 11:16.470
So let's copy this one also for the write function.

11:16.470 --> 11:17.310
So here.

11:18.640 --> 11:25.930
With this, we have concluded the declaration of the private functions of the Arduino interface class,

11:25.930 --> 11:31.840
and basically we have redefined the behavior of some of the functions that we have inherited from the

11:31.840 --> 11:33.610
System interface class.

11:33.790 --> 11:39.250
Now let's proceed to declare some private variables of this class.

11:39.250 --> 11:45.340
And since the hardware interface needs to communicate directly with the Arduino and this communication

11:45.340 --> 11:52.060
happen through the serial port, we are going to use the serial library in this script here, which

11:52.060 --> 11:57.460
we have already used in the previous lesson to create some simple examples, some templates for the

11:57.460 --> 12:00.010
communication between Ros two and the Arduino.

12:00.430 --> 12:11.530
So let's include from the Lib serial, the serial port class, and let's use it here.

12:11.620 --> 12:20.510
So from the Lib serial, let's create a new serial port object which we call Arduino.

12:21.240 --> 12:27.060
Next, let's also add a new private member of the Arduino Bot interface class, which is a string.

12:27.090 --> 12:32.460
So first let's include the string module.

12:32.490 --> 12:40.260
Then let's create a new string and let's call this one port, which is going to indicate the port to

12:40.260 --> 12:42.990
which the Arduino is connected to our PC.

12:43.290 --> 12:47.730
And finally, let's add also three vectors of decimal numbers.

12:49.920 --> 12:51.570
So of doubles.

12:53.170 --> 12:59.560
And let's call the first one position commands.

13:00.640 --> 13:06.100
Then let's copy this one and let's paste it two more times.

13:06.130 --> 13:12.640
The second one is called Previous Position commands and the last one.

13:12.640 --> 13:18.730
So this one is called Position states.

13:19.720 --> 13:27.010
With this, the Arduino interface dot PHP file is completed and this, as you can see, just declares

13:27.010 --> 13:31.150
the elements that belongs to the Arduino bot interface class.

13:31.450 --> 13:35.350
In the next lesson we will proceed to define all the functions.

13:35.350 --> 13:41.650
And so basically to add the logic and define the behavior of all these functions and also to initialize

13:41.650 --> 13:43.300
all these variables here.
