OC Let's dive into robotics simulation.
The tool which we will use for this is called Ignition Gazebo.
For those of you who have used ROS1 or RA Foxy, you probably have utilized Gazebo before.
Well, it is in the process of rebranding and integrating with Ignition robotics.
Now, the interesting thing for you as a developer is the usage of this simulation with Ros.
Well, before we get to that, let's have a look at the ignition command line interface.
In order to install the simulator, We'll go ahead and open up a terminal and run the following command.
So here we are installing the Ross ignition package and this Ross distro flag will just resolve to humble.
So let's be Ross Dash humble dash Ross dash IG and here's the ignition gazebo package.
Go ahead and put in your password.
And for most of you, this will take about 5 minutes install.
So feel free to pause this video.
I have gone ahead and installed this beforehand so I can just continue on with the lecture.
But feel free to pause here while you wait for your installation.
You can find a common example tutorial showcasing ignition gazebo at the following page.
So here it has a test world which you can run called Visualize Light R, which will open up this little
world here with a small robot and a play structure environment.
So I'll go ahead and put this on the side.
So that we can copy the commands and paste them into terminal.
So this opens up the gazebo simulation.
I'll go ahead and full screen this and it opens it up just as we saw it in the tutorial page.
So you can use your middle mouse button to rotate around the screen.
You can use your left mouse button to pan and you can use the right mouse button to zoom in and out.
You can also use your scroll wheel to zoom in and out.
If you're using the virtual machine like VMware, there have been reported issues of the render not
properly displaying.
And one of the ways to fix this issue is to use an older version of the rendering engine like so.
So here we see a playground area with a robot that has a lighter on it.
For those of you who don't know, a lighter is a type of sensor which can detect range using near-infrared
light, usually returning a point cloud of nearby objects.
Now we'll get into how to make a simulation like this in a bit, but let's get a feel for it first.
The top right, we see information about visualizing the leader, which is specific to this example.
Usually you wouldn't see this by default.
In the middle section, we see information about the simulation world, so we can see different things
such as the physics and even magnetic fields associated with this simulation.
And below that we have our entity tree, which has the individual components which are within this simulation.
We can even open this dropdown.
And here in the right we can see how the simulation is performing in real time.
So depending on your computer specs and load, this number may fluctuate.
And lastly, in the lower left, we can pause the simulation and even select the step size of time,
which we want to go forward in.
Now, the interesting thing for you as a ROS developer is the usage of the simulation with Ros.
Well, before we get to that, we have to look at the ignition command line interface with the terminal
open again.
I'll open a new terminal tab.
Again, don't worry about all the messages you may see there.
These are just general messages when running the simulation.
But now in this terminal tab, I can do ignition topic L And here ignition is shorthanded as I g.
N.
All right.
And here we see a series of topics, just like as if we would, if we ran across two topic lists and
had these corresponding topics running on our Ross system.
However, none of these topics are actually connected to Ros, which we could check by running the raw
topic list command.
So here we see none of these corresponding topics are linked to Ros.
That's because any ignition topics we are interested in using in Ross, we need to bridge over which
we can do with the ignition bridge driver.
So let's go ahead and install it.
So if we actually go back to the tutorial page, we can actually scroll down.
And this actually talks about installing the Ross Ignition Bridge like we just mentioned.
And if I scroll down a little bit further.
Can go over to this section talking about visualizing light our data in ROS two.
So here you'll be using the Ros gazebo bridge ROS package, the perimeter bridge node, and then we're
going to be mapping the light sensor message from ignition to a laser scan object in ROS.
So again, if I do the ignition topic L command.
We can see this light hour to topic right here.
And here there are simply specifying the message type, which they are translating it to.
So we're translating it to a sensor message.
Laser scan topic.
And here we specify the ignition message type, which is being transferred from.
So just like Ros topic types, these ignition topics have their own message types, which we are now
bridging over to a topic called laser scan in ROS two.
So let's go ahead and copy this command and try it out for ourselves.
All right.
So let's go on ahead and started running.
And now if we run across two topic list, we can now see we have access to a laser scan topic, which
I can go ahead and echo if I wanted to.
Now notice nothing is being published to.
Well, that's because in the simulation background I paused it.
So if I go ahead and hit play and return back to my terminal, we get a sensor feed being outputted
to our messages.
So I'll go ahead and stop this.
Going back to the tutorial page, it talks a little bit about how you can set up your service instance
to visualize this laser scan information within the Aave's visualizer.
So go ahead and feel free to do that.
But we already talked a little bit about our views.
So for now, let's just go ahead and move on to some of the other features that Ignition Bridge has
to offer.
So for now, I'm going to go ahead and stop this bridge node from running.
Go and clear the screen.
And with that, we should see that our laser scan topic is no longer being published to.
And I can go ahead and stop this simulation from running simply by hitting control C in the terminal,
which it was running in.
And don't worry if it says Ubuntu has a problem.
Sometimes it says that when you close out of the simulation.
Now let's try a different example such as the camera sensor example.
So this might take a while.
As you can see, the download in the background, it's downloading some of the resources.
So if you have a slow internet connection, just keep that in mind that if your simulation takes a while
to install that, that may be the reason.
All right.
So here we see a bunch of random shapes.
So we see this little cone object.
Here we see this oops, we see this cube object, we see a sphere and we see a little black cube.
So this little black box represents a camera.
So we can use this camera window here in the right to view the camera topic from within the ignition
ecosystem.
So if I hit the refresh button, it'll refresh the available topics that I can subscribe to.
And here we see the cube and the cone and the ball, which are currently sitting within this simulation
we have here.
Or alternatively, we can use the parameter bridge to again view this in Ross.
So again, if I do ignition topic L.
We can see we have this camera topic being published, too.
So if we go back to our old parameter bridge command, all we have to do is change some of these parameters
a bit to match what we're looking for.
So instead of the light hour two topic, we are trying to bridge the camera topic and instead of the
laser scan message type from sensor messages, we are going to be changing this to a image message type.
And instead of this being a laser scan instance in ignition, it's called an image as well.
Then we're passing in some Ross arcs, which all we're doing is mapping the default topic name, which
in this case it will get transferred to the same type of topic name.
So camera.
And we can set it to something else which may match the Rasta ecosystem a bit better, which may be
something along the lines of camera slash image raw.
All right.
And now if I go ahead and do raw topic list.
We have our image raw instance and if I echo it.
We see the pixel information being displayed to the screen and of course we could do something like
our go to visualizations image view.
Can refresh the topics and select the camera image raw.
We see that same image feed we were seeing in the ignition ecosystem, but now we're able to utilize
it within Ross.
I'll go ahead and close this.
All right.
So that should give you a gist of the workflow and ROS integration of this ignition gazebo simulation.
You can find the PDF files that come with the ignition gazebo installation at the following location.
So here we see a series of PSD files with different examples that you can run.
For example, let's try and look at the camera sensor as a file we have here running in the background.
So here in VW's code, we can simply see that this PDF file follows an XML syntax to it, and it has
several things such as a world attribute, physics attributes and a series of plug ins.
Instances which we are rendering the 3D scene and more plugins.
And if we scroll down further.
We can see there are models such as this box model, which is that red cube we saw earlier.
We see a sphere model which has different geometry attributes to it.
And we see our camera model, which in this case has just a simple box geometry to it.
But it also has this sensor tag to it, which links to the sensor plugin, which gives it attributes
such as the width and height of the image as well as the frame rate and field of view and even the topic
name.
Now, one of the biggest issues I have with this new user interface with Ignition Gazebo is that it
does not have a built in model editor to help automatically generate these PSD files.
So this can be a pain when you have to generate your own PSD files and then continuously run it to see
what it looks like in the simulation.
So for now, let's try to create our own SDF world file to run in ignition gazebo.
So I'll go ahead and set up our package to hold the files we are going to be creating in folders called
Worlds and Models.
And if I go ahead and open up a new file Explorer window and take a look at this.
We can see we have these new world and models folders which are empty.
So within Vsco, I can create a new world file, which I'll just call Test World.
First thing I will do is set my language syntax in the bottom right to XML.
And if you ever want to, you can always set this as the default setting.
You can always configure the file association for SDA to always be XML and this way VTS code will remember
it.
Now there's actually some handy functionality in this code for HTML files, which look very similar
to XML in which it will auto close tags for us when we create them.
So for the time being I will configure SDF files to be treated as HTML.
You can always just do this manually for each file like so.
And now we see the icon has changed to simulate the HTML five logo.
And for now, I'll go ahead and set my tab size to two.
So first things first, I'm going to put in a Steph and world tag and I will set Steph version to 1.7
and call my World Test World.
One of the easiest ways to get up and running is to include existing models, which we can find on the
Ignition Models page.
So if you ever want to look into easily exportable models for your simulation, you can check them out
here.
For now, I will include a sun instance to light our scene and a ground plane from open robotics.
You can always search these up within the models instance here.
So if I search up sun, we see the one from open robotics here and we can see here, we can easily copy
the SDF snippet to our clipboard.
And include it in our world.
So here we've created our include tags and then specified a URI, which in this case is the location
of this particular model.
We'll go back to the instance and I will search for a ground plane.
And I will just choose this simple gray one from open robotics and we'll do the same exact thing.
With that, I can go ahead and save the file.
Go into our terminal and I'll stop the current simulation that's running and the parameter bridge.
Go ahead and make some extra space for now and we'll change into the directory where our world file
is located.
So here we can see our test world PSD file and we can run it just like we did with the other files with
Iron Gazebo and the name of the world, which is Test World SDF.
Oh, and I forgot to set the version to 1.7.
Let's go ahead and save that.
Let's try this again.
And there we go.
So here we see nothing special, just a blank world with a sun and ground plain object, which is this
gray square we see here.
Now, this doesn't really teach you much on how to make your own models.
So let's create a model within our world file.
Let's start with something simple, like making our own ground plane that we can customize.
So I'll go ahead and comment out the ground plane, include statement by hitting control and forward
slash, which will do this format for doing a multi line comment.
And let's go ahead and create our own ground plane, which we start off with a model tag.
The model will contain attributes and links.
For example, one attribute we will want to set is called static to True, which will fix this object
in the simulation so it doesn't move.
Now let's go ahead and create a link for our model.
Now, in order for our ground plane to be visible in our simulation, we will need to create visual
attributes within our link.
Then I need to give this a geometry attribute.
In which case I want this to be a plane so I can format it like so.
Now I need to pass in attributes for this form.
You will have different attributes depending on which geometry you chose.
But in the case of the plane, I need to specify a normal, which is the direction the top part of the
plane points.
So in our case, I want the plane to be flat on the XY plane and I will specify the Z section as one,
then specify the size attribute which takes in the length and width, and I'll just set it to 25 by
25 metres.
Great.
Now let's set a material attribute outside of the geometry tag, but still within the visual tag.
Then there are three attributes to specify which are ambient, diffuse and specular, which reference
different ways which light can interact or emit from our model.
Each of these can take in a red, green, blue and alpha value.
So to set it to blue and not be transparent, I will set the last two numbers to be one.
And we can copy this between the diffuse and specular attribute names.
So I'll simply alt click to get multiple cursors and I can change the name like so.
All right, that's it.
We created a new model called ground plane set static to true, so it doesn't move within the simulation.
And then we created a link which has a visual geometry of plane where we specify the size and material
properties.
Let's save this file and rerun the simulation in our terminal.
So go ahead and clear the screen and rerun it.
So notice this looks very similar, except now we have a blue plane since we've changed the color attributes
within our SDF file here.
And if you went ahead and clicked on this model.
We can select the visual attribute of this particular ground link, go down to material, and we can
see here it is specifying the colors that we specified within the code editor.
And if you wanted to, you could go ahead and change the colors.
I'll go ahead and see what it looks like when I change all of those different types of ways light can
bounce off to orange.
Now, there's something I want to show you in which I can add a cube to the simulation by clicking on
this box in the upper left corner and placing it down.
And I'll actually go ahead and click on it, translate it, and I'll put it slightly above.
And I'll put it slightly above our ground plane.
Now if I hit play to start the simulation, notice it falls straight through our ground plane and begins
falling down below so we can see it falling very far away.
Now, that's hardly useful for us, right?
So we see this plane here, but it's not actually interacting with any of our physical objects.
Let's go ahead and pause this for now so the cube stops falling.
So in order to prevent this, we have to create collision tags.
So let's go ahead and add that now.
So outside of the visual scope of our model, I will create our collision tags and call this a collision
ground.
Then within the tags I will copy the same geometry attributes I have in my visual model.
All right.
So it's just a plane with a size of 25 by 25 and the Z normal pointing upwards.
Now, the reason we have to repeat this is because you can have different visuals from your collision.
Sometimes people will create complex meshes to make their simulation models look highly realistic,
but want to keep the collision geometry simple so that the physics engine does not have to try to calculate
physics for complex shapes with different components and densities.
But with that done, let's save the file and go ahead and rerun our simulation.
All right, So we see our blue plane again.
Put our cube down.
Raise it up above our plane.
And this time if I hit play, it doesn't go falling through the plane like it did earlier.
It's also worth noting you can interact with attributes of the simulation itself, such as gravity.
So in this case I can set gravity to be positive 0.5 meters per second squared in the Z direction.
So saving that and restarting our world.
So now if I place the cube down, hit play, we see the cube begins to float above the plane upwards
because we made gravity positive.
In this instance, instead of the -9.8 meters per second squared we're used to in real life.
Now I'll go back to our code and comment that out so that our simulations don't behave like that in
the future.
But keep it here so that you know, you can interact with it if you need it.
Now, you can probably imagine that if we keep adding all these model tags and all their attributes
within our world file, that this file will begin to get really crowded and we may end up editing attributes
from the wrong model.
So let's go ahead and separate our model into a separate file so we can simply include it into our world
instead.
I can do this by creating a new folder in our models folder called Ground Plane.
Then within this new folder, create a file called Model SDF.
We'll start this file off with some SDF tag and then in between the tags we can paste in the contents
of our model from our test world.
So I'll go ahead and comment this out from our test world file and place them into our model that SDF
file that we created here in the ground plane folder.
With that done, we now have to create a model config file within that same folder.
So I'll click new file model config.
And I will configure this file as XML.
Oh, and be sure to set this to HTML.
Here we go.
Then I can add a model tag which will contain information about your model's name, version and PSD
file.
Now, the nice thing is by default, you should specify your model as model SDF here in the config file.
But thanks to this config file, you can rename it to something that makes more sense.
That way if you have multiple files open for different models in your code editor, you have a better
idea what each one is that you're editing.
So just to prove that this works, I can change this to say, ground plane, SDF or here, I'll do better,
I'll do my ground plane at SDF.
So don't get confused with the standard ground plane.
And then rename this model that PDF file here to match.
All right.
So here we're specifying the My Ground plan, that PDF file, and we've specified that name as such
right here.
Then last thing to include is information about the model author, as well as a brief description of
what this model is.
Now I can be sure that both these files are saved.
Go into my test file.
And I'll copy over.
This includes statement with the URI strings and the URI, we will instead be specifying will be in
the model's slash ground plane folder.
And just to make this a bit more clean, I'll go ahead and format it like so.
And just to prove that this is using our new ground plane PSD file instead of the one we created directly
within the world file earlier, I can actually go ahead and change up the colors a little bit, so I'll
change this to teal.
And so I'll save the my ground plane PSD file.
So again, this is being included here.
I'm not modifying any of the commented alt model that was here before.
And if I go back to our terminal, stop our test world from running, rerun it.
We see we now have this world with a total ground plane model associated with it.
And we see the source file path is my ground plane dot SDF.
Now, this is great, but keep in mind, the thing I use for the location model won't always work.
For example, if I went a directory back and then tried to rerun these simulation like so.
We get an error message saying unable to find Yuri.
That's because the path is relative to the current working directory, not the world file.
The way we can resolve this is by instead setting an environment variable to point to the resource path
for our simulation.
In this case it is our model's directory, which I can get by printing the current directory and then
setting the environment variable like so.
Then I can go into the PDF file.
And delete the folder name.
So I'll go ahead and save this.
Rerun our simulation.
And here now, even though we're in a different directory, the simulation loads just fine because it's
able to load in the resource path since we set the particular environment variable.
All right.
This is a good place to stop this lecture.
So far, we've learned some basics about the ignition gazebo simulator, as well as how we can create
PSD files for the simulator to process.
We created a simple ground plane model which we learned how to include within our SDA file so that we
can keep all the code related to our models separate from our world file.
We also ran through the intro tutorial of an example simulation of a robot on a playground that used
a LIDAR sensor, and so how Ignition Gazebo has its own ecosystem of commands and topics which we can
then bridge into ROS.
So in the next lecture we'll be taking a closer look at how we can implement sensors and plug ins into
our SDF files to make them much more useful for us as robotics developers.