Fortress And Humble Tutorial
Build an Arena
Introduction and explanation
What software are we using and why
All of these instructions have been tested using the current version of Ubuntu: Jammy Jellyfish.We are going to use two packages: Gazebo for the physics based Simulator and ROS (Robot Operating System) for the control system. There are many releases of each of these, and only some combinations are mutually compatible. Also, since we are focusing on a stable development platform, we will use the Long Term Support (LTS) versions that are current at the time we are posting this. As of 20Mar2024, this means we will use Gazebo Fortress (release 6) which is supported until 2025.
One quirk: the current LTS version of Gazebo only seems to work with the LTS version of Ubuntu
How will the demonstration proceed.We will go through 7 steps: 1) Install Gazebo Fortress and confirm that it is correct. 2) Examine an empty world 3) Build a simple robot and test it using keyboard controls. 4) Build a 'world' for our robot to explore. 5) Install ROS (and its components) and confirm the installation. 6) Add Lidar to the robot 7) Write control software in ROS to make the robot autonomous.
This post covers Step 4
One quirk: the current LTS version of Gazebo only seems to work with the LTS version of Ubuntu
How will the demonstration proceed.We will go through 7 steps: 1) Install Gazebo Fortress and confirm that it is correct. 2) Examine an empty world 3) Build a simple robot and test it using keyboard controls. 4) Build a 'world' for our robot to explore. 5) Install ROS (and its components) and confirm the installation. 6) Add Lidar to the robot 7) Write control software in ROS to make the robot autonomous.
This post covers Step 4
Build an Arena
NOTE: If you are familiar with the code elements needed to describe a world you can skip ahead to the next part
If you want to download the complete code to follow along it is here: Pong-World-3.sdf
We have come quite a way - we have a robot and we can simulate its motion. The world we have is pretty limited - just an infinite flat plane, so the main focus of this part of the tutorial will be to add some variety to the world.
But, out little robot is a bit limited, since it can only go straight ahead, forever. So let's add some additional controls.
Note: this is based on the excellent tutorial at:https://gazebosim.org/docs/fortress/building_robot
For our example, we will • add in additional robot controls, then • add some structures (walls mostly) to our world. Let's get started!
For our example, we will • add in additional robot controls, then • add some structures (walls mostly) to our world. Let's get started!
Additional Robot Controls
At the end of the last part of the tutorial we added in the ability to listen for keyboard input, and to translate the up arrow key into a motion command for the Differential Drive.
We will now add in four more controls: stop and turn clockwise (to the right), counter-clockwise (to the left), to back up, and to stop dead in the world. The code looks very much like the plugin we already wrote.
These can be put in just below the existing Moving Forward plugin
The stop section listens for an 'S' input, and then cancels all linear and rotational motion
The left arrow cancels any linear motion and rotates counter-clockwise
the right arrow cancels linear motion and rotates clockwise
and the down arrow cancels any rotation and moves backwards.
Testing motion control
So this would be a great time to save the file as pong-world-3.sdf and see how it works.
1) Remember to start the simulator with:
> ign gazebo pong-world-3.sdf
2) Go to the pull down menu (upper right corner three dots) and load the Key Publisher plugin
3) Press the run simulator button in the lower left (play arrow)
4) move the cursor into the world display and send commands.
Now you can control the robot, but the world is still a pretty boring place.
Let's liven it up!
Add some limits
Right now we have an infinite plane to travel on, which isn't very reaistic. So let's put in some limits.
We can replace the infinite plane with a finite plane by replacing:
This will give us a platform that is 20m by 20m. What is outside the platform?
Nothing, void, emptiness.
So what happens if the robot goes off the edge?
Let's find out.
Save you new SDF file and launchthe simulator, (remember to load the Key Publisher, and start the simulation as we did before, then send your robot on its way....
On its way to negative infinity.
You can shut down the sim and restart it to test out the control keys:
up arrow - move forward
right arrow - turn clockwise
down arrow - move backwards
left arrow - move counter-clockwise
s key - stop
If you want to use different keys, you can reprogram them by changing the key values in the appropriate section of the movement plugins
Tired of driving your robot off the Edge of the World yet?
Okay, let's add some new stuff to the world, like some walls.
To define a wall, we will need to follow the same steps as with any object: define the collision surfaces, the visual aspects and place the object in the world (both position and orientation. Since this is a fixed object, we will define it using the Link structure and add it to the model of the world:
Place this inside the <model> ... </model> tag below the ground plane link description we just edited, and save this as
pong-world-4.sdf
It starts with the standard <link> … </link> tags and we name the link ‘far_wall’The next thing we do is define the placement of the wall relative to the model. Whenever you place a link, you define the location of the center point of the link structure.
<pose relative_to='__model__'>10.25 0 1 0 0 0</pose>
The position is defined by six values: x, y, z positions, and three rotation angles rotation around x (roll), rotation around y (pitch), and rotation around z (yaw).So this says put the wall center point 10.25 meters away, on the y center line, and 1m up with no rotations.
If you look box definition our wall is 0.5m thick, 20 m long, and 2m high). Since we want the surface of the wall to be at 10m and the thickness of the wall is 0.5m, we need the center of the wall at 10.25m. We want it to be centered on the y zero line, so we leave the y value at 0.0 and we want the bottom of the wall to be on the ground, so the center point needs to be 1.0 meters above the surface of the plane.The size of the link will often affect the placement of the center point.We then define the visual characteristics:<visual name='visual'> <geometry> <box> <size>0.5 21.0 2.0</size> </box> </geometry> <!--let's add color to our link--> <material> <ambient>0.5 0.15 0.15 1</ambient> <diffuse>0.5 0.15 0.15 1</diffuse> <specular>0.5 0.15 0.15 1</specular> </material> </visual>
With a geometry of a box, colored kind of a brick red. A note on specifying colors in Gazebo: In many systems color is defined as an red green blue triplet using byte values in the range [0..255]. Gazebo wants the same triplet, but on a scale of [0.0 .. 1.0], go figure. It also adds term for transparency, ranging from 0.0 (clear as glass) to 1.0 (opaque as a brick). So, you have a quartet of values r,g,b,t.
The last part of the wall definition is the collision surface. In most cases, the collision surface is identical to the visual surface, as it is here:
<collision name='collision'> <geometry> <box> <size>0.5 21.0 2.0</size> </box> </geometry> </collision> Now when you fire up the simulator, you should see a dark red (brick colored) wall at the far end of the arena surface, like below. You can now do two things in your world: drive off the edge or slam into a wall. Okay, you can also slam into the wall at an angle, then scrape along the wall, and then end up precariously balanced on the edge. This is left as an exercise for the student :-) Also - if you expand the Entity Tree for the ground_plane, you should see the entry for the far_wall as in the right panel in the image.
<pose relative_to='__model__'>10.25 0 1 0 0 0</pose>
The position is defined by six values: x, y, z positions, and three rotation angles rotation around x (roll), rotation around y (pitch), and rotation around z (yaw).So this says put the wall center point 10.25 meters away, on the y center line, and 1m up with no rotations.
If you look box definition our wall is 0.5m thick, 20 m long, and 2m high). Since we want the surface of the wall to be at 10m and the thickness of the wall is 0.5m, we need the center of the wall at 10.25m. We want it to be centered on the y zero line, so we leave the y value at 0.0 and we want the bottom of the wall to be on the ground, so the center point needs to be 1.0 meters above the surface of the plane.The size of the link will often affect the placement of the center point.We then define the visual characteristics:<visual name='visual'> <geometry> <box> <size>0.5 21.0 2.0</size> </box> </geometry> <!--let's add color to our link--> <material> <ambient>0.5 0.15 0.15 1</ambient> <diffuse>0.5 0.15 0.15 1</diffuse> <specular>0.5 0.15 0.15 1</specular> </material> </visual>
With a geometry of a box, colored kind of a brick red. A note on specifying colors in Gazebo: In many systems color is defined as an red green blue triplet using byte values in the range [0..255]. Gazebo wants the same triplet, but on a scale of [0.0 .. 1.0], go figure. It also adds term for transparency, ranging from 0.0 (clear as glass) to 1.0 (opaque as a brick). So, you have a quartet of values r,g,b,t.
The last part of the wall definition is the collision surface. In most cases, the collision surface is identical to the visual surface, as it is here:
<collision name='collision'> <geometry> <box> <size>0.5 21.0 2.0</size> </box> </geometry> </collision> Now when you fire up the simulator, you should see a dark red (brick colored) wall at the far end of the arena surface, like below. You can now do two things in your world: drive off the edge or slam into a wall. Okay, you can also slam into the wall at an angle, then scrape along the wall, and then end up precariously balanced on the edge. This is left as an exercise for the student :-) Also - if you expand the Entity Tree for the ground_plane, you should see the entry for the far_wall as in the right panel in the image.
Enclose the arena
From this you should be able to add additional walls to define an area with 20m left to right and 20m front to back. You will need to either rotate the side walls by 90 degrees (actually 1.5708 radians) or define the shapes by altering the X and Y dimensions. In the table below, we leave the size the same, and change the rotation and extents of the walls.
Wall name | Rotated Pose | Wall Size |
far_wall | <pose>
10.25 0 1 0 0 0
</pose> | <size>
0.5 20.0 2.0
</size> |
right_wall | <pose>
0.0 -10.25 1 0 0 1.5708 </pose> | <size>
0.5 21.0 2.0
</size> |
near_wall | <pose>
-10.25 0 1 0 0 0
</pose> | <size>
0.5 21.0 2.0
</size> |
left_wall | <pose>
0.0 10.25 1 0 0 1.5708 </pose> | <size>
0.5 20.0 2.0
</size> |
Add the three new walls - each one as its own <link>,,,</link> section beneath the existing wall. The size information will need to go into the box specifications for both the collision surface and the visual characteristics for the wall. Notice that we change the size of the side walls to be 21.0m If we left it at 20.0m we would still have a sealed arena, but the corners would just touch along a single edge. By extending the wall length, we get a full overlap on the walls. You can see that by looking at the wall corners from above. It may help to change the color of the side walls to see it more clearly. switching the color to 0.15 0.5 0.15 1.0 gives the side walls a green tint.
Again, we strongly recommend bulding and testing each wall one at a time.
One approach is to simplay copy the existing wall, rename it and edit the pose and the boxes, rather than starting from scratch.
When you are done, you should have an arena that looks like this:
Practice your World-building skills
Now you can practice your skills.
Things you might chage:
1) Put gaps in the walls so that your robot can fall to its death - replace one wall with two smaller walls separated by a gap big enough for the robot to get through.
2) Put a hole in the floor - build the floor out of several boxes that leave a hole to fall through.
3) Add some additional walls as barriers
Extra credit:
4) build a ramp that lets the robot climb over a wall, or onto a driving surface on top of the walls
What we did
This has been a long one, but we got a lot done:
We have:
1) Added motion control to our robot so it can explore
2) Converted the infinite plane into an arena floor
3) Added walls to the arean model and explored positioning and orientation of links with-in a model
4) Looked at the behavior of the robot when it collides with a wall, or falls to its death
5) Looked at possible modification to the arena to make if more deadly, um I mean more interesting/
Next step - now that we have things in the world, lets add some sensors to our robot so it can 'see' the world. To help with that, we will start by installing the Robot Operating System ROS!
Next step - now that we have things in the world, lets add some sensors to our robot so it can 'see' the world. To help with that, we will start by installing the Robot Operating System ROS!
Previous Step | Current Step | Next Step |
Make an Arena |