aidudezzz / deepbots

A wrapper framework for Reinforcement Learning in the Webots robot simulator using Python 3.
https://deepbots.readthedocs.io/
GNU General Public License v3.0
236 stars 50 forks source link

randomization possiblility? #44

Closed WSPeng closed 3 years ago

WSPeng commented 3 years ago

Hi, Do you know how to do randomization in webots via python? Like set the position of a solid randomly. I didn't find a way to move a object with python

tsampazk commented 3 years ago

Hello there!

In case you are not aware or for anyone else that might read this, on the official Webots documentation you can find all available methods for all nodes and their usage for multiple languages including python. Here you can find official guides and tutorials.

Moreover, the official Webots discord is great place for asking questions relating to Webots, usually answered by the developers of Webots. Also, you can find more third-party tutorials advertised in the discord server.

Nevertheless, i will do my best to answer your question. To set or get positions of nodes in the Webots simulation, you generally have to do it through a supervisor Robot node.

When a controller runs on a supervisor node it has access to additional methods. For your specific example you could possibly do it as follows:

  1. Create a Robot node and set it to supervisor through its atrributes on the tree view.
  2. Set the DEF of any node that you want to manipulate to your liking. You can set the DEF by left-clicking on a node in the tree view and a DEF field will appear to fill.
  3. Create a script and attach it to this node you want to manipulate.
  4. Use the getFromDef() method to get the reference to the node.
  5. From that node extract the translation field or whatever field you are interested in manipulating, using the `getField("translation") method.
  6. Use set methods to set the new value. For the translation field you need to use the setSFVec3f().

I am including an example supervisor controller and a world file demonstrating the solution. I hope it helps! :)

supervisor controller:

"""Supervisor that repeatedly randomizes the translation of an object"""
from controller import Supervisor
from random import uniform

# create the Supervisor instance.
supervisor = Supervisor()

# get the time step of the current world.
timestep = int(supervisor.getBasicTimeStep())

boxNode = supervisor.getFromDef("BOX")  # Get box node from its DEF
originalPosition = boxNode.getPosition()
print("Original position:", originalPosition)

boxTranslationField = boxNode.getField("translation")  # Get a handle of the translation field
# Main loop:
# - perform simulation steps until Webots is stopping the controller
countLimit = 50
count = 50
while supervisor.step(timestep) != -1:
    if count >= countLimit:
        newPos = originalPosition 
        newPos[0] = uniform(0.0, 0.3)  # x coordinate
        newPos[2] = uniform(0.0, 0.3)  # z coordinate

        # Here we set the translation field. 
        # Depending on the field type, other set methods need to be used
        boxTranslationField.setSFVec3f(newPos)

        print("New random position:", newPos)
        count = 0
    count += 1

.wbt file:

#VRML_SIM R2020b utf8
WorldInfo {
  coordinateSystem "NUE"
}
Viewpoint {
  orientation -0.6931032800836722 0.6931032800836722 0.1980295085953349 0.75
  position 0.6047745756810856 0.8076768137559899 0.9196826490423601
}
TexturedBackground {
}
TexturedBackgroundLight {
}
RectangleArena {
}
DEF BOX CardboardBox {
  translation 0 0.06 0
  size 0.1 0.1 0.1
}
Robot {
  controller "my_controller"
  supervisor TRUE
}