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
def __init__(self, resp: List[bytes]): """ :param resp: The response from the build. """ env = get_data(resp=resp, d_type=Envs) # Get the overall size of the scene. self.x_min = 1000 self.x_max = 0 self.z_min = 1000 self.z_max = 0 self.envs: List[Environment] = list() for i in range(env.get_num()): e = Environment(env=env, i=i) if e.x_0 < self.x_min: self.x_min = e.x_0 if e.z_0 < self.z_min: self.z_min = e.z_0 if e.x_1 > self.x_max: self.x_max = e.x_1 if e.z_1 > self.z_max: self.z_max = e.z_1 self.envs.append(e)
args = parser.parse_args() c = Controller() c.start() resp = c.communicate([ TDWUtils.create_empty_room(12, 12), c.get_add_object(model_name=args.model, object_id=0), { "$type": "send_composite_objects" }, { "$type": "send_segmentation_colors" } ]) c.communicate({"$type": "terminate"}) # Get the name of each object. colors = get_data(resp=resp, d_type=SegmentationColors) names = dict() for i in range(colors.get_num()): names[colors.get_object_id(i)] = colors.get_object_name(i) # Parse the composite object data. co = get_data(resp=resp, d_type=CompositeObjects) sub_objects = dict() for i in range(co.get_num()): object_id = co.get_object_id(i) for j in range(co.get_num_sub_objects(i)): machine = co.get_sub_object_machine_type(i, j) sub_object_id = co.get_sub_object_id(i, j) sub_objects[names[sub_object_id]] = { "amp": 0, "mass": 0,
"x": x, "y": 0, "z": z }, "scale": 0.3, "color": color }) # Create an overhead camera and capture an image. commands.extend( TDWUtils.create_avatar(position={ "x": 0, "y": 31, "z": 0 }, look_at=TDWUtils.VECTOR3_ZERO)) commands.extend([{ "$type": "set_pass_masks", "pass_masks": ["_img"] }, { "$type": "send_images" }]) resp = c.communicate(commands) # Save the image. images = get_data(resp=resp, d_type=Images) TDWUtils.save_images(images=images, filename=f"{scene}_{layout}", output_directory=output_dir, append_pass=False) print(scene, layout) c.communicate({"$type": "terminate"})
c = StickyMittenAvatarController() for scene in ["1a", "2a", "4a", "5a"]: for layout in [0, 1, 2]: print(scene, layout) c.init_scene(scene=scene, layout=layout) # Get the initial positions of each target object and container. positions = dict() for object_id in c.frame.object_transforms: if c.static_object_info[object_id].container or c.static_object_info[object_id].target_object: positions[object_id] = c.frame.object_transforms[object_id].position # Advance the simulation. for i in range(100): c.communicate([]) # Get the new position of the objects. resp = c.communicate({"$type": "send_transforms"}) tr = get_data(resp=resp, d_type=Transforms) distances = list() too_far = False for i in range(tr.get_num()): object_id = tr.get_id(i) if object_id in positions: distance = np.linalg.norm(positions[object_id] - np.array(tr.get_position(i))) if distance > 0.1: print(object_id, distance) too_far = True if not too_far: print("Good!\n") c.end()
commands.extend([{ "$type": "set_floorplan_roof", "show": False }, { "$type": "remove_position_markers" }, { "$type": "send_environments" }, { "$type": "send_version" }, { "$type": "send_segmentation_colors" }]) # Send the commands. resp = c.communicate(commands) env = Environments(resp=resp) is_standalone = get_data(resp=resp, d_type=Version).get_standalone() # Cache the names of all objects and get all surface models. segmentation_colors = get_data(resp=resp, d_type=SegmentationColors) object_names: Dict[int, str] = dict() surface_ids: List[int] = list() for i in range(segmentation_colors.get_num()): object_name = segmentation_colors.get_object_name(i).lower() object_id = segmentation_colors.get_object_id(i) object_names[object_id] = object_name # Check if this is a surface. # The record might be None if this is a composite object. if object_name in surface_object_categories: surface_ids.append(object_id)
spawn_positions = dict() # Iterate through each floorplan scene. for scene in [1, 2, 4, 5]: print(scene) spawn_positions[scene] = dict() # Get the scene bounds (use this to get the actual (x, z) coordinates). scene_bounds = sbd[str(scene)] # Load the scene and request Environments data. resp = c.communicate([ c.get_add_scene(scene_name=f"floorplan_{scene}a"), { "$type": "send_environments" } ]) envs = get_data(resp=resp, d_type=Environments) # Get the center of each room. centers = [] for i in range(envs.get_num()): centers.append(np.array(envs.get_center(i))) # Get the spawn positions per layout. for layout in [0, 1, 2]: spawn_positions[scene][layout] = list() for center in centers: # Load the occupancy map. occ = np.load( str( OCCUPANCY_MAP_DIRECTORY.joinpath( f"{scene}_{layout}.npy").resolve()))
target_object="a", images="cam") # Grasp and pick up the container. c.grasp_object(object_id=c.container_id, arm=Arm.right) c.reach_for_target(target={"x": 0.2, "y": 0.2, "z": 0.3}, arm=Arm.right) # Use low-level commands to rotate the head and save an image. # Don't use these in an actual simulation! # To rotate the camera, see: `StickyMittenAvatar.rotate_camera_by()` # To save an image, see: `FrameData` resp = c.communicate([{ "$type": "rotate_head_by", "axis": "pitch", "angle": 40 }, { "$type": "rotate_head_by", "axis": "yaw", "angle": 15 }, { "$type": "send_images", "frequency": "once", "avatar_id": "c" }]) # Save the image. TDWUtils.save_images(images=get_data(resp=resp, d_type=Images), output_directory=str(Path("..").resolve()), filename="social", append_pass=False) c.end()
def __init__(self, resp: List[bytes], objects: Dict[int, StaticObjectInfo], avatar: Avatar): """ :param resp: The response from the build. :param objects: Static object info per object. Key = the ID of the object in the scene. :param avatar: The avatar in the scene. """ self._frame_count = Controller.get_frame(resp[-1]) self.audio: List[Tuple[Base64Sound, int]] = list() collisions, env_collisions, rigidbodies = FrameData._P.get_collisions( resp=resp) # Record avatar collisions. if avatar is not None: self.avatar_object_collisions = avatar.collisions self.avatar_env_collisions = avatar.env_collisions self.held_objects = { Arm.left: avatar.frame.get_held_left(), Arm.right: avatar.frame.get_held_right() } else: self.avatar_object_collisions = None self.avatar_env_collisions = None self.held_objects = None # Get the object transform data. self.object_transforms: Dict[int, Transform] = dict() tr = get_data(resp=resp, d_type=Transforms) for i in range(tr.get_num()): o_id = tr.get_id(i) self.object_transforms[o_id] = Transform( position=np.array(tr.get_position(i)), rotation=np.array(tr.get_rotation(i)), forward=np.array(tr.get_forward(i))) # Get camera matrix data. matrices = get_data(resp=resp, d_type=CameraMatrices) self.projection_matrix = matrices.get_projection_matrix() self.camera_matrix = matrices.get_camera_matrix() # Get the transform data of the avatar. self.avatar_transform = Transform( position=np.array(avatar.frame.get_position()), rotation=np.array(avatar.frame.get_rotation()), forward=np.array(avatar.frame.get_forward())) self.avatar_body_part_transforms: Dict[int, Transform] = dict() for i in range(avatar.frame.get_num_body_parts()): self.avatar_body_part_transforms[avatar.frame.get_body_part_id( i)] = Transform( position=np.array(avatar.frame.get_body_part_position(i)), rotation=np.array(avatar.frame.get_body_part_rotation(i)), forward=np.array(avatar.frame.get_body_part_forward(i))) # Get the audio of each collision. for coll in collisions: if not FrameData._P.is_valid_collision(coll): continue collider_id = coll.get_collider_id() collidee_id = coll.get_collidee_id() collider_info: Optional[ObjectInfo] = None collidee_info: Optional[ObjectInfo] = None if collider_id in objects: collider_info = objects[collider_id].audio # Check if the object is a body part. else: if collider_id in avatar.body_parts_static: collider_info = avatar.body_parts_static[collider_id].audio if collidee_id in objects: collidee_info = objects[collidee_id].audio # Check if the object is a body part. else: if collidee_id in avatar.body_parts_static: collidee_info = avatar.body_parts_static[collidee_id].audio # If either object isn't a cached object, don't try to add audio. if collider_info is None or collidee_info is None: continue if collider_info.mass < collidee_info.mass: target_id = collider_id target_amp = collider_info.amp target_mat = collider_info.material.name other_id = collidee_id other_amp = collidee_info.amp other_mat = collider_info.material.name else: target_id = collidee_id target_amp = collidee_info.amp target_mat = collidee_info.material.name other_id = collider_id other_amp = collider_info.amp other_mat = collider_info.material.name rel_amp = other_amp / target_amp audio = FrameData._P.get_sound(coll, rigidbodies, other_id, other_mat, target_id, target_mat, rel_amp) self.audio.append((audio, target_id)) # Get the audio of each environment collision. for coll in env_collisions: collider_id = coll.get_object_id() if collider_id not in objects: continue v = FrameData._get_velocity(rigidbodies, collider_id) if (v is not None) and (v > 0): collider_info = objects[collider_id].audio audio = FrameData._P.get_sound( coll, rigidbodies, 1, FrameData._SURFACE_MATERIAL.name, collider_id, collider_info.material.name, 0.01) self.audio.append((audio, collider_id)) # Get the image data. self.id_pass: Optional[np.array] = None self.depth_pass: Optional[np.array] = None self.image_pass: Optional[np.array] = None for i in range(0, len(resp) - 1): if OutputData.get_data_type_id(resp[i]) == "imag": images = Images(resp[i]) for j in range(images.get_num_passes()): if images.get_pass_mask(j) == "_id": self.id_pass = images.get_image(j) elif images.get_pass_mask(j) == "_depth_simple": self.depth_pass = images.get_image(j) elif images.get_pass_mask(j) == "_img": self.image_pass = images.get_image(j)