Welcome to the Robotics Simulation project.
It's time to sum up everything we've learned in this section.
Now, I hope you have a good memory because the robot we are creating in this project is the example
robot I used in my animations to help you understand what Ros is.
The robot had a rectangular base with four wheels and a rod which protruded upward to hold up a camera.
So in this project you are tasked with recreating this robot in a simulation so that you can drive it
around the virtual environment and look at images coming in from the camera.
Your final result should be a single launch file, which, when launched, will open up Ignition gazebo
with this robot model, which you can then control over Ros.
Let's break down this project.
In this project, you will be creating a world and model SDF files.
This model PSD file will contain everything needed to create the robot for this project, which is the
wheeled robot with a camera.
Remember that you can create the general model of the robot within Gazebo Classics Model Editor.
Now your file should be configured such that the camera is a sensor which can transmit an image stream
and that we are able to control the wheels of the robot so we can drive it around within the simulation.
Then of course, you should create a launch file which starts up the ignition simulation with your world
SDF file and then bridges the topics between ignition and Ros, too, so we can control the simulation
over Ros.
So essentially, when you run your launch file in terminal, you should see the simulation open up with
your world and robot model.
We then should be able to interact with it over ROS so we can create our ROS nodes or use tools like
RCT to easily control the robot and process the image data.
All right.
This project is going to take some time.
Simulations are complex and tedious, so don't get impatient with yourself if it feels like it's taken
a while.
Of course.
Be sure to leverage all the code we've created in the previous lectures as we've created all the functionality
needed for this project in chunks throughout this course.
And feel free to rewatch some of those lectures if you are feeling lost.
But with that, give this project a go.
All right.
How'd it go?
Hopefully it was exciting to create a robot, which you could interact with in your simulation, which
also sent back simulated data from the simulation as if it was a real robot.
I'm going to go ahead and show you my approach in this walkthrough.
So the first thing I need to do is create the robot model.
So I will do this in Gazebo Classics Model editor.
Once here I will create the chassis, which will be a cube that I will size to be x equals 1y0 point
5z0 .25 metres and I'll place it near the origin like so.
Then I'll go ahead and create my wheel.
Which I can then duplicate to include each side.
Now when I do my control for the wheels, rather than having two sets of driving wheels, I'm just going
to have the front wheels be the ones which drive around.
This means I should reduce the friction on the back wheels so that my robot can easily make turns.
So I can do that by going into the back wheels, link descriptions and the collision model and setting
mu one and mu two of the wheels 2.1.
Then I will make the rod which holds the camera.
Now I will make the box which goes on top of the rod that acts as the camera.
It is worth noting by default, the camera plugin.
I will be using faces towards the positive x axis, so I'll need to make sure the x axis of the cube
faces towards the front of my robot.
And now it's time for the joints.
I will join together my front wheels first and go from left to right and choose the Z joint access.
I could set the back wheels as fix since I lowered their friction and they will just be sliding on the
ground.
But I will leave them as resolute in case I want to change how I control this robot later in the future.
Now I will join the camera.
Rhod, to the base.
And last but not least, I'll need to join this camera box to the camera rod as a fixed joint.
With that out of the way, I can go ahead and save my model.
I'll go ahead and save it as project robot model and exit the model editor.
This will save the model in our home directory.
So in the model editor models folder and here we have the project robot model that we just created with
our corresponding model that SDF and config file.
So I'm just going to go ahead and open up another tab and throw this into our package models folder.
So now let's go ahead and continue editing this model within VTS code.
So here under models, I have my project robot model, so we'll open up the model SDF file for it.
And just a reminder that if you're getting this red text, you can instead set the HTML to XML syntax
and that will fix it accordingly.
For clarity sake, I'll rename link zero to chassis link, rename my wheels and joints so I know where
they are on my robot chassis as well as name my camera rod link and camera link.
So with the link renaming out of the way, I can go ahead and copy and configure the diff drive plugin
from our wheeled model model on file.
So here at the bottom of our model we had the diff drive plug in configuring our left and right wheel
joints.
So I'll just go ahead and copy that.
And we will place it near the end of our robot model.
And now I'll go ahead and rename these joints.
Yeah.
And for this case, I believe my wheel separation was 0.62 and my wheel radius was 0.25.
And I'll go ahead and configure the topic to just be command velocity by default.
Then I can go ahead and copy the camera plugin contents from our test world that we had done earlier.
So here we have these sensor tags configuring our camera.
So I'll just go ahead and copy this and place this within our camera link model.
Which is right here.
So I'll go ahead and plug this at the end of this link.
All right.
That should be good.
Let's go ahead and save this and create a world file for this simulation.
So I'll go ahead and call this simulation project World SDF.
And I'll take our wheeled model world from earlier in the section and paste the contents here.
And instead of including our wheeled model, we will be including our project robot model, which should
match the name of this particular folder within our model's directory and our robots.
A little bit shorter this time, so I'll set the post to 0.4 offset off the z axis.
All right, let's save this file and test to see what we have so far.
So go ahead and rebuild our workspace to include these new models.
All right.
Now I can go back to terminal and be sure to source my models directory.
Then I can go ahead and launch the ignition gazebo simulation with this project world.
All right.
So let's go ahead and open.
Then we can see our wheeled project model here on our blue ground plane, and then I can go ahead and
double check that features like our camera are working.
So go ahead and check the topics that are in ignition.
And again, if you ever needed more information about a topic, you can do again, topic, info, topic
and the name of the particular topic.
So in this case, my camera ignition topic has a message type of ignition dot messages dot image which
may be useful for us in a bit when we go to create our launch file.
So let's go ahead and make that so that we can run this simulation using a single launch file instead
of having to export our model environment and launch our simulation and any other nodes from scratch.
So I'll create a new launch file and I'll just call this simulation underscore project launch dot pie,
and we can just copy over our simulation launch file we made in the previous lecture.
With the only difference being we all need to change the path of our world file.
In this case, we're using this simulation project world that SDF.
And then scrolling down further, I had simplified the name of the topic.
In our project robot model to instead be just command velocity.
So if I scroll all the way down.
We see I changed the mapping to just be command.
Vell, instead of that model's wheeled model type of format.
So I actually don't need to do the remapping here.
Instead, I do have to change the arguments here, so the ignition topic name should now be just command
Vel.
And then we don't need to remap anything here.
So I'll just go ahead and delete those lines for now.
But I will have to map my camera as well.
So to do that, I'll simply add another entry to this list.
All right.
So again, this time we're taking the sensor messages image Ros message type, and we're bridging it
from the ignition messages, image message type, which we saw was the message type of our particular
camera topic here.
And actually I will include the remapping argument for right now.
And for this case, I'm actually going to remap the camera topic to match something more suitable towards
what you would see in Ross, which would generally be camera slash, image underscore, raw to know
that this should be the topic which the raw images are coming over.
And of course, if I wanted to, I could have instead change the topic name within our model PSD file
when we were working with our camera joint.
So I could have changed the topic name here, but I'll just keep this in for now so that we have an
example of remapping topics within this example launch file.
So I'll go ahead and save this and rebuild it so that this new launch file gets included.
All righty.
So now let's run the simulation using the launch file.
So I'll go ahead and clear some of these screens.
Now, of course, first we have to source our workspace.
And then run the simulation project launch file.
All right.
So this has gone ahead and started.
And now if I go into my second window and do Ross two topic list.
We will see our command velocity topic as well as the image raw camera stream coming out.
So of course if we wanted to interact with this, I could open up our.
And I'll keep this simulation window open here on the side.
And I will open a new plugin for the image view.
So here we can control the direction which our robot drives.
And here we can see a camera view of what our robot is driving here.
So I'll just add some things to our scene just to add a little bit of.
Context as to where we are.
And so now I can go ahead and drive around a bit and publish this by clicking the checkmark.
Well, it's a bit too slow.
And there we go.
We now see our robot is turning slowly.
Although notice this issue here where the robot chassis is spinning slowly, but our camera rod and
camera link are actually keeping about the same position.
So this is definitely a weird interaction that you probably weren't expecting, and this has to do with
our physics simulation engine.
So essentially this is a joint and we never really provided much friction elements for it or dampening.
So it's just freely spinning around here, assuming that there is no type of normal friction or static
connection like we might assume this robot might have.
So I do want to keep this joint as a joint.
I don't want to fix it and keep it static.
So if I head back over to my Visual Studio code, I'll actually just search for damping.
And here we see several of them pop up.
And if we scroll down, we should find.
Where our chassis connects to our camera rod link and I will just increase this dampening to something
say along of 0.6.
And of course you could set other dynamic settings such as the spring stiffness and you can even specify
your coefficients of friction within the link itself.
But this should do for now.
So if I go ahead and save this.
And we will close the simulation.
And so the changes should have automatically taken effect since we've used Simulink install.
So if I go ahead and rerun this.
We're still publishing our message.
So our robot begins spinning, but we see the camera head stays attached so I can put objects in my
environment again, and we can see them in our field of view as the robot travels around.
Oh, it does seem I made a mistake here in terms of which way is forward and which way is backwards.
So I'll go ahead and fix that as well.
So this most likely has to do with the fact that I switched the axis when I set my joints.
I was supposed to set it to negative Z.
But instead I had set it at positive Z.
So if we actually look at the Axis for this joint, it says 001.
And what I'm actually going to do here is set this to negative one for both the front left and front
right wheel joint.
So now if I go ahead and save this, we run our simulation.
And now we're actually driving forward, as we expect that I'm turning a little bit here because I still
have a Z attribute to our angular velocity.
But here we see that our simulation is working properly.
We have a world file which we built with our robot model that we created in Gazebo Classic and then
placed into our ignition gazebo simulation.
Now, I can actually take the simulation one step further.
So remember, I created a joint here between our chassis and camera rod because I would be ideal if
we could actually control this on our robot.
So if we had a motorized base and the camera could turn.
So let's take advantage of this joint using what's called the joint position controller.
Joint controller plug ins are great as general purpose use cases to control your joints.
Say if you had a motorized joint, we can get an example of this from the examples Ignition Gazebo provides.
Specifically the joint position controller SDF file.
You could check out this file in the simulation, but I think it will be easier just to show you how
this plugin works in the context of this project.
So I'm just going to head to the bottom of the file.
And here we see a plugin before the closing model tag.
The plugin takes in the joint, name a topic and then you can configure and put limits on a PID controller,
which is a common controller in robots and automated machines to change the signal, which sends motion
commands in a fluid controlled manner.
For now, I'm just going to copy and paste it into my robot model SDF file after my drive, plug in
and change the joint name, which in this case mines is camera rod joint.
And I'll just change the topic name to camera rod, position command.
And I'll just leave the PID values as is.
And let me just confirm that this is indeed the joint name camera, joint.
So let's go ahead back into our joints and check.
So here is where the chassis connects to the camera rod link.
So I will change this joint name to make more sense to camera rod joint.
All righty.
So that things match up.
So I'll go ahead and save this file.
And now we need to bridge this camera rod position command topic from ignition gazebo to Ros.
So I'll add it to my launch file.
If we actually go back to the joint position controller, SDF all the way at the top.
It has instructions for us, so it tells us what gazebo message type this plugin uses, which in this
case is double.
Now Ros does not have a double message type, but the equivalent is a float 64 message type from the
standard messages package.
So I'll just go ahead and copy this.
And then in our launch file, we'll add one more argument to our ignition bridge.
So this is the ignition topic name I specified here in our model that file camera, rod, position,
command, and then we're going to convert this over to standard messages.
Float 64 from the ignition messages, double message type.
With that, I can save these files and restart the simulation.
All right.
So that's gone ahead and opened as normal.
So I'll go ahead and place some objects again, just to add some variety.
And I will stop our robot from turning.
All right, so we're faced this way towards the sphere.
And now I can go ahead and refresh my topics.
Go down and let me expand this a little bit so we can see better.
And we are interested in this camera rod position topic.
Whoops, I made a typo here.
This should be camera position command.
Let's go ahead and save that.
Try this one more time.
All right.
So I've added those objects and now we can go camera rod, position, command.
And I'll go ahead and add that.
And we just have this simple data attribute.
So if I set that to a particular position in Radiance, so let's say I want to turn 90 degrees, that
would be about 1.57 radiance.
So if I publish this, we see the camera goes and turns towards this elliptical figure here.
And of course, we could change that to -1.57 radians and it'll turn.
He'll turn out 90 degrees from the normal.
So it turns around and we can see the ball.
And of course, you can have different degree measurements here.
So we can do about 45 degrees, which is about 0.78 radians.
And we see here our sphere next to our cylinder.
Now notice it kind of wobbles a bit back and forth whenever I change these values.
And that just has to do with your PID controller and how it's trying to do the dampening.
So you can always change the dampening in the joint as well as play with your ID values of your controller
to smooth that out if you want it to.
But with that we've successfully created a simulation of a robot which utilizes plug ins to command
our robot and receive simulated sensor data over ROS.
Well, hopefully you got similar results than I did and were able to successfully interact with your
robot and ignition gazebo using Ros.
So congratulations on applying what you've learned in this section.
Now, this was a relatively simple simulation and our robot clearly doesn't have much purpose in the
simulation or any other ROS nodes to give it a higher level of autonomy.
Well, believe it or not, we've been creating a lot of functionality throughout this course which could
be incorporated into this simulated robot.
We created a publisher to simulate a wheel encoder so we could calculate the robot's speed.
We created service requests to have the robot return a picture after turning its head by the requested
amount of degrees, and we even implemented in action server to take in to navigate to a point of interest.
Also, if you remember in the ROS Framework animation video, I also mentioned the wheeled robot had
an IMU and Jeep's sensor.
So how could implementing these sensors within simulation help you out with your navigation?
So as an extra credit and a potential project to show off to job recruiters, I encourage you to create
an entirely new ROS package which will contain all the files needed for a simulation environment similar
to the one we just created, but with additional sensors and ROS nodes to help add to the robot's autonomous
functionality.
You could send commands through RCT or implement your own terminal command line interface to have the
robot execute customizable routines.
If you decide to go down this route, I encourage you to check for ROS packages the community has developed,
which may help, such as the robot localization package for using sensor data to more accurately determine
where your robot is, as well as the navigation to set of ROS to packages for implementing complex path
planning features.
Now that you know how to create simulations, it's time for you to really start putting your robotics
problem solving skills to the test, leveraging what you've learned in this course and from the amazing
ROS community.
So try to challenge yourself and see just how complicated creating robust robotic software in realistic
scenarios can be.
Good luck.