cyberbotics / webots

Webots Robot Simulator
https://cyberbotics.com
Apache License 2.0
3.26k stars 1.7k forks source link

Access to devices imported during simulation #1898

Closed tsampazk closed 4 years ago

tsampazk commented 4 years ago

Is your feature request related to a problem? Please describe. A previously exported device node .wbo that is imported into the simulation on runtime cannot be accessed with the getDevice() methods through a Robot controller.

This makes dynamic Robot creation impossible in a straightforward way, using the import* methods.

Describe the solution you'd like To somehow be possible to access previously imported devices during runtime.

Describe alternatives you've considered

  1. When building a dynamic robot, import (or preload) it with all the devices and nodes you might need and use the creation algorithm to delete nodes instead of importing, but this seems cumbersome and backwards.
  2. Access the devices some other way, e.g. through their respective node refs, which seems to also not be possible.

Thank you!

tsampazk commented 4 years ago

A workaround i am working on is to dynamically create the Robot node with all the appropriate devices etc. as a VRML string by using a custom parser and loading it altogether using importMFNodeFromString method, from another supervisor. Then the robot controller will have access to devices normally because it was initialized with them from the start.

omichel commented 4 years ago

Yes, that seems to be an excellent approach. Let us know whether it works as expected.

stefaniapedrazzi commented 4 years ago

The issue here is that the devices are all configured at the very first start of the controller program. So restarting the controller or (re-)creating the robot node both should work for you.

The workaround you described is perfectly fine. But just in case another option would also be to just restart the controller of the robot after importing all the devices wb_supervisor_node_restart_controller).

There is a third option that is to generate the Robot using procedural PROTO node with flags to choose the devices but depending on the application could be more complex than needed.

tsampazk commented 4 years ago

But just in case another option would also be to just restart the controller of the robot after importing all the devices wb_supervisor_node_restart_controller).

This workaround indeed works great and is probably way simpler to use than parsing VRML strings etc.

Here is a barebones example:

from controller import Supervisor

robot = Supervisor()
timestep = int(robot.getBasicTimeStep())

stringNode = """Solid {
  children [
    LightSensor {
    }
  ]
}"""

ls = robot.getLightSensor("light sensor")

if ls is None:
    robot.getSelf().getField("children").importMFNodeFromString(0, stringNode)
    robot.getSelf().restartController()
else:
    ls.enable(timestep)

while robot.step(timestep) != -1:
    if ls is not None:
        print(ls.getValue())
    else:
        print("ls is None")
stefaniapedrazzi commented 4 years ago

In Webots R2021a it is now possible to dynamically add devices and access them from the controller.