示例#1
0
    def get_trial_initialization_commands(self) -> List[dict]:
        commands = []

        # randomization across trials
        if not(self.randomize):
            self.trial_seed = (self.MAX_TRIALS * self.seed) + self._trial_num
            random.seed(self.trial_seed)
        else:
            self.trial_seed = -1 # not used

        # Place target zone
        commands.extend(self._place_target_zone())

        # Choose and drop an object.
        commands.extend(self._place_drop_object())

        # Choose and place a middle object.
        commands.extend(self._place_intermediate_object())

        # Teleport the avatar to a reasonable position based on the drop height.
        a_pos = self.get_random_avatar_position(radius_min=self.camera_radius_range[0],
                                                radius_max=self.camera_radius_range[1],
                                                angle_min=self.camera_min_angle,
                                                angle_max=self.camera_max_angle,
                                                y_min=self.drop_height * self.camera_min_height,
                                                y_max=self.drop_height * self.camera_max_height,
                                                center=TDWUtils.VECTOR3_ZERO)

        cam_aim = {"x": 0, "y": self.drop_height * 0.5, "z": 0}
        commands.extend([
            {"$type": "teleport_avatar_to",
             "position": a_pos},
            {"$type": "look_at_position",
             "position": cam_aim},
            {"$type": "set_focus_distance",
             "focus_distance": TDWUtils.get_distance(a_pos, cam_aim)}
        ])

        # Set the camera parameters
        self._set_avatar_attributes(a_pos)

        self.camera_position = a_pos
        self.camera_rotation = np.degrees(np.arctan2(a_pos['z'], a_pos['x']))
        dist = TDWUtils.get_distance(a_pos, self.camera_aim)
        self.camera_altitude = np.degrees(np.arcsin((a_pos['y'] - self.camera_aim['y'])/dist))

        # For distractor placements
        self.middle_scale = self.zone_scale

        # Place distractor objects in the background
        commands.extend(self._place_background_distractors(z_pos_scale=1))

        # Place occluder objects in the background
        commands.extend(self._place_occluders(z_pos_scale=1))

        # test mode colors
        if self.use_test_mode_colors:
            self._set_test_mode_colors(commands)        

        return commands
示例#2
0
 def __init__(self, c_0: Dict[str, float], c_1: Dict[str, float]):
     """
     :param c_0: Center of a subsector.
     :param c_1: Center of a subsector.
     """
     self.c_0 = TDWUtils.vector3_to_array(c_0)
     self.c_1 = TDWUtils.vector3_to_array(c_1)
示例#3
0
    def _get_object_position(object_positions: List[ObjectPosition], max_tries: int = 1000, radius: float = 2) -> \
            Dict[str, float]:
        """
        Try to get a valid random position that doesn't interpentrate with other objects.

        :param object_positions: The positions and radii of all objects so far that will be added to the scene.
        :param max_tries: Try this many times to get a valid position before giving up.
        :param radius: The radius to pick a position in.

        :return: A valid position that doesn't interpentrate with other objects.
        """

        o_pos = TDWUtils.array_to_vector3(
            TDWUtils.get_random_point_in_circle(center=np.array([0, 0, 0]),
                                                radius=radius))
        # Pick a position away from other objects.
        ok = False
        count = 0
        while not ok and count < max_tries:
            count += 1
            ok = True
            for o in object_positions:
                # If the object is too close to another object, try another position.
                if TDWUtils.get_distance(o.position, o_pos) <= o.radius:
                    ok = False
                    o_pos = TDWUtils.array_to_vector3(
                        TDWUtils.get_random_point_in_circle(center=np.array(
                            [0, 0, 0]),
                                                            radius=radius))
        return o_pos
示例#4
0
    def trial_loop(self,
                   num: int,
                   output_dir: str,
                   temp_path: str) -> None:

        output_dir = Path(output_dir)
        if not output_dir.exists():
            output_dir.mkdir(parents=True)
        temp_path = Path(temp_path)
        if not temp_path.parent.exists():
            temp_path.parent.mkdir(parents=True)
        # Remove an incomplete temp path.
        if temp_path.exists():
            temp_path.unlink()

        pbar = tqdm(total=num)
        # Skip trials that aren't on the disk, and presumably have been uploaded; jump to the highest number.
        exists_up_to = 0
        for f in output_dir.glob("*.hdf5"):
            if int(f.stem) > exists_up_to:
                exists_up_to = int(f.stem)

        if exists_up_to > 0:
            print('Trials up to %d already exist, skipping those' % exists_up_to)

        pbar.update(exists_up_to)
        for i in range(exists_up_to, num):
            filepath = output_dir.joinpath(TDWUtils.zero_padding(i, 4) + ".hdf5")
            self.stimulus_name = '_'.join([filepath.parent.name, str(Path(filepath.name).with_suffix(''))])

            if not filepath.exists():

                # Save out images
                self.png_dir = None
                if any([pa in PASSES for pa in self.save_passes]):
                    self.png_dir = output_dir.joinpath("pngs_" + TDWUtils.zero_padding(i, 4))
                    if not self.png_dir.exists():
                        self.png_dir.mkdir(parents=True)

                # Do the trial.
                self.trial(filepath=filepath,
                           temp_path=temp_path,
                           trial_num=i)

                # Save an MP4 of the stimulus
                if self.save_movies:
                    for pass_mask in self.save_passes:
                        mp4_filename = str(filepath).split('.hdf5')[0] + pass_mask
                        cmd, stdout, stderr = pngs_to_mp4(
                            filename=mp4_filename,
                            image_stem=pass_mask[1:]+'_',
                            png_dir=self.png_dir,
                            size=[self._height, self._width],
                            overwrite=True,
                            remove_pngs=True,
                            use_parent_dir=False)
                    rm = subprocess.run('rm -rf ' + str(self.png_dir), shell=True)

            pbar.update(1)
        pbar.close()
示例#5
0
    def _push(self, position: Dict[str, float], target: Dict[str, float],
              force_mag: float) -> List[dict]:
        """
        :param position: The initial position.
        :param target: The target position (used for the force vector).
        :param force_mag: The force magnitutde.

        :return: A list of commands to push the object along the floor.
        """

        commands, soft_id = self._get_squishable(position=position,
                                                 rotation={
                                                     "x": 0,
                                                     "y":
                                                     random.uniform(0, 360),
                                                     "z": 0
                                                 })
        # Get a force vector towards the target.
        p0 = TDWUtils.vector3_to_array(position)
        p1 = TDWUtils.vector3_to_array(target)
        force = ((p1 - p0) / (np.linalg.norm(p1 - p0))) * force_mag
        # Add the force.
        commands.append({
            "$type": "apply_force_to_flex_object",
            "force": TDWUtils.array_to_vector3(force),
            "id": soft_id
        })

        return commands
    def run(self):
        self.start()

        width = 12
        length = 12

        # Create an empty room.
        self.communicate(TDWUtils.create_empty_room(width, length))

        # Disable physics.
        self.communicate({"$type": "simulate_physics", "value": False})

        # Add the avatar.
        self.communicate(
            TDWUtils.create_avatar(position={
                "x": -5,
                "y": 10,
                "z": -2
            },
                                   look_at=TDWUtils.VECTOR3_ZERO))

        # Create the dining table.
        self.dining_table()

        # Create the sofa.
        self.sofa(width, length)

        # Bake the NavMesh.
        self.communicate({"$type": "bake_nav_mesh", "carve_type": "none"})
        # Get a random position on the NavMesh.
        position = TDWUtils.get_random_position_on_nav_mesh(
            self, width, length)
        position = TDWUtils.array_to_vector3(position)
        # Add a side table.
        self.side_table(position)
示例#7
0
    def run(self):
        self.start()
        init_setup_commands = [{
            "$type": "set_screen_size",
            "width": 1280,
            "height": 962
        }, {
            "$type": "set_render_quality",
            "render_quality": 5
        }]
        self.communicate(init_setup_commands)

        # Create an empty room.
        self.load_streamed_scene(scene="tdw_room_2018")

        # Disable physics.
        self.communicate({"$type": "simulate_physics", "value": False})

        # Add the avatar.
        self.communicate(
            TDWUtils.create_avatar(position={
                "x": 0.9,
                "y": 1.5,
                "z": 0.9
            },
                                   look_at=TDWUtils.array_to_vector3(
                                       [0, 0.8, 0]),
                                   avatar_id="avatar"))

        # Create the dining table.
        self.dining_table()
示例#8
0
    def run(self):
        self.start()
        # Create an empty room.
        self.communicate(TDWUtils.create_empty_room(12, 12))

        # Create the avatar.
        self.communicate(
            TDWUtils.create_avatar(position={
                "x": 0,
                "y": 3,
                "z": -4
            },
                                   look_at=TDWUtils.VECTOR3_ZERO))

        # Set the pass mask to _depth only.
        # Get an image.
        resp = self.communicate([
            self.get_add_object("rh10", object_id=0), {
                "$type": "set_pass_masks",
                "avatar_id": "a",
                "pass_masks": ["_depth"]
            }, {
                "$type": "send_images",
                "frequency": "once"
            }
        ])
        images = Images(resp[0])
        # Get the depth values of each pixel.
        depth = TDWUtils.get_depth_values(images.get_image(0))
        print(depth)
示例#9
0
    def run(self, target: str):
        """
        Take a screenshot per record.

        :param target: The target model. If none, target all models.
        """

        # Get an image of just one model.
        if args.target:
            records = [self._lib.get_record(target)]
        # Get an image of all models.
        else:
            records = self._lib.records

        pbar = tqdm(total=len(records))
        for record in records:
            if not self._record_is_ok(record):
                pbar.update(1)
                continue
            record_name = record.name

            # Skip an image that exists.
            if not Path(self.output_dir).joinpath(record_name + ".jpg").exists():
                # Capture a screenshot.
                images, frame = self.get_image(record)
                # Save the image.
                TDWUtils.save_images(images, record_name,
                                     output_directory=self.output_dir, append_pass=False)
            pbar.update(1)
        # Terminate the build.
        self.communicate({"$type": "terminate"})
        pbar.close()
示例#10
0
    def run(self):
        self.start()
        # Create an office.
        self.communicate(create_office(12, 24, 4, 4, 6))

        # Get a random position on the NavMesh.
        x, y, z = TDWUtils.get_random_position_on_nav_mesh(self, 12, 24)

        # Index of the next destination.
        d = 0

        # Create the avatar.
        self.communicate(
            TDWUtils.create_avatar(avatar_type="A_Nav_Mesh",
                                   position={
                                       "x": x,
                                       "y": 0.5,
                                       "z": 0
                                   }))
        # Teleport the avatar.
        # Set the speed of the avatar.
        # Set the destination of the avatar.
        self.communicate([{
            "$type": "set_nav_mesh_avatar",
            "avatar_id": "a",
            "speed": 2
        }, {
            "$type": "set_nav_mesh_avatar_destination",
            "avatar_id": "a",
            "destination": NavMesh.DESTINATIONS[d]
        }])

        # Go to 3 destinations.
        i = 0
        while i < 3:
            resp = self.communicate({"$type": "do_nothing"})

            # If there is only 1 element in the response, it is an empty frame.
            if len(resp) == 1:
                continue
            # The avatar arrived at the destination!
            else:
                assert OutputData.get_data_type_id(resp[0]) == "anmd"

                # Parse the output data.
                data = ArrivedAtNavMeshDestination(resp[0])
                print(data.get_avatar_id())
                print("")

                i += 1
                d += 1
                if d >= len(NavMesh.DESTINATIONS):
                    d = 0
                # Set a new destination.
                self.communicate({
                    "$type": "set_nav_mesh_avatar_destination",
                    "avatar_id": "a",
                    "destination": NavMesh.DESTINATIONS[d]
                })
示例#11
0
    def get_p_1(self) -> Dict[str, float]:
        """
        :return: A position in the c_1 sub-sector.
        """

        return TDWUtils.array_to_vector3(
            TDWUtils.get_random_point_in_circle(center=self.c_1,
                                                radius=self.RADIUS))
示例#12
0
    def run(self):
        self.start()
        commands = [TDWUtils.create_empty_room(self.size, self.size)]
        commands.extend(
            TDWUtils.create_avatar(position={
                "x": 0,
                "y": 1.5,
                "z": 0
            },
                                   avatar_id="a"))
        commands.extend([{
            "$type": "set_pass_masks",
            "avatar_id": "a",
            "pass_masks": ["_img"]
        }, {
            "$type": "send_images",
            "frequency": "always"
        }])
        self.communicate(commands)

        # Listen for keys.
        # Turn left.
        self.listen(key="left",
                    commands={
                        "$type": "rotate_sensor_container_by",
                        "axis": "yaw",
                        "angle": self.angle * -1,
                        "sensor_name": "SensorContainer",
                        "avatar_id": "a"
                    })
        # Turn right.
        self.listen(key="right",
                    commands={
                        "$type": "rotate_sensor_container_by",
                        "axis": "yaw",
                        "angle": self.angle,
                        "sensor_name": "SensorContainer",
                        "avatar_id": "a"
                    })
        # Quit the application.
        self.listen(key="esc", function=self.stop)

        # Continue until the quit key is pressed.
        i = 0
        while not self.done:
            # Listen for keyboard input. Receive output data.
            resp = self.communicate([])
            for r in resp[:-1]:
                r_id = OutputData.get_data_type_id(r)
                # Save images.
                if r_id == "imag":
                    TDWUtils.save_images(
                        images=Images(r),
                        output_directory=self.images_directory,
                        filename=TDWUtils.zero_padding(i, width=4))
                    # Increment the image number.
                    i += 1
        self.communicate({"$type": "terminate"})
示例#13
0
    def run(self):
        # Create the output directory.
        output_directory = "example_output"
        if os.path.exists(output_directory):
            shutil.rmtree(output_directory)
            sleep(0.5)
            os.mkdir(output_directory)
        print(f"Images will be saved to: {output_directory}")

        self.start()
        # Create an empty room.
        self.communicate(TDWUtils.create_empty_room(12, 12))

        # Add the objects.
        lamp_id = self.add_object("alma_floor_lamp",
                                  position={"x": 1, "y": 0, "z": 0},
                                  rotation={"x": 0, "y": 90, "z": 0})
        self.add_object("live_edge_coffee_table",
                        position={"x": 1.5, "y": 0, "z": 1.5},
                        rotation={"x": 0, "y": 30, "z": 0})
        self.add_object("small_table_green_marble",
                        position={"x": -0.9, "y": 0, "z": -1.35})

        # Create the avatar.
        self.communicate({"$type": "create_avatar",
                          "type": "A_Img_Caps_Kinematic",
                          "id": "a"})

        # Try to find a valid position on the NavMesh.
        x, y, z = TDWUtils.get_random_position_on_nav_mesh(self, 12, 12)

        # Teleport the avatar to the valid position.
        # Apply a force to the lamp.
        # Set the pass masks to _img.
        # Enable image capture.
        self.communicate([{"$type": "teleport_avatar_to",
                           "avatar_id": "a",
                           "position": {"x": x, "y": 1.5, "z": z}},
                          {"$type": "apply_force_to_object",
                           "force": {"x": 2, "y": 1, "z": 0},
                           "id": lamp_id},
                          {"$type": "set_pass_masks",
                           "avatar_id": "a",
                           "pass_masks": ["_img", "_id"]},
                          {"$type": "send_images",
                           "frequency": "always"},
                          ])

        # Capture 100 images.
        for i in range(100):
            # Look at the lamp.
            resp = self.communicate({"$type": "look_at",
                                     "avatar_id": "a",
                                     "object_id": lamp_id,
                                     "use_centroid": True})
            images = Images(resp[0])
            # Save the image.
            TDWUtils.save_images(images, TDWUtils.zero_padding(i), output_directory=output_directory)
示例#14
0
    def run(self):
        self.start()
        init_setup_commands = [{"$type": "set_screen_size",
                                "width": 1280,
                                "height": 962},
                               {"$type": "set_render_quality",
                                "render_quality": 5}]
        self.communicate(init_setup_commands)

        # Create an empty room.
        self.load_streamed_scene(scene="tdw_room_2018")

        # Disable physics.
        self.communicate({"$type": "set_gravity",
                          "value": False})

        # Add the avatar.
        self.communicate(TDWUtils.create_avatar(position={"x": 0, "y": 1, "z": 0},
                                                look_at=TDWUtils.array_to_vector3([2, 0.8, -1.5]),
                                                avatar_id="avatar"))

        # self.communicate({"$type": "set_field_of_view",
        #                   "field_of_view": 68.0,
        #                   "avatar_id": "avatar"})

        table_id = self.add_object(model_name="glass_table",
                                   position={"x": 2, "y": 0, "z": -1.5},
                                   library="models_full.json")

        table_bounds = self.get_bounds_data(table_id)
        top = table_bounds.get_top(0)

        self.add_object(model_name="flower_vase_set_2",
                        position={"x": 1.6, "y": top[1], "z": -1.5},
                        library="models_full.json")

        self.add_object(model_name="flower_vase_set_2",
                        position={"x": 2, "y": top[1], "z": -1.5},
                        library="models_full.json")

        self.add_object(model_name="flower_vase_set_2",
                        position={"x": 2.4, "y": top[1], "z": -1.5},
                        library="models_full.json")

        # Enable image capture
        self.communicate({"$type": "set_pass_masks",
                          "avatar_id": "avatar",
                          "pass_masks": ["_img", "_id"]})

        self.communicate({"$type": "send_images",
                          "frequency": "always"})

        scene_data = self.communicate({"$type": "look_at_position",
                                       "avatar_id": "avatar",
                                       "position": TDWUtils.array_to_vector3([2, 0.8, -1.5])})

        images = Images(scene_data[0])
        TDWUtils.save_images(images, "flowers_row", output_directory="replicated_images")
示例#15
0
    def create_scene(self):
        """
        Initialize a blank room.
        """

        self.start()
        commands = [TDWUtils.create_empty_room(12, 12)]
        commands.extend(TDWUtils.create_avatar(position={"x": 5, "y": 10, "z": 5}, look_at=TDWUtils.VECTOR3_ZERO))
        self.communicate(commands)
示例#16
0
 def is_done(self, resp: List[bytes], frame: int) -> bool:
     for r in resp[:-1]:
         r_id = OutputData.get_data_type_id(r)
         # If the ball reaches or overshoots the destination, the trial is done.
         if r_id == "tran":
             t = Transforms(r)
             d0 = TDWUtils.get_distance(
                 TDWUtils.array_to_vector3(t.get_position(0)), self._p0)
             d1 = TDWUtils.get_distance(self._p0, self._p1)
             return d0 > d1 * 1.5
     return False
示例#17
0
    def communicate(self, commands: Union[dict, List[dict]]) -> List[bytes]:
        resp = super().communicate(commands)

        # Save images per frame.
        images = get_data(resp=resp, d_type=Images)
        if images is not None:
            TDWUtils.save_images(images=images,
                                 filename=TDWUtils.zero_padding(
                                     self.frame_count, width=4),
                                 output_directory=self.output_dir)
            self.frame_count += 1
        return resp
示例#18
0
    def run(self, drag_on_land, angular_drag_on_land):
        self.start()
        self.communicate(TDWUtils.create_empty_room(40, 40))

        # Create the avatar.
        self.communicate(TDWUtils.create_avatar(avatar_type="A_Simple_Body",
                                                position={"x": 0, "y": 1, "z": 0}))

        # When the y value of the avatar's position is this value, the avatar is on the ground.
        ground_y = 1
        # When the y value of the avatar's position exceeds ground_y by this much, it is in the air.
        in_air_threshold = 0.05

        # If true, the avatar is in the air.
        is_in_air = False

        # Set high default drag values.
        # Set a low mass.
        # Apply a force.
        # Request avatar data.
        resp = self.communicate([{"$type": "set_avatar_drag",
                                  "avatar_id": "a",
                                  "drag": 30,
                                  "angular_drag": 80},
                                 {"$type": "send_avatars",
                                  "frequency": "always"},
                                 {"$type": "apply_force_to_avatar",
                                  "avatar_id": "a",
                                  "direction": {"x": 0.3, "y": 0.7, "z": 0},
                                  "magnitude": 900}])

        for i in range(500):
            x, y, z = AvatarSimpleBody(resp[0]).get_position()
            # If the avatar just launched in to the air, set its drag values to 0.
            if y > ground_y + in_air_threshold and not is_in_air:
                is_in_air = True
                resp = self.communicate({"$type": "set_avatar_drag",
                                         "avatar_id": "a",
                                         "drag": 0,
                                         "angular_drag": 0})
                print("The avatar is in the air on frame: " + str(Controller.get_frame(resp[-1])))
            # If the avatar just landed on the ground, set drag values.
            elif y <= ground_y + in_air_threshold and is_in_air:
                resp = self.communicate({"$type": "set_avatar_drag",
                                         "avatar_id": "a",
                                         "drag": drag_on_land,
                                         "angular_drag": angular_drag_on_land})
                is_in_air = False
                print("The avatar is on the ground on frame: " + str(Controller.get_frame(resp[-1])))
            # Wait.
            else:
                resp = self.communicate({"$type": "do_nothing"})
示例#19
0
    def run(self):
        self.start()

        # Create the room from an image.
        self.communicate(TDWUtils.create_room_from_image("room.png"))
        self.communicate({"$type": "set_post_process", "value": False})
        self.communicate(
            TDWUtils.create_avatar(position={
                "x": 0,
                "y": 40,
                "z": 0
            },
                                   look_at=TDWUtils.VECTOR3_ZERO))
示例#20
0
    def run(self):
        self.start()
        init_setup_commands = [{"$type": "set_screen_size",
                                "width": 600,
                                "height": 480},
                               {"$type": "set_render_quality",
                                "render_quality": 5}]
        self.communicate(init_setup_commands)

        width = 8
        length = 8

        # Create an empty room.
        self.load_streamed_scene("box_room_2018")

        # Disable physics.
        self.communicate({"$type": "set_gravity",
                          "value": False})

        # Add the avatar.
        self.communicate(TDWUtils.create_avatar(position={"x": 0, "y": 1.7, "z": 0},
                                                look_at={"x": 0.3, "y": 0.8, "z": 2.2},
                                                avatar_id="avatar"))

        self.communicate({"$type": "set_field_of_view",
                          "field_of_view": 68.0,
                          "avatar_id": "avatar"})

        self.add_object(model_name="b06_bikenew",
                        position={"x": 0.3, "y": 0, "z": 2.2},
                        rotation={"x": 0, "y": 180, "z": 0},
                        library="models_full.json")

        self.add_object(model_name="animal_dog_rtsit_1280",
                        position={"x": 0.35, "y": 0, "z": 1.8},
                        library="models_full.json")

        # Enable image capture
        self.communicate({"$type": "set_pass_masks",
                          "avatar_id": "avatar",
                          "pass_masks": ["_img", "_id"]})

        self.communicate({"$type": "send_images",
                          "frequency": "always"})

        scene_data = self.communicate({"$type": "look_at_position",
                                       "avatar_id": "avatar",
                                       "position": {"x": 0.3, "y": 0.8, "z": 2.2}})

        images = Images(scene_data[0])
        TDWUtils.save_images(images, "dog_bike", output_directory="replicated_images/interior")
示例#21
0
 def run(self):
     # Create the scene.
     # Set image encoding globals.
     self.start()
     commands = [TDWUtils.create_empty_room(12, 12),
                 {"$type": "set_screen_size",
                  "width": 128,
                  "height": 128},
                 {"$type": "set_img_pass_encoding",
                  "value": False}]
     # Create the avatar.
     commands.extend(TDWUtils.create_avatar(position={"x": 2.478, "y": 1.602, "z": 1.412},
                                            look_at=TDWUtils.VECTOR3_ZERO,
                                            avatar_id="a"))
     # Enable all pass masks. Request an image for this frame only.
     commands.extend([{"$type": "set_pass_masks",
                       "pass_masks": ["_img", "_id", "_category", "_mask", "_depth", "_normals", "_flow",
                                      "_depth_simple", "_albedo"],
                       "avatar_id": "a"},
                      {"$type": "send_images",
                       "ids": ["a"],
                       "frequency": "once"}])
     # Add objects.
     commands.append(self.get_add_object("small_table_green_marble",
                                         position=TDWUtils.VECTOR3_ZERO,
                                         rotation=TDWUtils.VECTOR3_ZERO,
                                         object_id=0))
     commands.append(self.get_add_object("rh10",
                                         position={"x": 0.7, "y": 0, "z": 0.4},
                                         rotation={"x": 0, "y": 30, "z": 0},
                                         object_id=1))
     commands.append(self.get_add_object("jug01",
                                         position={"x": -0.3, "y": 0.9, "z": 0.2},
                                         rotation=TDWUtils.VECTOR3_ZERO,
                                         object_id=3))
     commands.append(self.get_add_object("jug05",
                                         position={"x": 0.3, "y": 0.9, "z": -0.2},
                                         rotation=TDWUtils.VECTOR3_ZERO,
                                         object_id=4))
     # Send the commands.
     resp = self.communicate(commands)
     # Save the images.
     for r in resp[:-1]:
         r_id = OutputData.get_data_type_id(r)
         if r_id == "imag":
             # Save the images.
             TDWUtils.save_images(output_directory="dist", images=Images(r), filename="0")
             print(f"Images saved to: {Path('dist').resolve()}")
     # Stop the build.
     self.communicate({"$type": "terminate"})
示例#22
0
    def run(self):
        self.start()
        self.communicate(TDWUtils.create_empty_room(20, 20))
        self.communicate(TDWUtils.create_avatar(position={"x": 0, "y": 3, "z": -6},
                                                look_at=TDWUtils.VECTOR3_ZERO))
        model_name = "rh10"

        z = -3

        x = -1.5
        print("With the add_object command (complex syntax but you have maximum control):")
        record = ModelLibrarian().get_record(model_name)
        self.communicate({"$type": "add_object",
                          "name": model_name,
                          "url": record.get_url(),
                          "scale_factor": record.scale_factor,
                          "position": {"x": x, "y": 0, "z": z},
                          "rotation": TDWUtils.VECTOR3_ZERO,
                          "category": record.wcategory,
                          "id": self.get_unique_id()})

        x = 0
        print("With the wrapper function Controller.add_object() "
              "(easy to use, but you can't add additional commands to this frame):")
        self.add_object(model_name=model_name,
                        position={"x": x, "y": 0, "z": z},
                        rotation=TDWUtils.VECTOR3_ZERO, 
                        library="models_core.json")

        x = 1.5
        print("With the wrapper function Controller.get_add_object() "
              "(harder to use, but you can add commands to this frame):")
        self.communicate(self.get_add_object(model_name=model_name,
                                             object_id=self.get_unique_id(),
                                             position={"x": x, "y": 0, "z": 0},
                                             rotation=TDWUtils.VECTOR3_ZERO,
                                             library="models_core.json"))

        print("With the add_object command, minus all optional parameters (the model won't scale properly!):")
        self.communicate({"$type": "add_object",
                          "name": model_name,
                          "url": record.get_url(),
                          "id": self.get_unique_id()})

        print("With the wrapper function Controller.add_object(), minus all optional parameters:")
        self.add_object(model_name)

        print("With the wrapper function Controller.get_add_object(), minus all optional parameters:")
        self.communicate(self.get_add_object(model_name=model_name,
                                             object_id=self.get_unique_id()))
示例#23
0
    def get_rotated_target(self, target: np.array) -> np.array:
        """
        Rotate the target by the avatar's forward directional vector.

        :param target: The target position.

        :return: The rotated position.
        """

        angle = TDWUtils.get_angle_between(v1=FORWARD,
                                           v2=self.frame.get_forward())

        return TDWUtils.rotate_position_around(position=target -
                                               self.frame.get_position(),
                                               angle=-angle)
示例#24
0
    def push_into_other(self) -> List[dict]:
        """
        :return: A list of commands to push one object into another object.
        """

        # Get two points some distance from each other.
        p0 = np.array([0, 0, 0])
        p1 = np.array([0, 0, 0])
        center = np.array([0, 0, 0])
        count = 0
        while count < 1000 and np.linalg.norm(np.abs(p1 - p0)) < 1.5:
            p0 = TDWUtils.get_random_point_in_circle(center=center, radius=2)
            p1 = TDWUtils.get_random_point_in_circle(center=center, radius=2)
            count += 1
        p0 = TDWUtils.array_to_vector3(p0)
        p0["y"] = 0.2
        p1 = TDWUtils.array_to_vector3(p1)
        p1["y"] = 0.1
        # Get commands to create the first object and push it.
        commands = self._push(position=p0,
                              target=p1,
                              force_mag=random.uniform(1000, 2000))
        # Add commands for the second object.
        second_object_commands, s_id = self._get_squishable(position=p1,
                                                            rotation={
                                                                "x":
                                                                0,
                                                                "y":
                                                                random.uniform(
                                                                    0, 360),
                                                                "z":
                                                                0
                                                            })
        commands.extend(second_object_commands)

        # Set the avatar.
        # Get the midpoint between the objects and use this to place the avatar.
        p_med = TDWUtils.array_to_vector3(
            np.array([(p0["x"] + p1["x"]) / 2, 0, (p0["z"] + p1["z"]) / 2]))
        commands.extend(
            self._set_avatar(a_pos=self.get_random_avatar_position(
                radius_min=1.8,
                radius_max=2.3,
                y_min=1,
                y_max=1.75,
                center=p_med),
                             cam_aim=p1))
        return commands
示例#25
0
    def get_trial_initialization_commands(self) -> List[dict]:
        commands = []

        # place a ramp
        commands.extend(self._place_ramp_object())

        # Choose and place a target object.
        # commands.extend(self._place_target_object())

        # Choose and drop an object.
        #commands.extend(self._place_drop_object())

        # Teleport the avatar to a reasonable position based on the drop height.
        a_pos = self.get_random_avatar_position(radius_min=0.5,
                                                radius_max=1,
                                                angle_min=0,
                                                angle_max=10,
                                                y_min=0.5,
                                                y_max=1,
                                                center=TDWUtils.VECTOR3_ZERO)
        print("avatar pos", a_pos)

        cam_aim = {"x": 0, "y": 0, "z": 0}
        commands.extend([
            {"$type": "teleport_avatar_to",
             "position": a_pos},
            {"$type": "look_at_position",
             "position": cam_aim},
            {"$type": "set_focus_distance",
             "focus_distance": TDWUtils.get_distance(a_pos, cam_aim)}
        ])
        return commands
示例#26
0
    def _set_avatar(a_pos: Dict[str, float],
                    cam_aim: Dict[str, float]) -> List[dict]:
        """
        :param a_pos: The avatar position.
        :param cam_aim: The camera aim point.

        :return: A list of commands to teleport the avatar and rotate the sensor container.
        """

        return [{
            "$type": "teleport_avatar_to",
            "position": a_pos
        }, {
            "$type": "look_at_position",
            "position": cam_aim
        }, {
            "$type": "set_focus_distance",
            "focus_distance": TDWUtils.get_distance(a_pos, cam_aim)
        }, {
            "$type": "rotate_sensor_container_by",
            "axis": "pitch",
            "angle": random.uniform(-3, 3)
        }, {
            "$type": "rotate_sensor_container_by",
            "axis": "yaw",
            "angle": random.uniform(-3, 3)
        }]
示例#27
0
    def get_falling_commands(self, mass: float = 3) -> List[List[dict]]:
        """
        :param mass: Objects with <= this mass might receive a force.

        :return: A list of lists; per-frame commands to make small objects fly up.
        """

        per_frame_commands: List[List[dict]] = []

        # Get a list of all small objects.
        small_ids = self.get_objects_by_mass(mass)
        random.shuffle(small_ids)
        max_num_objects = len(small_ids) if len(small_ids) < 8 else 8
        min_num_objects = max_num_objects - 3
        if min_num_objects <= 0:
            min_num_objects = 1
        # Add some objects.
        for i in range(random.randint(min_num_objects, max_num_objects)):
            o_id = small_ids.pop(0)
            force_dir = np.array([random.uniform(-0.125, 0.125), random.uniform(0.7, 1), random.uniform(-0.125, 0.125)])
            force_dir = force_dir / np.linalg.norm(force_dir)
            min_force = self.physics_info[o_id].mass * 2
            max_force = self.physics_info[o_id].mass * 4
            force = TDWUtils.array_to_vector3(force_dir * random.uniform(min_force, max_force))
            per_frame_commands.append([{"$type": "apply_force_to_object",
                                        "force": force,
                                        "id": o_id}])
            # Wait some frames.
            for j in range(10, 30):
                per_frame_commands.append([])
        return per_frame_commands
示例#28
0
    def _place_camera(self) -> List[dict]:
        commands = []
        a_pos = self.get_random_avatar_position(
            radius_min=self.camera_radius_range[0],
            radius_max=self.camera_radius_range[1],
            angle_min=self.camera_min_angle,
            angle_max=self.camera_max_angle,
            y_min=self.camera_min_height,
            y_max=self.camera_max_height,
            center=TDWUtils.VECTOR3_ZERO,
            reflections=self.camera_left_right_reflections)
        self._set_avatar_attributes(a_pos)
        commands.extend([{
            "$type": "teleport_avatar_to",
            "position": self.camera_position
        }, {
            "$type": "look_at_position",
            "position": self.camera_aim
        }, {
            "$type":
            "set_focus_distance",
            "focus_distance":
            TDWUtils.get_distance(a_pos, self.camera_aim)
        }])

        return commands
示例#29
0
    def run():
        # Create the asset bundle and the record.
        asset_bundle_paths, record_path = AssetBundleCreator(
        ).create_asset_bundle("cube.fbx", True, 123, "", 1)
        # Get the name of the bundle for this platform. For example, Windows -> "StandaloneWindows64"
        bundle = SYSTEM_TO_UNITY[system()]
        # Get the correct asset bundle path.
        for p in asset_bundle_paths:
            # Get the path to the asset bundle.
            if bundle in str(p.parent.resolve()):
                url = "file:///" + str(p.resolve())

                # Launch the controller.
                c = Controller()
                c.start()
                # Create the environment.
                # Add the object.
                commands = [{
                    "$type": "create_empty_environment"
                }, {
                    "$type": "add_object",
                    "name": "cube",
                    "url": url,
                    "scale_factor": 1,
                    "id": c.get_unique_id()
                }]
                # Create the avatar.
                commands.extend(
                    TDWUtils.create_avatar(position={
                        "x": 0,
                        "y": 0,
                        "z": -3.6
                    }))
                c.communicate(commands)
                return
示例#30
0
 def get_per_frame_commands(self, resp: List[bytes], frame) -> List[dict]:
     commands = []
     # Apply a force.
     if frame < self._num_force_frames:
         for r in resp[:-1]:
             if FlexParticles.get_data_type_id(r) == "flex":
                 fp = FlexParticles(r)
                 for i in range(fp.get_num_objects()):
                     # Find the cloth.
                     if fp.get_id(i) == self.cloth_id:
                         forces = []
                         p_id = 0
                         for p in fp.get_particles(i):
                             # Add a force if this is a "corner particle".
                             if np.abs(np.linalg.norm(p[:-1] - self._corner)
                                       ) <= self._corner_radius:
                                 # Calculate the force.
                                 pos = np.array(p[:-1])
                                 force = ((pos - self._corner) / np.linalg.norm(pos - self._corner)) * self.\
                                     _force_per_frame
                                 # Add the force and particle ID.
                                 forces.extend(force)
                                 forces.append(p_id)
                             p_id += 1
                         # Encode and send the force.
                         commands.extend([{
                             "$type":
                             "apply_forces_to_flex_object_base64",
                             "forces_and_ids_base64":
                             TDWUtils.get_base64_flex_particle_forces(
                                 forces),
                             "id":
                             self.cloth_id
                         }])
     return commands