Skip to content

Latest commit

 

History

History
176 lines (135 loc) · 6.84 KB

scene_setup.md

File metadata and controls

176 lines (135 loc) · 6.84 KB
Magnebot

Scene Setup

For more information regarding TDW scene setup strategies, read this.

By design, scene setup for a Magnebot can be much more complicated than scene setup for a MagnebotController. This is intentional; the Magnebot agent is meant to be usable in any TDW controller.

Add Magnebot to a minimal scene

This is a minimal example of how to create a scene and add a Magnebot agent:

from tdw.controller import Controller
from tdw.tdw_utils import TDWUtils
from magnebot import Magnebot

c = Controller()
m = Magnebot()
c.add_ons.append(m)
c.communicate(TDWUtils.create_empty_room(12, 12))
print(m.dynamic.transform.position)
c.communicate({"$type": "terminate"})

This will set the initial position and rotation of the Magnebot:

from tdw.controller import Controller
from tdw.tdw_utils import TDWUtils
from magnebot import Magnebot

c = Controller()
m = Magnebot(position={"x": 1, "y": 0, "z": -2},
             rotation={"x": 0, "y": 30, "z": 0})
c.add_ons.append(m)
c.communicate(TDWUtils.create_empty_room(12, 12))
print(m.dynamic.transform.position)
c.communicate({"$type": "terminate"})

To replicate MagnebotController.init_scene() we need to add a few more things:

  • A load_scene command to totally re-load the scene (this isn't necessary for a minimal example but it's useful for when you want to reset the scene)
  • An ObjectManager add-on to cache static object data and manage dynamic object data per-frame.
  • A StepPhysics add-on to skip n frames per communicate call.
  • Post-processing commands

This controller adds a Magnebot and an object to a scene:

from tdw.controller import Controller
from tdw.tdw_utils import TDWUtils
from tdw.add_ons.step_physics import StepPhysics
from tdw.add_ons.object_manager import ObjectManager
from magnebot import Magnebot
from magnebot.util import get_default_post_processing_commands

c = Controller()
magnebot = Magnebot()
objects = ObjectManager()
step_physics = StepPhysics(num_frames=10)
c.add_ons.extend([magnebot, objects, step_physics])

commands = [{"$type": "load_scene",
             "scene_name": "ProcGenScene"},
            TDWUtils.create_empty_room(12, 12)]
commands.extend(c.get_add_physics_object(model_name="rh10",
                                         position={"x": -2, "y": 0, "z": -1.5},
                                         object_id=c.get_unique_id()))
commands.extend(get_default_post_processing_commands())
c.communicate(commands)
print(magnebot.dynamic.transform.position)
for object_id in objects.transforms:
    print(object_id, objects.transforms[object_id].position)
c.communicate({"$type": "terminate"})

Add Magnebot to floorplan scene

You can also add a Magnebot to a floorplan scene by adding a Floorplan. You can spawn the Magnebot in a given room by reading the spawn positions data file. Note that floorplan is first in the add_ons array; this is because add-ons are read sequentially. You must initialize the scene before adding the Magnebot.

from json import loads
from tdw.controller import Controller
from tdw.add_ons.step_physics import StepPhysics
from tdw.add_ons.object_manager import ObjectManager
from tdw.add_ons.floorplan import Floorplan
from magnebot import Magnebot
from magnebot.paths import SPAWN_POSITIONS_PATH

spawn_positions = loads(SPAWN_POSITIONS_PATH.read_text())

# Scene 1a, layout 0, room 2.
scene = "1a"
layout = 0
magnebot_position = spawn_positions["1"]["0"]["2"]

c = Controller()
magnebot = Magnebot(position=magnebot_position)
objects = ObjectManager()
step_physics = StepPhysics(num_frames=10)
floorplan = Floorplan()
floorplan.init_scene(scene=scene, layout=layout)
c.add_ons.extend([floorplan, magnebot, objects, step_physics])

c.communicate([])

print(magnebot.dynamic.transform.position)
for object_id in objects.transforms:
    print(object_id, objects.transforms[object_id].position)
c.communicate({"$type": "terminate"})

Images of the floorplans can be found here.

Images of the floorplan rooms can be found here.

Reset a scene

For more information regarding how to reset a scene, read this.

When resetting a scene, be sure to call magnebot.reset(position, rotation). If you're using an object manager, set object_manager.initialized = False.

from tdw.controller import Controller
from tdw.tdw_utils import TDWUtils
from tdw.add_ons.object_manager import ObjectManager
from magnebot import Magnebot, ActionStatus


class ResetScene(Controller):
    def __init__(self, port: int = 1071, check_version: bool = True, launch_build: bool = True):
        super().__init__(port=port, check_version=check_version, launch_build=launch_build)
        self.position = {"x": 1, "y": 0, "z": -2}
        self.rotation = {"x": 0, "y": 30, "z": 0}
        self.magnebot: Magnebot = Magnebot(position=self.position,
                                           rotation=self.rotation)
        self.object_manager: ObjectManager = ObjectManager()
        self.add_ons.extend([self.magnebot, self.object_manager])

    def init_scene(self):
        self.magnebot.reset(position=self.position, rotation=self.rotation)
        self.object_manager.initialized = False
        self.communicate([{"$type": "load_scene",
                           "scene_name": "ProcGenScene"},
                          TDWUtils.create_empty_room(12, 12)])


if __name__ == "__main__":
    c = ResetScene()
    c.init_scene()
    c.magnebot.move_by(2)
    while c.magnebot.action.status == ActionStatus.ongoing:
        c.communicate([])
    c.communicate([])
    c.init_scene()
    c.magnebot.move_by(1)
    while c.magnebot.action.status == ActionStatus.ongoing:
        c.communicate([])
    c.communicate([])
    c.communicate({"$type": "terminate"})

Next: Output data

Return to the README


Example controllers: