-
Notifications
You must be signed in to change notification settings - Fork 32
Tutorial 1: Make Your First Script
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!
Test this out with checking out git checkout tutorial
and you can find the tutorial code in the tutorial folder located in the root of the repository.
Presuming you are writing within Revolve project
-
Withing the project root create an empty file
tutorial1.py
. -
Make sure it is executable:
sudo chmod +x tutorial1.py
-
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!')
-
Create Python virtual environment:
virtualenv --python python3 .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.
- Run the script:
(.venv) ./revolve.py --simulator-cmd=gazebo --manager=tutorial/tutorial1.py
The output should be:
...
[2019-09-19 13:19:45,266 revolve] INFO Hello World!
...
This means that rvpath
points to the revolve
absolute directory path with usage of os.path.abspath(os.path.join(here, '..', 'revolve'))
command.
Why is this important?
Well, in the next step we will import Revolve-specific parts.
It will search for the Revolve classes within the search paths that we set, so it is important to know where our script is positioned.
The revolve.py
takes care of starting the simulator, but you can connect to it, insert and delete models from your script.
-
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.")
-
Run the script:
(.venv) ./revolve.py --simulator-cmd=gazebo --manager ./tutorial1.py
The output should be:
[manager] Hello World!`
[manager] Connected to the simulator world.
Program 'manager' exited normally
Terminating processes...
What changed!? Well, several things:
- First, we introduced
WorldManager
. It is a Python class that takes care of connecting to the simulator world and making changes during the simulation. - Second, you may notice that we imported
asyncio
library, and thatdef run():
now has a special prefixasync
. 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 withinWorldManager
class. - Third, 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.
-
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)
-
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
withawait world.pause(True)
. - Second, we added an asynchronous sleep so that the script does not exit instantly.
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 pyrevolve.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: Insert a Model
For more information about the Triangle of Life concept visit http://evosphere.eu/.
_________________
/ Premature \
| optimization |
| is the root of |
| all evil. |
| |
\ -- D.E. Knuth /
-----------------
\ ^__^
\ (oo)\_______
(__)\ )\/\
||----w |
|| ||