From 2ec75f19a34b8e9ceff996b7ef76bf20aa6f2320 Mon Sep 17 00:00:00 2001 From: Evan Liu Date: Mon, 2 Oct 2023 10:12:12 -0700 Subject: [PATCH 1/3] Allow sim runner to pickup from previous state if failed --- sim/scripts/run_sim.py | 8 +++++--- sim/scripts/sim_runner.py | 37 ++++++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 10 deletions(-) diff --git a/sim/scripts/run_sim.py b/sim/scripts/run_sim.py index b5f4c4d..716101e 100644 --- a/sim/scripts/run_sim.py +++ b/sim/scripts/run_sim.py @@ -78,7 +78,7 @@ def init_and_sim_fastener(C, fastener, scenes, height=60): post_rotation = fastener.matrix_world.to_euler() return post_rotation[-1] -def play_scene(C, until_frame=250): +def play_scene(C, until_frame=230): frame = 0 for _ in range(until_frame): C.scene.frame_set(frame) @@ -112,6 +112,7 @@ def run_sim(model_path, output_path, copies, label): json.dump(label, f) for copy in range(copies): + copy = copy + 1 C = bpy.context scenes = {scene.name: scene for scene in bpy.data.scenes} bpy.ops.import_mesh.stl(filepath=str(model_path), axis_up='X', axis_forward="-Y") @@ -132,9 +133,10 @@ def run_sim(model_path, output_path, copies, label): C.window.scene = scenes[SIDEON_SCENE] play_scene(C) - z_angle_of_fastener += math.radians(random.randint(-15, 15)) - rotate_and_take_image(C, fastener, output_model_path, model_name, z_angle=z_angle_of_fastener) + #z_angle_of_fastener += math.radians(random.randint(-15, 15)) + #rotate_and_take_image(C, fastener, output_model_path, model_name, z_angle=z_angle_of_fastener) + print("Finished") bpy.data.objects.remove(fastener, do_unlink=True) def main(): diff --git a/sim/scripts/sim_runner.py b/sim/scripts/sim_runner.py index 995918e..5e7324b 100644 --- a/sim/scripts/sim_runner.py +++ b/sim/scripts/sim_runner.py @@ -2,6 +2,7 @@ import json import logging import os +import shutil import subprocess from pathlib import Path @@ -11,7 +12,8 @@ @click.option("--output_folder_path", "output_folder_path", required=True, help="Output folder to put generated images") @click.option("--copies", "copies", required=True, help="Number of copies for each fastener") @click.option("--batch_size", "batch_size", required=True, default=10, help="Number of models to handle at a time") -def main(input_folder_path, output_folder_path, copies, batch_size): +@click.option("--curr_state_path", "curr_state_path", required=False, default=None, help="Path to curr_state.json from previous run") +def main(input_folder_path, output_folder_path, copies, batch_size, curr_state_path): logging.basicConfig(level=logging.INFO) input_folder_path = Path(input_folder_path) @@ -19,18 +21,36 @@ def main(input_folder_path, output_folder_path, copies, batch_size): output_folder_path = Path(output_folder_path) assert output_folder_path.exists(), f"{output_folder_path} does not exist" - cad_models = set([d for d in os.listdir(input_folder_path) if os.path.isdir(input_folder_path / d)]) - existing = set([d for d in os.listdir(output_folder_path) if os.path.isdir(output_folder_path / d)]) + remaining = [] + if curr_state_path: + curr_state_path = Path(curr_state_path) + assert curr_state_path.exists(), f"{curr_state_path} does not exist" + with open(curr_state_path) as f: + curr_state = json.load(f) - logging.info(f"{len(cad_models)} total") - logging.info(f"{len(existing)} existing") - logging.info(f"{len(cad_models - existing)} to convert") + to_delete = [output_folder_path / model_id for model_id in curr_state["to_convert"] + curr_state["failed"]] + for delete_path in to_delete: + if delete_path.exists(): + shutil.rmtree(delete_path) + + remaining = curr_state["remaining"] + curr_state["to_convert"] + curr_state["failed"] + else: + + cad_models = set([d for d in os.listdir(input_folder_path) if os.path.isdir(input_folder_path / d)]) + existing = set([d for d in os.listdir(output_folder_path) if os.path.isdir(output_folder_path / d)]) + + logging.info(f"{len(cad_models)} total") + logging.info(f"{len(existing)} existing") + logging.info(f"{len(cad_models - existing)} to convert") + remaining = list(cad_models - existing) curr_state = { - "remaining": list(set(cad_models) - set(existing)), + "remaining": remaining, "to_convert": [], "failed": [], } + logging.info(f"{len(curr_state['remaining'])} remaining") + curr_state_json_path = output_folder_path / "curr_state.json" while curr_state["remaining"]: @@ -56,10 +76,13 @@ def main(input_folder_path, output_folder_path, copies, batch_size): if res.returncode: logging.error(f"Errored out, adding to failed field in {str(curr_state_json_path)}") + logging.error(res.stderr) curr_state["failed"] = curr_state["to_convert"] logging.info(f"Finished with status code: {res.returncode}") curr_state["to_convert"] = [] + with open(curr_state_json_path, 'w') as f: + json.dump(curr_state, f) if __name__ == "__main__": main() From c3dec19a7404f4944e81f91876d215e560e77b01 Mon Sep 17 00:00:00 2001 From: Evan Liu Date: Sun, 22 Oct 2023 23:23:00 -0700 Subject: [PATCH 2/3] Code to generate calibration date --- sim/scripts/run_sim.py | 28 +++++++++++++++++++--------- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/sim/scripts/run_sim.py b/sim/scripts/run_sim.py index 716101e..0f489c0 100644 --- a/sim/scripts/run_sim.py +++ b/sim/scripts/run_sim.py @@ -56,8 +56,10 @@ def init_and_sim_fastener(C, fastener, scenes, height=60): fastener.select_set(True) apply_texture(C, fastener) - x = random.randint(-2000, 2000) / 1000.0 - y = random.randint(-2000, 2000) / 1000.0 + #x = random.randint(-2000, 2000) / 1000.0 + #y = random.randint(-2000, 2000) / 1000.0 + x = 0 + y = 0 x_angle = math.radians(random.randint(0, 360)) @@ -67,7 +69,8 @@ def init_and_sim_fastener(C, fastener, scenes, height=60): y_angle = math.radians(random.randint(150, 210)) z_angle = math.radians(random.randint(0, 359)) - fastener.location = (x, y, 60) + #fastener.location = (x, y, 60) + fastener.location = (x, y, 10) fastener.rotation_euler = (x_angle, y_angle, z_angle) bpy.ops.rigidbody.objects_add(type='ACTIVE') @@ -78,7 +81,7 @@ def init_and_sim_fastener(C, fastener, scenes, height=60): post_rotation = fastener.matrix_world.to_euler() return post_rotation[-1] -def play_scene(C, until_frame=230): +def play_scene(C, until_frame=50): frame = 0 for _ in range(until_frame): C.scene.frame_set(frame) @@ -104,6 +107,7 @@ def rotate_and_take_image(C, fastener, output_model_path, model_name, z_angle=No take_image(C, rotate_image_path) def run_sim(model_path, output_path, copies, label): + copies = 1 output_path.mkdir(exist_ok=True) model_name = model_path.stem @@ -111,8 +115,12 @@ def run_sim(model_path, output_path, copies, label): with open(label_path, 'w') as f: json.dump(label, f) - for copy in range(copies): - copy = copy + 1 + camera = bpy.data.objects.get('top-down-cam') + increment = 0.5 + increments = 41 + start_z = 310 + + for i in range(increments): C = bpy.context scenes = {scene.name: scene for scene in bpy.data.scenes} bpy.ops.import_mesh.stl(filepath=str(model_path), axis_up='X', axis_forward="-Y") @@ -120,10 +128,13 @@ def run_sim(model_path, output_path, copies, label): z_angle_of_fastener = init_and_sim_fastener(C, fastener, scenes) - output_model_path = output_path / f"{model_name}_{copy}" + + z_height = start_z + increment*i + camera.location = (0, 0, z_height) + output_model_path = output_path / f"{model_name}" output_model_path.mkdir(exist_ok=True) - top_down_image_path = output_model_path / f"{model_name}_top.jpg" + top_down_image_path = output_model_path / f"{model_name}_{z_height:.1f}.jpg" C.window.scene = scenes[TOPDOWN_SCENE] play_scene(C) @@ -136,7 +147,6 @@ def run_sim(model_path, output_path, copies, label): #z_angle_of_fastener += math.radians(random.randint(-15, 15)) #rotate_and_take_image(C, fastener, output_model_path, model_name, z_angle=z_angle_of_fastener) - print("Finished") bpy.data.objects.remove(fastener, do_unlink=True) def main(): From a9ab90e477e8c71e754cc8ca19301d06e0fff611 Mon Sep 17 00:00:00 2001 From: Evan Liu Date: Mon, 23 Oct 2023 21:03:04 -0700 Subject: [PATCH 3/3] Change increments to be larger range --- sim/scripts/run_sim.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/sim/scripts/run_sim.py b/sim/scripts/run_sim.py index 0f489c0..3bffc36 100644 --- a/sim/scripts/run_sim.py +++ b/sim/scripts/run_sim.py @@ -71,7 +71,8 @@ def init_and_sim_fastener(C, fastener, scenes, height=60): #fastener.location = (x, y, 60) fastener.location = (x, y, 10) - fastener.rotation_euler = (x_angle, y_angle, z_angle) + fastener.rotation_euler = (0, 0, 0) + #fastener.rotation_euler = (x_angle, y_angle, z_angle) bpy.ops.rigidbody.objects_add(type='ACTIVE') bpy.ops.object.origin_set(type='ORIGIN_CENTER_OF_VOLUME') @@ -81,7 +82,7 @@ def init_and_sim_fastener(C, fastener, scenes, height=60): post_rotation = fastener.matrix_world.to_euler() return post_rotation[-1] -def play_scene(C, until_frame=50): +def play_scene(C, until_frame=230): frame = 0 for _ in range(until_frame): C.scene.frame_set(frame) @@ -116,9 +117,9 @@ def run_sim(model_path, output_path, copies, label): json.dump(label, f) camera = bpy.data.objects.get('top-down-cam') - increment = 0.5 - increments = 41 - start_z = 310 + increments = 75 + increment = 2 + start_z = 260 for i in range(increments): C = bpy.context