diff --git a/.github/workflows/benchmark.yml b/.github/workflows/benchmark.yml new file mode 100644 index 0000000000..d9f0e5bab5 --- /dev/null +++ b/.github/workflows/benchmark.yml @@ -0,0 +1,76 @@ +name: Benchmark + +on: + pull_request: + branches: + - og-develop + +permissions: + # deployments permission to deploy GitHub pages website + deployments: write + # contents permission to update benchmark contents in gh-pages branch + contents: write + +concurrency: + group: ${{ github.workflow }}-${{ github.event_name == 'pull_request' && github.head_ref || github.sha }} + cancel-in-progress: true + +jobs: + test: + runs-on: [self-hosted, linux, gpu] + container: + image: stanfordvl/omnigibson-dev:latest + options: --gpus=all --privileged --user=root + env: + DISPLAY: "" + OMNIGIBSON_HEADLESS: 1 + volumes: + - /scr/omni-data/datasets:/data + - /usr/share/vulkan/icd.d/nvidia_icd.json:/etc/vulkan/icd.d/nvidia_icd.json + - /usr/share/vulkan/icd.d/nvidia_layers.json:/etc/vulkan/implicit_layer.d/nvidia_layers.json + - /usr/share/glvnd/egl_vendor.d/10_nvidia.json:/usr/share/glvnd/egl_vendor.d/10_nvidia.json + - /scr/omni-data/isaac-sim/cache/ov:/root/.cache/ov:rw + - /scr/omni-data/isaac-sim/cache/pip:/root/.cache/pip:rw + - /scr/omni-data/isaac-sim/cache/glcache:/root/.cache/nvidia/GLCache:rw + - /scr/omni-data/isaac-sim/cache/computecache:/root/.nv/ComputeCache:rw + - /scr/omni-data/isaac-sim/logs:/root/.nvidia-omniverse/logs:rw + - /scr/omni-data/isaac-sim/config:/root/.nvidia-omniverse/config:rw + - /scr/omni-data/isaac-sim/data:/root/.local/share/ov/data:rw + - /scr/omni-data/isaac-sim/documents:/root/Documents:rw + + defaults: + run: + shell: micromamba run -n omnigibson /bin/bash -leo pipefail {0} + + steps: + - name: Fix home + run: echo "HOME=/root" >> $GITHUB_ENV + + - name: Checkout source + uses: actions/checkout@v2 + with: + submodules: true + path: omnigibson-src + + - name: Install dev requirements + working-directory: omnigibson-src + run: pip install -r requirements-dev.txt + + - name: Install + working-directory: omnigibson-src + run: pip install -e . + + - name: Run performance benchmark + working-directory: omnigibson-src + run: source /isaac-sim/setup_conda_env.sh && source tests/benchmark.sh + + - name: Store benchmark result + uses: benchmark-action/github-action-benchmark@v1 + with: + tool: 'customBiggerIsBetter' + output-file-path: output.json + fail-on-alert: true + alert-threshold: '200%' + github-token: ${{ secrets.GITHUB_TOKEN }} + comment-on-alert: true + auto-push: true diff --git a/omnigibson/examples/profiling/benchmark.py b/omnigibson/examples/profiling/benchmark.py new file mode 100644 index 0000000000..e7495a042c --- /dev/null +++ b/omnigibson/examples/profiling/benchmark.py @@ -0,0 +1,81 @@ +#!/usr/bin/env python + +import os +import argparse +import json +import omnigibson as og +import numpy as np + +from omnigibson.macros import gm +from omnigibson.utils.profiling_utils import ProfilingEnv + +OUTPUT_DIR = os.path.join(os.path.expanduser("~"), "Desktop") + +parser = argparse.ArgumentParser() + +parser.add_argument("-r", "--robot", action='store_true') +parser.add_argument("-s", "--scene", action='store_true') +parser.add_argument("-f", "--flatcache", action='store_true') +parser.add_argument("-p", "--particles", action='store_true') + +PROFILING_FIELDS = ["Total step fps", "Action generation fps", "Physics step fps", "Render step time", "Non physics step fps"] + +def main(): + args = parser.parse_args() + # Modify flatcache, pathtracing, GPU, and object state settings + gm.ENABLE_FLATCACHE = args.flatcache + gm.ENABLE_HQ_RENDERING = False + gm.ENABLE_OBJECT_STATES = True + gm.ENABLE_TRANSITION_RULES = True + gm.ENABLE_GPU_DYNAMICS = True + + cfg = {} + if args.robot: + cfg["robots"] = [{ + "type": "Fetch", + "obs_modalities": ["scan", "rgb", "depth"], + "action_type": "continuous", + "action_normalize": True, + "controller_config": {"arm_0": {"name": "JointController"}} + }] + if args.particles: + pass + if args.scene: + cfg["scene"] = { + "type": "InteractiveTraversableScene", + "scene_model": "Rs_int", + } + else: + cfg["scene"] = { + "type": "InteractiveTraversableScene", + "scene_model": "Rs_int", + } + env = ProfilingEnv(configs=cfg, action_timestep=1/60., physics_timestep=1/240.) + env.reset() + + output, results = [], [] + for i in range(500): + if args.robot: + result = env.step(np.random.uniform(-0.1, 0.1, env.robots[0].action_dim))[4][:5] + else: + result = env.step(None)[4][:5] + results.append(result) + + results = np.array(results) + for i, field in enumerate(PROFILING_FIELDS): + field += " (Rs_int, " if args.scene else " (Rs_int, " + field += "with Fetch, " if args.robot else "without Fetch, " + field += "with particles & softbody " if args.flatcache else "without particles & softbody " + field += "flatcache on)" if args.flatcache else "flatcache off)" + output.append({ + "name": field, + "unit": "fps", + "value": 1 / np.mean(results[-200:, i]) + }) + + with open("output.json", "w") as f: + json.dump(output, f) + og.shutdown() + +if __name__ == "__main__": + main() diff --git a/omnigibson/examples/profiling/speed.py b/omnigibson/examples/profiling/speed.py new file mode 100644 index 0000000000..9334271752 --- /dev/null +++ b/omnigibson/examples/profiling/speed.py @@ -0,0 +1,55 @@ +#!/usr/bin/env python + +import os +import omni +import logging +import argparse +import omnigibson as og +import json + +from omnigibson.macros import gm +from omnigibson.utils.profiling_utils import * + +OUTPUT_DIR = os.path.join(os.path.expanduser("~"), "Desktop") + +parser = argparse.ArgumentParser() + +parser.add_argument("-p", "--particles", action='store_true') +parser.add_argument("-s", "--scenes", action='store_true') +parser.add_argument("-o", "--objects", action='store_true') +parser.add_argument("-r", "--robots", action='store_true') + + +def main(): + args = parser.parse_args() + # Modify flatcache, pathtracing, GPU, and object state settings + gm.ENABLE_FLATCACHE = False + gm.ENABLE_HQ_RENDERING = False + gm.ENABLE_OBJECT_STATES = True + gm.ENABLE_TRANSITION_RULES = True + gm.SHOW_DISCLAIMERS = False + # Disable OmniGibson logging + log = omni.log.get_log() + log.enabled = False + og.log.setLevel(logging.FATAL) + + env = ProfilingEnv(configs=dict(scene={"type": "Scene"}), action_timestep=1/60., physics_timestep=1/240.) + env.reset() + + results = dict() + if args.objects: + results["objects"] = benchmark_objects(env) + if args.robots: + results["robots"] = benchmark_robots(env) + if args.scenes: + results["scenes"] = benchmark_scenes(env) + if args.particles: + results["fluids"] = benchmark_particle_system(env) + + with open(os.path.join(OUTPUT_DIR, "benchmark_results.json"), 'w') as f: + json.dump(results, f) + plot_results(results, os.path.join(OUTPUT_DIR, "omnigibson_benchmark.pdf")) + og.shutdown() + +if __name__ == "__main__": + main() diff --git a/omnigibson/utils/profiling_utils.py b/omnigibson/utils/profiling_utils.py new file mode 100644 index 0000000000..87c4affe48 --- /dev/null +++ b/omnigibson/utils/profiling_utils.py @@ -0,0 +1,246 @@ +import gym +import tqdm +import numpy as np +import omnigibson as og +import matplotlib.pyplot as plt + +from time import time +from omnigibson import object_states +from omnigibson.objects import PrimitiveObject +from omnigibson.robots import REGISTERED_ROBOTS +from omnigibson.utils.asset_utils import get_available_og_scenes +from omnigibson.envs.env_base import Environment +from omnigibson.macros import gm + +PROFILING_FIELDS = ["total time", "action time", "physics time", "render time", "non physics time", "get observation time", "task time"] + +class ProfilingEnv(Environment): + def step(self, action): + start = time() + # If the action is not a dictionary, convert into a dictionary + if not isinstance(action, dict) and not isinstance(action, gym.spaces.Dict): + action_dict = dict() + idx = 0 + for robot in self.robots: + action_dim = robot.action_dim + action_dict[robot.name] = action[idx: idx + action_dim] + idx += action_dim + else: + # Our inputted action is the action dictionary + action_dict = action + + # Iterate over all robots and apply actions + for robot in self.robots: + robot.apply_action(action_dict[robot.name]) + action_end = time() + # Run simulation step + # Possibly force playing + for i in range(og.sim.n_physics_timesteps_per_render): + super(type(og.sim), og.sim).step(render=False) + physics_end = time() + og.sim.render() + render_end = time() + # Additionally run non physics things if we have a valid scene + if og.sim._scene is not None: + og.sim._omni_update_step() + if og.sim.is_playing(): + og.sim._non_physics_step() + if gm.ENABLE_TRANSITION_RULES: + og.sim._transition_rule_step() + non_physics_end = time() + # Grab observations + obs = self.get_obs() + obs_end = time() + # Grab reward, done, and info, and populate with internal info + reward, done, info = self.task.step(self, action) + self._populate_info(info) + + if done and self._automatic_reset: + # Add lost observation to our information dict, and reset + info["last_observation"] = obs + obs = self.reset() + + # Increment step + self._current_step += 1 + end = time() + ret = [end-start, action_end-start, physics_end-action_end, render_end-physics_end, \ + non_physics_end-render_end, obs_end-non_physics_end, end-obs_end] + if self._current_step % 100 == 0: + print("total time: {:.3f} ms, action time: {:.3f} ms, physics time: {:.3f} ms, render time: {:.3f} ms, non physics time: {:.3f} ms, get obs time: {:.3f} ms, task time: {:.3f} ms".format(*ret)) + return obs, reward, done, info, ret + + +def plot_results(results_dict, output_fp): + num_plots = np.sum([len(results) for results in results_dict.values()]) + cur_plot = 1 + plt.figure(figsize=(7, 3.5 * num_plots)) + for cat, results in results_dict.items(): + n_candidates = len(list(results.values())[0]) + for field in results: + result = [results[field][candidate][0] for candidate in results[field]] + ax = plt.subplot(num_plots, 1, cur_plot) + ax.set_xlabel(f"{cat}: {field}") + ax.set_ylabel("time (ms)") + plt.bar(range(n_candidates), result, tick_label=list(results[field].keys())) + cur_plot += 1 + plt.tight_layout() + plt.savefig(output_fp) + + +def benchmark_objects(env): + NUM_ITER = 30 + NUM_OBJECTS_PER_ITER = 10 + NUM_STEP_PER_ITER = 200 + + og.sim.stop() + env.reload({"scene": {"type": "Scene"}}) + env.reset() + + results = {field: {} for field in PROFILING_FIELDS} + for i in tqdm.trange(NUM_ITER): + objs = [] + cur_results = [] + for j in range(NUM_OBJECTS_PER_ITER): + obj = PrimitiveObject( + prim_path=f"/World/obj_{i}_{j}", + name=f"obj_{i}_{j}", + primitive_type="Cube", + ) + og.sim.import_object(obj) + obj.set_position(np.array([i, j, 1]) * 1.2) + objs.append(obj) + og.sim.step() # always taks a step after importing objects + for _ in range(NUM_STEP_PER_ITER): + cur_result = env.step(None) + cur_results.append(cur_result[4]) + cur_results = np.array(cur_results) + for k, field in enumerate(PROFILING_FIELDS): + results[field][(i + 1) * NUM_OBJECTS_PER_ITER] = [ + np.mean(cur_results[-100:, k]), np.std(cur_results[-100:, k]), np.median(cur_results[-100:, k]), np.max(cur_results[-100:, k]), np.min(cur_results[-100:, k]) + ] + for obj in objs: + obj.sleep() + + return results + + + +def benchmark_robots(env): + NUM_STEP = 300 + + og.sim.stop() + env.reload({"scene": {"type": "Scene"}}) + env.reset() + + results = {field: {} for field in PROFILING_FIELDS} + for robot_name, robot_cls in tqdm.tqdm(REGISTERED_ROBOTS.items()): + cur_results = [] + robot = robot_cls( + prim_path=f"/World/{robot_name}", + name=robot_name, + obs_modalities=[] + ) + og.sim.import_object(robot) + og.sim.play() + og.sim.step() + + for _ in range(NUM_STEP): + cur_result = env.step(np.random.uniform(-0.1, 0.1, robot.action_dim)) + cur_results.append(cur_result[4]) + cur_results = np.array(cur_results) + for i, field in enumerate(PROFILING_FIELDS): + results[field][robot_name] = [ + np.mean(cur_results[-100:, i]), np.std(cur_results[-100:, i]), np.median(cur_results[-100:, i]), np.max(cur_results[-100:, i]), np.min(cur_results[-100:, i]) + ] + og.sim.stop() + og.sim.remove_object(robot) + + return results + + + +def benchmark_scenes(env): + NUM_STEP = 600 + + og.sim.stop() + + results = {field: {} for field in PROFILING_FIELDS} + for scene_model in tqdm.tqdm(get_available_og_scenes()[12:13]): + cur_results = [] + env.reload({"scene": {"type": "InteractiveTraversableScene", "scene_model": scene_model}}) + env.reset() + + for _ in range(NUM_STEP): + cur_result = env.step(None) + cur_results.append(cur_result[4]) + cur_results = np.array(cur_results) + for i, field in enumerate(PROFILING_FIELDS): + results[field][scene_model] = [ + np.mean(cur_results[-100:, i]), np.std(cur_results[-100:, i]), np.median(cur_results[-100:, i]), np.max(cur_results[-100:, i]), np.min(cur_results[-100:, i]) + ] + og.sim.stop() + + return results + + +def benchmark_particle_system(env): + NUM_STEP = 300 + + og.sim.stop() + + cfg = {"scene": {"type": "Scene"}} + + def check_toggledon(obj): + return obj.states[object_states.ToggledOn].get_value() + + # Define objects to load into the environment + sink_cfg = dict( + type="DatasetObject", + name="sink", + category="sink", + model="yfaufu", + scale=[0.8, 0.8, 0.8], + abilities={ + "toggleable": {}, + "particleSource": { + "conditions": { + "water": [check_toggledon], # Must be toggled on for water source to be active + }, + "source_radius": 0.0125, + "source_height": 0.05, + "initial_speed": 0.0, # Water merely falls out of the spout + }, + "particleSink": { + "conditions": { + "water": None, # No conditions, always sinking nearby particles + }, + "sink_radius": 0.05, + "sink_height": 0.05, + }, + }, + position=[-0.7, 0, 0.56], + ) + cfg["objects"] = [sink_cfg] + env.reload(cfg) + env.reset() + initial_state = og.sim.dump_state() + results = {field: {} for field in PROFILING_FIELDS} + for cond in tqdm.tqdm([True, False]): + cur_results = [] + gm.ENABLE_OBJECT_STATES = cond + og.sim.play() + og.sim.step() + + for _ in range(NUM_STEP): + cur_result = env.step(None) + cur_results.append(cur_result[4]) + cur_results = np.array(cur_results) + for i, field in enumerate(PROFILING_FIELDS): + results[field][cond] = [ + np.mean(cur_results[-100:, i]), np.std(cur_results[-100:, i]), np.median(cur_results[-100:, i]), np.max(cur_results[-100:, i]), np.min(cur_results[-100:, i]) + ] + og.sim.stop() + og.sim.load_state(initial_state) + + return results + diff --git a/tests/benchmark.sh b/tests/benchmark.sh new file mode 100644 index 0000000000..cc76152c34 --- /dev/null +++ b/tests/benchmark.sh @@ -0,0 +1,17 @@ +pip install tqdm +python omnigibson/examples/profiling/benchmark.py +python omnigibson/examples/profiling/benchmark.py -r +python omnigibson/examples/profiling/benchmark.py -f +python omnigibson/examples/profiling/benchmark.py -p +python omnigibson/examples/profiling/benchmark.py -s +python omnigibson/examples/profiling/benchmark.py -r -f +python omnigibson/examples/profiling/benchmark.py -r -p +python omnigibson/examples/profiling/benchmark.py -r -s +python omnigibson/examples/profiling/benchmark.py -f -p +python omnigibson/examples/profiling/benchmark.py -f -s +python omnigibson/examples/profiling/benchmark.py -p -s +python omnigibson/examples/profiling/benchmark.py -r -f -p +python omnigibson/examples/profiling/benchmark.py -r -f -s +python omnigibson/examples/profiling/benchmark.py -r -p -s +python omnigibson/examples/profiling/benchmark.py -f -p -s +python omnigibson/examples/profiling/benchmark.py -r -f -p -s \ No newline at end of file diff --git a/tests/benchmark/benchmark_interactive_scene.py b/tests/benchmark/benchmark_interactive_scene.py deleted file mode 100644 index 1bdbf6b4e8..0000000000 --- a/tests/benchmark/benchmark_interactive_scene.py +++ /dev/null @@ -1,139 +0,0 @@ -#!/usr/bin/env python - -import os -import time - -import matplotlib.pyplot as plt -import numpy as np - -import omnigibson as og -from omnigibson.macros import gm -from omnigibson.robots.turtlebot import Turtlebot -from omnigibson.scenes.interactive_traversable_scene import InteractiveTraversableScene -from omnigibson.utils.asset_utils import get_og_assets_version - - -# Params to be set as needed. -SCENES = ["restaurant_hotel"] -OUTPUT_DIR = os.path.join(os.path.expanduser("~"), "Desktop") -NUM_STEPS = 2000 -gm.DEFAULT_VIEWER_WIDTH = 128 -gm.DEFAULT_VIEWER_HEIGHT = 128 - -# scenes = ["Beechwood_0_int", -# "Beechwood_1_int", -# "Benevolence_0_int", -# "Benevolence_1_int", -# "Benevolence_2_int", -# "Ihlen_0_int", -# "Ihlen_1_int", -# "Merom_0_int", -# "Merom_1_int", -# "Pomaria_0_int", -# "Pomaria_1_int", -# "Pomaria_2_int", -# "Rs_int", -# "Wainscott_0_int", -# "Wainscott_1_int"] - - -def benchmark_scene(scene_name, optimized=False, import_robot=True): - assets_version = get_og_assets_version() - print("assets_version", assets_version) - scene = InteractiveTraversableScene(scene_name) - start = time.time() - og.sim.import_scene(scene) - print(time.time() - start) - - og.sim.viewer_camera.set_position_orientation( - position=np.array([-13.27634359, -12.70026879, -2.68970369]), - orientation=np.array([0.70597155, 0.10758371, 0.10545935, 0.69203196]), - ) - - # Hide main viewport - og.sim.viewer_visibility = False - - if import_robot: - turtlebot = Turtlebot(prim_path="/World/robot", name="agent") - og.sim.import_object(turtlebot, auto_initialize=True) - og.sim.step() - if scene_name == "restaurant_hotel": - turtlebot.set_position_orientation([-12.2627573, -10.60511875, -3.4790891], [0, 0, 0, 1.0]) - - og.sim.play() - og.sim.step() - fps = [] - physics_fps = [] - render_fps = [] - obj_awake = [] - for i in range(NUM_STEPS): - start = time.time() - if import_robot: - # Apply random actions. - turtlebot.apply_action(turtlebot.action_space.sample()) - og.sim.step(render=False) - physics_end = time.time() - - # og.sim.render() - end = time.time() - - if i % 100 == 0: - print("Elapsed time: ", end - start) - print("Render Frequency: ", 1 / (end - physics_end)) - print("Physics Frequency: ", 1 / (physics_end - start)) - print("Step Frequency: ", 1 / (end - start)) - fps.append(1 / (end - start)) - physics_fps.append(1 / (physics_end - start)) - render_fps.append(1 / (end - physics_end)) - # obj_awake.append(sim.body_links_awake) - - plt.figure(figsize=(7, 25)) - ax = plt.subplot(6, 1, 1) - plt.hist(render_fps) - ax.set_xlabel("Render fps") - ax.set_title( - "Scene {} version {}\noptimized {} num_obj {}\n import_robot {}".format( - scene_name, assets_version, optimized, scene.n_objects, import_robot - ) - ) - ax = plt.subplot(6, 1, 2) - plt.hist(physics_fps) - ax.set_xlabel("Physics fps") - ax = plt.subplot(6, 1, 3) - plt.hist(fps) - ax.set_xlabel("Step fps") - ax = plt.subplot(6, 1, 4) - plt.plot(render_fps) - ax.set_xlabel("Render fps with time, converge to {}".format(np.mean(render_fps[-100:]))) - ax.set_ylabel("fps") - ax = plt.subplot(6, 1, 5) - plt.plot(physics_fps) - ax.set_xlabel("Physics fps with time, converge to {}".format(np.mean(physics_fps[-100:]))) - ax.set_ylabel("fps") - ax = plt.subplot(6, 1, 6) - plt.plot(fps) - ax.set_xlabel("Overall fps with time, converge to {}".format(np.mean(fps[-100:]))) - ax.set_ylabel("fps") - # TODO! Reading objects' wake state not available yet from omniverse - # ax = plt.subplot(6, 1, 6) - # plt.plot(obj_awake) - # ax.set_xlabel("Num object links awake, converge to {}".format(np.mean(obj_awake[-100:]))) - plt.tight_layout() - plt.savefig(os.path.join( - OUTPUT_DIR, - "scene_benchmark_{}_o_{}_r_{}.pdf".format(scene_name, optimized, import_robot))) - - from IPython import embed; embed() - - -def main(): - for scene in SCENES: - benchmark_scene(scene, optimized=True, import_robot=True) - # og.sim.stop() - # benchmark_scene(scene, optimized=True, import_robot=False) - - og.shutdown() - - -if __name__ == "__main__": - main() diff --git a/tests/benchmark/benchmark_object_count.py b/tests/benchmark/benchmark_object_count.py deleted file mode 100644 index 1c83d356ca..0000000000 --- a/tests/benchmark/benchmark_object_count.py +++ /dev/null @@ -1,105 +0,0 @@ -""" -Script to benchmark speed vs. no. of objects in the scene. -""" - -import os -import time - -import matplotlib.pyplot as plt -import numpy as np - -from omnigibson import app, Simulator -from omnigibson.objects.primitive_object import PrimitiveObject -from omnigibson.scenes.scene_base import Scene -from omnigibson.utils.asset_utils import get_og_assets_version - - -# Params to be set as needed. -MAX_NUM_OBJS = 400 # Maximum no. of objects to add. -NUM_OBJS_PER_ITER = 20 # No. of objects to add per iteration. -NUM_STEPS_PER_ITER = 30 # No. of steps to take for each n of objects. -OBJ_SCALE = 0.05 # Object scale to be set appropriately to sim collisions. -RAND_POSITION = True # True to randomize positions. -OUTPUT_DIR = os.path.join(os.path.expanduser("~"), "Desktop") - -# Internal constants. -_N_PER_ROW = int(np.sqrt(MAX_NUM_OBJS)) -_MIN_VAL = -2.0 -_MAX_VAL = 2.0 -_STEP_SIZE = (_MAX_VAL - _MIN_VAL) / _N_PER_ROW - - -def _get_position(obj_idx, is_random=False): - if is_random: - pos_arange = np.arange(_MIN_VAL, _MAX_VAL, step=0.1, dtype=np.float32) - x, y, z = np.random.choice(pos_arange, size=3) - return x, y, z - x = _MIN_VAL + _STEP_SIZE * (obj_idx % _N_PER_ROW) - y = _MIN_VAL + _STEP_SIZE * (obj_idx // _N_PER_ROW) - return x, y, 0.1 - - -def benchmark_scene(sim): - assets_version = get_og_assets_version() - print("assets_version", assets_version) - - scene = Scene(floor_plane_visible=True) - sim.import_scene(scene) - sim.play() - - xs = [] - ys = [] - yerrs = [] - for i in range(MAX_NUM_OBJS // NUM_OBJS_PER_ITER): - new_objs = [] - for j in range(NUM_OBJS_PER_ITER): - obj_idx = i * NUM_OBJS_PER_ITER + j - obj = PrimitiveObject( - prim_path=f"/World/obj{obj_idx}", - primitive_type="Sphere", - name=f"obj{obj_idx}", - scale=OBJ_SCALE, - visual_only=False, - ) - sim.import_object(obj=obj, auto_initialize=False) - # x, y, z = _get_position(obj_idx, RAND_POSITION) - x, y = 0, 0 - z = 0.5 + j * OBJ_SCALE * 2.25 - obj.set_position(position=np.array([x, y, z])) - new_objs.append(obj) - - # Take a step to initialize the new objects (done in _non_physics_step()). - sim.step() - step_freqs = [] - for _ in range(NUM_STEPS_PER_ITER): - start = time.time() - sim.step() - end = time.time() - step_freqs.append(1 / (end - start)) - - xs.append(i * NUM_OBJS_PER_ITER) - max_freq, min_freq = np.max(step_freqs), np.min(step_freqs) - ys.append(np.mean((max_freq, min_freq))) - yerrs.append(max_freq - ys[-1]) - - plt.figure(figsize=(9, 6)) - ax = plt.subplot(1, 1, 1) - plt.errorbar(xs, ys, yerr=yerrs, elinewidth=0.75) - ax.set_xlabel("No. of objects") - ax.set_ylabel("Step fps") - ax.set_title(f"Version {assets_version}") - plt.tight_layout() - plt.savefig(os.path.join( - OUTPUT_DIR, f"scene_objs_benchmark_{MAX_NUM_OBJS}_{OBJ_SCALE}.png")) - - -def main(): - assert MAX_NUM_OBJS <= 1000 - - sim = Simulator() - benchmark_scene(sim) - app.close() - - -if __name__ == "__main__": - main()