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) # Create an empty room. self.communicate(TDWUtils.create_empty_room(10, 10)) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) self.communicate(self.get_add_hdri_skybox("autumn_hockey_4k")) # Add the avatar. self.communicate(TDWUtils.create_avatar(position={"x": 3, "y": 1.3, "z": 0}, look_at=TDWUtils.array_to_vector3([0, 0.5, 0]), avatar_id="avatar")) lib = MaterialLibrarian(library="materials_med.json") record = lib.get_record("grass_countryside") print(record) self.communicate({"$type": "add_material", "name": "grass_countryside", "url": record.get_url()}) self.communicate({"$type": "set_proc_gen_floor_material", "name": "grass_countryside"}) # self.communicate({"$type": "set_field_of_view", # "field_of_view": 68.0, # "avatar_id": "avatar"}) self.add_object(model_name="b05_clochild4", position={"x": 0, "y": 0, "z": 0}, rotation={"x": 0, "y": 30, "z": 0}, library="models_full.json") self.add_object(model_name="baseballbat", position={"x": 0.5, "y": 0, "z": 0.3}, rotation={"x": 0, "y": 30, "z": 0}, library="models_full.json") self.add_object(model_name="base-ball", position={"x": 0.4, "y": 0, "z": 0.22}, rotation={"x": 0, "y": 30, "z": 10}, 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([0, 0.5, 0])}) images = Images(scene_data[0]) TDWUtils.save_images(images, "kid_baseball", output_directory="/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior")
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) # Create an empty room. self.communicate(TDWUtils.create_empty_room(32, 32)) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate(TDWUtils.create_avatar(position={"x": -1.5, "y": 1.5, "z": -15}, look_at=TDWUtils.array_to_vector3([-1.7, 0.7, -2.3]), avatar_id="avatar")) lib = MaterialLibrarian(library="materials_med.json") record = lib.get_record("concrete_chipped_cracked") self.communicate({"$type": "add_material", "name": "concrete_chipped_cracked", "url": record.get_url()}) self.communicate({"$type": "set_proc_gen_floor_material", "name": "concrete_chipped_cracked"}) # self.communicate({"$type": "set_proc_gen_walls_material", "name": "concrete"}) self.communicate({"$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar"}) bus = self.add_object(model_name="b06_bus_new", position={"x": -2, "y": 0, "z": 0}, rotation={"x": 0, "y": -70, "z": 0}, library="models_full.json") bus_bounds = self.get_bounds_data(bus) bus_front = bus_bounds.get_front(0) print(bus_front) self.add_object(model_name="3dscan_man_004", position={"x": -3.7, "y": 0, "z": -7.3}, rotation={"x": 0, "y": 0, "z": 0}, 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([-1.7, 0.7, -2.3])}) images = Images(scene_data[0]) TDWUtils.save_images(images, "bus", output_directory="/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior")
def __init__(self, port: int = 1071): super().__init__(port=port) self._occluders: List[ModelRecord] = ModelLibrarian(str(Path("occluders.json").resolve())).records self._ball = ModelLibrarian("models_flex.json").get_record("sphere") self._ball_id = 0 self._occ_id = 1 self.material_librarian = MaterialLibrarian()
def get_add_material(self, material_name: str, library: str = "") -> dict: """ Returns a valid add_material command. :param material_name: The name of the material. :param library: The path to the records file. If left empty, the default library will be selected. See `MaterialLibrarian.get_library_filenames()` and `MaterialLibrarian.get_default_library()`. :return An add_material command that the controller can then send. """ if self.material_librarian is None: self.material_librarian = MaterialLibrarian(library=library) record = self.material_librarian.get_record(material_name) return { "$type": "add_material", "name": material_name, "url": record.get_url() }
def run(self): self.create_scene() print("Using Controller.get_add_material wrapper function:") self.communicate([self.get_add_material("parquet_long_horizontal_clean"), {"$type": "set_proc_gen_floor_material", "name": "parquet_long_horizontal_clean"}]) sleep(5) self.create_scene() print("Using the add_material command without any wrappers:") lib = MaterialLibrarian() record = lib.get_record("parquet_long_horizontal_clean") self.communicate([{"$type": "add_material", "name": record.name, "url": record.get_url()}, {"$type": "set_proc_gen_floor_material", "name": "parquet_long_horizontal_clean"}])
def __init__(self, port=1071, visual_material_swapping=False, new=False, screen_size=256, output_size=256, hdri=False, show_objects=True, clamp_rotation=False, max_height=1.0, grayscale_threshold=0.5, less_dark=False, id_pass=False, no_overwrite=False, do_zip=False, train=1300000, val=50000, library="models_full.json"): """ :param port: The port used to connect to the build. :param visual_material_swapping: If true, set random visual materials per frame. :param new: If true, clear the list of models that have already been used. :param screen_size: The screen size of the build. :param output_size: The size of the output images. :param hdri: If true, use a random HDRI skybox per frame. :param show_objects: If true, show objects. :param clamp_rotation: If true, clamp the rotation to +/- 30 degrees around each axis. :param max_height: The percentage of the environment height that is the ceiling for the avatar and object. Must be between 0 and 1. :param grayscale_threshold: The grayscale threshold. Higher value = slower FPS, better composition. Must be between 0 and 1. :param less_dark: If true, there will be more daylight exterior skyboxes (requires hdri == True) :param id_pass: If true, send the _id pass. :param no_overwrite: If true, don't overwrite images. :param do_zip: If true, zip the directory at the end. :param train: Number of train images. :param val: Number of val images. :param library: The path to the library records file. """ self.screen_size = screen_size self.output_size = output_size self.show_objects = show_objects self.clamp_rotation = clamp_rotation self.max_height = max_height self.grayscale_threshold = grayscale_threshold self.id_pass = id_pass self.no_overwrite = no_overwrite self.do_zip = do_zip self.train = train self.val = val assert 0 < max_height <= 1.0, f"Invalid max height: {max_height}" assert 0 < grayscale_threshold <= 1.0, f"Invalid grayscale threshold: {grayscale_threshold}" self.less_dark = less_dark self.substructures: Dict[str, List[dict]] = {} self.new = new super().__init__(port=port) self.model_librarian = ModelLibrarian(library=library) self.material_librarian = MaterialLibrarian("materials_high.json") self.hdri_skybox_librarian = HDRISkyboxLibrarian() # Get material records. if visual_material_swapping: self.materials = self.material_librarian.records else: self.materials = None # Get skybox records. if hdri: self.skyboxes = self.hdri_skybox_librarian.records # Prefer exterior daytime skyboxes by adding them multiple times to the list. if self.less_dark: temp = self.skyboxes[:] for skybox in temp: if skybox.location != "interior" and skybox.sun_elevation >= 145: self.skyboxes.append(skybox) else: self.skyboxes = None
def _get_librarian(self, library: str): return MaterialLibrarian(library + ".json")
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) # Create an empty room. self.communicate(TDWUtils.create_empty_room(16, 16)) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": -7.5, "y": 1.5, "z": 0 }, look_at=TDWUtils.array_to_vector3( [0, 0.7, 0]), avatar_id="avatar")) lib = MaterialLibrarian(library="materials_med.json") record = lib.get_record("concrete_asphalt_rolled") self.communicate({ "$type": "add_material", "name": "concrete_asphalt_rolled", "url": record.get_url() }) self.communicate({ "$type": "set_proc_gen_floor_material", "name": "concrete_asphalt_rolled" }) # self.communicate({"$type": "set_proc_gen_walls_material", "name": "concrete"}) self.communicate({ "$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar" }) self.add_object(model_name="b05_2018_chevy_tahoe_rst", position={ "x": 3, "y": 0, "z": 0.5 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") self.add_object(model_name="b05_chevrolet_camaro_3ds_max_2010_v-ray", position={ "x": -2, "y": 0, "z": -3 }, rotation={ "x": 0, "y": 0, "z": 0 }, library="models_full.json") self.add_object(model_name="b04_harley_davidson_3dsmax2014", position={ "x": -4.2, "y": 0, "z": 2 }, rotation={ "x": 0, "y": 0, "z": 0 }, library="models_full.json") self.add_object(model_name="audia7_2018_vray", position={ "x": -6.5, "y": 0, "z": -3 }, rotation={ "x": 0, "y": 0, "z": 0 }, 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([0, 0.7, 0]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "cars_bikes", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior" )
print(vars(parser.parse_args())) return args if __name__ == '__main__': # args = get_collide_args("collide") # print([m.name for m in MODEL_LIBRARIES['models_full.json'].records \ # if 'incline' == m.wcategory]) # c = SceneLibrarian() # print([r.name for r in c.search_records(search="room")]) c = MaterialLibrarian() ms = c.get_material_types() print(ms) print([m.name for m in c.get_all_materials_of_type("Plastic")]) # metal = [m for m in c.get_all_materials_of_type("Metal") if "steel_rusty" in m.name] # print(metal[0], metal[0].name) # for m in ms: # more_ms = c.get_all_materials_of_type(m) # print(m, [_m.name for _m in more_ms]) # C = MultiDominoes() # m = C.get_add_material("steel_rusty") # print(m)
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) # Create an empty room. self.communicate({ "$type": "create_empty_environment", "center": { "x": 0, "y": 0, "z": 0 }, "bounds": { "x": 8, "y": 8, "z": 8 } }) self.communicate({"$type": "set_gravity", "value": False}) cube_record = ModelLibrarian("models_special.json").get_record( "prim_cube") self.communicate({ "$type": "add_object", "name": "prim_cube", "url": cube_record.get_url(), "scale_factor": cube_record.scale_factor, "position": { "x": 0, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0 }, "category": cube_record.wcategory, "id": 1 }) self.communicate({ "$type": "scale_object", "scale_factor": { "x": 30, "y": 0.0001, "z": 30 }, "id": 1 }) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": 0, "y": 0.6, "z": 0 }, look_at=TDWUtils.array_to_vector3( [0.5, 0.5, 0]), avatar_id="avatar")) self.communicate(self.get_add_hdri_skybox("table_mountain_1_4k")) self.communicate({"$type": "rotate_hdri_skybox_by", "angle": 90}) lib = MaterialLibrarian(library="materials_med.json") record = lib.get_record("bricks_chatham_gray_used") self.communicate({ "$type": "add_material", "name": "bricks_chatham_gray_used", "url": record.get_url() }) self.communicate( TDWUtils.set_visual_material(c=self, substructure=cube_record.substructure, object_id=1, material="bricks_chatham_gray_used")) # self.communicate({"$type": "set_field_of_view", # "field_of_view": 68.0, # "avatar_id": "avatar"}) bench = self.add_object(model_name="b04_wood_metal_park_bench", position={ "x": 2, "y": 0, "z": 0.5 }, rotation={ "x": 0, "y": -90, "z": 0 }, library="models_full.json") self.add_object(model_name="b04_wood_metal_park_bench", position={ "x": 5, "y": 0, "z": 0.5 }, rotation={ "x": 0, "y": -90, "z": 0 }, library="models_full.json") bench_bounds = self.get_bounds_data(bench) top = bench_bounds.get_top(0) self.add_object(model_name="cgaxis_models_65_06_vray", position={ "x": 1.8, "y": top[1] - 0.42, "z": 0.35 }, rotation={ "x": 0, "y": 0, "z": 0 }, 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([0.5, 0.5, 0]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "bench_book", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior" )
def run(self): self.start() init_setup_commands = [{"$type": "set_screen_size", "width": 640, "height": 480}, {"$type": "set_render_quality", "render_quality": 5}] self.communicate(init_setup_commands) self.communicate({"$type": "create_empty_environment", "center": {"x": 0, "y": 0, "z": 0}, "bounds": {"x": 15, "y": 15, "z": 15}}) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate(TDWUtils.create_avatar(position={"x": -1.5, "y": 1.4, "z": 0.6}, look_at=TDWUtils.array_to_vector3([3, 0.5, 0.5]), avatar_id="avatar")) self.communicate(self.get_add_hdri_skybox("table_mountain_1_4k")) self.communicate({"$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar"}) cube_record = ModelLibrarian("models_special.json").get_record("prim_cube") self.communicate({"$type": "add_object", "name": "prim_cube", "url": cube_record.get_url(), "scale_factor": cube_record.scale_factor, "position": {"x": 0, "y": 0, "z": 0}, "rotation": {"x": 0, "y": 0, "z": 0}, "category": cube_record.wcategory, "id": 1}) self.communicate({"$type": "scale_object", "scale_factor": {"x": 30, "y": 0.0001, "z": 30}, "id": 1}) grass_record = MaterialLibrarian("materials_high.json").get_record("grass_countryside") self.communicate({"$type": "add_material", "name": "grass_countryside", "url": grass_record.get_url()}) self.communicate(TDWUtils.set_visual_material(c=self, substructure=cube_record.substructure, object_id=1, material="grass_countryside")) self.add_object(model_name="b03_horse", position={"x": 3, "y": 0.0001, "z": 0.5}, rotation={"x": 0, "y": 0, "z": 0}, library="models_full.json") bird = self.add_object(model_name="polysurface63", position={"x": 1.2, "y": 0.0001, "z": 1}, rotation={"x": 0, "y": 0, "z": 0}, library="models_full.json") self.communicate({"$type": "scale_object", "scale_factor": {"x": 2, "y": 2, "z": 2}, "id": bird}) bird = self.add_object(model_name="b03_realistic_pigeon_max", position={"x": 1.8, "y": 0.0001, "z": 0.45}, rotation={"x": 0, "y": -95, "z": 0}, library="models_full.json") self.communicate({"$type": "scale_object", "scale_factor": {"x": 2, "y": 2, "z": 2}, "id": bird}) bird = self.add_object(model_name="rockdove_polysurface77", position={"x": 1, "y": 0.0001, "z": 0.7}, rotation={"x": 0, "y": -80, "z": 0}, library="models_full.json") self.communicate({"$type": "scale_object", "scale_factor": {"x": 2, "y": 2, "z": 2}, "id": bird}) # 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([3, 0.5, 0])}) images = Images(scene_data[0]) TDWUtils.save_images(images, "bird2", output_directory="/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior")
def run(self): self.start() init_setup_commands = [{ "$type": "set_screen_size", "width": 640, "height": 480 }, { "$type": "set_render_quality", "render_quality": 5 }] self.communicate(init_setup_commands) self.communicate(TDWUtils.create_empty_room(8, 8)) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) lib = MaterialLibrarian(library="materials_med.json") record = lib.get_record("laser_cut_white_norway_spruce") self.communicate({ "$type": "add_material", "name": "laser_cut_white_norway_spruce", "url": record.get_url() }) self.communicate({ "$type": "set_proc_gen_floor_material", "name": "laser_cut_white_norway_spruce" }) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": 1.5, "y": 1.6, "z": 0 }, look_at=TDWUtils.array_to_vector3( [0, 0.5, 0]), avatar_id="avatar")) self.communicate({ "$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar" }) table = self.add_object( model_name="boconcept_lugo_dining_table_vray1.5", position={ "x": 0, "y": 0, "z": 0.0 }, rotation={ "x": 0, "y": -90, "z": 0 }, library="models_full.json") table_bounds = self.get_bounds_data(table) top = table_bounds.get_top(0) self.add_object(model_name='macbook_001', position={ "x": 0, "y": top[1], "z": 0.1 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") self.add_object(model_name='spunlight_designermesh_lamp', position={ "x": -0.19, "y": top[1], "z": -0.4 }, rotation={ "x": 0, "y": 0, "z": 0 }, library="models_full.json") self.add_object(model_name="apple_magic_mouse_2_(2015)_vray", position={ "x": 0, "y": top[1], "z": 0.32 }, rotation={ "x": 0, "y": 86, "z": 0 }, library="models_full.json") self.add_object(model_name="f10_apple_iphone_4", position={ "x": 0.14, "y": top[1], "z": -0.3 }, rotation={ "x": 0, "y": 12, "z": 0 }, 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([0, 0.5, 0]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "phone", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/interior" )
class Util: """ Utility class. """ _LIB_MATERIALS = MaterialLibrarian("materials_high.json") _LIB_MODELS = ModelLibrarian(str(Path("models.json").resolve())) @staticmethod def update_library() -> None: """ Update the local records library to correct the local URLs for this machine. """ for record in Util._LIB_MODELS.records: # This is a local asset bundle. if record.get_url().startswith("file:///"): # Update the URLs to match the local machine. for platform in record.urls: p = Path(platform).joinpath(record.name) record.urls[platform] = "file:///" + str( p.resolve()).replace('\\', '/') Util._LIB_MODELS.add_or_update_record(record, overwrite=True, write=False) Util._LIB_MODELS.write() @staticmethod def get_add_material(name: str) -> dict: """ Returns a valid add_material command. :param name: The name of the material. """ record = Util._LIB_MATERIALS.get_record(name) return {"$type": "add_material", "name": name, "url": record.get_url()} @staticmethod def get_add_object(name: str, object_id: int, position: Dict[str, float]) -> dict: """ Returns a valid add_object command. :param name: The name of the model. :param object_id: The unique ID of the object. :param position: The initial position. """ record = Util._LIB_MODELS.get_record(name) return { "$type": "add_object", "name": record.name, "url": record.get_url(), "scale_factor": record.scale_factor, "position": position, "category": record.wcategory, "id": object_id } @staticmethod def get_set_visual_material_commands(material_name: str, object_id: int, model_name: str) -> List[dict]: """ Returns the commands required to set the visual material of each sub-object. :param material_name: The name of the material. :param object_id: The ID of the parent object. :param model_name: The name of the model. """ record = Util._LIB_MODELS.get_record(model_name) commands = [Util.get_add_material(material_name)] for sub_object in record.substructure: for i in range(len(sub_object["materials"])): commands.extend([{ "$type": "set_visual_material", "id": object_id, "material_name": material_name, "object_name": sub_object["name"], "material_index": i }]) return commands
def run(self): self.start() init_setup_commands = [{ "$type": "set_screen_size", "width": 640, "height": 480 }, { "$type": "set_render_quality", "render_quality": 5 }] self.communicate(init_setup_commands) self.communicate({ "$type": "create_empty_environment", "center": { "x": 0, "y": 0, "z": 0 }, "bounds": { "x": 15, "y": 15, "z": 15 } }) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": 5, "y": 1.4, "z": 0.6 }, look_at=TDWUtils.array_to_vector3( [0, 0.5, 0.5]), avatar_id="avatar")) self.communicate(self.get_add_hdri_skybox("sky_white")) self.communicate({ "$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar" }) cube_record = ModelLibrarian("models_special.json").get_record( "prim_cube") self.communicate({ "$type": "add_object", "name": "prim_cube", "url": cube_record.get_url(), "scale_factor": cube_record.scale_factor, "position": { "x": 0, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0 }, "category": cube_record.wcategory, "id": 1 }) self.communicate({ "$type": "scale_object", "scale_factor": { "x": 30, "y": 0.0001, "z": 30 }, "id": 1 }) grass_record = MaterialLibrarian("materials_high.json").get_record( "iceland_mossy_meadow") self.communicate({ "$type": "add_material", "name": "iceland_mossy_meadow", "url": grass_record.get_url() }) self.communicate( TDWUtils.set_visual_material(c=self, substructure=cube_record.substructure, object_id=1, material="iceland_mossy_meadow")) bench = self.add_object(model_name="b04_wood_metal_park_bench", position={ "x": 3, "y": 0, "z": 0.5 }, rotation={ "x": 0, "y": 0, "z": 0 }, library="models_full.json") bench_bounds = self.get_bounds_data(bench) top = bench_bounds.get_top(0) self.add_object(model_name="3dscan_man_004", position={ "x": 2.5, "y": 0, "z": 0 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") hummingbird = self.add_object(model_name="b04_pigeon", position={ "x": 3, "y": top[1] - 0.05, "z": 0.75 }, rotation={ "x": 0, "y": 0, "z": 0 }, library="models_full.json") self.add_object(model_name="b03_realistic_pigeon_max", position={ "x": 3, "y": top[1] - 0.05, "z": 0.35 }, rotation={ "x": 0, "y": 90, "z": 0 }, 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([0, 0.5, 0.5]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "bird1", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior" )
from tdw.tdw_utils import TDWUtils from tdw.librarian import ModelRecord, MaterialLibrarian from tdw.output_data import OutputData, Transforms from tdw_physics.rigidbodies_dataset import (RigidbodiesDataset, get_random_xyz_transform, get_range, handle_random_transform_args) from tdw_physics.util import (MODEL_LIBRARIES, get_parser, xyz_to_arr, arr_to_xyz, str_to_xyz, none_or_str, none_or_int, int_or_bool) from tdw_physics.target_controllers.dominoes import Dominoes, MultiDominoes, get_args from tdw_physics.postprocessing.labels import is_trial_valid MODEL_NAMES = [r.name for r in MODEL_LIBRARIES['models_flex.json'].records] M = MaterialLibrarian() MATERIAL_TYPES = M.get_material_types() MATERIAL_NAMES = {mtype: [m.name for m in M.get_all_materials_of_type(mtype)] \ for mtype in MATERIAL_TYPES} def get_gravity_args(dataset_dir: str, parse=True): common = get_parser(dataset_dir, get_help=False) domino, domino_postproc = get_args(dataset_dir, parse=False) parser = ArgumentParser(parents=[common, domino], conflict_handler='resolve', fromfile_prefix_chars='@') parser.add_argument( "--ramp",
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) self.communicate(self.get_add_hdri_skybox("industrial_sunset_4k")) # Create an empty room. self.communicate(TDWUtils.create_empty_room(8, 8)) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": 1, "y": 1.5, "z": 0.3 }, look_at=TDWUtils.array_to_vector3( [2.5, 0.5, 0.5]), avatar_id="avatar")) lib = MaterialLibrarian(library="materials_med.json") record = lib.get_record("concrete_049") self.communicate({ "$type": "add_material", "name": "concrete_049", "url": record.get_url() }) self.communicate({ "$type": "set_proc_gen_floor_material", "name": "concrete_049" }) # self.communicate({"$type": "set_proc_gen_walls_material", "name": "concrete"}) # self.communicate({"$type": "set_field_of_view", # "field_of_view": 68.0, # "avatar_id": "avatar"}) bench = self.add_object(model_name="cgaxis_models_51_19_01", position={ "x": 2.5, "y": 0, "z": 0.5 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") bench_bounds = self.get_bounds_data(bench) top = bench_bounds.get_top(0) self.add_object(model_name="b05_cat_model_3dmax2012", position={ "x": 2.5, "y": top[1], "z": 0.2 }, rotation={ "x": 0, "y": 0, "z": 0 }, library="models_full.json") self.add_object(model_name="azor", position={ "x": 3, "y": 0, "z": 0.5 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") """ Post-scene construction """ # Enable image capture self.communicate({ "$type": "set_pass_masks", "avatar_id": "avatar", "pass_masks": ["_id"] }) scene_data = self.communicate({ "$type": "look_at_position", "avatar_id": "avatar", "position": TDWUtils.array_to_vector3([3, 0.5, 0.5]) }) # images = Images(scene_data[0]) im = cv2.imread( "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/" "compare_COCO_TDW/replicated_images/exterior/id_bench_bike.png") im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB) # WRITE THIS TO JSON! segmentation_data = [] COCO_to_TDW = pd.read_csv( '/Users/leonard/Desktop/coco/COCO_to_TDW.csv', header=None, index_col=0, squeeze=True).to_dict() segmentation_colors = self.communicate({ "$type": "send_segmentation_colors", "frequency": "once" }) for r in segmentation_colors[:-1]: r_id = OutputData.get_data_type_id(r) if r_id == "segm": s = SegmentationColors(r) for i in range(s.get_num()): name = s.get_object_name(i) category = get_COCO(name, COCO_to_TDW) color = s.get_object_color(i) indices = np.where(im != 0) # Segmentation pixels print(color) print(indices) print(im[indices[0][0]] ) # some random RGB val -- MUSt match one of the 3 segmentation_data.append([indices, category]) # TDWUtils.save_images(images, "bench_bike", # output_directory="/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior") # Consider using zip() to clean up coordinates return segmentation_data
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) # Create an empty room. self.communicate(TDWUtils.create_empty_room(16, 16)) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": -7.5, "y": 1.5, "z": 0 }, look_at=TDWUtils.array_to_vector3( [0, 0.7, 0]), avatar_id="avatar")) self.communicate(self.get_add_hdri_skybox("industrial_sunset_4k")) lib = MaterialLibrarian(library="materials_med.json") record = lib.get_record("concrete_asphalt_rolled") self.communicate({ "$type": "add_material", "name": "concrete_asphalt_rolled", "url": record.get_url() }) self.communicate({ "$type": "set_proc_gen_floor_material", "name": "concrete_asphalt_rolled" }) # self.communicate({"$type": "set_proc_gen_walls_material", "name": "concrete"}) self.communicate({ "$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar" }) self.add_object(model_name="b05_model_sell", position={ "x": 2.5, "y": 0, "z": 4 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") self.add_object(model_name="b03_fire_hydrant", position={ "x": 2, "y": 0, "z": -1 }, rotation={ "x": 0, "y": 0, "z": 0 }, library="models_full.json") # record = ModelLibrarian(library='models_full.json').get_record("bigben_clock") # self.communicate({"$type": "add_object", # "name": "bigben_clock", # "url": record.get_url(), # "scale_factor": record.scale_factor * 10, # "position": {"x": 1.7, "y": 0, "z": -3}, # "rotation": TDWUtils.VECTOR3_ZERO, # "category": record.wcategory, # "id": self.get_unique_id()}) self.add_object(model_name="bench", position={ "x": 1.7, "y": 0, "z": -3 }, rotation={ "x": 0, "y": 90, "z": 0 }, 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([0, 0.7, 0]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "hydrant_clock", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior" )
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) # Create an empty scene (no walls) self.communicate({ "$type": "create_empty_environment", "center": { "x": 0, "y": 0, "z": 0 }, "bounds": { "x": 30, "y": 30, "z": 30 } }) self.communicate(self.get_add_hdri_skybox("pink_sunrise_4k")) cube = self.communicate({ "$type": "load_primitive_from_resources", "primitive_type": "Cube", "id": 1, "position": { "x": 0, "y": 0, "z": 0 }, "orientation": { "x": 0, "y": 0, "z": 0 } }) self.communicate({ "$type": "scale_object", "scale_factor": { "x": 30, "y": 0.0001, "z": 30 }, "id": 1 }) lib = MaterialLibrarian(library="materials_med.json") record = lib.get_record("concrete_chipped_cracked") self.communicate({ "$type": "add_material", "name": "concrete_chipped_cracked", "url": record.get_url() }) # self.communicate({"$type": "set_visual_material", # "material_index": 1, # "material_name": "concrete_chipped_cracked", # "object_name": "cube", # "id": 1}) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": -13, "y": 1.5, "z": 0 }, look_at=TDWUtils.array_to_vector3( [5, 1.5, 0]), avatar_id="avatar")) self.communicate({ "$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar" }) self.add_object(model_name="spitfire_2012", position={ "x": 0, "y": 0, "z": 2 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") self.add_object(model_name="b03_topkicktruck", position={ "x": -7, "y": 0, "z": -5 }, rotation={ "x": 0, "y": 0, "z": 0 }, library="models_full.json") self.add_object(model_name="3dscan_man_012", position={ "x": -4, "y": 0, "z": 3 }, rotation={ "x": 0, "y": 0, "z": 0 }, 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([5, 1.5, 0]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "airplane", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior" )
class Controller(object): """ Base class for all controllers. Usage: ```python from tdw.controller import Controller c = Controller() c.start() ``` """ def __init__(self, port: int = 1071, check_version: bool = True, launch_build: bool = True): """ Create the network socket and bind the socket to the port. :param port: The port number. :param check_version: If true, the controller will check the version of the build and print the result. :param launch_build: If True, automatically launch the build. If one doesn't exist, download and extract the correct version. Set this to False to use your own build, or (if you are a backend developer) to use Unity Editor. """ # Compare the installed version of the tdw Python module to the latest on PyPi. # If there is a difference, recommend an upgrade. if check_version: self._check_pypi_version() # Launch the build. if launch_build: Controller.launch_build() context = zmq.Context() self.socket = context.socket(zmq.REP) self.socket.bind('tcp://*:' + str(port)) self.socket.recv() self.model_librarian: Optional[ModelLibrarian] = None self.scene_librarian: Optional[SceneLibrarian] = None self.material_librarian: Optional[MaterialLibrarian] = None self.hdri_skybox_librarian: Optional[HDRISkyboxLibrarian] = None self.humanoid_librarian: Optional[HumanoidLibrarian] = None self.humanoid_animation_librarian: Optional[ HumanoidAnimationLibrarian] = None # Compare the version of the tdw module to the build version. if check_version and launch_build: self._check_build_version() def communicate(self, commands: Union[dict, List[dict]]) -> list: """ Send commands and receive output data in response. :param commands: A list of JSON commands. :return The output data from the build. """ if not isinstance(commands, list): commands = [commands] self.socket.send_multipart([json.dumps(commands).encode('utf-8')]) return self.socket.recv_multipart() def start(self, scene="ProcGenScene") -> None: """ Init TDW. :param scene: The scene to load. """ self.communicate([{"$type": "load_scene", "scene_name": scene}]) def get_add_object(self, model_name: str, object_id: int, position={ "x": 0, "y": 0, "z": 0 }, rotation={ "x": 0, "y": 0, "z": 0 }, library: str = "") -> dict: """ Returns a valid add_object command. :param model_name: The name of the model. :param position: The position of the model. :param rotation: The starting rotation of the model, in Euler angles. :param library: The path to the records file. If left empty, the default library will be selected. See `ModelLibrarian.get_library_filenames()` and `ModelLibrarian.get_default_library()`. :param object_id: The ID of the new object. :return An add_object command that the controller can then send. """ if self.model_librarian is None or ( library != "" and self.model_librarian.library != library): self.model_librarian = ModelLibrarian(library=library) record = self.model_librarian.get_record(model_name) return { "$type": "add_object", "name": model_name, "url": record.get_url(), "scale_factor": record.scale_factor, "position": position, "rotation": rotation, "category": record.wcategory, "id": object_id } def get_add_material(self, material_name: str, library: str = "") -> dict: """ Returns a valid add_material command. :param material_name: The name of the material. :param library: The path to the records file. If left empty, the default library will be selected. See `MaterialLibrarian.get_library_filenames()` and `MaterialLibrarian.get_default_library()`. :return An add_material command that the controller can then send. """ if self.material_librarian is None: self.material_librarian = MaterialLibrarian(library=library) record = self.material_librarian.get_record(material_name) return { "$type": "add_material", "name": material_name, "url": record.get_url() } def get_add_scene(self, scene_name: str, library: str = "") -> dict: """ Returns a valid add_scene command. :param scene_name: The name of the scene. :param library: The path to the records file. If left empty, the default library will be selected. See `SceneLibrarian.get_library_filenames()` and `SceneLibrarian.get_default_library()`. :return An add_scene command that the controller can then send. """ if self.scene_librarian is None: self.scene_librarian = SceneLibrarian(library=library) record = self.scene_librarian.get_record(scene_name) return { "$type": "add_scene", "name": scene_name, "url": record.get_url() } def get_add_hdri_skybox(self, skybox_name: str, library: str = "") -> dict: """ Returns a valid add_hdri_skybox command. :param skybox_name: The name of the skybox. :param library: The path to the records file. If left empty, the default library will be selected. See `HDRISkyboxLibrarian.get_library_filenames()` and `HDRISkyboxLibrarian.get_default_library()`. :return An add_hdri_skybox command that the controller can then send. """ if self.hdri_skybox_librarian is None: self.hdri_skybox_librarian = HDRISkyboxLibrarian(library=library) record = self.hdri_skybox_librarian.get_record(skybox_name) return { "$type": "add_hdri_skybox", "name": skybox_name, "url": record.get_url(), "exposure": record.exposure, "initial_skybox_rotation": record.initial_skybox_rotation, "sun_elevation": record.sun_elevation, "sun_initial_angle": record.sun_initial_angle, "sun_intensity": record.sun_intensity } def get_add_humanoid(self, humanoid_name: str, object_id: int, position={ "x": 0, "y": 0, "z": 0 }, rotation={ "x": 0, "y": 0, "z": 0 }, library: str = "") -> dict: """ Returns a valid add_humanoid command. :param humanoid_name: The name of the humanoid. :param position: The position of the humanoid. :param rotation: The starting rotation of the humanoid, in Euler angles. :param library: The path to the records file. If left empty, the default library will be selected. See `HumanoidLibrarian.get_library_filenames()` and `HumanoidLibrarian.get_default_library()`. :param object_id: The ID of the new object. :return An add_humanoid command that the controller can then send. """ if self.humanoid_librarian is None or ( library != "" and self.humanoid_librarian.library != library): self.humanoid_librarian = HumanoidLibrarian(library=library) record = self.humanoid_librarian.get_record(humanoid_name) return { "$type": "add_humanoid", "name": humanoid_name, "url": record.get_url(), "position": position, "rotation": rotation, "id": object_id } def get_add_humanoid_animation( self, humanoid_animation_name: str, library="") -> (dict, HumanoidAnimationRecord): """ Returns a valid add_humanoid_animation command and the record (which you will need to play an animation). :param humanoid_animation_name: The name of the animation. :param library: The path to the records file. If left empty, the default library will be selected. See `HumanoidAnimationLibrarian.get_library_filenames()` and `HumanoidAnimationLibrarian.get_default_library()`. return An add_humanoid_animation command that the controller can then send. """ if self.humanoid_animation_librarian is None: self.humanoid_animation_librarian = HumanoidAnimationLibrarian( library=library) record = self.humanoid_animation_librarian.get_record( humanoid_animation_name) return { "$type": "add_humanoid_animation", "name": humanoid_animation_name, "url": record.get_url() }, record def load_streamed_scene(self, scene="tdw_room_2018") -> None: """ Load a streamed scene. This is equivalent to: `c.communicate(c.get_add_scene(scene))` :param scene: The name of the streamed scene. """ self.communicate(self.get_add_scene(scene)) def add_object(self, model_name: str, position={ "x": 0, "y": 0, "z": 0 }, rotation={ "x": 0, "y": 0, "z": 0 }, library: str = "") -> int: """ Add a model to the scene. This is equivalent to: `c.communicate(c.get_add_object())` :param model_name: The name of the model. :param position: The position of the model. :param rotation: The starting rotation of the model, in Euler angles. :param library: The path to the records file. If left empty, the default library will be selected. See `ModelLibrarian.get_library_filenames()` and `ModelLibrarian.get_default_library()`. :return The ID of the new object. """ object_id = Controller.get_unique_id() self.communicate( self.get_add_object(model_name, object_id, position, rotation, library)) return object_id def get_version(self) -> Tuple[str, str]: """ Send a send_version command to the build. :return The TDW version and the Unity Engine version. """ resp = self.communicate({"$type": "send_version"}) for r in resp[:-1]: if Version.get_data_type_id(r) == "vers": v = Version(r) return v.get_tdw_version(), v.get_unity_version() if len(resp) == 1: raise Exception( "Tried receiving version output data but didn't receive anything!" ) raise Exception(f"Expected output data with ID vers but got: " + Version.get_data_type_id(resp[0])) @staticmethod def get_unique_id() -> int: """ Generate a unique integer. Useful when creating objects. :return The new unique ID. """ return int.from_bytes(os.urandom(3), byteorder='big') @staticmethod def get_frame(frame: bytes) -> int: """ Converts the frame byte array to an integer. :param frame: The frame as bytes. :return The frame as an integer. """ return int.from_bytes(frame, byteorder='big') @staticmethod def launch_build() -> None: """ Launch the build. If a build doesn't exist at the expected location, download one to that location. """ # Download the build. if not Build.BUILD_PATH.exists(): print( f"Couldn't find build at {Build.BUILD_PATH}\nDownloading now..." ) success = Build.download() if not success: print("You need to launch your own build.") else: success = True # Launch the build. if success: Popen(str(Build.BUILD_PATH.resolve())) def _check_build_version(self, version: str = __version__, build_version: str = None) -> None: """ Check the version of the build. If there is no build, download it. If the build is of the wrong version, recommend an upgrade. :param version: The version of TDW. You can set this to an arbitrary version for testing purposes. :param build_version: If not None, this overrides the expected build version. Only override for debugging. """ v = PyPi.strip_post_release(version) tdw_version, unity_version = self.get_version() # Override the build version for testing. if build_version is not None: tdw_version = build_version pypi_version = PyPi.get_latest_minor_release(tdw_version) print( f"Build version {tdw_version}\nUnity Engine {unity_version}\nPython tdw module version {version}" ) if v < tdw_version: print( "WARNING! Your TDW build is newer than your tdw Python module. They might not be compatible." ) print( f"To download the correct build:\n\nfrom tdw.release.build import Build\nBuild.download(version={v})" ) print( f"\nTo upgrade your Python module (usually recommended):\n\npip3 install tdw=={pypi_version}" ) elif v > tdw_version: print( "WARNING! Your TDW build is older than your tdw Python module. Downloading the correct build..." ) Build.download(v) @staticmethod def _check_pypi_version(v_installed_override: str = None, v_pypi_override: str = None) -> None: """ Compare the version of the tdw Python module to the latest on PyPi. If there is a mismatch, offer an upgrade recommendation. :param v_installed_override: Override for the installed version. Change this to debug. :param v_pypi_override: Override for the PyPi version. Change this to debug. """ # Get the version of the installed tdw module. installed_tdw_version = PyPi.get_installed_tdw_version() # Get the latest version of the tdw module on PyPi. pypi_version = PyPi.get_pypi_version() # Apply overrides if v_installed_override is not None: installed_tdw_version = v_installed_override if v_pypi_override is not None: pypi_version = v_pypi_override # If there is a mismatch, recommend an upgrade. if installed_tdw_version != pypi_version: # Strip the installed version of the post-release suffix (e.g. 1.6.3.4 to 1.6.3). stripped_installed_version = PyPi.strip_post_release( installed_tdw_version) # This message is here only for debugging. if stripped_installed_version != __version__: print( f"Your installed version: {stripped_installed_version} " f"doesn't match tdw.version.__version__: {__version__} " f"(this may be because you're using code from the tdw repo that is ahead of PyPi)." ) # Strip the latest PyPi version of the post-release suffix. stripped_pypi_version = PyPi.strip_post_release(pypi_version) print( f"You are using TDW {installed_tdw_version} but version {pypi_version} is available." ) # If user is behind by a post release, recommend an upgrade to the latest. # (Example: installed version is 1.6.3.4 and PyPi version is 1.6.3.5) if stripped_installed_version == stripped_pypi_version: print( f"Upgrade to the latest version of TDW:\npip3 install tdw -U" ) # Using a version behind the latest (e.g. latest is 1.6.3 and installed is 1.6.2) # If the user is behind by a major or minor release, recommend either upgrading to a minor release # or to a major release. # (Example: installed version is 1.6.3.4 and PyPi version is 1.7.0.0) else: installed_major = PyPi.get_major_release( stripped_installed_version) pypi_minor = PyPi.get_latest_minor_release( stripped_installed_version) # Minor release mis-match. if PyPi.strip_post_release( pypi_minor) != stripped_installed_version: print( f"To upgrade to the last version of 1.{installed_major}:\n" f"pip3 install tdw=={pypi_minor}") pypi_major = PyPi.get_major_release(stripped_pypi_version) # Major release mis-match. if installed_major != pypi_major: # Offer to upgrade to a major release. print( f"Consider upgrading to the latest version of TDW ({stripped_pypi_version}):" f"\npip3 install tdw -U") else: print("Your installed tdw Python module is up to date with PyPi.")
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) # Create an empty room. self.communicate(TDWUtils.create_empty_room(8, 8)) # 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( [4, 0.3, -0.3]), avatar_id="avatar")) lib = MaterialLibrarian(library="materials_med.json") record = lib.get_record("concrete") self.communicate({ "$type": "add_material", "name": "concrete", "url": record.get_url() }) self.communicate({ "$type": "set_proc_gen_floor_material", "name": "concrete" }) self.communicate({ "$type": "set_proc_gen_wall_material", "name": "concrete" }) # self.communicate({"$type": "set_field_of_view", # "field_of_view": 68.0, # "avatar_id": "avatar"}) self.add_object(model_name="b05_skateboard", position={ "x": 3.2, "y": 0.3, "z": -0.5 }, rotation={ "x": 0, "y": 0, "z": 80 }, library="models_full.json") self.add_object(model_name="skateboard_3", position={ "x": 3, "y": 0, "z": 0.6 }, rotation={ "x": 0, "y": 30, "z": 0 }, library="models_full.json") self.add_object(model_name="b03_3wheels", position={ "x": 1.8, "y": 0, "z": 0.2 }, rotation={ "x": 0, "y": 30, "z": 0 }, library="models_full.json") self.add_object(model_name="bicycle_001", position={ "x": 2.7, "y": 0, "z": -1.1 }, rotation={ "x": 0, "y": 34, "z": 0 }, 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([4, 0.3, -0.3]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "skateboard", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/interior" )
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) # Create an empty scene (no walls) self.communicate({ "$type": "create_empty_environment", "center": { "x": 0, "y": 0, "z": 0 }, "bounds": { "x": 20, "y": 20, "z": 20 } }) self.communicate(self.get_add_hdri_skybox("kiara_5_noon_4k")) self.communicate({"$type": "rotate_hdri_skybox_by", "angle": 90}) cube_record = ModelLibrarian("models_special.json").get_record( "prim_cube") self.communicate({ "$type": "add_object", "name": "prim_cube", "url": cube_record.get_url(), "scale_factor": cube_record.scale_factor, "position": { "x": 0, "y": 0, "z": 0 }, "rotation": { "x": 0, "y": 0, "z": 0 }, "category": cube_record.wcategory, "id": 1 }) self.communicate({ "$type": "scale_object", "scale_factor": { "x": 30, "y": 0.0001, "z": 30 }, "id": 1 }) grass_record = MaterialLibrarian("materials_high.json").get_record( "limestone_white") self.communicate({ "$type": "add_material", "name": "limestone_white", "url": grass_record.get_url() }) self.communicate( TDWUtils.set_visual_material(c=self, substructure=cube_record.substructure, object_id=1, material="limestone_white")) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": -5, "y": 1.5, "z": 0 }, look_at=TDWUtils.array_to_vector3( [0, 1.5, 0]), avatar_id="avatar")) self.communicate({ "$type": "set_field_of_view", "field_of_view": 68.0, "avatar_id": "avatar" }) self.add_object(model_name="b03_topkicktruck", position={ "x": 4, "y": 0, "z": 0.4 }, rotation={ "x": 0, "y": -30, "z": 0 }, library="models_full.json") self.add_object(model_name="b05_iz-49_3", position={ "x": -1, "y": 0, "z": -1.7 }, rotation={ "x": 0, "y": 90, "z": 0 }, library="models_full.json") self.add_object(model_name="3dscan_man_002", position={ "x": -1.6, "y": 0, "z": -2 }, rotation={ "x": 0, "y": 90, "z": 0 }, 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([0, 1.5, 0]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "truck_moto", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior" )
def run(self): self.start() # Create an empty room. self.communicate(TDWUtils.create_empty_room(12, 12)) material_librarian = MaterialLibrarian() # Fetch a random wood material record. wood_records = material_librarian.get_all_materials_of_type("Wood") wood_record: MaterialRecord = choice(wood_records) # Fetch a random concrete record material. concrete_records = material_librarian.get_all_materials_of_type( "Concrete") concrete_record: MaterialRecord = choice(concrete_records) # Set the floor material. # Set the floor material texture scale. # Set the walls material. # Set the wall material texture scale. self.communicate([ self.get_add_material(wood_record.name), self.get_add_material(concrete_record.name), { "$type": "set_proc_gen_floor_material", "name": wood_record.name }, { "$type": "set_proc_gen_floor_texture_scale", "scale": { "x": 8, "y": 8 } }, { "$type": "set_proc_gen_walls_material", "name": concrete_record.name }, { "$type": "set_proc_gen_walls_texture_scale", "scale": { "x": 2, "y": 8 } } ]) # Create a random table. model_librarian = ModelLibrarian() wnids = model_librarian.get_model_wnids_and_wcategories() table_wnid = [wnid for wnid in wnids if wnids[wnid] == "table"][0] table_records = model_librarian.get_all_models_in_wnid(table_wnid) # Filter out unusable tables. table_records = [t for t in table_records if not t.do_not_use] table_record: ModelRecord = choice(table_records) # Add the table. table_id = self.add_object(table_record.name) # Set a random visual material for each sub-object in the model. commands = list() for sub_object in table_record.substructure: for i in range(len(sub_object["materials"])): material_record: MaterialRecord = choice( material_librarian.records) commands.extend([ self.get_add_material(material_record.name), { "$type": "set_visual_material", "id": table_id, "material_name": material_record.name, "object_name": sub_object["name"], "material_index": i } ]) self.communicate(commands) # Create the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": 4, "y": 3, "z": 2 }, look_at=TDWUtils.VECTOR3_ZERO))
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) # Create an empty room. self.communicate(TDWUtils.create_empty_room(8, 8)) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": 2.5, "y": 1.5, "z": 0.3 }, look_at=TDWUtils.array_to_vector3( [3, 0.5, 0.5]), avatar_id="avatar")) lib = MaterialLibrarian(library="materials_med.json") record = lib.get_record("gravel_white") self.communicate({ "$type": "add_material", "name": "gravel_white", "url": record.get_url() }) self.communicate({ "$type": "set_proc_gen_floor_material", "name": "gravel_white" }) # self.communicate({"$type": "set_proc_gen_walls_material", "name": "concrete"}) # self.communicate({"$type": "set_field_of_view", # "field_of_view": 68.0, # "avatar_id": "avatar"}) bench = self.add_object(model_name="b04_wood_metal_park_bench", position={ "x": 3, "y": 0, "z": 0.5 }, rotation={ "x": 0, "y": 0, "z": 0 }, library="models_full.json") bench_bounds = self.get_bounds_data(bench) top = bench_bounds.get_top(0) self.add_object(model_name="b05_baseball_bat_01", position={ "x": 2.8, "y": top[1] - 0.35, "z": 0 }, rotation={ "x": 0, "y": 90, "z": 90 }, library="models_full.json") self.add_object(model_name="b05_baseballnew_v03_12", position={ "x": 2.9, "y": top[1] - 0.35, "z": 0.4 }, rotation={ "x": 0, "y": 0, "z": 0 }, 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([3, 0.5, 0.5]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "bench_ball", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/exterior" )
class Shadows(RigidbodiesDataset): """ Move a ball to and from areas with different lighting. Use HDRI skyboxes and visual materials (for the ball) to change the lighting per trial. """ _BALL_SCALE = 0.5 _BALL_MATERIAL_RECORDS: List[MaterialRecord] = MaterialLibrarian( str(Path("ball_materials.json").resolve())).records # These sectors have different lighting at each point, e.g. c_0 is more shadowed than c_1. SECTORS = [ _Sector(c_0={ "x": 0.5, "y": 0, "z": 0 }, c_1={ "x": -0.5, "y": 0, "z": 0 }), _Sector(c_0={ "x": 0, "y": 0, "z": 3 }, c_1={ "x": -1.2, "y": 0, "z": 3.7 }), _Sector(c_0={ "x": 0, "y": 0, "z": -3 }, c_1={ "x": -1.2, "y": 0, "z": -3.7 }), _Sector(c_0={ "x": 2.15, "y": 0, "z": -2.6 }, c_1={ "x": 4, "y": 0, "z": -3 }), _Sector(c_0={ "x": 2.15, "y": 0, "z": 2.6 }, c_1={ "x": 4, "y": 0, "z": 3 }), _Sector(c_0={ "x": -2.15, "y": 0, "z": 2.6 }, c_1={ "x": -4, "y": 0, "z": 3 }), _Sector(c_0={ "x": -2.15, "y": 0, "z": -2.6 }, c_1={ "x": -4, "y": 0, "z": -3 }) ] def __init__(self, port: int = 1071): super().__init__(port=port) # Cache the ball data. self._ball = ModelLibrarian("models_special.json").get_record( "prim_sphere") self._ball_id = 0 # The position the ball starts in and the position the ball is directed at. self._p0: Dict[str, float] = {} self._p1: Dict[str, float] = {} # Cache the skybox records. skybox_lib = HDRISkyboxLibrarian() self._skyboxes: List[str] = [ r.name for r in skybox_lib.records if r.sun_intensity >= 0.8 ] def get_scene_initialization_commands(self) -> List[dict]: return [ self.get_add_scene(scene_name="box_room_2018"), { "$type": "set_aperture", "aperture": 4.8 }, { "$type": "set_focus_distance", "focus_distance": 1.25 }, { "$type": "set_post_exposure", "post_exposure": 0.4 }, { "$type": "set_ambient_occlusion_intensity", "intensity": 0.175 }, { "$type": "set_ambient_occlusion_thickness_modifier", "thickness": 3.5 } ] def get_trial_initialization_commands(self) -> List[dict]: # Select a random sector. sector: _Sector = random.choice(self.SECTORS) # Decide where the ball will go and in which direction. if random.random() < 0.5: self._p0 = sector.get_p_0() self._p1 = sector.get_p_1() else: self._p0 = sector.get_p_1() self._p1 = sector.get_p_0() self._p0["y"] = self._BALL_SCALE / 2 self._p1["y"] = self._BALL_SCALE / 2 commands = [] # Add the ball. mass = random.uniform(1, 4) commands.extend( self.add_physics_object(record=self._ball, position=self._p0, rotation=TDWUtils.VECTOR3_ZERO, o_id=self._ball_id, mass=mass, dynamic_friction=random.uniform(0, 0.1), static_friction=random.uniform(0, 0.1), bounciness=random.uniform(0, 0.1))) ball_material: MaterialRecord = random.choice( self._BALL_MATERIAL_RECORDS) # Scale the ball and apply a force and a spin. # Set a random visual material. # Add a random skybox. commands.extend([{ "$type": "scale_object", "scale_factor": { "x": self._BALL_SCALE, "y": self._BALL_SCALE, "z": self._BALL_SCALE }, "id": self._ball_id }, { "$type": "rotate_object_by", "angle": random.uniform(30, 45), "id": self._ball_id, "axis": "pitch", "is_world": True }, { "$type": "apply_force_magnitude_to_object", "magnitude": random.uniform(0.01, 0.03), "id": self._ball_id }, { "$type": "object_look_at_position", "position": self._p1, "id": self._ball_id }, { "$type": "apply_force_magnitude_to_object", "magnitude": random.uniform(5.2 * mass, 8 * mass), "id": self._ball_id }, { "$type": "add_material", "name": ball_material.name, "url": ball_material.get_url() }, { "$type": "set_visual_material", "id": self._ball_id, "material_name": ball_material.name, "object_name": "PrimSphere", "material_index": 0 }, self.get_add_hdri_skybox( skybox_name=random.choice(self._skyboxes)), { "$type": "rotate_hdri_skybox_by", "angle": random.uniform(0, 360) }]) # Teleport the avatar such that it can see both points. d0 = TDWUtils.get_distance(self._p0, self._p1) p_med = np.array([(self._p0["x"] + self._p1["x"]) / 2, 0, (self._p0["z"] + self._p1["z"]) / 2]) p_cen = np.array([0, 0, 0]) a_pos = p_med + ( (p_cen - p_med) / np.abs(np.linalg.norm(p_cen - p_med)) * (d0 + random.uniform(-0.01, -0.05))) a_pos[1] = random.uniform(1.2, 1.5) commands.extend([{ "$type": "teleport_avatar_to", "position": TDWUtils.array_to_vector3(a_pos) }, { "$type": "look_at_position", "position": TDWUtils.array_to_vector3(p_med) }]) return commands def get_per_frame_commands(self, resp: List[bytes], frame: int) -> List[dict]: return [{ "$type": "focus_on_object", "object_id": self._ball_id, "use_centroid": True }] def get_field_of_view(self) -> float: return 68 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
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) # Create an empty room. self.communicate(TDWUtils.create_empty_room(8, 8)) # Disable physics. self.communicate({"$type": "set_gravity", "value": False}) lib = MaterialLibrarian(library="materials_med.json") record = lib.get_record("parquet_wood_mahogany") self.communicate({ "$type": "add_material", "name": "parquet_wood_mahogany", "url": record.get_url() }) self.communicate({ "$type": "set_proc_gen_floor_material", "name": "parquet_wood_mahogany" }) # Add the avatar. self.communicate( TDWUtils.create_avatar(position={ "x": -1, "y": 1.4, "z": -1 }, look_at=TDWUtils.array_to_vector3( [-0.1, 0.7, -0.1]), 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= "b03_restoration_hardware_pedestal_salvaged_round_tables", position={ "x": 0, "y": 0, "z": 0 }, library="models_full.json") table_bounds = self.get_bounds_data(table_id) top = table_bounds.get_top(0) self.add_object(model_name="club_sandwich", position={ "x": 0.45, "y": top[1], "z": 0.25 }, rotation={ "x": 0, "y": 30, "z": 0 }, library="models_full.json") self.add_object(model_name="coffeemug", position={ "x": 0.03, "y": top[1], "z": 0.03 }, library="models_full.json") self.add_object(model_name="knife3", position={ "x": -0.17, "y": top[1], "z": 0.15 }, rotation={ "x": 0, "y": 24, "z": 90 }, library="models_full.json") self.add_object(model_name="notes_02", position={ "x": 0.17, "y": top[1], "z": -0.12 }, rotation={ "x": 0, "y": 24, "z": 0 }, 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([-0.1, 0.7, -0.1]) }) images = Images(scene_data[0]) TDWUtils.save_images( images, "sadnwich2", output_directory= "/Users/leonard/Desktop/TDWBase-1.5.0/Python/Leonard/compare_COCO_TDW/replicated_images/interior" )
class Controller(object): """ Base class for all controllers. Usage: ```python from tdw.controller import Controller c = Controller() c.start() ``` """ def __init__(self, port: int = 1071, check_version: bool = True): """ Create the network socket and bind the socket to the port. :param port: The port number. :param check_version: If true, the controller will check the version of the build and print the result. """ context = zmq.Context() self.socket = context.socket(zmq.REP) self.socket.bind('tcp://*:' + str(port)) self.socket.recv() self.model_librarian: Optional[ModelLibrarian] = None self.scene_librarian: Optional[SceneLibrarian] = None self.material_librarian: Optional[MaterialLibrarian] = None self.hdri_skybox_librarian: Optional[HDRISkyboxLibrarian] = None self.humanoid_librarian: Optional[HumanoidLibrarian] = None self.humanoid_animation_librarian: Optional[ HumanoidAnimationLibrarian] = None # Compare the version of the tdw module to the build version. if check_version: tdw_version, unity_version = self.get_version() print( f"Build version {tdw_version}\nUnity Engine {unity_version}\nPython tdw module version {__version__}" ) if __version__ != tdw_version: print( "WARNING! Your Python code is not the same version as the build. They might not be compatible." ) print( "Either use the latest prerelease build, or use the last stable release via:\n" ) print("git checkout v" + last_stable_release) def communicate(self, commands: Union[dict, List[dict]]) -> list: """ Send commands and receive output data in response. :param commands: A list of JSON commands. :return The output data from the build. """ if not isinstance(commands, list): commands = [commands] self.socket.send_multipart([json.dumps(commands).encode('utf-8')]) return self.socket.recv_multipart() def start(self, scene="ProcGenScene") -> None: """ Init TDW. :param scene: The scene to load. """ self.communicate([{"$type": "load_scene", "scene_name": scene}]) def get_add_object(self, model_name: str, object_id: int, position={ "x": 0, "y": 0, "z": 0 }, rotation={ "x": 0, "y": 0, "z": 0 }, library: str = "") -> dict: """ Returns a valid add_object command. :param model_name: The name of the model. :param position: The position of the model. :param rotation: The starting rotation of the model, in Euler angles. :param library: The path to the records file. If left empty, the default library will be selected. See `ModelLibrarian.get_library_filenames()` and `ModelLibrarian.get_default_library()`. :param object_id: The ID of the new object. :return An add_object command that the controller can then send. """ if self.model_librarian is None or ( library != "" and self.model_librarian.library != library): self.model_librarian = ModelLibrarian(library=library) record = self.model_librarian.get_record(model_name) return { "$type": "add_object", "name": model_name, "url": record.get_url(), "scale_factor": record.scale_factor, "position": position, "rotation": rotation, "category": record.wcategory, "id": object_id } def get_add_material(self, material_name: str, library: str = "") -> dict: """ Returns a valid add_material command. :param material_name: The name of the material. :param library: The path to the records file. If left empty, the default library will be selected. See `MaterialLibrarian.get_library_filenames()` and `MaterialLibrarian.get_default_library()`. :return An add_material command that the controller can then send. """ if self.material_librarian is None: self.material_librarian = MaterialLibrarian(library=library) record = self.material_librarian.get_record(material_name) return { "$type": "add_material", "name": material_name, "url": record.get_url() } def get_add_scene(self, scene_name: str, library: str = "") -> dict: """ Returns a valid add_scene command. :param scene_name: The name of the scene. :param library: The path to the records file. If left empty, the default library will be selected. See `SceneLibrarian.get_library_filenames()` and `SceneLibrarian.get_default_library()`. :return An add_scene command that the controller can then send. """ if self.scene_librarian is None: self.scene_librarian = SceneLibrarian(library=library) record = self.scene_librarian.get_record(scene_name) return { "$type": "add_scene", "name": scene_name, "url": record.get_url() } def get_add_hdri_skybox(self, skybox_name: str, library: str = "") -> dict: """ Returns a valid add_hdri_skybox command. :param skybox_name: The name of the skybox. :param library: The path to the records file. If left empty, the default library will be selected. See `HDRISkyboxLibrarian.get_library_filenames()` and `HDRISkyboxLibrarian.get_default_library()`. :return An add_hdri_skybox command that the controller can then send. """ if self.hdri_skybox_librarian is None: self.hdri_skybox_librarian = HDRISkyboxLibrarian(library=library) record = self.hdri_skybox_librarian.get_record(skybox_name) return { "$type": "add_hdri_skybox", "name": skybox_name, "url": record.get_url(), "exposure": record.exposure, "initial_skybox_rotation": record.initial_skybox_rotation, "sun_elevation": record.sun_elevation, "sun_initial_angle": record.sun_initial_angle, "sun_intensity": record.sun_intensity } def get_add_humanoid(self, humanoid_name: str, object_id: int, position={ "x": 0, "y": 0, "z": 0 }, rotation={ "x": 0, "y": 0, "z": 0 }, library: str = "") -> dict: """ Returns a valid add_humanoid command. :param humanoid_name: The name of the humanoid. :param position: The position of the humanoid. :param rotation: The starting rotation of the humanoid, in Euler angles. :param library: The path to the records file. If left empty, the default library will be selected. See `HumanoidLibrarian.get_library_filenames()` and `HumanoidLibrarian.get_default_library()`. :param object_id: The ID of the new object. :return An add_humanoid command that the controller can then send. """ if self.humanoid_librarian is None or ( library != "" and self.humanoid_librarian.library != library): self.humanoid_librarian = HumanoidLibrarian(library=library) record = self.humanoid_librarian.get_record(humanoid_name) return { "$type": "add_humanoid", "name": humanoid_name, "url": record.get_url(), "position": position, "rotation": rotation, "id": object_id } def get_add_humanoid_animation( self, humanoid_animation_name: str, library="") -> (dict, HumanoidAnimationRecord): """ Returns a valid add_humanoid_animation command and the record (which you will need to play an animation). :param humanoid_animation_name: The name of the animation. :param library: The path to the records file. If left empty, the default library will be selected. See `HumanoidAnimationLibrarian.get_library_filenames()` and `HumanoidAnimationLibrarian.get_default_library()`. return An add_humanoid_animation command that the controller can then send. """ if self.humanoid_animation_librarian is None: self.humanoid_animation_librarian = HumanoidAnimationLibrarian( library=library) record = self.humanoid_animation_librarian.get_record( humanoid_animation_name) return { "$type": "add_humanoid_animation", "name": humanoid_animation_name, "url": record.get_url() }, record def load_streamed_scene(self, scene="tdw_room_2018") -> None: """ Load a streamed scene. This is equivalent to: `c.communicate(c.get_add_scene(scene))` :param scene: The name of the streamed scene. """ self.communicate(self.get_add_scene(scene)) def add_object(self, model_name: str, position={ "x": 0, "y": 0, "z": 0 }, rotation={ "x": 0, "y": 0, "z": 0 }, library: str = "") -> int: """ Add a model to the scene. This is equivalent to: `c.communicate(c.get_add_object())` :param model_name: The name of the model. :param position: The position of the model. :param rotation: The starting rotation of the model, in Euler angles. :param library: The path to the records file. If left empty, the default library will be selected. See `ModelLibrarian.get_library_filenames()` and `ModelLibrarian.get_default_library()`. :return The ID of the new object. """ object_id = Controller.get_unique_id() self.communicate( self.get_add_object(model_name, object_id, position, rotation, library)) return object_id def get_version(self) -> Tuple[str, str]: """ Send a send_version command to the build. :return The TDW version and the Unity Engine version. """ resp = self.communicate({"$type": "send_version"}) for r in resp[:-1]: if Version.get_data_type_id(r) == "vers": v = Version(r) return v.get_tdw_version(), v.get_unity_version() if len(resp) == 1: raise Exception( "Tried receiving version output data but didn't receive anything!" ) raise Exception(f"Expected output data with ID vers but got: " + Version.get_data_type_id(resp[0])) @staticmethod def get_unique_id() -> int: """ Generate a unique integer. Useful when creating objects. :return The new unique ID. """ return int.from_bytes(os.urandom(3), byteorder='big') @staticmethod def get_frame(frame: bytes) -> int: """ Converts the frame byte array to an integer. :param frame: The frame as bytes. :return The frame as an integer. """ return int.from_bytes(frame, byteorder='big')