Skip to content

Tutorial 2: Insert a Model

Jie Luo edited this page Jan 24, 2021 · 1 revision

In the previous tutorial, we learned how to make a simple Revolve manager in Python. Now we will see how to insert a model into a world. A model can be any object - a sphere, a block, a cylinder, but also any 3D mesh that we define in STL or Collada format. Let's start easy and use a simple sphere.

Quickstart with SDF

Gazebo uses SDFormat, an XML file format, for defining environments and models. The SDF specification defines all the XML elements for describing world and models. You can accurately describe all aspects of a model using SDF, whether the model is a simple chassis with wheels or a humanoid robot. For example, if we want to insert a simple sphere, this is the SDF that we need to inject into the simulation:

<sdf version="1.5">
   <model name="sphere">
      <pose>1 0 0 0 0 0</pose>
      <link name="link">
         <pose>0 0 .5 0 0 0</pose>
         <collision name="collision">
            <geometry>
               <sphere><radius>0.5</radius></sphere>
            </geometry>
         </collision>
         <visual name="visual">
            <geometry>
               <sphere><radius>0.5</radius></sphere>
            </geometry>
         </visual>
      </link>
   </model>
</sdf>

It seem very confusing! Dont worry, the following is the explanation. There are top-level elements of <sdf> that should be noted:

  • <world>: The world element encapsulates an entire world description including: models, scene, physics, joints, and plugins;
  • <model>: The model element defines a complete robot or any other physical object;
  • <actor>: A special kind of model which can have a scripted motion. This includes both global waypoint type animations and skeleton animations;
  • <light>: The light element describes a light source.

It is important to note that that every SDF can be considered an array of one or more of elements. This mean that in one SDF we can define the <world> environment and one or more <model> objects.

In order to make a <model> object, child elements are used to define it:

  • <static>: If set to true, the model is immovable. Otherwise the model is simulated in the dynamics engine;
  • <model>: A nested model element;
  • <pose>: A position(x, y, z) and orientation(roll, pitch yaw) with respect to the specified frame;
  • <link>: A physical link with inertia, collision, and visual properties. A link must be a child of a model, and any number of links may exist in a model;
  • <joint>: A joint connections two links with kinematic and dynamic properties;
  • <plugin>: A plugin is a dynamically loaded chunk of code. It can exist as a child of world, model, and sensor.

There are others, but these are the most prominent ones Revolve uses.

Finally, we should mention briefly important part of <link> element:

  • <pose>: A position(x, y, z) and orientation(roll, pitch yaw) with respect to the specified frame;
  • <inertial>: The inertial properties of the link;
  • <collision>: The collision properties of a link. Note that this can be different from the visual properties of a link, for example, simpler collision models are often used to reduce computation time;
  • <visual>: The visual properties of the link. This element specifies the shape of the object (box, cylinder, etc.) for visualization purposes;
  • <sensor>: The sensor tag describes the type and properties of a sensor.

Take another look on our SDF example above. Now it is starting to make sense! OK, let's insert it now in the simulator and see how it looks.

Step 1: Inserting a model

Presuming you are writing within Revolve project

  1. Within the project root create an empty file tutorial2.py.

  2. Make sure it is executable:

    sudo chmod +x tutorial2.py
  3. Open the file with a text editor, add the following piece of code to the script, and save it:

    #!/usr/bin/env python3
    import asyncio
    import os
    import sys
    from pyrevolve.util.supervisor.supervisor_multi import DynamicSimSupervisor
    from pyrevolve import parser
    
    here = os.path.dirname(os.path.abspath(__file__))
    rvpath = os.path.abspath(os.path.join(here, '..', 'revolve'))
    sys.path.append(os.path.dirname(os.path.abspath(__file__)))
    
    from pyrevolve.gazebo.manage import WorldManager as World
    
    
    async def run():
        # Start Simulator
        settings = parser.parse_args()
        if settings.simulator_cmd != 'debug':
            simulator_supervisor = DynamicSimSupervisor(
                world_file=settings.world,
                simulator_cmd=settings.simulator_cmd,
                simulator_args=["--verbose"],
                plugins_dir_path=os.path.join('.', 'build', 'lib'),
                models_dir_path=os.path.join('.', 'models'),
                simulator_name='gazebo'
            )
            await simulator_supervisor.launch_simulator(port=settings.port_start)
            await asyncio.sleep(0.1)
    
        world = await World.create()
        if world:
            print("Connected to the simulator world.")
    
        sdf_model = """
        <sdf version ='1.5'>
            <model name ='sphere'>
                <pose>1 0 0 0 0 0</pose>
                <link name ='link'>
                    <pose>0 0 .5 0 0 0</pose>
                    <collision name ='collision'>
                        <geometry>
                            <sphere>
                                <radius>0.5</radius>
                            </sphere>
                        </geometry>
                    </collision>
                    <visual name ='visual'>
                        <geometry>
                            <sphere>
                                <radius>0.5</radius>
                            </sphere>
                        </geometry>
                    </visual>
                </link>
            </model>
        </sdf>"""
    
        await world.insert_model(sdf_model)
        await world.pause(True)
    
        while True:
            await asyncio.sleep(10.0)
    
    
    def main():
        loop = asyncio.get_event_loop()
        loop.run_until_complete(run())
    
    
    if __name__ == "__main__":
        main()
  4. Create Python virtual environment:

    virtualenv .venv
    source .venv/bin/activate
    (.venv) pip install -r requirements.txt

NOTE: When the virtual environment is activated, you will see (.venv) designation appearing on the active line within your terminal window. Revolve works within this environment in order to keep your installed Python isolated from unexpected changes. Otherwise, if you feel proficient enough, you can install Revolve as part of your system. For now, we will show examples from the virtual environment.

  1. Run the script:
    (.venv) ./revolve.py --simulator-cmd=gazebo --manager ./tutorial2.py

The output should be:

We can see that it accuratelly renders the sphere in the world. However, it can be a tedious and erroneous task to write this SDF models manually. That is why Revolve can define this elements for you. In the next step we will see how to do that in Python.



See next: Tutorial 3: Insert a Robot


_________________
/ Premature      \
| optimization   |
| is the root of |
| all evil.      |
|                |
\ -- D.E. Knuth  /
-----------------
    \   ^__^
     \  (oo)\_______
        (__)\       )\/\
            ||----w |
            ||     ||
Clone this wiki locally