gazebo_models:https://bitbucket.org/osrf/gazebo_models
模型庫下載,可以參考如下命令:
~/Rob_Soft/Gazebo7$ hg clone https://bitbucket.org/osrf/gazebo_models下載更改目錄下載到指定文件夾中。
模型庫的結構 目錄 配置等可以參考官方文檔,注意model.sdf。
當然也可以將自己制作的模型上傳到庫中,文檔中也有具體說明。
code$ hg clone https://[email protected]/yourname/gazebo_models gazebo_models$ hg add mymodel gazebo_models$ hg add mymodel/model.config gazebo_models$ hg add mymodel/model.sdf gazebo_models$ hg commit gazebo_models$ hg push
~/Rob_Soft/Gazebo7$ gedit box.sdf在其中輸入:
<?xml version='1.0'?> <sdf version="1.4"> <model name="my_model"> <pose>0 0 0.5 0 0 0</pose> <static>true</static> <link name="link"> <inertial> <mass>1.0</mass> <inertia> <!-- interias are tricky to compute --> <!-- http://answers.gazebosim.org/question/4372/the-inertia-matrix-explained/ --> <ixx>0.083</ixx> <!-- for a box: ixx = 0.083 * mass * (y*y + z*z) --> <ixy>0.0</ixy> <!-- for a box: ixy = 0 --> <ixz>0.0</ixz> <!-- for a box: ixz = 0 --> <iyy>0.083</iyy> <!-- for a box: iyy = 0.083 * mass * (x*x + z*z) --> <iyz>0.0</iyz> <!-- for a box: iyz = 0 --> <izz>0.083</izz> <!-- for a box: izz = 0.083 * mass * (x*x + y*y) --> </inertia> </inertial> <collision name="collision"> <geometry> <box> <size>1 1 1</size> </box> </geometry> </collision> <visual name="visual"> <geometry> <box> <size>1 1 1</size> </box> </geometry> </visual> </link> </model> </sdf>然後保存即可。
機器人模型
1 設置模型目錄
~/.gazebo/models$ mkdir -p ~/.gazebo/models/my_robot ~/.gazebo/models$ gedit ~/.gazebo/models/my_robot/model.config
<?xml version="1.0"?> <model> <name>My Robot</name> <version>1.0</version> <sdf version='1.4'>model.sdf</sdf> <author> <name>My Name</name> <email>[email protected]</email> </author> <description> My awesome robot. </description> </model>
~/.gazebo/models$ gedit ~/.gazebo/models/my_robot/model.sdf加入如下內容:
<?xml version='1.0'?> <sdf version='1.4'> <model name="my_robot"> <static>false</static> <link name='chassis'> <pose>0 0 .1 0 0 0</pose> <collision name='collision'> <geometry> <box> <size>.4 .2 .1</size> </box> </geometry> </collision> <visual name='visual'> <geometry> <box> <size>.4 .2 .1</size> </box> </geometry> </visual> <collision name='caster_collision'> <pose>-0.15 0 -0.05 0 0 0</pose> <geometry> <sphere> <radius>.05</radius> </sphere> </geometry> <surface> <friction> <ode> <mu>0</mu> <mu2>0</mu2> <slip1>1.0</slip1> <slip2>1.0</slip2> </ode> </friction> </surface> </collision> <visual name='caster_visual'> <pose>-0.15 0 -0.05 0 0 0</pose> <geometry> <sphere> <radius>.05</radius> </sphere> </geometry> </visual> </link> <link name="left_wheel"> <pose>0.1 0.13 0.1 0 1.5707 1.5707</pose> <collision name="collision"> <geometry> <cylinder> <radius>.1</radius> <length>.05</length> </cylinder> </geometry> </collision> <visual name="visual"> <geometry> <cylinder> <radius>.1</radius> <length>.05</length> </cylinder> </geometry> </visual> </link> <link name="right_wheel"> <pose>0.1 -0.13 0.1 0 1.5707 1.5707</pose> <collision name="collision"> <geometry> <cylinder> <radius>.1</radius> <length>.05</length> </cylinder> </geometry> </collision> <visual name="visual"> <geometry> <cylinder> <radius>.1</radius> <length>.05</length> </cylinder> </geometry> </visual> </link> <joint type="revolute" name="left_wheel_hinge"> <pose>0 0 -0.03 0 0 0</pose> <child>left_wheel</child> <parent>chassis</parent> <axis> <xyz>0 1 0</xyz> </axis> </joint> <joint type="revolute" name="right_wheel_hinge"> <pose>0 0 0.03 0 0 0</pose> <child>right_wheel</child> <parent>chassis</parent> <axis> <xyz>0 1 0</xyz> </axis> </joint> </model> </sdf>
這樣就構建了一個簡單的兩輪差動的移動機器人模型。使用Force工具,可以使其在仿真中運動。
~/.gazebo/models$ gedit ~/.gazebo/models/my_robot/model.sdf修改其中如下部分:
<visual name='visual'> <geometry> <mesh> <uri>model://pioneer2dx/meshes/chassis.dae</uri> <scale>0.9 0.5 0.5</scale> </mesh> </geometry> </visual>效果如下圖所示:
<include> <uri>model://hokuyo</uri> <pose>0.2 0 0.2 0 0 0</pose> </include> <joint name="hokuyo_joint" type="revolute"> <child>hokuyo::link</child> <parent>chassis</parent> <axis> <xyz>0 0 1</xyz> <limit> <upper>0</upper> <lower>0</lower> </limit> </axis> </joint>
Gazebo is able to dynamically load models into simulation either programmatically or through the GUI. Models exist on your computer, after they have been downloaded or created by you. This tutorial describes Gazebo's model directory structure, and the necessary files within a model directory.
Models in Gazebo define a physical entity with dynamic, kinematic, andvisual properties. In addition, a model may have one or more plugins, whichaffect the model's behavior. A model can represent anything from a simpleshape to a complex robot; even the ground is a model.
Gazebo relies on a database to store and maintain models available for usewithin simulation. The model database is a community-supported resource, soplease upload and maintain models that you create and use.
The model database is a bitbucket repository found here.
You can clone the repository using:
hg clone https://bitbucket.org/osrf/gazebo_models
A model database must abide by a specific directory and file structure. Theroot of a model database contains one directory for each model, and adatabase.config
file with information about the model database. Each modeldirectory also has a model.config
file that contains meta data about themodel. A model directory also contains the SDF for the model and any materials,meshes, and plugins.
The structure is as follows (in this example the database has only one model called model_1
):
textures
and scripts
subdirectories
This is an optional directory that contains all of the plugins for the model.
This is an optional directory that contains all of the COLLADA and/or STL files for the model.
This is an optional directory that contains all of the textures, images, and OGRE scripts for the model. Texture images must be placed in the textures
subdirectory, and OGRE script files in the scripts
directory.
This is the database.config
file in the root of the model database. This file contains license information for the models, a name for the database, and a list of all the valid models.
Note: The database.config
file is only required for online repositories. A directory full of models on your local computer does not need a database.config
file.
The format of this database.config
is:
<?xml version='1.0'?>
<database>
<name>name_of_this_database</name>
<license>Creative Commons Attribution 3.0 Unported</license>
<models>
<uri>file://model_directory</uri>
</models>
</database>
The name of the database. This is used by the GUI and other tools.
The license for the models within the database. We highly recommend theCreative Commons Attribution 3.0 Unported license.
A listing of all the model URIs within the database.
<uri>
The URI for a model, this should be file://model_directory_name
Each model must have a model.config
file in the model's root directory that contains meta information about the model.
The format of this model.config
is:
<?xml version="1.0"?>
<model>
<name>My Model Name</name>
<version>1.0</version>
<sdf version='1.5'>model.sdf</sdf>
<author>
<name>My name</name>
<email>[email protected]</email>
</author>
<description>
A description of the model
</description>
</model>
Name of the model.
Version of this model.
Note: This is not the version of sdf that the model uses. That informationis kept in the model.sdf
file.
The name of a SDF or URDF file that describes this model. The version
attribute indicates what SDF version the file uses, and is not required for URDFs. Multiple <sdf> elements may be used in order to support multiple SDF versions.
<author> required
Name of the model author.* <email> required
Email address of the author.
<description> required
Description of the model should include:
- What the model is (e.g., robot, table, cup)
- What the plugins do (functionality of the model)
All the dependencies for this model. This is typically other models.
<model> optional
<uri> required
URI of the model dependency.
<version> required
Version of the model.
Each model requires a model.sdf
file that contains the Simulator Description Format of the model. You can find more information on the SDF website.
Standard SDF file which can contain ruby code embedded. This option is used toprogramatically generate SDF files using Embedded Ruby codetemplates. Please note that the ruby conversion should be done manually (erbmodel.sdf.erb > model.sdf
) and the final model.sdf
file must be uploadedtogether with the model.sdf.erb
(this one only for reference).
Examples of sdf.erb
files are available in thegazebo_models repository(some of them use the deprecated suffix .rsdf
). An easy ERB file is theflocking.world.erbwhich uses a simple loop.
This tutorial assumes that you have an account on Bitbucket, and that you have a client for Mercurial.
Go to https://bitbucket.org/osrf/gazebo_models and, from the menu on the left hand side of the screen, choose "Fork". The default options are generally fine. After you have forked the repository, clone it. Assuming that you chose the default name for the repository, you will clone using commands similar to the following:
code$ hg clone https://[email protected]/yourname/gazebo_models
where yourname is your Bitbucket username.
Create a directory for your model under the gazebo_models directory. For this tutorial, we will assume that this directory is called mymodel. That directory must include the file model.config, and it may include other files as well (plugins, makefiles, README's, etc.)
The model.config file provides information necessary to pick the proper SDF file, information on authorship of the model, and a textual description of the model.
A sample model.config looks like this:
<?xml version="1.0"?>
<model>
<name>Wedge juggler</name>
<version>1.0</version>
<sdf version="1.5">model.sdf</sdf>
<author>
<name>Evan Drumwright</name>
<email>[email protected]</email>
</author>
<description>
A ball-in-wedge juggler.
</description>
</model>
This model.config file indicates that the simulator's definition of the model (i.e., visual, inertial, kinematic, and geometric properties, among others), is located in model.sdf, and follows SDF standard 1.5. It is possible to define multiple versions of your model, which may be useful if you intend for your model to be used with different versions of Gazebo. For example, we now change the contents of the file above, to support three different versions of SDF:
<?xml version="1.0"?>
<model>
<name>Wedge juggler</name>
<version>1.0</version>
<sdf version="1.5">model.sdf</sdf>
<sdf version="1.4">model-1.4.sdf</sdf>
<author>
<name>Evan Drumwright</name>
<email>[email protected]</email>
</author>
<description>
A ball-in-wedge juggler.
</description>
</model>
You can add all of your files to the repository by typing:
gazebo_models$ hg add mymodel
or, if you have some files that you do not wish to track, you can add files individually:
gazebo_models$ hg add mymodel/model.config
gazebo_models$ hg add mymodel/model.sdf
etc.
Commit and push your changes to Bitbucket:
gazebo_models$ hg commit
gazebo_models$ hg push
From your Bitbucket repository https://bitbucket.org/yourname/gazebo_models (assuming that your Bitbucket username is yourname and you used the defaults for the fork, this is where you would find the forked repository), create a pull request. Pick "Create pull request" from the menu on the left side of the web page. Make sure that "osrf/gazebo_models" is selected to the right of the arrow. When satisfied with your other options, click "Create pull request". OSRF will review your pull request and begin integrating your changes into the model database.
This tutorial describes the details of a SDF Model Object.
SDF Models can range from simple shapes to complex robots. It refers to the <model>
SDF tag, and is essentially a collection of links, joints, collision objects, visuals, and plugins. Generating a model file can be difficult depending on the complexity of the desired model. This page will offer some tips on how to build your models.
Links: A link contains the physical properties of one body of the model. This can be a wheel, or a link in a joint chain. Each link may contain many collision and visual elements. Try to reduce the number of links in your models in order to improve performance and stability. For example, a table model could consist of 5 links (4 for the legs and 1 for the top) connected via joints. However, this is overly complex, especially since the joints will never move. Instead, create the table with 1 link and 5 collision elements.
Collision: A collision element encapsulates a geometry that is used to collision checking. This can be a simple shape (which is preferred), or a triangle mesh (which consumes greater resources). A link may contain many collision elements.
Visual: A visual element is used to visualize parts of a link. A link may contain 0 or more visual elements.
Inertial: The inertial element describes the dynamic properties of the link, such as mass and rotational inertia matrix.
Sensor: A sensor collects data from the world for use in plugins. A link may contain 0 or more sensors.
Joints: A joint connects two links. A parent and child relationship is established along with other parameters such as axis of rotation, and joint limits.
Plugins: A plugin is a shared library created by a third party to control a model.
This step involves gathering all the necessary 3D mesh files that are required to build your model. Gazebo provides a set of simple shapes: box, sphere, and cylinder. If your model needs something more complex, then continue reading.
Meshes come from a number of places. Google's 3D warehouse is a good repository of 3D models. Alternatively, you may already have the necessary files. Finally, you can make your own meshes using a 3D modeler such as Blender or Sketchup.
Gazebo requires that mesh files be formatted as STL or Collada, with Collada being the preferred format.
Tip: Use your 3D modeling software to move each mesh so that it is centered on the origin. This will make placement of the model in Gazebo significantly easier.
Tip: Collada file formats allow you to attach materials to the meshes. Use this mechanism to improve the visual appearance of your meshes.
Tip: Keep meshes simple. This is especially true if you plan on using the mesh as a collision element. A common practice is to use a low polygon mesh for a collision element, and higher polygon mesh for the visual. An even better practice is to use one of the built-in shapes (box, sphere, cylinder) as the collision element.
Start by creating an extremely simple model file, or copy an existing model file. The key here is to start with something that you know works, or can debug very easily.
Here is a very rudimentary minimum box model file with just a unit sized box shape as a collision geometry and the same unit box visual with unit inertias:
Create the box.sdf
model file
gedit box.sdf
Copy the following contents into box.sdf:
<?xml version='1.0'?>
<sdf version="1.4">
<model name="my_model">
<pose>0 0 0.5 0 0 0</pose>
<static>true</static>
<link name="link">
<inertial>
<mass>1.0</mass>
<inertia> <!-- interias are tricky to compute -->
<!-- http://answers.gazebosim.org/question/4372/the-inertia-matrix-explained/ -->
<ixx>0.083</ixx> <!-- for a box: ixx = 0.083 * mass * (y*y + z*z) -->
<ixy>0.0</ixy> <!-- for a box: ixy = 0 -->
<ixz>0.0</ixz> <!-- for a box: ixz = 0 -->
<iyy>0.083</iyy> <!-- for a box: iyy = 0.083 * mass * (x*x + z*z) -->
<iyz>0.0</iyz> <!-- for a box: iyz = 0 -->
<izz>0.083</izz> <!-- for a box: izz = 0.083 * mass * (x*x + y*y) -->
</inertia>
</inertial>
<collision name="collision">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</collision>
<visual name="visual">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</visual>
</link>
</model>
</sdf>
Note that the origin of the Box-geometry is at the geometric center of the box, so in order to have the bottom of the box flush with the ground plane, an origin of <pose>0 0 0.5 0 0 0</pose>
is added to raise the box above the ground plane.
Tip: The above example sets the simple box model to be static, which makes the model immovable. This feature is useful during model creation. Once you are done creating your model, set the
<static>
tag to false if you want your model to be movable.
With a working .sdf
file, slowly start adding in more complexity. With each new addition, load the model using the graphical client to make sure your model is correct.
Here is a good order in which to add features:
The tutorial demonstrates Gazebo's basic model management, and exercises familiarity with basic model representation inside the model database by taking the user through the process of creating a two wheeled mobile robot that uses a differential drive mechanism for movement.
Read through the Model Database documentation. You will be creating your own model, which must follow the formatting rules for the Gazebo Model Database directory structure. Also, for details on model description formats, please refer to the SDF reference.
Create a model directory:
mkdir -p ~/.gazebo/models/my_robot
Create a model config file:
gedit ~/.gazebo/models/my_robot/model.config
Paste in the following contents:
<?xml version="1.0"?>
<model>
<name>My Robot</name>
<version>1.0</version>
<sdf version='1.4'>model.sdf</sdf>
<author>
<name>My Name</name>
<email>[email protected]</email>
</author>
<description>
My awesome robot.
</description>
</model>
Create a ~/.gazebo/models/my_robot/model.sdf
file.
gedit ~/.gazebo/models/my_robot/model.sdf
Paste in the following.
<?xml version='1.0'?>
<sdf version='1.4'>
<model name="my_robot">
</model>
</sdf>
At this point we have the basic contents for a model. The model.config
file describes the robot with some extra meta data. The model.sdf
file contains the necessary tags to instantiate a model named my_robot
using Gazebo linked against SDF version 1.4.
This step will create a rectangular base with two wheels.
It is important to start simple, and build up a model in steps. The first step is to layout the basic shapes of the model. To do this we will make our model static
, which means it will be ignored by the physics engine. As a result the model will stay in one place and allow us to properly align all the components.
Make the model static by adding a <static>true</static>
element to the ~/.gazebo/models/my_robot/model.sdf
file:
<?xml version='1.0'?> <sdf version='1.4'> <model name="my_robot">
<static>true</static>
</model> </sdf>
Add the rectangular base by editing the ~/.gazebo/models/my_robot/model.sdf
file:
<?xml version='1.0'?> <sdf version='1.4'> <model name="my_robot"> <static>true</static>
<link name='chassis'>
<pose>0 0 .1 0 0 0</pose>
<collision name='collision'>
<geometry>
<box>
<size>.4 .2 .1</size>
</box>
</geometry>
</collision>
<visual name='visual'>
<geometry>
<box>
<size>.4 .2 .1</size>
</box>
</geometry>
</visual>
</link>
</model> </sdf>
Here we have created a box
with a size of 0.4 x 0.2 x 0.1
meters. The collision
element specifies the shape used by the collision detection engine. The visual
element specifies the shape used by the rendering engine. For most use cases the collision
and visual
elements are the same. The most common use for different collision
and visual
elements is to have a simplified collision
element paired with a visual
element that uses a complex mesh. This will help improve performance.
Try out your model by running gazebo, and importing your model through theInsert Modelinterface on the GUI.
gazebo
You should see a white box floating .1 meters above the ground plane.
Now we can add a caster to the robot. The caster is a sphere with no friction. This kind of caster is better than adding a wheel with a joint since it places fewer constraints on the physics engine.
<?xml version='1.0'?> <sdf version='1.4'> <model name="my_robot"> <static>true</static> <link name='chassis'> <pose>0 0 .1 0 0 0</pose> <collision name='collision'> <geometry> <box> <size>.4 .2 .1</size> </box> </geometry> </collision> <visual name='visual'> <geometry> <box> <size>.4 .2 .1</size> </box> </geometry> </visual>
<collision name='caster_collision'>
<pose>-0.15 0 -0.05 0 0 0</pose>
<geometry>
<sphere>
<radius>.05</radius>
</sphere>
</geometry>
<surface>
<friction>
<ode>
<mu>0</mu>
<mu2>0</mu2>
<slip1>1.0</slip1>
<slip2>1.0</slip2>
</ode>
</friction>
</surface>
</collision>
<visual name='caster_visual'>
<pose>-0.15 0 -0.05 0 0 0</pose>
<geometry>
<sphere>
<radius>.05</radius>
</sphere>
</geometry>
</visual>
</link> </model> </sdf>
Try out your model to make sure the caster appears at the end of the robot. Spawn it in gazebo to see (you don't need to restart Gazebo; it will reload your modified model from disk each time you insert it):
Now let's add a left wheel. Modify the ~/.gazebo/models/my_robot/model.sdf
file to be the following:
<?xml version='1.0'?> <sdf version='1.4'> <model name="my_robot"> <static>true</static> <link name='chassis'> <pose>0 0 .1 0 0 0</pose> <collision name='collision'> <geometry> <box> <size>.4 .2 .1</size> </box> </geometry> </collision> <visual name='visual'> <geometry> <box> <size>.4 .2 .1</size> </box> </geometry> </visual> <collision name='caster_collision'> <pose>-0.15 0 -0.05 0 0 0</pose> <geometry> <sphere> <radius>.05</radius> </sphere> </geometry> <surface> <friction> <ode> <mu>0</mu> <mu2>0</mu2> <slip1>1.0</slip1> <slip2>1.0</slip2> </ode> </friction> </surface> </collision> <visual name='caster_visual'> <pose>-0.15 0 -0.05 0 0 0</pose> <geometry> <sphere> <radius>.05</radius> </sphere> </geometry> </visual> </link>
<link name="left_wheel">
<pose>0.1 0.13 0.1 0 1.5707 1.5707</pose>
<collision name="collision">
<geometry>
<cylinder>
<radius>.1</radius>
<length>.05</length>
</cylinder>
</geometry>
</collision>
<visual name="visual">
<geometry>
<cylinder>
<radius>.1</radius>
<length>.05</length>
</cylinder>
</geometry>
</visual>
</link>
</model> </sdf>
Run Gazebo, insert your robot model and make sure the wheel has appeared and is in the correct location.
We can make a right wheel by copying the left wheel, and adjusting the wheel link's pose:
<?xml version='1.0'?> <sdf version='1.4'> <model name="my_robot"> <static>true</static> <link name='chassis'> <pose>0 0 .1 0 0 0</pose> <collision name='collision'> <geometry> <box> <size>.4 .2 .1</size> </box> </geometry> </collision> <visual name='visual'> <geometry> <box> <size>.4 .2 .1</size> </box> </geometry> </visual> <collision name='caster_collision'> <pose>-0.15 0 -0.05 0 0 0</pose> <geometry> <sphere> <radius>.05</radius> </sphere> </geometry> <surface> <friction> <ode> <mu>0</mu> <mu2>0</mu2> <slip1>1.0</slip1> <slip2>1.0</slip2> </ode> </friction> </surface> </collision> <visual name='caster_visual'> <pose>-0.15 0 -0.05 0 0 0</pose> <geometry> <sphere> <radius>.05</radius> </sphere> </geometry> </visual> </link> <link name="left_wheel"> <pose>0.1 0.13 0.1 0 1.5707 1.5707</pose> <collision name="collision"> <geometry> <cylinder> <radius>.1</radius> <length>.05</length> </cylinder> </geometry> </collision> <visual name="visual"> <geometry> <cylinder> <radius>.1</radius> <length>.05</length> </cylinder> </geometry> </visual> </link>
<link name="right_wheel">
<pose>0.1 -0.13 0.1 0 1.5707 1.5707</pose>
<collision name="collision">
<geometry>
<cylinder>
<radius>.1</radius>
<length>.05</length>
</cylinder>
</geometry>
</collision>
<visual name="visual">
<geometry>
<cylinder>
<radius>.1</radius>
<length>.05</length>
</cylinder>
</geometry>
</visual>
</link>
</model> </sdf>
At this point the robot should have a chassis with a caster and two wheels.
Make the model dynamic by setting <static>
to false, and add two hinge joints for the left and right wheels.
<?xml version='1.0'?> <sdf version='1.4'> <model name="my_robot">
<static>false</static>
<link name='chassis'> <pose>0 0 .1 0 0 0</pose> <collision name='collision'> <geometry> <box> <size>.4 .2 .1</size> </box> </geometry> </collision> <visual name='visual'> <geometry> <box> <size>.4 .2 .1</size> </box> </geometry> </visual> <collision name='caster_collision'> <pose>-0.15 0 -0.05 0 0 0</pose> <geometry> <sphere> <radius>.05</radius> </sphere> </geometry> <surface> <friction> <ode> <mu>0</mu> <mu2>0</mu2> <slip1>1.0</slip1> <slip2>1.0</slip2> </ode> </friction> </surface> </collision> <visual name='caster_visual'> <pose>-0.15 0 -0.05 0 0 0</pose> <geometry> <sphere> <radius>.05</radius> </sphere> </geometry> </visual> </link> <link name="left_wheel"> <pose>0.1 0.13 0.1 0 1.5707 1.5707</pose> <collision name="collision"> <geometry> <cylinder> <radius>.1</radius> <length>.05</length> </cylinder> </geometry> </collision> <visual name="visual"> <geometry> <cylinder> <radius>.1</radius> <length>.05</length> </cylinder> </geometry> </visual> </link> <link name="right_wheel"> <pose>0.1 -0.13 0.1 0 1.5707 1.5707</pose> <collision name="collision"> <geometry> <cylinder> <radius>.1</radius> <length>.05</length> </cylinder> </geometry> </collision> <visual name="visual"> <geometry> <cylinder> <radius>.1</radius> <length>.05</length> </cylinder> </geometry> </visual> </link>
<joint type="revolute" name="left_wheel_hinge">
<pose>0 0 -0.03 0 0 0</pose>
<child>left_wheel</child>
<parent>chassis</parent>
<axis>
<xyz>0 1 0</xyz>
</axis>
</joint>
<joint type="revolute" name="right_wheel_hinge">
<pose>0 0 0.03 0 0 0</pose>
<child>right_wheel</child>
<parent>chassis</parent>
<axis>
<xyz>0 1 0</xyz>
</axis>
</joint>
</model> </sdf>
The two joints rotate about the y axis <xyz>0 1 0</xyz>
, and connect each wheel to the chassis.
Start gazebo, and insert your model. Click on the three white rectangles to the right of the screen and drag them to the left.
A new window should appear that contains various controllers for each joint. (Note Make sure the model you want to control is selected)
Under the Force
tab, increase the force applied to each joint to about 0.1N-m. The robot should move around:
Congrats, you now have a basic mobile robot.
Be creative and make a new robot.
Idea: A quadruped that consists of torso with four cylindrical legs. Each leg is attached to the torso with a revolute joint.
Idea: A six wheeled vehicle with a scoop front loading mechanism.
Next: Attach Meshes
Prerequisites: Make a mobile robot
Meshes can add realism to a model both visually and for sensors. This tutorial demonstrates how the user can use custom meshes to define how their model will appear in simulation.
The most common use case for a mesh is to create a realistic looking visual.
Navigate to the my_robot
directory
cd ~/.gazebo/models/my_robot
Open the model.sdf
file using your favorite editor
gedit ~/.gazebo/models/my_robot/model.sdf
We'll add a mesh to the chassis visual. Find the visual with name=visual
, which looks like:
<visual name='visual'>
<geometry>
<box>
<size>.4 .2 .1</size>
</box>
</geometry>
</visual>
A mesh can come a file on disk, or from another model. In this example we'll use a mesh from the pioneer2dx model. Change the visual element to the following (but keep the the rest of the file intact):
<visual name='visual'>
<geometry>
<mesh>
<uri>model://pioneer2dx/meshes/chassis.dae</uri>
</mesh>
</geometry>
</visual>
Look in your locally cached model database to see if you have the pioneer2dx
model referenced by above <mesh>
block:
ls -l ~/.gazebo/models/pioneer2dx/meshes/chassis.dae
If the mesh file does not exist, make Gazebo pull the model from the Model Database by spawning the Pioneer 2DX
model at least once in gazebo (under Insert->http://gazebosim.org/models
).
Or manually download the model files to your local cache:
cd ~/.gazebo/models
wget -q -R *index.html*,*.tar.gz --no-parent -r -x -nH http://models.gazebosim.org/pioneer2dx/
In Gazebo, drag the My Robot
model in the world. The visual for the chassis will look like a pioneer2dx.
The chassis is obviously too big for our robot, so we need to scale the visual.
Modify the visual to have a scaling factor.
<visual name='visual'> <geometry> <mesh> <uri>model://pioneer2dx/meshes/chassis.dae</uri>
<scale>0.9 0.5 0.5</scale>
</mesh> </geometry> </visual>
The visual is also a little too low (along the z-axis). Let's raise it up a little by specifying a pose for the visual:
<visual name='visual'>
<pose>0 0 0.05 0 0 0</pose>
<geometry> <mesh> <uri>model://pioneer2dx/meshes/chassis.dae</uri> <scale>0.9 0.5 0.5</scale> </mesh> </geometry> </visual>
Note that at this point we have simply modified the <visual>
elements of the robot, so the robot will look like a scaled down version of the Pioneer 2DX model through the GUI and to GPU based sensors such as camera, depth camera and GPU Lasers. Since we did not modify the <collision>
elements in this model, the box geometry will still be used by the physics engine for collision dynamics and by CPU based ray sensors.
When creating a new robot, you'll likely want to use your own mesh file. The import a mesh tutorial describes how to go about importing a mesh into a format suitable for Gazebo.
Find and download a new mesh on 3D Warehouse. Make sure the mesh is in the Collada (.dae) format.
Put the mesh in the ~/.gazebo/models/my_robot/meshes
, creating the meshes
subdirectory if necessary
Use your new mesh on the robot, either as a replacement for the chassis, or as an additional <visual>
.
Note: Materials (texture files such with extension like .png or .jpg), should be placed in ~/.gazebo/models/my_robot/materials/textures
.
Next: Add a Sensor to a Robot
Prerequisites: Attach a Mesh as Visual
This tutorials demonstrates how the user can create composite models directlyfrom other models in theGazebo Model Databaseby using the<include>tags and<joint>to connect different components of a composite model.
Adding a laser to a robot, or any model, is simply a matter of including the sensor in the model.
Go into your model directory from the previous tutorial:
cd ~/.gazebo/models/my_robot
Open model.sdf
in your favorite editor.
Add the following lines directly before the </model>
tag near the end of the file.
<include>
<uri>model://hokuyo</uri>
<pose>0.2 0 0.2 0 0 0</pose>
</include>
<joint name="hokuyo_joint" type="revolute">
<child>hokuyo::link</child>
<parent>chassis</parent>
<axis>
<xyz>0 0 1</xyz>
<limit>
<upper>0</upper>
<lower>0</lower>
</limit>
</axis>
</joint>
The <include>
block tells Gazebo to find a model, and insert it at agiven <pose>
relative to the parent model. In this case we place thehokuyo laser forward and above the robot. The <uri>
block tells gazebowhere to find the model inside its model database (note, you can see alisting of the model database uri used by these tutorialshere, and at the corresponding mercurialrepository).
The new <joint>
connects the inserted hokuyo laser onto the chassis of the robot. The joint has and <upper>
and <lower>
limit of zero to prevent it from moving.
The <child>
name in the joint is derived from the hokuyo model's SDF, which begins with:
<?xml version="1.0" ?> <sdf version="1.4"> <model name="hokuyo"> <link name="link">
When the hokuyo model is inserted, the hokuyo's links are namespaced with their model name. In this case the model name is hokuyo
, so each link in the hokuyo model is prefaced with hokuyo::
.
Now start gazebo, and add the robot to the simulation using the Insert tab on the GUI. You should see the robot with a laser attached.
(Optional) Try adding a camera to the robot. The camera's model URI is model://camera
, it should have been locally caches for you in:
ls ~/.gazebo/models/camera/
For reference, the SDF documentation can be found here.
Next: Make a Simple Gripper
This tutorial describes how to make a simple two-bar pinching gripper byediting SDF files.
For editing models graphically, see theModel Editortutorial.
Reference Model Database documentation and SDF documentation for this tutorial.
Create a directory for the world file.
mkdir ~/simple_gripper_tutorial; cd ~/simple_gripper_tutorial
We will begin with a simple empty world. Create a world file:
gedit ~/simple_gripper_tutorial/gripper.world
Copy the following SDF into gripper.world:
<?xml version="1.0"?>
<sdf version="1.4">
<world name="default">
<!-- A ground plane -->
<include>
<uri>model://ground_plane</uri>
</include>
<!-- A global light source -->
<include>
<uri>model://sun</uri>
</include>
<include>
<uri>model://my_gripper</uri>
</include>
</world>
</sdf>
Create a model directory inside ~/.gazebo. This is where we'll put the model files:
mkdir -p ~/.gazebo/models/my_gripper
cd ~/.gazebo/models/my_gripper
Let's layout the basic structure of our gripper. The easiest way to accomplish this is to make a static
model and add in the links one at a time. A static model means the links will not move when the simulator starts. This will allow you to start the simulator, and visually inspect the link placement before adding joints.
Create a model.config file:
gedit model.config
And copy the following contents:
<?xml version="1.0"?>
<model>
<name>My Gripper</name>
<version>1.0</version>
<sdf version='1.4'>simple_gripper.sdf</sdf>
<author>
<name>My Name</name>
<email>[email protected]</email>
</author>
<description>
My awesome robot.
</description>
</model>
Likewise, create asimple_gripper.sdffile:
gedit simple_gripper.sdf
And copy the following code into it:
<?xml version="1.0"?>
<sdf version="1.4">
<model name="simple_gripper">
<link name="riser">
<pose>-0.15 0.0 0.5 0 0 0</pose>
<inertial>
<pose>0 0 -0.5 0 0 0</pose>
<inertia>
<ixx>0.01</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.01</iyy>
<iyz>0</iyz>
<izz>0.01</izz>
</inertia>
<mass>10.0</mass>
</inertial>
<collision name="collision">
<geometry>
<box>
<size>0.2 0.2 1.0</size>
</box>
</geometry>
</collision>
<visual name="visual">
<geometry>
<box>
<size>0.2 0.2 1.0</size>
</box>
</geometry>
<material>
<script>Gazebo/Purple</script>
</material>
</visual>
</link>
<link name="palm">
<pose>0.0 0.0 0.05 0 0 0</pose>
<inertial>
<inertia>
<ixx>0.01</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.01</iyy>
<iyz>0</iyz>
<izz>0.01</izz>
</inertia>
<mass>0.5</mass>
</inertial>
<collision name="collision">
<geometry>
<box>
<size>0.1 0.2 0.1</size>
</box>
</geometry>
</collision>
<visual name="visual">
<geometry>
<box>
<size>0.1 0.2 0.1</size>
</box>
</geometry>
<material>
<script>Gazebo/Red</script>
</material>
</visual>
</link>
<link name="left_finger">
<pose>0.1 0.2 0.05 0 0 -0.78539</pose>
<inertial>
<inertia>
<ixx>0.01</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.01</iyy>
<iyz>0</iyz>
<izz>0.01</izz>
</inertia>
<mass>0.1</mass>
</inertial>
<collision name="collision">
<geometry>
<box>
<size>0.1 0.3 0.1</size>
</box>
</geometry>
</collision>
<visual name="visual">
<geometry>
<box>
<size>0.1 0.3 0.1</size>
</box>
</geometry>
<material>
<script>Gazebo/Blue</script>
</material>
</visual>
</link>
<link name="left_finger_tip">
<pose>0.336 0.3 0.05 0 0 1.5707</pose>
<inertial>
<inertia>
<ixx>0.01</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.01</iyy>
<iyz>0</iyz>
<izz>0.01</izz>
</inertia>
<mass>0.1</mass>
</inertial>
<collision name="collision">
<geometry>
<box>
<size>0.1 0.2 0.1</size>
</box>
</geometry>
</collision>
<visual name="visual">
<geometry>
<box>
<size>0.1 0.2 0.1</size>
</box>
</geometry>
<material>
<script>Gazebo/Blue</script>
</material>
</visual>
</link>
<link name="right_finger">
<pose>0.1 -0.2 0.05 0 0 .78539</pose>
<inertial>
<inertia>
<ixx>0.01</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.01</iyy>
<iyz>0</iyz>
<izz>0.01</izz>
</inertia>
<mass>0.1</mass>
</inertial>
<collision name="collision">
<geometry>
<box>
<size>0.1 0.3 0.1</size>
</box>
</geometry>
</collision>
<visual name="visual">
<geometry>
<box>
<size>0.1 0.3 0.1</size>
</box>
</geometry>
<material>
<script>Gazebo/Green</script>
</material>
</visual>
</link>
<link name="right_finger_tip">
<pose>0.336 -0.3 0.05 0 0 1.5707</pose>
<inertial>
<inertia>
<ixx>0.01</ixx>
<ixy>0</ixy>
<ixz>0</ixz>
<iyy>0.01</iyy>
<iyz>0</iyz>
<izz>0.01</izz>
</inertia>
<mass>0.1</mass>
</inertial>
<collision name="collision">
<geometry>
<box>
<size>0.1 0.2 0.1</size>
</box>
</geometry>
</collision>
<visual name="visual">
<geometry>
<box>
<size>0.1 0.2 0.1</size>
</box>
</geometry>
<material>
<script>Gazebo/Green</script>
</material>
</visual>
</link>
<static>true</static>
</model>
</sdf>
Run the world file to visualize what we have created up to this point.
gazebo ~/simple_gripper_tutorial/gripper.world
You should see something like this:
Once we are happy with the layout of the links, we can add in the joints, by copying the following code into the simple_gripper.sdf
file before the </model>
line.
gedit ~/.gazebo/models/my_gripper/simple_gripper.sdf
<joint name="palm_left_finger" type="revolute">
<pose>0 -0.15 0 0 0 0</pose>
<child>left_finger</child>
<parent>palm</parent>
<axis>
<limit>
<lower>-0.4</lower>
<upper>0.4</upper>
</limit>
<xyz>0 0 1</xyz>
</axis>
</joint>
<joint name="left_finger_tip" type="revolute">
<pose>0 0.1 0 0 0 0</pose>
<child>left_finger_tip</child>
<parent>left_finger</parent>
<axis>
<limit>
<lower>-0.4</lower>
<upper>0.4</upper>
</limit>
<xyz>0 0 1</xyz>
</axis>
</joint>
<joint name="palm_right_finger" type="revolute">
<pose>0 0.15 0 0 0 0</pose>
<child>right_finger</child>
<parent>palm</parent>
<axis>
<limit>
<lower>-0.4</lower>
<upper>0.4</upper>
</limit>
<xyz>0 0 1</xyz>
</axis>
</joint>
<joint name="right_finger_tip" type="revolute">
<pose>0 0.1 0 0 0 0</pose>
<child>right_finger_tip</child>
<parent>right_finger</parent>
<axis>
<limit>
<lower>-0.4</lower>
<upper>0.4</upper>
</limit>
<xyz>0 0 1</xyz>
</axis>
</joint>
<joint name="palm_riser" type="prismatic">
<child>palm</child>
<parent>riser</parent>
<axis>
<limit>
<lower>0</lower>
<upper>0.9</upper>
</limit>
<xyz>0 0 1</xyz>
</axis>
</joint>
And make the model non-static:
...
<static>false</static>
...
Start Gazebo again:
gazebo ~/simple_gripper_tutorial/gripper.world
Right-click on the model and select "View->Joints". The newly created joints will be displayed:
palm_riser
to 10 (Newtons), and you should see something like:Optional:
Tip: You may need to adjust reasonable inertia to the object.
Next: Attach Gripper to Robot
Prerequisites:
Make a Mobile Robot
Make a Simple Gripper
This tutorial explains how to create a composite robot from existing robot parts, i.e. mobile base, simple arm and simple gripper.
Start up gazebo and make sure you can load the models from the two previous tutorials.
Per instructions in Make a Mobile Robot tutorial, you should have a mobile base robot at your disposal:
For this exercise, modify ~/.gazebo/models/my_robot/model.sdf
to make the model larger so it can accommodate the gripper we are about to append to it:
gedit ~/.gazebo/models/my_robot/model.sdf
update the contents to make the model body larger and re-position the wheels accordingly:
<?xml version='1.0'?>
<sdf version='1.4'>
<model name="mobile_base">
<link name='chassis'>
<pose>0 0 .25 0 0 0</pose>
<inertial>
<mass>20.0</mass>
<pose>-0.1 0 -0.1 0 0 0</pose>
<inertia>
<ixx>0.5</ixx>
<iyy>1.0</iyy>
<izz>0.1</izz>
</inertia>
</inertial>
<collision name='collision'>
<geometry>
<box>
<size>2 1 0.3</size>
</box>
</geometry>
</collision>
<visual name='visual'>
<geometry>
<box>
<size>2 1 0.3</size>
</box>
</geometry>
</visual>
<collision name='caster_collision'>
<pose>-0.8 0 -0.125 0 0 0</pose>
<geometry>
<sphere>
<radius>.125</radius>
</sphere>
</geometry>
<surface>
<friction>
<ode>
<mu>0</mu>
<mu2>0</mu2>
</ode>
</friction>
</surface>
</collision>
<visual name='caster_visual'>
<pose>-0.8 0 -0.125 0 0 0</pose>
<geometry>
<sphere>
<radius>.125</radius>
</sphere>
</geometry>
</visual>
</link>
<link name="left_wheel">
<pose>0.8 0.6 0.125 0 1.5707 1.5707</pose>
<collision name="collision">
<geometry>
<cylinder>
<radius>.125</radius>
<length>.05</length>
</cylinder>
</geometry>
</collision>
<visual name="visual">
<geometry>
<cylinder>
<radius>.125</radius>
<length>.05</length>
</cylinder>
</geometry>
</visual>
</link>
<link name="right_wheel">
<pose>0.8 -0.6 0.125 0 1.5707 1.5707</pose>
<collision name="collision">
<geometry>
<cylinder>
<radius>.125</radius>
<length>.05</length>
</cylinder>
</geometry>
</collision>
<visual name="visual">
<geometry>
<cylinder>
<radius>.125</radius>
<length>.05</length>
</cylinder>
</geometry>
</visual>
</link>
<joint type="revolute" name="left_wheel_hinge">
<pose>0 0 -0.03 0 0 0</pose>
<child>left_wheel</child>
<parent>chassis</parent>
<axis>
<xyz>0 1 0</xyz>
</axis>
</joint>
<joint type="revolute" name="right_wheel_hinge">
<pose>0 0 0.03 0 0 0</pose>
<child>right_wheel</child>
<parent>chassis</parent>
<axis>
<xyz>0 1 0</xyz>
</axis>
</joint>
</model>
</sdf>
To create a mobile robot with a simple gripper attached, create a new models directory
mkdir ~/.gazebo/models/simple_mobile_manipulator
And edit the model config file:
gedit ~/.gazebo/models/simple_mobile_manipulator/model.config
populate it with the following contents:
<?xml version="1.0"?>
<model>
<name>Simple Mobile Manipulator</name>
<version>1.0</version>
<sdf version='1.4'>manipulator.sdf</sdf>
<author>
<name>My Name</name>
<email>[email protected]</email>
</author>
<description>
My simple mobile manipulator
</description>
</model>
Next, create the model SDF file:
gedit ~/.gazebo/models/simple_mobile_manipulator/manipulator.sdf
and populate with following contents:
<?xml version="1.0" ?>
<sdf version="1.3">
<model name="simple_mobile_manipulator">
<include>
<uri>model://my_gripper</uri>
<pose>1.3 0 0.1 0 0 0</pose>
</include>
<include>
<uri>model://my_robot</uri>
<pose>0 0 0 0 0 0</pose>
</include>
<joint name="arm_gripper_joint" type="revolute">
<parent>mobile_base::chassis</parent>
<child>simple_gripper::riser</child>
<axis>
<limit>
<lower>0</lower>
<upper>0</upper>
</limit>
<xyz>0 0 1</xyz>
</axis>
</joint>
<!-- attach sensor to the gripper -->
<include>
<uri>model://hokuyo</uri>
<pose>1.3 0 0.3 0 0 0</pose>
</include>
<joint name="hokuyo_joint" type="revolute">
<child>hokuyo::link</child>
<parent>simple_gripper::palm</parent>
<axis>
<xyz>0 0 1</xyz>
<limit>
<upper>0</upper>
<lower>0</lower>
</limit>
</axis>
</joint>
</model>
</sdf>
Make sure the model.config
and manipulator.sdf
files above are saved, start Gazebo and spawn the model above by using the insert tab and choosing Simple Mobile Manipulator model. You should see something similar to:
This tutorial describes how to import 3D meshes into Gazebo.
Gazebo uses a right-hand coordinate system where +Z is up (vertical), +X is forward (into the screen), and +Y is to the left.
Reduce Complexity
Many meshes can be overly complex. A mesh with many thousands of triangles should be reduced or split into separate meshes for efficiency. Look at the documentation of your 3D mesh editor for information about reducing triangle count or splitting up a mesh.
Center the mesh
The first step is to center the mesh at (0,0,0) and orient the front (which can be subjective) along the x-axis.
Scale the mesh
Gazebo uses the metric system. Many meshes (especially those from 3D warehouse), use English units. Use your favorite 3D editor to scale the mesh to a metric size.
Once the mesh has been properly prepared, export it as a Collada file. This format will contain all the 3D information and the materials.
The easiest way to test a mesh is to create a simple world file my_mesh.world that loads the mesh. Replace my_mesh.dae
with the actual filename of the mesh.
<?xml version="1.0"?>
<sdf version="1.4">
<world name="default">
<include>
<uri>model://ground_plane</uri>
</include>
<include>
<uri>model://sun</uri>
</include>
<model name="my_mesh">
<pose>0 0 0 0 0 0</pose>
<static>true</static>
<link name="body">
<visual name="visual">
<geometry>
<mesh><uri>file://my_mesh.dae</uri></mesh>
</geometry>
</visual>
</link>
</model>
</world>
</sdf>
Then just launch Gazebo in the directory where is the file:
gazebo my_mesh.world
You can use these duck.dae and duck.png mesh files. Put them together in the same directory as the world file. Since the duck mesh is defined with the y-axis as up, you can put a rotation in the sdf so that it displays upright:
<visual name="visual">
<pose>0 0 0 1.5708 0 0</pose>
<geometry>
<mesh><uri>file://duck.dae</uri></mesh>
</geometry>
</visual>
Prerequisites: Make a model
This tutorial describes how you can embed a model inside another to create anassembly of models.
It was seen in theMake a model tutorial that amodel SDF is composed of a collection of links
and joints
. As of SDF 1.5,the <model>
SDF element has been extended to support self-referencing, whichmeans allowing <model>
elements to be nested. Support for loading nested<model>
elements has been added in Gazebo 7.
Here is a basic example of a nested model SDF:
<sdf version="1.6">
<model name="model_00">
<pose>0 0 0.5 0 0 0</pose>
<link name="link_00">
<pose>0.0 0 0 0 0 0</pose>
<collision name="collision_00">
<geometry>
<sphere>
<radius>0.5</radius>
</sphere>
</geometry>
</collision>
<visual name="visual_00">
<geometry>
<sphere>
<radius>0.5</radius>
</sphere>
</geometry>
</visual>
</link>
<model name="model_01">
<pose>1.0 0 0.0 0 0 0</pose>
<link name="link_01">
<pose>0.25 0 0.0 0 0 0</pose>
<collision name="collision_01">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</collision>
<visual name="visual_01">
<geometry>
<box>
<size>1 1 1</size>
</box>
</geometry>
</visual>
</link>
</model>
</model>
</sdf>
This model SDF is composed of a link (link_00
), and a nested model(model_01
) with another link (link_01
). Since a model in Gazebo is just anabstract container for a group of objects, loading this model in Gazebo willresult in just two rigid bodies being created in the physics engine; one for thesphere link and the other for the nested box link. By default, they will notself-collide just like other links within the same model. On the GUI client,you will see a sphere and a box sitting side-by-side and should not noticeany visual difference between nested models and links.
Joints can also be created between links in nested models. Here is an exampleof a joint that can be added to the model SDF above:
<joint name="joint_00" type="revolute">
<parent>link_00</parent>
<child>model_01::link_01</child>
<pose>0.0 0.0 0.0 0.0 0.0 0.0</pose>
<axis>
<xyz>1.0 0.0 0.0</xyz>
</axis>
</joint>
This joint SDF element can be added to either the top level or nested <model>
element. A revolute joint is then created between the sphere and the box links.Pay attention to the scoping of <parent>
and <child>
names; references tonested model links need to be scoped but minus the top level model name prefix.
Another approach for nesting models is demonstrated in theAdd a Sensor to a Robot tutorialwhich introduces the use of the <include>
element.
The <include>
element works by taking all the links from the included modeland embedding them into the parent model. The downside of this approach is thatthe model representation is modified during the process, i.e. saving the worldwill result in a model with all the links combined together in one <model>
element without preserving the <include>
tag. This is one of the shortcomingswhich the nested <model>
element is designed to address.
On the other hand, the <include>
element is a simple and clean solution thatonly requires a reference to an SDF file for creating a model assembly.Future work will look into extending the nested <model>
SDF element withthis feature.
This tutorial describes the process of creating a model using the Model Editor.
Make sure Gazebo is installed.
Start up gazebo.
$ gazebo
On the Edit
menu, go to Model Editor
, or hit Ctrl+M
to open the editor.
The editor is composed of the following 2 areas:
The Palette on the left has two tabs. The Insert
tab lets you insertparts (links and other models) into the scene to build the model. The Model
tab displays a list of all the parts that make up the model you are building.
The 3D View on the right where you can see a preview of your model andinteract with it to edit its properties and create joints between links.
The GUI tools on the top toolbar can be used to manipulate joints and links inthe 3D View.
The model editor has three simple primitive geometries that the user can insertinto the 3D view to make a link of the model.
On the Palette, click on the box
, sphere
, or cylinder
icon underSimple Shapes.
Move your mouse cursor over the 3D view to see the visual appear, andclick/release anywhere to add it to the model.
Tip: You can press
Esc
to cancel adding the currentlink attached to the mouse cursor.
To add a custom mesh,
Click on the Add
button under Custom Shapes, which pops up a dialogthat lets you find the mesh you want to add.
Click on Browse
button and use the file browser to find the mesh fileon your local machine. If you know the path of the mesh file, you can enter itdirectly in the text field box next to the Browse
button. Note Gazebocurrently only supports importing COLLADA (dae), STereoLithography (stl),and Scalable Vector Graphics (svg) files.
Click Import
to load the mesh file. Then, add it to the 3D view.
The model editor supports creating several types of joints between links in themodel being edited. To create a joint:
Click on the joint
icon on the tool bar. This brings up the Joint CreationDialog which allows you to specify different properties of the joint youwant to create. As you can see in the dialog, the default joint type isa Revolute
joint.
Begin by moving your mouse over the link you wish to create a joint for tosee it being highlighted and click on it. This link will be the parent link ofthe joint.
Next, move your mouse to the link which you would like to be the child linkof the joint. Click on it to see a colored line connecting the two links anda joint visual attached to the child link.
The line representing the joint is color-coded. Play around with differentjoint types to see the colors.
The joint visual consists of RGB axes which help to give an idea of thecoordinate frame of the joint. The yellow arrow indicates the primary axis ofthe joint. For example, in the case of a revolute joint, this is the axis ofrotation.
Once you have specified all the desired properties of the joint in theJoint Creation Dialog, click on the Create
button at the bottom to finalizejoint creation.
Tip: You can press
Esc
any time to cancel the joint creation process.
Note: Be careful when editing your model; the editor currently has no option to undo your actions.
Tip: All measurements are in meters.
The model editor supports editing properties of a link which you wouldalso find in its SDF.
Note: Gazebo 6+ supports editinglinks, visuals, and collisions. The ability to edit sensors andplugins are to be implemented in later versions.
To edit a link's properties: Double-click on the link or right click and selectOpen Link Inspector
. A dialog window will appear which containsLink
, Visual
, and Collision
property tabs.
As an example, try changing the link pose and visual colors. Once you are done, click onOK
to close the inspector.
As mentioned earlier, joint properties can also be edited. These are propertiesthat you would find in the joint SDF.
To edit a joint: Double-click on the line connecting the links or right clickon it and select Open Joint Inspector
. The joint inspector will appear.
As an example, try changing the joint pose and joint type. Once you are done, click onOK
to close the inspector.
Saving will create a directory, SDF and config files for your model.
As an exercise, let's build a simple car and save it. The car will have abox chassis and four cylinder wheels. Each wheel will be connected to thechassis with a revolute joint:
Once you're happy with the model you created, go to the Model
tab in the leftpanel and give it a name.
To save the model, choose File
, then Save As
(or hit Ctrl+S
) in the topmenu. A dialog will come up where you can choose the location for your model.
When you're done creating the model and you've saved it, go to File
and thenExit Model Editor
.
Your model will show up in the main window.
Rather than creating a model from the ground up;you can also edit existing models that are already in the simulation.
To edit an existing model:
Make sure you have saved the model you created, and you have exited the model editor. Alternatively, start from a fresh Gazebo instance.
Insert a model from the Insert
tab on the left. For example, let'sinsert a Simple Arm
.
Right click on the model you just inserted and select Edit Model
.
Now you are in the model editor and you are free to add new links to themodel or edit existing ones.
This tutorial creates a simulation world with a simple box that is animatedin a 10 second repeating loop where it slides around on the ground.
This tutorial also demonstrates several different ways of viewing,accessing, and interacting with simulation using the Gazebo executableor your own custom executable.
The simulated box broadcasts its pose,and a callback is created to receive the poseand print out the location and timestamp of the box.
Create a working directory.
mkdir ~/gazebo_animatedbox_tutorial
cd ~/gazebo_animatedbox_tutorial
Copy animated_box.cc, independent_listener.cc, integrated_main.cc, CMakeLists.txt, and animated_box.world into the current directory.
On OS X, you can replace wget
with curl -OL
.
wget http://bitbucket.org/osrf/gazebo/raw/gazebo6/examples/stand_alone/animated_box/animated_box.cc
wget http://bitbucket.org/osrf/gazebo/raw/gazebo6/examples/stand_alone/animated_box/independent_listener.cc
wget http://bitbucket.org/osrf/gazebo/raw/gazebo6/examples/stand_alone/animated_box/integrated_main.cc
wget http://bitbucket.org/osrf/gazebo/raw/gazebo6/examples/stand_alone/animated_box/CMakeLists.txt
wget http://bitbucket.org/osrf/gazebo/raw/gazebo6/examples/stand_alone/animated_box/animated_box.world
Build the plugin
mkdir build
cd build
cmake ../
make
Make sure Gazebo can load the plugins later
export GAZEBO_PLUGIN_PATH=`pwd`:$GAZEBO_PLUGIN_PATH
This example demonstrates how to use the normalgazebo executable with a plugin.
Run using gazebo itself with:
cd ~/gazebo_animatebox_tutorial
gazebo animated_box.world
In another terminal, use "gz topic" user interface to view the pose:
gz topic -v /gazebo/animated_box_world/pose/info
You should see a graphical interface that displays the pose of the box.
Make sure Gazebo is not running.
We will start Gazebo as above, and then run the independent listenerexecutable that connects to Gazebo. The independent listener receivesthe location and timestamp of the box and prints it out.
cd ~/gazebo_animatebox_tutorial
gazebo animated_box.world & ./build/independent_listener
Make sure Gazebo is not running.
The integrated_main example demonstrates the following:
Run integrated_main:
cd ~/gazebo_animatebox_tutorial
./build/integrated_main animated_box.world
To view the simulation run the command:
gzclient
Executable that will connect to a running simulation, receive updates from the pose information topic, and print the object position.
Executable that will create a simulation, receive updates from the pose information topic, and print the object position.
Shared library plugin that defines the animation component of the simulation, moving the box that is in the world.
XML file that defines the simulation physical world space and the single box that is in it.
CMake build script.
An accurate simulation requires physically plausible inertial parameters:the mass, center of mass location,and the moment of inertia matrix of all links.This tutorial will guide you through the process of obtaining and settingthese parameters if you have 3D models of the links.
Assuming homogeneous bodies (uniform mass density),it is shown how to obtain inertial data using the free software MeshLab.You can also use the commercial product SolidWorks to compute these information.For a guide on using SolidWorks, please refer tothis question on answers.ros.org.
The mass is most easily measured by weighing an object.It is a scalar with default units in Gazebo of kilograms (kg).For a 3D uniform mesh, mass is computed bycalculating the geometric volume [length3]and multiplying by density [mass / length3].
The center of mass is the point where the sum of weighted mass moments is zero.For a uniform body, this is equivalent to the geometric centroid.This parameter is a Vector3 with units of position [length].
The moments of inertiarepresent the spatial distribution of mass in a rigid body.It depends on the mass, size, and shape of a bodywith units of [mass * length2].The moments of inertia can be expressed as the componentsof a symmetric positive-definite 3x3 matrix,with 3 diagonal elements, and 3 unique off-diagonal elements.Each inertia matrix is defined relative to a coordinate frameor set of axes.Diagonalizing the matrixyields its principal moments of inertia (the eigenvalues)and the orientation of its principal axes (the eigenvectors).
The moments of inertia are proportional to massbut vary in a non-linear manner with respect to size.Additionally, there are constraints on the relative valuesof the principal momentsthat typically make it much more difficult to estimate moments of inertiathan mass or center of mass location.This difficulty motivates the use of software tools for computingmoment of inertia.
If you're curious about the math behind the inertia matrix, or just want an easy way to calculate the tensor for simple shapes,this wikipedia entry is a great resource.
Download MeshLab from the official website and install it on your computer.The installation should be straightforward.
Once installed, you can view your meshes in MeshLab (both DAE and STL formats are supported, which are those ones supported by Gazebo/ROS).
Open the mesh file in MeshLab.For this example, asphere.daemesh is used.To compute the inertial parameters, you first need to display the Layers dialog - View->Show Layer Dialog
.A panel opens in the right part of the window which is split in half - we're interested in the lower part containing text output.
Next, command MeshLab to compute the inertial parameters.Choose Filters->Quality Measure and Computations->Compute Geometric Measures
from the menu.The lower part of the Layers dialog should now show some info about the inertial measures.The sphere gives the following output:
Mesh Bounding Box Size 2.000000 2.000000 2.000000
Mesh Bounding Box Diag 3.464102
Mesh Volume is 4.094867
Mesh Surface is 12.425012
Thin shell barycenter -0.000000 -0.000000 -0.000000
Center of Mass is -0.000000 0.000000 -0.000000
Inertia Tensor is :
| 1.617916 -0.000000 0.000000 |
| -0.000000 1.604620 -0.000000 |
| 0.000000 -0.000000 1.617916 |
Principal axes are :
| 0.000000 1.000000 0.000000 |
| -0.711101 -0.000000 0.703089 |
| -0.703089 0.000000 -0.711101 |
axis momenta are :
| 1.604620 1.617916 1.617916 |
The bounding box of the sphere is a cube with side length 2.0,which implies that the sphere has a radius of 1.0.
A sphere of radius 1.0 should have a volume of 4/3*PI
(4.189),which is close to the computed value of 4.095.It is not exact since it is a triangular approximation.
The surface area should be 4*PI
(12.566),which is close to the computed value of 12.425.
The center of mass is given as the origin (0,0,0).
The inertia matrix (aka inertia tensor) of a sphere should be diagonal withprincipal moments of inertiaof 2/5 mass
since radius = 1
.It is not explicitly stated in the output, but the massis equal to the volume (implicitly using a density of 1),so we would expect diagonal matrix entries of 8/15*PI
(1.676).The computed inertia tensor appears diagonalfor the given precision with principal momentsranging from [1.604,1.618], which is close to the expected value.
One thing to keep in mind is that duplicate faces within a mesh will affectthe calculation of volume and moment of inertia.For example, consider another spherical mesh:ball.dae.Meshlab gives the following output for this mesh:
Mesh Bounding Box Size 1.923457 1.990389 1.967965
Mesh Bounding Box Diag 3.396207
Mesh Volume is 7.690343
Mesh Surface is 23.967396
Thin shell barycenter 0.000265 0.000185 0.000255
Center of Mass is 0.000257 0.000195 0.000292
Inertia Tensor is :
| 2.912301 0.001190 0.000026 |
| 0.001190 2.903731 0.002124 |
| 0.000026 0.002124 2.906963 |
Principal axes are :
| 0.108262 -0.895479 0.431738 |
| -0.120000 0.419343 0.899862 |
| 0.986853 0.149229 0.062058 |
axis momenta are :
| 2.902563 2.907949 2.912483 |
This mesh is approximately the same size,with bounding box dimensions in the range [1.92,1.99],but its calculations are different by nearly double:
There is a clue to the difference when you look at the numbersof vertices and faces (listed in the bottom of the MeshLab window):
Each mesh has a similar number of vertices, but ball.dae
hasroughly twice as many faces.Running the commandFilters
->
Cleaning and Repairing
->
Remove Duplicate Faces
reduces the number of faces in ball.dae
to 720 and givesmore reasonable values for the volume (3.84)and principal moments of inertia (1.45).It makes sense that these values are slightly smallersince the bounding box is slightly smaller as well.
Meshlab currently prints the geometric informationwith 6 digits of fixed point precision.If your mesh is too small, this may substantiallylimit the precision of the inertia tensor,for example:
Mesh Bounding Box Size 0.044000 0.221000 0.388410
Mesh Bounding Box Diag 0.449043
Mesh Volume is 0.001576
Mesh Surface is 0.136169
Thin shell barycenter -0.021954 0.008976 0.012835
Center of Mass is -0.021993 0.001259 0.001489
Inertia Tensor is :
| 0.000008 -0.000000 -0.000000 |
| -0.000000 0.000001 -0.000000 |
| -0.000000 -0.000000 0.000007 |
Principal axes are :
| 0.999999 0.000166 0.001241 |
| -0.000113 0.999104 -0.042310 |
| -0.001247 0.042310 0.999104 |
axis momenta are :
| 0.000008 0.000001 0.000007 |
It seems like we have what we were seeking for.But when you look thoroughly, you will see one bad thing - the output is written out only up to 6 decimal digits.As a consequence, we lose most of the valuable information in the inertia tensor.To overcome lack of precision in the Inertia Tensor,you can scale up the model so that the magnitude of the inertia is increased.The model can be scaled using Filters->Normals, Curvatures and Orientation->Transform: Scale
.Enter a scale in the dialog and hit Apply
.
To decide the scaling factor s
to choose, recall that MeshLab uses the volumeas a proxy for mass, which will vary as s3.Furthermore, the inertia has an addition dependence on length2,so the moment of inertia will change according to s5.Since there is such a large dependence on s
,scaling by a factor of 10 or 100 may be sufficient.
Now, instruct MeshLab to recompute the geometrical measures again,and the Inertia Tensor
entry should have more precision.Then multiply the inertia tensor by 1/s5 to undo the scaling.
It is not always the case that MeshLab uses the same length units as you'd want (meters for Gazebo).However, you can easily tell the ratio of MeshLab units to your desired units by looking at the Mesh Bounding Box Size
entry.You can e.g. compute the bounding box size in your desired units and compare to the MeshLab's one.
Multiply the Center of Mass
entry with the computed ratio and you have the coordinates of the Center of Mass of your mesh.However, if the link you are modeling is not homogeneous, you will have to compute the Center of Mass using other methods (most probably by real experiments).
Just like the center of mass location must be scaled to the correct units,the moment of inertia should be scaled as well,though the scale factor should be squared to account for thelength2 dependence in the moment of inertia.In addition, the inertia should be multiplied bythe measured mass
and divided by the computed volume fromthe text output.
The next step is to record the computed values to the URDF or SDF file containing your robot (it is assumed you already have the robot model; if not, follow the tutorialMake a Model).
In each link you should have the <inertial>
tag.It should look like the following (in SDF):
<link name='antenna'>
<inertial>
<pose>-0.022 0.0203 0.02917 0 0 0</pose>
<mass>0.56</mass>
<inertia>
<ixx>0.004878</ixx>
<ixy>-6.2341e-07</ixy>
<ixz>-7.4538e-07</ixz>
<iyy>0.00090164</iyy>
<iyz>-0.00014394</iyz>
<izz>0.0042946</izz>
</inertia>
</inertial>
<collision name='antenna_collision'>
...
</collision>
<visual name='antenna_visual'>
...
</visual>
...
</link>
or like this one (in URDF):
<link name="antenna">
<inertial>
<origin rpy="0 0 0" xyz="-0.022 0.0203 0.02917"/>
<mass value="0.56"/>
<inertia ixx="0.004878" ixy="-6.2341e-07" ixz="-7.4538e-07" iyy="0.00090164" iyz="-0.00014394" izz="0.0042946"/>
</inertial>
<visual>
...
</visual>
<collision>
...
</collision>
</link>
The <mass>
should be entered in kilograms and you have to find it out experimentally (or from specifications).
The <origin>
or <pose>
are used to enter the Center of Mass position (relative to the link's origin; especially not relative to the link's visual or collision origin).The rotational elements can define a different coordinate from for the moment of inertia axes.If you've found out the center of mass experimentally, fill in this value, otherwise fill in the correctly scaled value computed by MeshLab.
The <inertia>
tag contains the inertia tensor you have computed in the previous step.Since the matrix is symmetric, only 6 numbers are sufficient to represent it.The mapping from MeshLab's output is the following:
| ixx ixy ixz |
| ixy iyy iyz |
| ixz iyz izz |
As a quick check that the matrix is sane, you can use the rule that the diagonal entries should have the largest values and be positive, and the off-diagonal numbers should more or less approach zero.
Precisely, the matrix has to be positive definite (use your favorite maths tool to verify that).Its diagonal entries also have tosatisfy the triangle inequality,ie. ixx + iyy >= izz
, ixx + izz >= iyy
and iyy + izz >= ixx
.
To check if everything is done correctly, you can use Gazebo's GUI client.
Using Gazebo standalone
Run Gazebo
gazebo
Spawn your robot
gz model -f my_robot.sdf
Using Gazebo with ROS
Run Gazebo
roslaunch gazebo_ros empty_world.launch
Spawn your robot (substitute my_robot
, my_robot_description
and MyRobot
with your robot's package/name):
SDF model:
rosrun gazebo_ros spawn_model -sdf -file `rospack find my_robot_description`/urdf/my_robot.sdf -model MyRobot
URDF model:
rosrun gazebo_ros spawn_model -urdf -file `rospack find my_robot_description`/urdf/my_robot.urdf -model MyRobot
As soon as your model loads, pause the world and delete the ground_plane (this is not needed, but it usually makes debugging easier).
Go to the Gazebo menu and select View->Inertia
.Every link should now display a purple box with green axes.The center of each box is aligned with the specified center of mass of its link.The sizes and orientations of the boxes correspond to unit-mass boxes with the same inertial behavior as their corresponding links.This is useful for debugging the inertial parameters, but we can make one more thing to have the debugging easier.
You can temporarily set all the links to have a mass of 1.0 (by editing the URDF or SDF file).Then all the purple boxes should have more or less the same shapes as the bounding boxes of their links.This way you can easily detect problems like misplaced Center of Mass or wrongly rotated Inertia Matrix.Do not forget to enter the correct masses when you finish debugging.
To fix a wrongly rotated Inertia Matrix (which in fact happens often), just swap the ixx, iyy, izz entries in the model file until the purple box aligns with its link.Then you obviously also have to appropriately swap the ixy, ixz and iyz values (when you swap ixx<->
iyy, then you should negate ixy and swap ixz<->
iyz).
MeshLab only computes correct inertia parameters for closed shapes.If your link is open or if it is a very complex or concave shape, it might be a good idea to simplify the model (e.g.in Blender) before computing the inertial parameters.Or, if you have the collision shapes for your model, use them in place of the full-resolution model.
For strongly non-homogeneous bodies, this tutorial might not work.There are two problems.The first one is that MeshLab assumes uniform-density bodies.The other is that MeshLab computes the Inertia Tensor relative to the computed center of mass.However, for strongly non-homogeneous bodies, the computed center of mass will be far from the real center of mass, and therefore the computed inertia tensor might be just wrong.
One solution is to subdivide your link to more homogeneous parts and connect them with fixed joints, but that is not always possible.The only other solution would be to find out the inertia tensor experimentally, which would surely take a lot of time and effort.
We have shown the process of getting the correct inertia parameters for your robot model,the way how to enter them in a URDF or SDF file,and also the way how to make sure the parameters are entered correctly.
With Gazebo 6 it is possible to add meta data to the visuals in yoursimulation. This tutorial explains how to add layer meta data to visuals soyou can control which layers are visible via the graphical interface.
Currently, layers are identified by numbers. In your model SDF file, undereach <visual>
tag, you can add a <meta>
tag for meta information andthen a <layer>
tag with the layer number as follows:
<visual name='visual_0'>
<meta>
<layer>0</layer>
</meta>
...
</visual>
Visuals without a layer assigned can't have their visibility toggled andwill always be visible.
An example world is distributed with Gazebo. You can load this world using the following command:
gazebo worlds/shapes_layers.world
You can toggle the visibility of each layer via the Layers
tab on the left panel:
If no visuals on the simulation have a layer, the layers tab will be empty.