WEBVTT

00:00.020 --> 00:06.980
To create the task server, which is the action server that executes various actions on the robot.

00:06.980 --> 00:11.660
We need to create a new Ros2 package inside our workspace.

00:11.690 --> 00:13.970
So let's open a new terminal.

00:14.030 --> 00:20.120
Let's go to the workspace and to the source folder in which we have already created several packages

00:20.120 --> 00:23.180
that implements several functionalities for our robot.

00:23.210 --> 00:30.140
And here let's create a new package with the command Ros2 package create.

00:30.140 --> 00:32.450
Then let's select the build type.

00:32.990 --> 00:40.850
So the build type that is ARM and CMake as we are going to use both Python and C plus plus code in this

00:40.850 --> 00:41.450
package.

00:41.450 --> 00:47.630
And then let's insert also the name of the package that is Arduino Robot Remote.

00:47.630 --> 00:51.200
So we're going to call this new package Arduino Robot Remote.

00:51.200 --> 00:57.290
And this will contain all the remote interface with the Amazon Alexa voice assistant.

00:57.290 --> 00:59.090
So let's press enter.

00:59.110 --> 01:05.140
And now if we take a look at the packages, we can see that there is the Arduino bot remote package.

01:05.170 --> 01:12.490
So let's go back and let's build our workspace in order to compile also the new package.

01:12.490 --> 01:14.590
So here the Arduino bot remote.

01:14.590 --> 01:21.070
And now back in Visual Studio Code we can create the task server that we are going to use to interface

01:21.070 --> 01:25.510
with the Moovit API, and also with the Alexa voice assistant.

01:25.960 --> 01:33.970
So here in the Arduino bot remote package, let's create a new folder called Arduino Bot Remote.

01:33.970 --> 01:41.020
And now within this folder let's create a new empty file that is called init dot pi.

01:41.020 --> 01:45.010
And then let's create also another file, another Python file.

01:45.010 --> 01:48.460
So the one that will actually contain the code for the task server.

01:48.460 --> 01:52.990
And let's call it task server dot Pi.

01:53.020 --> 01:53.830
Perfect.

01:53.830 --> 01:55.870
And now in this file here.

01:55.870 --> 02:02.310
So in the task server we want to develop an action server that actually offers several tasks to move

02:02.310 --> 02:03.030
the robot.

02:03.030 --> 02:08.310
So instead of implementing the action server from scratch, we can copy actually the implementation

02:08.310 --> 02:12.960
of the action server that we did in the Arduino Pi examples.

02:12.960 --> 02:16.050
So this one here, the simple action server.

02:16.050 --> 02:21.630
So let's copy all of this and let's paste it here within the task server.

02:21.660 --> 02:27.300
Now the first thing that we want to do here is to rename the class from Simple Action Server.

02:27.300 --> 02:29.130
That is the one that we used here.

02:29.130 --> 02:31.710
So let's do a Ctrl f.

02:31.710 --> 02:37.560
And here let's replace the simple action server into task server.

02:37.590 --> 02:40.290
And so let's replace all the occurrences.

02:40.290 --> 02:44.370
Then let's also rename here the name of the node.

02:44.370 --> 02:49.380
It's also task server perfect.

02:49.380 --> 02:51.870
And also we can change here.

02:51.870 --> 02:56.700
This is not anymore the simple action server but it's called task Server.

02:56.700 --> 03:03.420
So let's also change the name of this variable here when we are creating the instance of the task server.

03:03.450 --> 03:04.320
Perfect.

03:04.320 --> 03:11.040
And now let's initialize the action server so we can still initialize it with the action server class.

03:11.040 --> 03:15.690
So as an instance of the action server class and now the name.

03:15.690 --> 03:18.570
So this one is the name of the task server.

03:18.630 --> 03:22.080
And let's simply call this one task server.

03:22.110 --> 03:22.710
Perfect.

03:22.710 --> 03:28.830
And also we need to change here the communication interface that we want to use in order to contact.

03:28.830 --> 03:32.370
So in order to send a goal to this action server.

03:32.370 --> 03:35.310
So in the previous lesson we have used this one here.

03:35.310 --> 03:40.110
So the Fibonacci interface that we declared in the Arduino bot messages.

03:40.110 --> 03:45.030
And now for the purpose of this lesson we are going to need a new interface.

03:45.030 --> 03:47.550
So the interface with the task server.

03:47.550 --> 03:51.870
Again we can declare it here within the Arduino bot messages package.

03:51.870 --> 04:03.200
And here within the action folder here let's create a new file called Arduino Bot task dot action.

04:03.350 --> 04:04.340
Perfect.

04:04.340 --> 04:08.960
And now here we need first to define the goal message.

04:08.960 --> 04:12.950
So the goal interface that's the action server will receive.

04:12.980 --> 04:15.650
And this will just contain a single number.

04:15.650 --> 04:19.070
So the ID of the task that we want to execute.

04:19.190 --> 04:20.690
So this is an integer.

04:20.690 --> 04:24.560
And let's call it task number perfect.

04:24.560 --> 04:27.440
And actually that's it for the goal message.

04:27.440 --> 04:33.470
Then let's use three dashes in order to insert the result message.

04:33.470 --> 04:39.560
And the result message just contains a boolean that is the success.

04:39.560 --> 04:45.350
So this variable here will contain a boolean that indicates whether the action server completed the

04:45.350 --> 04:47.540
action successfully or not.

04:47.630 --> 04:55.780
And finally, let's insert a feedback message that actually we are not going to use, but that I leave

04:55.780 --> 05:04.660
as an exercise for you to implement that just contains another integer and that contains the percentage.

05:04.660 --> 05:10.120
So this is the completion percentage of the task that is executing the robot.

05:10.150 --> 05:15.790
Now once we have declared this Arduino bot task action, we can install it.

05:15.790 --> 05:18.880
So we can go to the Cmakelists.txt file.

05:18.880 --> 05:26.230
And here along with the action Fibonacci that we used in the previous lesson, let's also declare the

05:28.120 --> 05:30.310
Arduino bot task action.

05:30.310 --> 05:33.730
So the one that we have just created and actually that's it.

05:33.730 --> 05:39.070
So these are the only instructions that we need in order to define this interface.

05:39.070 --> 05:42.730
So the task interface that will be used by the task server.

05:42.760 --> 05:50.110
Now in order to be able to start using this action interface here in our node, we can simply open the

05:50.110 --> 05:50.860
terminal.

05:51.160 --> 05:55.050
We can go to the workspace and we can build it.

05:55.050 --> 06:01.620
So basically this will install the Arduino bot task interface so that we will be able to use it here

06:01.620 --> 06:04.110
in the task server dot pi node.

06:04.740 --> 06:05.400
Perfect.

06:05.400 --> 06:10.740
So once the compilation is completed we can go back to the task server.

06:10.740 --> 06:14.430
And here from the Arduino bot messages and from the action folder.

06:14.430 --> 06:19.950
Instead of importing the Fibonacci here we can import the Arduino bot task.

06:19.950 --> 06:24.540
And so we can also see that we have the auto completion of Python, and if you don't.

06:24.540 --> 06:30.480
So if you don't have automatically the auto completion of Python, you can use the key combination Ctrl

06:30.510 --> 06:35.760
shift P and then look for Ros update Python path.

06:35.760 --> 06:38.220
So this one here and just click on this one.

06:38.220 --> 06:40.800
So this will refresh the dependencies.

06:40.800 --> 06:43.530
And so then you will be able to see this one here.

06:43.530 --> 06:49.980
So to have the auto completion for the Arduino bot task message now we can use it actually here.

06:49.980 --> 06:54.380
So when we declare the action server now we can start using this one here.

06:54.380 --> 06:56.210
So the Arduino bot task.

06:56.240 --> 07:01.940
Now before moving on to the goal callback function, let's complete the constructor of the task server

07:01.940 --> 07:04.670
by initializing also the Moveit interface.

07:04.670 --> 07:13.310
So the Moveit API that will allow us to send a goal to the robot, and also to plan a trajectory so

07:13.310 --> 07:20.330
we can import from the Moveit planning the.

07:21.080 --> 07:24.590
Let's import the movie py class.

07:24.620 --> 07:25.400
Perfect.

07:25.400 --> 07:35.480
And now also let's import another class, this time from the Moveit core robot state.

07:36.020 --> 07:42.080
So let's import the class that is called Robot State now in order to initialize the Moveit API.

07:42.110 --> 07:47.660
So here within the constructor, let's create a new instance of the movie py class.

07:47.840 --> 07:51.160
Let's call this one Arduino board.

07:51.190 --> 07:56.440
So as the name of the robot and this is an instance of the movie Pi class.

07:56.440 --> 08:02.890
And as you might remember when we developed the simple movie interface here, we need to provide the

08:02.920 --> 08:10.120
node name to the constructor of this class that we can simply call move it Pi.

08:10.150 --> 08:11.080
Perfect.

08:11.080 --> 08:13.360
And then let's also access.

08:13.360 --> 08:19.600
So still here in the constructor, let's also access the two planning groups that we have defined for

08:19.600 --> 08:20.260
our robot.

08:20.260 --> 08:27.070
So the planning group of the R that we can call Arduino robot arm.

08:27.160 --> 08:32.530
And we can access this group from the Arduino board.

08:32.560 --> 08:36.160
We can use the function get planning component.

08:36.160 --> 08:42.040
So this one here and we want to access to the planning component that we simply called R.

08:42.130 --> 08:44.140
Let's also do the same for the gripper.

08:44.140 --> 08:46.090
So we can copy this instruction.

08:46.090 --> 08:53.210
And we can create a new variable called Arduino Bot Gripper and steal from our robot.

08:53.210 --> 09:00.320
So from the movie Pi instance, we can access to the planning component that we called gripper.

09:00.380 --> 09:01.310
Perfect.

09:01.310 --> 09:06.080
So with this now we have initialized the movie Pi class.

09:06.080 --> 09:09.440
And also we have accessed the two planning components.

09:09.440 --> 09:13.550
So the two move groups that are there and the gripper.

09:13.640 --> 09:17.150
Now we can finally implement the actual logic of the server.

09:17.150 --> 09:22.310
So the operation that the action server will execute whenever it receives a new goal.

09:22.310 --> 09:27.440
So basically the logic of the goal callback function actually here.

09:27.440 --> 09:32.480
So the first thing that we want to do in the goal callback function is to print an informative message

09:32.480 --> 09:40.760
in the terminal in which we indicate so the received goal with request with task number.

09:40.760 --> 09:44.780
So we indicate the task number that we received in the goal message.

09:44.780 --> 09:50.640
In fact, as you might remember from the Arduino bot task interface, the goal message just contains

09:50.640 --> 09:53.010
an integer that is the task number.

09:53.010 --> 09:56.670
And so let's print it from the goal handle from the request.

09:56.700 --> 10:00.930
Let's print the task number.

10:01.500 --> 10:02.820
Here there is a typo.

10:02.850 --> 10:05.430
It's number perfect.

10:05.430 --> 10:08.880
And then actually we can remove all of these.

10:08.880 --> 10:14.250
So all of these instructions that instead implemented the logic for the calculation of the Fibonacci

10:14.250 --> 10:14.970
sequence.

10:14.970 --> 10:16.500
So let's remove it.

10:16.500 --> 10:23.070
And instead we are going to insert here the logic of our node that sends a goal to the robot.

10:23.070 --> 10:24.450
So to move it to pi.

10:24.450 --> 10:27.420
And that moves the robot to the desired position.

10:27.510 --> 10:31.920
So the first thing that we want to do here is to get the current state of the robot.

10:31.920 --> 10:35.610
So first the arm state.

10:35.610 --> 10:40.650
And here this is an instance of the robot state class.

10:40.650 --> 10:49.760
And with this we want to access to the Arduino, both variable and we want to get the robot model.

10:49.790 --> 10:50.420
Perfect.

10:50.450 --> 10:53.690
Let's do the same also for the gripper state.

10:53.690 --> 10:55.910
So let's copy this one and let's paste it.

10:55.910 --> 10:59.840
And here this is the gripper state.

10:59.870 --> 11:00.680
Perfect.

11:00.680 --> 11:01.880
And this one here.

11:01.880 --> 11:07.700
So the arm state and the gripper state now contains the current state of the arm and the gripper.

11:07.700 --> 11:09.860
And actually we are going to change this one.

11:09.860 --> 11:13.880
So this instance of the robot state with the desired state.

11:13.880 --> 11:19.820
So with the desired position of each of the joints that belong to the arm or to the gripper.

11:19.910 --> 11:28.970
To do so we're going to need other two variables, other two vectors that we can call our joint goal.

11:29.030 --> 11:38.270
So let's initialize this one with an empty vector and the other one that is gripper joint goal that

11:38.270 --> 11:40.640
we can also initialize with an empty vector.

11:40.640 --> 11:45.700
And we are going to use the numpy library now to fill these vectors.

11:45.700 --> 11:47.470
So let's import it here.

11:47.500 --> 11:50.230
Actually the same library we are not going to need it.

11:50.230 --> 11:58.990
And instead we can import the numpy library as NP perfect.

11:58.990 --> 12:06.250
And so now as I said we can start filling the value of the joints for the arm and for the gripper.

12:06.250 --> 12:10.390
So now what we want actually to do is to set a different value.

12:10.390 --> 12:16.840
So a different position of the arm joint and of the gripper joint based on the task number.

12:16.840 --> 12:19.750
So based on the task ID that we received.

12:19.750 --> 12:29.470
So we want to take the goal handle and the request and the task number.

12:29.470 --> 12:30.580
And we want to check.

12:30.580 --> 12:35.140
So we want to move the robot differently depending on the task number that we received.

12:35.140 --> 12:41.080
So if we received the task with number zero.

12:41.100 --> 12:45.690
So in this case, we want to move our robot simply to the home position.

12:45.690 --> 12:51.960
So we want to set the arm joint goal to a numpy array.

12:51.960 --> 12:58.380
And this numpy array simply moves the robot to the position zero, zero and zero.

12:58.380 --> 13:05.760
So all the joints are back to the home position and for the gripper joint goal also this one.

13:05.760 --> 13:09.870
Let's initialize it with a numpy array.

13:09.900 --> 13:10.680
Perfect.

13:10.680 --> 13:11.670
And in this case.

13:11.670 --> 13:15.840
So in the on position we want the gripper to be slightly open.

13:15.840 --> 13:23.430
So let's initialize the joint for to the position -0.7 and the joint five.

13:23.460 --> 13:27.510
That reflects actually the joint for as the same angle.

13:27.510 --> 13:31.260
So 0.7 but in the opposite side perfect.

13:31.260 --> 13:37.110
And so this is the position in which the robot will move if we send the task number zero.

13:37.140 --> 13:40.670
Otherwise if the task number.

13:40.670 --> 13:45.740
So again this one here is equal to the task number one.

13:45.740 --> 13:52.940
So if we ask the robot to perform the task number one, we can simulate that the robot moves to a hypothetical

13:52.940 --> 13:54.110
picking position.

13:54.110 --> 13:58.880
So in this picking position actually we can copy these two instructions.

13:58.880 --> 14:04.610
And we want to send the robot to a joint position that I have already calculated.

14:04.610 --> 14:12.080
And that for example for the base is -1.4 then -0.6.

14:12.110 --> 14:16.370
And then for the elbow is -0.07.

14:16.370 --> 14:22.040
So this is just values of the three joints that compose the arm and then the gripper.

14:22.040 --> 14:28.160
So in this picking position we want to simulate that the gripper closes in order to grasp an object.

14:28.160 --> 14:32.780
And so we simply set the value of the joints of the gripper to zero.

14:33.230 --> 14:38.270
Then otherwise if we receive a gold handle.

14:38.270 --> 14:38.300
Galindo.

14:38.300 --> 14:42.230
So a task number with the number two.

14:42.260 --> 14:49.070
So if we ask the robot to perform the task number two, for example, we can send it to an hypothetical

14:49.070 --> 14:50.870
rest position.

14:51.080 --> 14:54.710
So we can copy again these two variables.

14:54.710 --> 14:59.960
And this time we can send the arm to a different position that I have calculated.

14:59.960 --> 15:06.980
And that is -1.57 and then zero and then -0.9.

15:06.980 --> 15:12.380
So basically this position of the arm will correspond to our rest position of the arm in which the arm

15:12.380 --> 15:14.300
is bent on itself.

15:14.300 --> 15:19.220
And also in this case let's keep the gripper closed finally.

15:19.250 --> 15:20.330
Otherwise.

15:20.960 --> 15:22.220
So we are here.

15:22.220 --> 15:27.170
If we receive any other task number that is different from these three ones.

15:27.170 --> 15:33.140
Here we simply want to print an error because we have not implemented any other action.

15:33.140 --> 15:37.450
But here, for example, if you want, you can also create new task numbers.

15:37.450 --> 15:42.520
So you can also create and set new tasks for the robot and for the moment.

15:42.520 --> 15:46.120
For the purpose of this lesson, I'm just going to stop here.

15:46.150 --> 15:52.750
And so in this case, I'm just going to print an error message with the get logger.

15:53.920 --> 15:59.650
And let's print an error message that says invalid task number.

15:59.650 --> 16:05.710
So we're going to accept only task numbers that are between 0 and 2.

16:05.740 --> 16:06.730
Perfect.

16:06.790 --> 16:11.380
And in this case, as we cannot execute this task let's simply return.

16:11.380 --> 16:14.680
So let's simply terminate the execution of the action server.

16:14.680 --> 16:17.920
So the execution of the goal callback function.

16:18.460 --> 16:19.180
Perfect.

16:19.180 --> 16:23.590
So now after this function here we have initialized these two vectors.

16:23.590 --> 16:29.950
So the arm joint goal with one of these three values that corresponds to the position of the joints

16:29.950 --> 16:30.670
of the arm.

16:30.670 --> 16:33.520
And also we have initialized this second vector here.

16:33.520 --> 16:39.480
So the gripper joint goal that corresponds to the desired position of the joints of the gripper.

16:39.510 --> 16:42.960
Now it's time to set this target position.

16:42.960 --> 16:46.620
So this is a target position of the arm and of the gripper.

16:46.740 --> 16:55.590
So let's access to the arm state and let's use the function set joint group positions.

16:55.620 --> 17:02.460
And so for the move group that is called arm we want to set the arm joint goal.

17:02.460 --> 17:05.790
So this one here is the desired position of the arm.

17:05.820 --> 17:09.030
Let's do the same also for the gripper state.

17:09.030 --> 17:13.770
So let's set joint group positions.

17:14.250 --> 17:17.580
And this one is for the gripper.

17:17.580 --> 17:21.570
And we want to send the gripper joint goal.

17:21.570 --> 17:23.130
So this value here.

17:23.130 --> 17:25.320
So this vector here that we have created.

17:25.380 --> 17:26.280
Perfect.

17:26.280 --> 17:29.040
So now we have defined the desired state.

17:29.040 --> 17:36.050
So this arm state and the gripper state are instances of the robot state class that contains the desired

17:36.050 --> 17:38.900
position of each of the joints of the robot.

17:38.930 --> 17:43.580
Now it's time to update also the state of the move groups.

17:43.850 --> 17:51.440
So let's access to the move group that we called Arduino Bot R, and then let's first set the start

17:51.440 --> 18:01.280
state with the function set start state to current state.

18:01.280 --> 18:05.690
And so as the name of this function says this will simply initialize.

18:05.690 --> 18:08.750
So we'll set the current state of the robot.

18:08.750 --> 18:15.050
So the current position of the robot as its start state, so that the planner can use it in order to

18:15.080 --> 18:16.370
calculate the trajectory.

18:16.370 --> 18:18.320
So this will be the starting point.

18:18.530 --> 18:21.890
Let's also do the same for the second move group.

18:21.950 --> 18:26.240
So from the Arduino bot gripper.

18:26.270 --> 18:26.810
Perfect.

18:26.810 --> 18:29.750
Let's set the start state of the Arduino board to gripper.

18:29.780 --> 18:30.470
Perfect.

18:30.470 --> 18:35.980
And finally, once we have set the start state, we can also set the goal state.

18:36.160 --> 18:41.050
So again, let's use the Arduino to move group.

18:41.050 --> 18:46.810
And on this one let's use the function set goal state.

18:46.840 --> 18:48.190
Let's do the same.

18:48.190 --> 18:54.640
Also for the second move group that is the Arduino bot gripper.

18:54.670 --> 18:55.300
Perfect.

18:55.300 --> 19:04.480
And here let's set as a goal state an object of type robot state that is the arm state perfect.

19:04.510 --> 19:14.380
And also for the gripper, let's set an object of type robot state that is the gripper state.

19:14.380 --> 19:21.670
So this variable here in which you have set as a joint position one of these three here.

19:21.670 --> 19:26.080
So one of these three positions here depending on the task that we have received.

19:26.290 --> 19:26.950
Perfect.

19:26.950 --> 19:29.380
So at this point our move groups.

19:29.380 --> 19:32.310
So the Arduino bot arm and the Arduino bot gripper.

19:32.340 --> 19:35.940
They have a start state and they also have a goal state.

19:35.940 --> 19:42.240
So finally, we can plan a trajectory that brings the robot from the start state to the goal state.

19:42.480 --> 19:49.260
So again we can use the Arduino bot R and we can simply execute the plan function.

19:49.260 --> 19:54.180
And also we can do the same for the Arduino bot gripper.

19:54.660 --> 19:57.990
And also on this one let's execute the plan function.

19:58.320 --> 19:59.610
This function here.

19:59.610 --> 20:05.490
So the plan returns an object and let's store it within the variable arm.

20:05.940 --> 20:08.910
Plan result.

20:08.910 --> 20:15.420
And also for the gripper, let's store the result of the planner into the gripper.

20:15.750 --> 20:16.680
Plan.

20:18.120 --> 20:18.870
Result.

20:18.870 --> 20:19.560
Perfect.

20:19.560 --> 20:25.800
And now at this point before executing this trajectory so this plan let's first verify that actually

20:25.800 --> 20:30.210
the result is valid both for the R and for the gripper.

20:30.240 --> 20:40.350
So let's check that the arm plan result is valid, and also that the gripper plan result is valid.

20:40.350 --> 20:44.340
And so in this case we simply know that both.

20:44.340 --> 20:50.760
So for the arm and for the gripper the planner was able to calculate a trajectory that brings it from

20:50.760 --> 20:52.470
the start state to the goal state.

20:52.470 --> 20:54.540
And so we can execute it.

20:54.930 --> 21:00.240
So we can take the Arduino board and we can execute.

21:00.240 --> 21:02.640
So we can call the execute function.

21:02.640 --> 21:04.800
And we can execute the planner.

21:04.800 --> 21:13.020
So from the arm plan result we can execute the trajectory that was calculated.

21:13.020 --> 21:18.030
And let's set the controllers to an empty vector.

21:18.030 --> 21:18.810
So like this.

21:18.810 --> 21:22.830
And this will use the default controllers for this move group.

21:22.830 --> 21:27.600
Here let's execute also the second plan.

21:27.600 --> 21:31.670
showed one of the gripper perfect.

21:31.670 --> 21:36.890
And again we're going to execute the trajectory that was here in the result message.

21:36.920 --> 21:41.870
Otherwise if one of the two planners failed.

21:41.870 --> 21:49.460
So if one of these two is not valid here, we just want to set a message in the terminal.

21:49.460 --> 21:54.920
So let's use the get logger function.

21:55.040 --> 22:03.020
And let's print an informative message that simply says one or more planners failed.

22:03.020 --> 22:03.590
Perfect.

22:03.590 --> 22:08.720
And here in this case we just want to print this informative message.

22:08.720 --> 22:09.470
Perfect.

22:09.500 --> 22:11.450
Now after this if statement.

22:11.450 --> 22:15.080
So this means that the path was correctly executed.

22:15.080 --> 22:17.030
And so we can already return.

22:17.030 --> 22:21.110
So remember that here we are in a goal callback function for an action server.

22:21.110 --> 22:22.850
So for this action server here.

22:22.850 --> 22:30.100
So now at the end of the execution of this action Here we want to return a result for the action server.

22:30.100 --> 22:36.490
So first let's set the goal handle as succeed.

22:36.490 --> 22:41.200
So this will inform the action client that actually the execution of the goal succeeded.

22:41.200 --> 22:43.990
And then we want also to return our result.

22:44.650 --> 22:53.050
So let's return a result that is an instance of the Arduino bot task action.

22:53.830 --> 22:56.140
And from the result message.

22:56.140 --> 22:58.060
And in the result message.

22:58.060 --> 23:02.200
As you might remember here we have just the success variable.

23:02.200 --> 23:06.910
And so let's set it the success variable to true.

23:06.910 --> 23:11.590
And so this will inform the client that the action was successfully executed.

23:11.590 --> 23:15.490
And also let's return the result message.

23:15.490 --> 23:21.520
So this one here this instance of the Arduino bot task result message is the one that we are going to

23:21.550 --> 23:23.530
send to the action client.

23:24.210 --> 23:30.150
Finally as this Python script here, we inserted it within a package.

23:30.150 --> 23:35.460
So the Arduino bot remote that we created using as a build type amend CMake.

23:35.490 --> 23:42.030
Here at the beginning of this file, we also need to define the directory of the Python interpreter.

23:42.120 --> 23:43.710
And so this is the.

23:45.750 --> 23:53.670
User bin and the environment is the Python three.

23:54.630 --> 23:55.290
Perfect.

23:55.290 --> 23:56.940
So we can save this script.

23:56.940 --> 23:59.670
And with this our action server.

23:59.670 --> 24:03.690
So the task server that implements this interface here.

24:03.690 --> 24:06.810
So the Arduino bot task interface is completed.

24:06.810 --> 24:10.920
And now we can start using it to send a task to our robot.

24:10.920 --> 24:13.470
And so it will move the robot accordingly.

24:13.470 --> 24:20.940
So based on the task number that we have asked to the robot, before doing so we need to install actually

24:20.940 --> 24:22.980
this Python script here.

24:22.980 --> 24:24.440
So we need to open the file.

24:24.470 --> 24:26.060
Cmakelists.txt.

24:26.240 --> 24:33.200
Here we can remove all the commented lines in order to have a file that we can read more easily.

24:33.230 --> 24:34.100
Perfect.

24:34.100 --> 24:41.900
And here let's add a new dependency from the CMake Python package.

24:41.930 --> 24:42.620
Perfect.

24:42.650 --> 24:49.880
Then let's also add a dependency from the rcl py package that we've used here in our node.

24:49.880 --> 24:54.170
And also we need a dependency from the Arduino bot.

24:56.360 --> 24:57.740
Messages package.

24:57.740 --> 24:58.490
Perfect.

24:58.520 --> 25:05.120
Then after these find packages instruction, we also need to inform the compiler that here within the

25:05.120 --> 25:08.360
Arduino bot remote there will be Python nodes.

25:08.360 --> 25:17.900
So let's use the command Python install package instruction.

25:17.900 --> 25:24.250
And here we need to indicate that the Python script will be in the folder that is called as the package

25:24.250 --> 25:24.730
itself.

25:24.730 --> 25:33.610
So Arduino bot remote that we can also access with the variable project name.

25:33.790 --> 25:39.100
And with this one we have informed the compiler about the existence of our Python node.

25:39.100 --> 25:41.200
And now we have also to install it.

25:41.680 --> 25:43.450
So we want to install.

25:43.450 --> 25:45.910
And here we want to install a program.

25:47.890 --> 25:52.000
And now we need to indicate the directory of the program that we want to install.

25:52.030 --> 25:55.930
And so this is the in the Arduino bot remote folder.

25:55.930 --> 26:04.390
So in the folder that has the same name of the package that we can access with the variable project

26:04.420 --> 26:05.260
name.

26:05.260 --> 26:09.670
And within this folder the file that we want to install is this one here.

26:09.670 --> 26:13.330
So the task server dot pi.

26:13.360 --> 26:14.200
Perfect.

26:14.350 --> 26:16.960
And then we also need to set the destination.

26:17.950 --> 26:24.430
And we want to install it in the lib folder and within the sub folder again that is called as the package

26:24.430 --> 26:25.030
itself.

26:25.030 --> 26:28.030
So again we can use the variable project name.

26:28.060 --> 26:28.870
Perfect.

26:28.870 --> 26:30.670
So we can save also this file.

26:30.670 --> 26:36.190
And we are missing also to declare the dependencies here in the package dot XML file.

26:36.190 --> 26:44.890
So here the first thing that we need to do is to add a build tool dependency from the amend cmake python.

26:44.890 --> 26:57.400
And then we can also declare a dependency from the CLP library and another one from the Arduino bot

26:58.270 --> 26:59.860
messages package.

26:59.920 --> 27:07.810
And then also we need to declare an execution dependency from the move it by package.

27:07.810 --> 27:11.170
And actually this dependency here is a conditional dependency.

27:11.170 --> 27:16.600
So we're going to need this dependency only when this condition is satisfied.

27:16.600 --> 27:26.190
And actually the condition is that you are using a Ros distribution that is bigger than or equal to

27:26.220 --> 27:26.700
ion.

27:26.700 --> 27:32.670
So you are using Ros distribution that is newer than ion, like for example Ros chassis.

27:32.700 --> 27:35.280
You will have this package available.

27:35.280 --> 27:41.130
Otherwise if you are on Ros you cannot actually implement this node here in Python.

27:41.130 --> 27:46.110
But you will just have to implement it in C plus plus because this package here.

27:46.110 --> 27:49.590
So the movie Pi is not available in Ros2 humble.

27:49.800 --> 27:51.420
We can save also this file.

27:51.420 --> 27:53.610
And that's it for this lesson.

27:54.090 --> 27:59.670
In the following lesson, after developing the C plus plus implementation of the task server, we are

27:59.670 --> 28:05.760
going to launch it and we are going to see how it works and how we can send any of these tasks.

28:05.760 --> 28:09.720
So how we can execute any of these tasks in the robot.

28:09.960 --> 28:12.000
So how we can use the movie Pi.

28:12.030 --> 28:17.550
So this API here in order to move the robot to a predefined location.
