WEBVTT

00:00.120 --> 00:06.240
With this lesson, we conclude the creation of the robots digital twin, which will be a fundamental

00:06.240 --> 00:12.000
component throughout the course to continue implementing and testing the remaining functionalities.

00:12.520 --> 00:19.160
In fact, you can also continue using it to test your own ideas and receive a fast feedback that will

00:19.160 --> 00:21.600
help you to accelerate the development.

00:22.240 --> 00:26.440
So back in Visual Studio Code, let's start by creating a new launch file.

00:26.680 --> 00:29.880
So still here within the Arduino board description package.

00:29.880 --> 00:37.480
Within the launch folder, let's create a new launch file called gazebo dot launch dot Pi.

00:37.520 --> 00:38.360
Perfect.

00:38.360 --> 00:39.520
And now as usual.

00:39.520 --> 00:51.440
So as we did also for the display.launch.py file, let's import from the launch package the launch description

00:51.440 --> 00:52.080
class.

00:52.080 --> 01:02.460
And actually the launch file will just contain one function that is the generate It launch description

01:02.460 --> 01:09.620
function, and this function will actually just return an object of type launch description and the

01:09.620 --> 01:10.740
constructor of this class.

01:10.740 --> 01:15.940
So the constructor of the launch description class will just take a list as input.

01:16.100 --> 01:20.220
And now we are going to fill this list here with all the actions.

01:20.220 --> 01:26.020
So with all the nodes that we want to execute with this launch file for the simulation of our robot

01:26.020 --> 01:32.220
in gazebo, we need to start the robot Estate publisher node, which, as we saw in one of the previous

01:32.220 --> 01:38.740
lessons, reads the Urdf model of the robot and publish the Urdf model into a topic.

01:38.740 --> 01:45.340
So into a Ros two topic that then we can use to visualize the robot interface, or also to simulate

01:45.340 --> 01:46.500
it in gazebo.

01:46.940 --> 01:52.780
So instead of rewriting all the instructions for the robot estate publisher node, we can just copy

01:52.780 --> 01:56.020
all of them from the display dot pi.

01:56.340 --> 01:59.000
So here we can copy the model argument.

01:59.000 --> 02:01.720
We can also copy the robot description.

02:01.720 --> 02:04.760
And also here the robot state publisher node.

02:04.960 --> 02:08.440
So let's copy the three of them and let's paste it here.

02:08.760 --> 02:11.720
So in the generate launch description perfect.

02:11.720 --> 02:18.880
We need to import all the missing classes so we can copy also the include statements.

02:20.800 --> 02:21.520
Perfect.

02:21.960 --> 02:25.360
And also as you can see here we are missing to declare this variable.

02:25.360 --> 02:28.280
So the Arduino bot description directory variable.

02:28.680 --> 02:31.760
And let's copy also this variable here.

02:32.440 --> 02:35.880
And let's paste it in our gazebo simulation.

02:35.880 --> 02:40.000
So perfect in our gazebo launch file in this case.

02:40.000 --> 02:47.240
So here when we launch the robot state publisher node, apart from setting the parameter robot description

02:47.240 --> 02:49.760
we can also set an additional parameter.

02:50.240 --> 02:58.070
So here after the robot description let's set the parameter called Use same time.

02:58.350 --> 03:01.990
And now let's set this parameter to true.

03:02.350 --> 03:07.870
And this is due to the fact that now we are starting the robot estate publisher node for the gazebo

03:07.870 --> 03:08.710
simulation.

03:08.710 --> 03:12.710
And so we want to set the user sim time argument to true.

03:12.870 --> 03:14.870
And this is a general parameter.

03:14.870 --> 03:18.950
So the user sim time that is available in any ros2 node.

03:18.990 --> 03:23.550
So basically when you create any ros2 node it will have automatically this parameter here.

03:23.550 --> 03:29.790
So the user sim time that will inform the node whether it is running on a simulation of the robot or

03:29.790 --> 03:33.110
whether the node is running on the real robot.

03:34.150 --> 03:34.790
Perfect.

03:34.990 --> 03:42.710
So after starting the Robot Estate Publisher node, we can also create and set a new environmental variable

03:42.710 --> 03:43.470
in Linux.

03:43.470 --> 03:50.750
So in ubuntu where we are running that will be used by gazebo in order to load and to simulate the Urdf

03:50.750 --> 03:52.750
model of our robot properly.

03:53.190 --> 04:00.170
So to set an environmental variable from a launch file, we can import from the launch actions package.

04:00.170 --> 04:05.050
So from this package here we can import the set environmental variable class.

04:05.210 --> 04:07.530
And now we can create a new instance of this class.

04:07.530 --> 04:09.570
For example let's do it here.

04:09.970 --> 04:12.410
And this is called gazebo.

04:12.410 --> 04:17.770
So let's call this variable gazebo resource path.

04:17.970 --> 04:21.530
And so this is an instance of the set environmental variable.

04:21.730 --> 04:27.650
And now here within the constructor of this class we need to indicate the name of the environmental

04:27.650 --> 04:29.290
variable that we want to set.

04:29.330 --> 04:36.010
And this is the gazebo same resource path.

04:36.170 --> 04:41.890
And basically with this environmental variable we want to communicate to the gazebo simulation where

04:42.010 --> 04:48.370
in the file system it should look for the Urdf model of our robot, and also for all the meshes that

04:48.370 --> 04:50.410
will be used for the simulation.

04:50.850 --> 04:56.190
So actually simply we can say that the value of this variable.

04:56.390 --> 04:57.710
So this is a list.

04:57.710 --> 05:05.550
And for the moment we just want to insert one single value that is the Arduino board description directory.

05:05.550 --> 05:10.790
And so actually we want to tell to gazebo that it has to look within this package here.

05:10.790 --> 05:16.510
So within the Arduino board description package in order to find the meshes of our robot and also the

05:16.550 --> 05:18.470
Urdf model of our robot.

05:18.750 --> 05:24.790
But instead of passing it like this, so instead of passing it as a plain directory, we need to convert

05:24.790 --> 05:26.350
it to a Python path.

05:26.830 --> 05:33.030
So let's import from the path library the path class.

05:33.030 --> 05:38.550
And so we can convert this one here into a Python path.

05:38.830 --> 05:39.590
Perfect.

05:39.590 --> 05:42.550
And to this Python path we can access to its parent.

05:44.270 --> 05:45.030
Perfect.

05:45.870 --> 05:53.210
And let's use the function resolve in order to access to the path of the parent of this directory here.

05:53.370 --> 06:00.010
And finally, let's simply convert all of these into the format that is just a string.

06:00.010 --> 06:05.130
So we are converting the parent of this directory here into a string.

06:05.130 --> 06:10.730
And we are setting this one as an environmental variable in our ubuntu system that then gazebo will

06:10.730 --> 06:11.210
read.

06:11.210 --> 06:13.410
So this one here will be read by gazebo.

06:13.650 --> 06:19.530
And it will be used in order to know the directory of the meshes and the urdf of our robot.

06:20.090 --> 06:22.530
So now we can finally also start gazebo.

06:22.770 --> 06:24.730
And to do so we are going to start.

06:24.730 --> 06:29.050
So we're going to execute another launch file from this launch file.

06:29.050 --> 06:33.690
So basically we're going to nest a launch file in order to do so.

06:33.810 --> 06:36.930
Still from the launch actions package.

06:36.930 --> 06:43.450
So from this one here we need to import another class that is the include launch description.

06:43.450 --> 06:48.910
And so we can use this class here to include a launch file within another launch file.

06:49.270 --> 06:54.910
So let's create here a new variable of this class that is called gazebo.

06:54.950 --> 06:59.230
So with this variable here we're going to start the gazebo simulation.

06:59.710 --> 07:03.070
And this is an instance of the include launch description.

07:03.430 --> 07:07.950
Now here we need to specify the type of the file that we want to launch.

07:08.070 --> 07:12.670
And also we have to specify the directory of the launch file that we want to start.

07:13.150 --> 07:17.390
The other launch file that we want to start is also a Python launch file.

07:17.950 --> 07:19.870
So let's import it.

07:20.990 --> 07:27.590
So from the launch and the launch description sources.

07:27.590 --> 07:33.590
So this one with the final s let's import the Python launch description source.

07:33.870 --> 07:38.310
And now we can use this class here within the include launch description.

07:38.310 --> 07:44.510
In order to declare that the other launch file that we want to execute is also a Python launch file.

07:44.550 --> 07:45.190
Perfect.

07:45.510 --> 07:51.180
And now we can finally insert the directory of these other Python launch file that we want to start.

07:51.180 --> 07:57.220
So again we can use the OS path join.

07:57.380 --> 08:03.140
And the launch file that we want to start is in the Ros gazebo simulation package.

08:03.140 --> 08:06.780
So one of the packages that we have installed at the beginning of the course.

08:07.180 --> 08:11.860
So let's access it with the Get package Share directory function.

08:12.140 --> 08:17.900
And we want to access to the directory of the Ros gazebo simulation package.

08:18.100 --> 08:24.740
And from this package from the launch folder we want to start the launch file that is called.

08:25.060 --> 08:26.460
So let's go here.

08:26.460 --> 08:37.220
So after the Os.path.join we want to start the launch file gazebo sim dot launch dot pi.

08:38.140 --> 08:43.900
And actually here we are missing to insert this one into a vector.

08:45.440 --> 08:45.960
perfect.

08:45.960 --> 08:49.320
So the input of the Python launch description sources class.

08:49.320 --> 08:51.480
So this one here has to be a vector.

08:51.800 --> 08:57.160
And so this one indicates the directory of the launch folder that is within this package here.

08:57.160 --> 09:04.160
And so from the launch folder of this package of the gazebo we want to execute the gazebo SIM.

09:04.200 --> 09:05.400
Don't launch don't pi.

09:05.760 --> 09:07.560
Now we can also configure this node.

09:07.560 --> 09:13.160
So we can configure this launch file with some launch arguments.

09:13.160 --> 09:19.520
And also in this case we need to set a list of launch arguments starting with the argument that is called

09:19.560 --> 09:21.200
gazebo args.

09:21.560 --> 09:24.400
So now we can set all the arguments.

09:24.400 --> 09:28.520
So all the gazebo arguments within a new vector.

09:28.520 --> 09:29.680
So within a new array.

09:30.160 --> 09:35.680
And now here we can insert another string with all the arguments that we want to set to get.

09:36.440 --> 09:37.880
And so we can use a space.

09:38.080 --> 09:41.400
And then we can add the flag minus v four.

09:41.680 --> 09:44.300
And this one indicates the verbosity level.

09:44.340 --> 09:49.700
And so by setting this 1 to 4, we are setting that we want to print the output of this node.

09:49.700 --> 09:56.940
So the output of gazebo in the terminal in order to see its output and eventually inspect any error.

09:57.380 --> 10:04.180
Then let's also use the flag minus r in order to inform that we want to start the simulation immediately.

10:04.340 --> 10:10.620
So as soon as we start the gazebo launch file, we want to start the simulation.

10:10.620 --> 10:13.420
And also we need to specify the name of the word.

10:13.540 --> 10:17.060
So the name of the simulated word in which we want to spawn.

10:17.060 --> 10:19.660
So in which we want to simulate our robot.

10:19.900 --> 10:25.940
And for the moment we are just fine by simulating it within an empty word.

10:25.940 --> 10:29.900
So within a word that has no elements, it has just a ground.

10:29.900 --> 10:31.540
So it has just the ground floor.

10:31.660 --> 10:38.820
And also it has a light source that we can use in order to visualize our robot with this.

10:38.820 --> 10:43.520
So with this instruction here we will start an empty gazebo simulation.

10:43.520 --> 10:49.920
So we will start an empty gazebo environment without any simulated object inside this world.

10:50.040 --> 10:55.280
So in fact, here, as you can see, we are just starting the empty gazebo world.

10:55.280 --> 10:57.720
So a world which has no element in it.

10:58.280 --> 11:02.200
And now, within this empty gazebo world, we want to start.

11:02.200 --> 11:08.640
So we want to simulate our robot using another node that is still available in this package here.

11:08.640 --> 11:11.120
So in the Ros gazebo SIM package.

11:11.880 --> 11:20.640
So we can create a new instance of the node class and let's call it gazebo spawn entity.

11:21.520 --> 11:23.600
And so this is an instance of the node class.

11:23.600 --> 11:28.320
And we want to use this instance in order to start from the package.

11:28.320 --> 11:31.840
That is again the Ros gazebo SIM package.

11:32.200 --> 11:39.460
So from this package here we want to start the executable that is called the create executable.

11:39.820 --> 11:42.420
And also we want to configure this executable.

11:42.460 --> 11:43.300
And so this one.

11:43.300 --> 11:49.500
So this executable here is the one that will spawn our robot model into the gazebo simulation.

11:49.940 --> 11:51.060
So let's configure it.

11:51.060 --> 11:56.900
And let's first set its output to be screen.

11:57.940 --> 12:00.500
So like this in order to visualize.

12:00.500 --> 12:02.620
So here there is a typo it's screen.

12:02.740 --> 12:06.700
In order to visualize the log messages for this node into the terminal.

12:06.980 --> 12:11.180
And then we need to configure it with some arguments.

12:11.620 --> 12:13.740
So this take a list of arguments.

12:14.060 --> 12:22.020
And here so we can start by configuring the flag topic which we can use in order to indicate the name

12:22.020 --> 12:25.620
of the topic where the Urdf model of our robot is being published.

12:25.900 --> 12:32.300
And actually this topic here is the robot description topic.

12:32.300 --> 12:39.800
And in fact so this note here the robot state publisher node which opens so which reads the Urdf model

12:39.800 --> 12:41.760
of our robot will publish it.

12:41.760 --> 12:45.440
So in the topic that is called the robot description topic.

12:45.440 --> 12:47.000
And so now this node here.

12:47.000 --> 12:52.960
So the create node can read the Urdf model of the robot directly from this topic here.

12:52.960 --> 12:55.880
So directly from the robot description topic.

12:56.320 --> 12:58.440
Also let's configure another argument.

12:58.440 --> 13:04.360
So let's use a comma and let's configure the argument that is called name.

13:04.560 --> 13:11.200
And here let's simply set the name of our robot which we have called just Arduino bot.

13:11.240 --> 13:12.000
Perfect.

13:12.000 --> 13:17.040
And so this node here then we will spawn this robot here.

13:17.040 --> 13:18.120
So this description.

13:18.120 --> 13:21.920
So this urdf within this gazebo and the environment.

13:22.440 --> 13:23.000
Perfect.

13:23.000 --> 13:30.360
So now we need to start just one last node that is the gazebo Ros2 bridge.

13:30.520 --> 13:35.430
So this is another instance of the node class and now this node.

13:35.430 --> 13:42.270
So we want to start from the package that is called Ros gazebo bridge.

13:42.710 --> 13:46.030
So from this package we want to start a node that is called.

13:46.070 --> 13:53.550
So the executable is called parameter bridge.

13:53.870 --> 13:54.790
And this node here.

13:54.790 --> 13:59.190
So we can use the parameter bridge node in order to remap.

13:59.190 --> 14:05.950
Namely in order to connect the gazebo messages that are transmitted in the gazebo simulation using the

14:05.990 --> 14:09.550
gazebo transport protocol into Ros two messages.

14:09.550 --> 14:11.630
So we want to create this remap.

14:11.630 --> 14:17.710
We want to create this connection so that other Ros two nodes and other Ros two applications can use.

14:17.710 --> 14:21.670
So can access all the messages that are generated in gazebo.

14:22.310 --> 14:28.590
So in order to do so, in order to define how to do this remap we need to set some arguments.

14:30.070 --> 14:31.950
So again this is a list.

14:32.150 --> 14:34.890
And in this list of arguments we need to specify.

14:34.930 --> 14:38.890
So here let's start by specifying the name of the topic.

14:39.250 --> 14:43.490
So the name of the Ross two topic in which we want to publish some messages.

14:44.330 --> 14:48.810
So let's say that we want to publish a new message in the topic called clock.

14:49.450 --> 14:56.650
And the type of the message that we want to publish is a Ross graph messages.

14:57.290 --> 15:01.330
And from the messages we want to publish a message of type clock.

15:01.650 --> 15:04.930
So here simply we are saying that in this topic here.

15:04.930 --> 15:09.930
So in this Ross two topic called clock, we are going to publish a message of this type.

15:10.210 --> 15:12.130
And actually now we want to specify.

15:12.370 --> 15:14.770
So which is the gazebo information.

15:14.770 --> 15:20.250
So which is the gazebo message that we want to remap into this Ross two message.

15:20.650 --> 15:23.010
So we can use a single parentheses.

15:23.010 --> 15:24.650
So a single squared parentheses.

15:24.890 --> 15:33.630
And here we can specify that the gazebo message that we want to remap is the gazebo Go messages and

15:33.630 --> 15:35.110
the message of type clock.

15:35.470 --> 15:36.110
Perfect.

15:36.310 --> 15:43.910
So with this note here we are converting a gazebo message of this type here that is created and generated

15:43.910 --> 15:45.390
in gazebo simulation.

15:45.390 --> 15:50.190
And we are converting this one into a message of this type here.

15:50.190 --> 15:55.630
So Ros graph messages clock that will be published in this Ros two topic here.

15:56.190 --> 16:02.230
Now with this we have declared all the instructions that we need in order to simulate our modeling gazebo.

16:02.230 --> 16:08.190
So all of these are all the declaration of the instructions that we need now in order to actually start

16:08.190 --> 16:08.990
using them.

16:08.990 --> 16:10.790
We need to declare them here.

16:10.790 --> 16:15.030
So we need to list them in the launch description class constructor.

16:15.030 --> 16:19.870
And so here let's start with the declaration of the model argument.

16:20.230 --> 16:27.390
Then we also have here this one here this environmental variable that is the gazebo resource path.

16:27.750 --> 16:31.650
Then after that we have also the robot estate publisher node.

16:32.850 --> 16:38.810
So the one that reads the Urdf model of our robot and publishes it in the robot description topic.

16:39.370 --> 16:42.490
Then also let's start the gazebo simulation.

16:42.490 --> 16:44.250
So the empty gazebo simulation.

16:44.490 --> 16:52.370
And then within this empty gazebo simulation, let's also spawn our robot using the gazebo spawn empty

16:52.410 --> 16:52.890
node.

16:52.930 --> 16:55.490
And finally, let's also start this node here.

16:55.890 --> 17:02.690
So the gazebo Ros two bridge, which is that will remap this topic here.

17:02.690 --> 17:07.850
So this message from the gazebo simulation to Ros2 a perfect.

17:08.170 --> 17:11.610
So with this one we can also save this launch file here.

17:11.610 --> 17:18.890
And we have completed the creation of this launch file that starts in the order the robot state publisher,

17:18.930 --> 17:20.770
then the empty gazebo simulation.

17:20.770 --> 17:22.170
Then it spawns.

17:22.370 --> 17:26.410
So this one here will spawn our robot in the empty gazebo simulation.

17:26.410 --> 17:31.110
And then we will expose some gazebo messages into Ros two topics.

17:31.630 --> 17:36.190
Now, as we have declared so as we have used some nodes.

17:36.190 --> 17:41.950
So here we can see the create node and also the parameter bridge node from these two packages.

17:41.950 --> 17:48.350
So from the Ros gazebo SIM package and from the Ros gazebo bridge package, we also need to declare

17:48.350 --> 17:51.110
them here in the package dot XML.

17:51.630 --> 17:59.710
So here we need to declare a new execution dependency from the Ros gazebo SIM package.

17:59.990 --> 18:07.310
And then also another execution dependency from the Ros gazebo bridge package.

18:07.550 --> 18:08.070
Perfect.

18:08.070 --> 18:11.710
And so also with this we have completed the package dot XML.

18:11.710 --> 18:15.510
So we have just introduced these two new dependencies.

18:15.510 --> 18:17.110
So we can save also this file.

18:17.110 --> 18:20.830
And finally we can see our launch file works.

18:20.870 --> 18:25.310
And now it starts the gazebo simulation and spawns our robot in it.

18:26.140 --> 18:29.020
So to do so, let's open a new terminal.

18:29.540 --> 18:34.340
Here, let's go to the workspace and let's build it in order to apply the changes.

18:34.580 --> 18:35.300
Here we go.

18:35.660 --> 18:41.220
And then in a new window of the terminal let's source the workspace and then let's launch.

18:41.420 --> 18:49.580
So with Ros2 launch we can start from the Arduino board description package.

18:49.660 --> 18:54.060
So we can start the node that is called gazebo dot launch dot pi.

18:54.220 --> 18:57.540
So we can start this launch file here that we have just created.

18:58.140 --> 18:59.540
So let's press enter.

18:59.860 --> 19:05.580
And as soon as we do so we can see that the simulation of our robot starts in gazebo.

19:05.740 --> 19:09.580
So we can see that automatically the gazebo window is started.

19:09.620 --> 19:14.220
We can also see that our robot is automatically spawned in the gazebo simulation.

19:14.220 --> 19:19.980
And also we can see that it is bending on itself because the control system is not yet started.

19:20.020 --> 19:25.400
And so here we can see that now our robot is perfectly visible in the gazebo simulation.

19:25.400 --> 19:27.680
So we can start using this tool.

19:27.680 --> 19:31.440
So this gazebo simulation in order to develop new applications.

19:31.480 --> 19:38.240
And so also in order to explore new projects and new ideas, and also to get an immediate feedback on

19:38.240 --> 19:39.480
the robot's behavior.

19:40.000 --> 19:48.160
Now, if in your case, as you can see here, you are having a quite small real time factor as I am,

19:48.760 --> 19:55.320
you can just change the physics of the gazebo world so you can click anywhere in the gazebo world,

19:55.560 --> 19:57.320
and then you can go to physics.

19:57.640 --> 20:00.560
So here and then you can increase the step size.

20:00.560 --> 20:07.520
For example from instead of using 0.001 we can just use 0.01.

20:07.520 --> 20:08.840
So let's press enter.

20:08.920 --> 20:10.760
And so this will increase the step size.

20:10.760 --> 20:15.640
And we can see that as we do so we are getting a real time factor that is much better.

20:15.640 --> 20:21.760
And so this will create a simulation that in general will be lighter and also faster to execute.
