def test_rgb_camera_ticks_per_capture(ticks_per_capture): """Validate that the ticks_per_capture method actually makes the RGBCamera take fewer screenshots. Capture a screenshot, wait for it to change, then make sure that the image doesn't change until ticks_per_capture ticks have elapsed. """ global shared_ticks_per_capture_env if shared_ticks_per_capture_env is None: make_ticks_per_capture_env() env = shared_ticks_per_capture_env env.reset() # The agent needs to be moving for the image to change env.act("sphere0", [2]) env.agents["sphere0"].sensors["TestCamera"].set_ticks_per_capture( ticks_per_capture) # Take the initial capture, and wait until it changes initial = env.tick()['TestCamera'][:, :, 0:3] MAX_TRIES = 50 tries = 0 while tries < MAX_TRIES: intermediate = env.tick()['TestCamera'][:, :, 0:3] if mean_square_err(initial, intermediate) > 10: break tries += 1 assert MAX_TRIES != tries, "Timed out waiting for the image to change!" # On the last tick, intermediate changed. Now, it should take # ticks_per_capture ticks for it to change again. initial = intermediate for _ in range(ticks_per_capture - 1): # Make sure it doesn't change intermediate = env.tick()['TestCamera'][:, :, 0:3] assert mean_square_err( initial, intermediate) < 10, "The RGBCamera output changed unexpectedly!" # Now it should change final = env.tick()['TestCamera'][:, :, 0:3] assert mean_square_err( initial, final) > 10, "The RGBCamera output did not change when expected!"
def test_rgb_camera(resolution, request): """Makes sure that the RGB camera is positioned and capturing correctly. Capture pixel data, and load from disk the baseline of what it should look like. Then, use mse() to see how different the images are. """ global base_cfg cfg = copy.deepcopy(base_cfg) cfg["agents"][0]["sensors"][0]["configuration"] = { "CaptureWidth": resolution, "CaptureHeight": resolution } binary_path = holodeck.packagemanager.get_binary_path_for_package( "DefaultWorlds") with holodeck.environments.HolodeckEnvironment(scenario=cfg, binary_path=binary_path, show_viewport=False, uuid=str( uuid.uuid4())) as env: for _ in range(5): env.tick() pixels = env.tick()['TestCamera'][:, :, 0:3] baseline = cv2.imread( os.path.join(request.fspath.dirname, "expected", "{}.png".format(resolution))) err = mean_square_err(pixels, baseline) assert err < 2000
def test_viewport_capture(resolution, request): """Validates that the ViewportCapture camera is working at the expected resolutions Also incidentally validates that the viewport can be sized correctly """ global base_cfg cfg = copy.deepcopy(base_cfg) cfg["window_width"] = resolution cfg["window_height"] = resolution cfg["agents"][0]["sensors"][0]["configuration"] = { "CaptureWidth": resolution, "CaptureHeight": resolution } binary_path = holodeck.packagemanager.get_binary_path_for_package("DefaultWorlds") with holodeck.environments.HolodeckEnvironment(scenario=cfg, binary_path=binary_path, show_viewport=False, uuid=str(uuid.uuid4())) as env: env.should_render_viewport(True) env.tick(5) pixels = env.tick()['ViewportCapture'][:, :, 0:3] assert pixels.shape == (resolution, resolution, 3) baseline = cv2.imread(os.path.join(request.fspath.dirname, "expected", "{}_viewport.png".format(resolution))) err = mean_square_err(pixels, baseline) assert err < 1000, "The expected screenshot did not match the actual screenshot!"
def compare_rgb_sensor_data(sensor_data_1, sensor_data_2, show_images=False) -> float: """ Compare data from RGB sensors return mean squared error """ pixels_1 = sensor_data_1[:, :, 0:3] pixels_2 = sensor_data_2[:, :, 0:3] if show_images: # Show images when debugging--this will block tests until user input # is provided display_multiple([(pixels_1, "image 1"), (pixels_2, "image 2")]) return mean_square_err(pixels_1, pixels_2)
def test_sensor_rotation_resets_after_reset(rotation_env): """Validates that the sensor rotation is reset back to the starting position after calling ``.reset()``. """ # Re-use the screenshot for test_rgb_camera rotation_env.agents["sphere0"].sensors["RGBCamera"].rotate([0, 0, 0]) pixels_before = rotation_env.tick(5)["RGBCamera"][:, :, 0:3] rotation_env.reset() pixels_after = rotation_env.tick(5)["RGBCamera"][:, :, 0:3] err = mean_square_err(pixels_before, pixels_after) assert err > 2000, \ "The images were too similar! Did the sensor not rotate back?"
def compare_rgb_sensor_data_with_baseline(sensor_data, base_path, baseline_name, show_images=False) -> float: """ Compare data from RGB sensor with baseline file in `expected` folder and return mean squared error """ pixels = sensor_data[:, :, 0:3] baseline = cv2.imread( os.path.join(base_path, "expected", "{}.png".format(baseline_name))) if show_images: # Show images when debugging--this will block tests until user input # is provided display_multiple([(pixels, "pixels"), (baseline, "baseline")]) return mean_square_err(pixels, baseline)
def test_sensor_rotation(rotation_env, request): """Validates that calling rotate actually rotates the sensor using the RGBCamera. Positions the SphereAgent above the target cube so that if it rotates down, it will capture the test pattern. """ # Re-use the screenshot for test_rgb_camera rotation_env.agents["sphere0"].sensors["RGBCamera"].rotate([0, 0, 0]) pixels = rotation_env.tick(10)["RGBCamera"][:, :, 0:3] baseline = cv2.imread( os.path.join(request.fspath.dirname, "expected", "256.png")) err = mean_square_err(pixels, baseline) assert err < 2000, \ "The sensor appeared to not rotate!"
def test_viewport_capture_after_teleport(env_1024, request): """Validates that the ViewportCapture is updated after teleporting the camera to a different location. Incidentally tests HolodeckEnvironment.teleport_camera as well """ # Other tests muck with this. Set it to true just in case env_1024.should_render_viewport(True) env_1024.move_viewport([.9, -1.75, .5], [0, 0, 0]) for _ in range(5): env_1024.tick() pixels = env_1024.tick()['ViewportCapture'][:, :, 0:3] baseline = cv2.imread(os.path.join(request.fspath.dirname, "expected", "teleport_viewport_test.png")) err = mean_square_err(pixels, baseline) assert err < 1000, "The captured viewport differed from the expected screenshot!"
def validate_rendering_viewport_disabled(env_1024, between_tests_callback): """Helper function for a few tests. Validates that rendering the viewport is actually disabled by teleporting the agent and comparing the before/after RGBCamera captures. Args: env_1024: environment to use between_tests_callback: callback to call before teleporting the camera and taking a 2nd screenshot """ start = time.perf_counter() for _ in range(10): env_1024.tick() elapsed_with_viewport = time.perf_counter() - start initial_screenshot = env_1024.tick()['ViewportCapture'][:, :, 0:3] between_tests_callback(env_1024) env_1024.move_viewport([781, 643, 4376], [381, 403, 3839]) start = time.perf_counter() for _ in range(10): env_1024.tick() elapsed_without_viewport = time.perf_counter() - start final_screenshot = env_1024.tick()['ViewportCapture'][:, :, 0:3] err = mean_square_err(initial_screenshot, final_screenshot) assert err < 100, "The screenshots were not identical after disabling rendering" # This is unreliable 👇 :/ # assert elapsed_without_viewport < elapsed_with_viewport, \ # "Holodeck did not tick faster without rendering the viewport. Was it actually " \ # "disabled?" # cleanup environment env_1024.should_render_viewport(True) env_1024.tick()