• Home
  • Blog
  • Tutorials
  • About
  • Contact
303-725-5814

Harmonic And Jazzy Tutorial

Examining an empty world

Introduction and explanation

What software are we using and why

All of these instructions have been tested using the current version of Ubuntu: Nobel Numbat.We are going to use two packages: Gazebo for the physics based Simulator and ROS2 (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 28Aug2024, this means we will use Gazebo Harmonic which is supported until 2028.
How will the demonstration proceed.We will go through 7 steps: 1) Install Gazebo Harmonic 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 ROS2 (and its components) and confirm the installation. 6) Add Lidar to the robot 7) Write control software in ROS2 to make the robot autonomous.
This post covers Step 2
NOTE: if you are already familiar with the basic elements of an empty gazebo world specification, you can jump ahead to Building a Pong-Bot

Examining an Empty World

When talking about simulations there is really no such thing as an empty world. In Gazebo, there are two main components that need to be defined: the characteristics of the world and descriptions of the things in the world.The world definition contains the description of the underlying structure, things like the physics model to use, the manner in which collisions are calculated, and the gravity (or lack of gravity).The models describe the things in the world, the surface that objects rest on, the models of robots, and obstacles – in short anything that exists in the space. If this sound like a lot of work – you are right. But, there are a lot of helpful parts that are pre-built, so it can be easier than it sounds.Our long term goal is to build a simple simulation, a world with the physics we are used to, and a simple two-wheeled robot to wander around in an enclosed space. Since we don’t want the poor little robot to bump into things, we will give it a simple sensor to detect when it gets close to a wall, and turn away.Let’s start with the world. We will walk through the empty world file chunk by chunk and see what is needed to describe a world.

Housekeeping

If you haven't done so, use a text editor to open the pong-world-1.sdf file. If you don't have this file, you can create one by following the steps in the previous part of the tutorial

building an empty world

The world description is encoded as an xml file, so if your favorite editor provides syntax highlighting you can add <?xml version="1.0" ?> as the first line The SDF file begins with a tag set identifying the version of the sdf file<sdf version=’1.10’>…</sdf>This tells the simulator what to expect and which versions are compatible.The next layer of tags tell the simulator that you are opening a world: <sdf version=’1.10’> <world name=’empty’>… <!-- everything in the world --> </world></sdf>Now that we have taken care of the housekeeping, we can start defining the world.

Describing the physics

The next section of the file describes the simulation physics: how fast does the simulation run, how frequently does it recalculate,etc. These are defined inside the <physics> … </physics> tag set:
<physics name='1ms' type='ignored'> <max_step_size>0.001</max_step_size> <real_time_factor>1</real_time_factor> <real_time_update_rate>1000</real_time_update_rate> </physics>
Now that we have given the setup instructions to the simulator, we need to tell it what to do. This is done by adding specific plugins to the description. A plugin defines a dynamic component of the world, something that defines the behavior of objects in the world. The default world has 4 plugins:<plugin name='gz::sim::systems::Physics' filename='gz-sim-physics-system'/> <plugin name='gz::sim::systems::UserCommands' filename='gz-sim-user-commands-system'/> <plugin name='gz::sim::systems::SceneBroadcaster' filename='gz-sim-scene-broadcaster-system'/> <plugin name='gz::sim::systems::Contact' filename='gz-sim-contact-system'/>
• Physics Plugin: this is the actual physics of the world, • UserCommands Plugin: these allow you it interact with the world, • SceneBroadcaster Plugin: this converts the world into something that can be viewed and streams it, and • Contact Plugin: this plugin calculates collisions.
Next we add some world simulation characteristics like gravity, magnetic fields, and atmosphere. Finally, we put in some lighting characteristics for the entire scene. <gravity>0 0 -9.8000000000000007</gravity> <magnetic_field>5.5644999999999998e-06 2.2875799999999999e-05 -4.2388400000000002e-05</magnetic_field> <atmosphere type='adiabatic'/>Note: if you want to you can set the gravity to anything you want (Mars, Jupiter, Deep space?) and you can adjust the atmosphere and magnetic fields the same way.The final section here is the general scene characteristics. These don’t change the behavior, but they provide some light so that you can see what is going on: <scene> <ambient>0.4 0.4 0.4 1</ambient> <background>0.7 0.7 0.7 1</background> <shadows>true</shadows> </scene> NOTE: depending on your system, the numeric values may be rounded of not.Okay, so here is a quirk. At the bottom of the stock file generated from an empty world is another section on lighting, we will get to that later.

What's in a model

We are now going to describe the only thing in this empty world using a model:<model name=’ground_plane’> <static>true</static>… <!-- the description of the model> <pose>0 0 0 0 0 0</pose> <self_collide>false</self_collide></model>
Let’s look at these: • The model has a name, in this case ground_plane. • The described model is static – the simulator doesn’t need to spend cycle recalculating it every millisecond • The model is placed in a specific position in the world using a pose: ◦ The pose is defined as a six-tuple: ◦ The first three numbers are the position: the X, Y, and Z coordinates ◦ The second three numbers are the orientation: R (roll), P (pitch), and Y (yaw) • The model can’t bump into itself: self-collide=false. If this seems puzzling, think about things like a robot arm that can hit itself.

Parts of a model

So we have setup the big picture of a model, but we haven’t really defined what the model is.Our model is pretty simple, since it is just an infinite flat plane, but there is still a lot to define.In general, a model can consist of three basic components: • Links which represent physical component that makes up the model. In this case an infinite plane with a grid of hash lines in the middle. For a mobile robot one link might be the chassis, or a drive wheel. • Joints which describe how the links are connected to each other and how they can move relative to each other. • Plugins which describe how the model reacts to the world - how it behaves. Since this model only has one link (the ground plane) no Joints or Plugins are needed in the empty world, but don't worry in the next part of the tutorial we will cover both.

Describing the ground plane link

A link represents a physical object in the world, but to simulate it we need to define five things: • A name (so that other things in the world can refer to it). • Collision properties to tell the simulator the size and shape of the thing to be used to calculate collisions • Inertial properties to tell the simulator how to calculate what happens when forces are applied to the object • Visual properties to tell the simulator renderer how to show the object. • A pose (usually) to tell the system where it is relative to the models position.Let’s look at each of these:

Name:

<link name='link'>, well that is pretty simple, you might want to change the name to 'plane' or something.

Collision properties:

There are a number of things to define: • The name • The geometry (the shape and size) • The type of surface, including friction, elasticicy, and contact typeFor our ground-plane these look like: <collision name='collision'> <geometry> <plane> <normal>0 0 1</normal> <size>100 100</size> </plane> </geometry> <surface> <friction> <ode/> </friction> <bounce/> <contact/> </surface> </collision>

Inertial Properties:

These describe how the body acts under forces (what happens when you hit it with something)These describe • Pose: where the center of mass is • Mass: umm, the mass of the body • Inertia: the “cental inertial properties” essentially where the mass is distributed (maybe) <inertial> <pose>0 0 0 0 -0 0</pose> <mass>1</mass> <inertia> <ixx>1</ixx> <ixy>0</ixy> <ixz>0</ixz> <iyy>1</iyy> <iyz>0</iyz> <izz>1</izz> </inertia> </inertial>

Visual Properties:

The visual properties include: • A name • A geometry (should be the same as the collision) • Material (how it reacts to light (color, shininess, etc.) <visual name='visual'> <geometry> <plane> <normal>0 0 1</normal> <size>100 100</size> </plane> </geometry> <material> <ambient>0.8 0.8 0.8 1</ambient> <diffuse>0.8 0.8 0.8 1</diffuse> <specular>0.8 0.8 0.8 1</specular> </material> </visual>

Pose and miscellany

This link needs to exist in some place relative to the model, so we need to specify a pose. Remember this is an offset from the model's pose - not the position in the world. <pose>0 0 0 0 0 0</pose>
For some reason, the empty world also takes pains to define a wind setting: <enable_wind>false</enable_wind>
That closes out the <link> tag and we now have a model with one link in it, the ground-plane.

Lighting up the world

Of course, the simulator doesn't really care about light, it would work perfectly well in a dark room or a cave. But we'd like to see what is happening, so let's add the sun! To do this, we need to define: • Where it is, • Does it cast shadows (direct sunlight versus a cloudy day) • How bright is it, • What direction does it point • What color is it when diffused • What color is it direct • How fast does it fade out (how far will it shine) • How tight a beam is it (a tight spot or a general flood light) The empty world encodes the sun as: <light name='sun' type='directional'> <pose>0 0 10 0 0 0</pose> <cast_shadows>true</cast_shadows> <intensity>1</intensity> <direction>-0.5 0.1 -0.9</direction> <diffuse>0.8 0.8 0.8 1</diffuse> <specular>0.2 0.2 0.2 1</specular> <attenuation> <range>1000</range> <linear>0.01</linear> <constant>0.90000000000000002</constant> <quadratic>0.001</quadratic> </attenuation> <spot> <inner_angle>0</inner_angle> <outer_angle>0</outer_angle> <falloff>0</falloff> </spot> </light>

We are done examining the empty world

With this last addition: poof! you have created a world. We got a lot for free in this 'empty' world. We have: 1) defined the simulator parameters 2) told the sim to load 4 plugins for running the simulation 3) set up characteristics for gravity, atmosphere, light, and a magnetic field 4) defined a ground plane model, which required: a name, a collision surface, inertial characteristics, visual characteristics. a) we also learned that to place models we need a pose that defines both the linear (X,Y, and Z) and the orientation (Roll, Pitch, and Yaw) 5) defined a 'Link' - a physical body in the model, and specified its own collision, inertial, visual, and pose characteristics 6) finally, we added a light source to the world, so that we could see what was happening. It seems like a lot of things need to be defined to make a simulation work – this is the downside of a physics based model. See the discussion in Part 0 – To Sim or not to Sim.
Now that we have an idea of what is needed, let's make a simple robot in Part 3
Previous Step
Current Step
Next Step
Installing Gazebo Harmonic
Examine an Empty World
Building a Simple Robot
Copyright © 2021 - 2024 ReiFxSolutions.com. All Rights Reserved.

We use cookies to enable essential functionality on our website, and analyze website traffic. By clicking Accept you consent to our use of cookies. Read about how we use cookies.

Your Cookie Settings

We use cookies to enable essential functionality on our website, and analyze website traffic. Read about how we use cookies.

Cookie Categories
Essential

These cookies are strictly necessary to provide you with services available through our websites. You cannot refuse these cookies without impacting how our websites function. You can block or delete them by changing your browser settings, as described under the heading "Managing cookies" in the Privacy and Cookies Policy.

Analytics

These cookies collect information that is used in aggregate form to help us understand how our websites are being used or how effective our marketing campaigns are.