Skip to content

Tutorial 1: Making Your First Script

Margarita Rebolledo edited this page Sep 19, 2019 · 23 revisions

Revolve is a wrapper for Gazebo, a multi-purpose robotics simulator. It was designed with an idea of simplifying the process of running the experiments related to the Triangle of Life project. Here, we will learn how to write a script that runs Gazebo. Now, let's make our first script!

Step 1: Writing the script

Presuming you are writing within Revolve project

  1. Withing the project root create an empty file tutorial1.py.

  2. Make sure it is executable:

    sudo chmod +x tutorial1.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 os
    import sys
    from pyrevolve.custom_logging.logger import logger
    
    async def run():
        logger.info('Hello World!')
  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 tutorial1.py

The output should be:

...

[2019-09-19 13:19:45,266 revolve] INFO Hello World!

...

This means the file points to the absolute directory of revolve. This is important because now we can import Revolve-specific parts into our manager.

Step 2: Connecting to the simulator

The revolve.py takes care of starting the simulator, but you can connect to it, insert and delete models from your script.

  1. Let's introduce a Revolve class and connect our script to the simulator world. Insert the following code:

    #!/usr/bin/env python3
    import asyncio
    import os
    from pyrevolve.custom_logging.logger import logger
    from pyrevolve.gazebo.manage import WorldManager as World
    from pyrevolve.util.supervisor.supervisor_multi import DynamicSimSupervisor
    
    
    async def run():
        logger.info('Hello World!')
    
        # Start Simulator
        simulator_supervisor = DynamicSimSupervisor(
            world_file='worlds/plane.world',
            simulator_cmd='gazebo',
            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()
        await asyncio.sleep(0.1)
    
        connection = await World.create()
        if connection:
            logger.info("Connected to the simulator world.")
  2. Run the script:

    (.venv) ./revolve.py --simulator-cmd=gazebo --manager tutorial1.py

The output should look like this:

...

[2019-09-19 15:37:43,278 revolve] INFO Hello World!

[2019-09-19 15:37:43,279 gazebo] INFO Created Supervisor with:

...

[2019-09-19 15:41:38,451 gazebo] INFO Launching the simulator...

[2019-09-19 15:41:39,747 revolve] INFO Connected to the simulator world.

[2019-09-19 15:41:39,748 gazebo] INFO Terminating processes...

...

What changed!? Well, several things:

  • First, we introduced DynamicSimSupervisor. This Python class is the supervisor in charge of launching the world and the manager needed to run the experiment.
  • Second, WorldManager. It is a Python class that takes care of connecting to the simulator world and making changes during the simulation.
  • Third, you may notice that we imported asyncio library, and that def run(): now has a special prefix async. Also, run() is not called directly anymore, but through Asyncio event loop. This is because all communication with the simulator is done through asynchronous message passing. For Gazebo, there is no direct communication with Python, so we use PyGazebo library to communicate. The implementation details are hidden within WorldManager class.
  • Lasty, we managed to connect to the Gazebo world. But that is not enough. We want to send some commands to the world, so this is what we will do in the next step.

Step 3: Control the world

  1. Now, we will add the code to pause the simulated world. Insert the following code:

    #!/usr/bin/env python3
    import asyncio
    import os
    import sys
    from pyrevolve.custom_logging.logger import logger
    from pyrevolve.gazebo.manage import WorldManager as World
    from pyrevolve.util.supervisor.supervisor_multi import DynamicSimSupervisor
    
    
    async def run():
        logger.info('Hello World!')
    
        # Start Simulator
        simulator_supervisor = DynamicSimSupervisor(
            world_file='worlds/plane.world',
            simulator_cmd='gazebo',
            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()
        await asyncio.sleep(0.1)
    
        connection = await World.create()
        if connection:
            logger.info("Connected to the simulator world.")
    
        await connection.pause(True)
    
        while True:
            await asyncio.sleep(10.0)
  2. Run the script:

    (.venv) ./revolve.py --simulator-cmd=gazebo --manager ./tutorial1.py

The result of this command should be the same in the terminal as before. However, something changed. If you take a look at your Gazebo simulator, in the lower left corner you can see the button instead of . This means that the world is currently paused.

What did we change now!?

  • First, we have sent a command to the simulator from our WorldManager with await world.pause(True).
  • Second, we added an asynchronous sleep so that the script does not exit instantly.

To end the execution of the code just press ctrl+c

Final script

The final script should look like:

#!/usr/bin/env python3
import asyncio
import os
import sys
import time
from pyrevolve import parser
from pyrevolve.custom_logging.logger import logger
from pyrevolve.gazebo.manage import WorldManager as World
from util.supervisor.supervisor_multi import DynamicSimSupervisor


async def run():
    logger.info('Hello World!')
    settings = parser.parse_args()

    # Start Simulator
    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)
    
    connection = await World.create()
    if connection:
        logger.info("Connected to the simulator world.")

    await connection.pause(True)

    while True:
        await asyncio.sleep(10.0)

In the final script, you can see that we also added some guardian code to execute our program. Also, keyboard handler is added so we can stop the script running from infinite execution.

You can find this example with other tutorial scripts within Revolve experiments/examples directory.

This tutorial gives you some basic idea on how it all works. Now, let us insert some model into the world!


See next: Tutorial 2: Inserting a Model


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