def __init__(self, camera_arm_control_service):
     self._local_world_detector = LocalWorldDetector(camera_arm_control_service)
     self._local_world_map_drawing_service = LocalWorldMapDrawingService()
     self._on_detection_complete = EventHandler()
     self._detection_mode = LocalWorldMapDetectionMode.NONE
     self._local_world_map = LocalWorldMap()
     self._camera_arm_control_service = camera_arm_control_service
     self._detection_lock = Lock()
class LocalWorldMapService(object):

    DETECTION_MODE_SWITCH_WAIT_TIME = 1

    @property
    def local_world_map(self):
        return self._local_world_map

    @property
    def detection_mode(self):
        return self._detection_mode

    @detection_mode.setter
    def detection_mode(self, value):
        self._switch_detection_mode(value)

    @property
    def on_detection_complete(self):
        return self._on_detection_complete

    @on_detection_complete.setter
    def on_detection_complete(self, value):
        self._on_detection_complete = value

    def __init__(self, camera_arm_control_service):
        self._local_world_detector = LocalWorldDetector(camera_arm_control_service)
        self._local_world_map_drawing_service = LocalWorldMapDrawingService()
        self._on_detection_complete = EventHandler()
        self._detection_mode = LocalWorldMapDetectionMode.NONE
        self._local_world_map = LocalWorldMap()
        self._camera_arm_control_service = camera_arm_control_service
        self._detection_lock = Lock()

    def detect_objects(self, image):
        self._detection_lock.acquire()
        try:
            self._execute_detection(image)
        finally:
            self._detection_lock.release()
        self._on_detection_complete.fire()

    def _execute_detection(self, image):
        local_world_descriptor = self._local_world_detector.detect_objects(image, self._detection_mode, self._local_world_map)
        if local_world_descriptor is not None:
            self._local_world_map.merge_local_world_descriptor(local_world_descriptor)

    def reset(self, local_world_object_types):
        self._local_world_map.reset(local_world_object_types)

    def draw_local_world_map(self):
        self._local_world_map_drawing_service.draw(self._local_world_map)
        return self._local_world_map.reference_image 

    def wait_for_detection(self, local_world_object_types, timeout):
        start_time = datetime.datetime.now()
        while not self._local_world_map.contains(local_world_object_types):
            self._on_detection_complete.join(timeout)
            if (datetime.datetime.now() - start_time).total_seconds() > timeout:
                raise TimeoutError("Timeout was reached while waiting for the specified detection status.")
        return self._local_world_map

    def _switch_detection_mode(self, detection_mode):
        self._detection_mode = detection_mode
        self._detection_lock.acquire()
        if self._detection_mode == LocalWorldMapDetectionMode.TREASURE_PICKUP_SUCCESS_DETECTION:
            self._local_world_map.reset([LocalWorldObjectType.TREASURE])
        elif self._detection_mode != LocalWorldMapDetectionMode.NONE:
            self._local_world_map.reset(LocalWorldObjectType.all())
        self._detection_lock.release()
class TestLocalWorldDetector(object):

    BASE_PATH = "../resources/test_data/image_detection/"
    DISTANCE_ERROR_MARGIN = Vector2(1, 2)
    DELIMITING_SEGMENT_ERROR_MARGIN = Vector2(30, 15)
    SAMPLE_CAMERA_MOVEMENT_PROGRESS = 100

    @mock.patch('services.camera_arm_control.CameraArmControlService.CameraArmControlService', autospec = False)
    def setup(self, camera_arm_control_service_mock):
        self._camera_arm_control_service_mock_instance = camera_arm_control_service_mock.return_value
        self._camera_arm_control_service_mock_instance.movement_in_progress = False
        self._local_world_detector = LocalWorldDetector(self._camera_arm_control_service_mock_instance)
        self._results = {}
        
    def test_given_test_image_set_when_detecting_treasure_pickup_then_objects_are_detected(self):
        self._perform_test(self.TREASURE_PICKUP_TEST_SET_CONFIG, LocalWorldMapDetectionMode.TREASURE_PICKUP_DETECTION)

    def test_given_test_image_set_when_detecting_treasure_pickup_success_then_objects_are_detected(self):
        self._perform_test(self.TREASURE_PICKUP_SUCCESS_TEST_SET_CONFIG, LocalWorldMapDetectionMode.TREASURE_PICKUP_SUCCESS_DETECTION)

    def test_given_test_image_set_when_detecting_end_zone_treasures_then_objects_are_detected(self):
        self._perform_test(self.END_ZONE_TREASURE_TEST_SET_CONFIG, LocalWorldMapDetectionMode.END_ZONE_TREASURE_DETECTION)

    def _perform_test(self, test_set_config, detection_mode):
        for test_config in test_set_config:
            self._test_image(test_config, detection_mode)

    def _test_image(self, test_config, detection_mode):
        test_image = Image.from_file(self.BASE_PATH + test_config['filename'])
        local_world_map = LocalWorldMap()
        if 'gripper_mock_location' in test_config:
            local_world_map._gripper = Gripper(test_config['gripper_mock_location'])
        detection_results = self._local_world_detector.detect_objects(test_image, detection_mode, local_world_map)
        Logger.get_instance().log(self, "World Detection Test Results", log_entry_type = LogEntryType.INFORMATIONAL, details = "'{0}': {1}.".format(test_config['filename'], detection_results))
        self._verify_results(test_config, detection_results) 

    def _verify_results(self, test_config, detection_results):
        result_string = ""
        self._results[test_config['filename']] = False
        self._verify_objects(test_config, detection_results)
        self._results[test_config['filename']] = True
        return result_string

    def _verify_objects(self, test_config, detection_results):
        if 'playfield' in test_config:
            self._verify_playfield(detection_results.playfield, test_config['playfield'])
        if 'gripper' in test_config:
            self._verify_gripper(detection_results.gripper, test_config['gripper'])
        self._verify_treasures(detection_results.treasures, test_config['treasure'])
        if 'approx_distance' in test_config['treasure']:
            self._verify_treasure_distance(detection_results.gripper, detection_results.treasures, test_config['treasure'])

    def _verify_playfield(self, playfield, playfield_test_config):
        if 'present' in playfield_test_config:
            assert_true(playfield is not None, playfield_test_config['present'])
        if 'delimiting_segment' in playfield_test_config:
            self._verify_delimiting_playfield_segment(playfield, playfield_test_config['delimiting_segment'])

    def _verify_delimiting_playfield_segment(self, playfield, delimiting_segment_test_config):
        assert_true(MathUtils.in_range_approx(playfield.delimiting_segment.point1, delimiting_segment_test_config['point1'], self.DELIMITING_SEGMENT_ERROR_MARGIN))
        assert_true(MathUtils.in_range_approx(playfield.delimiting_segment.point2, delimiting_segment_test_config['point2'], self.DELIMITING_SEGMENT_ERROR_MARGIN))

    def _verify_gripper(self, gripper, gripper_test_config):
        assert_equals(gripper is not None, gripper_test_config['present'])

    def _verify_treasures(self, treasures, treasure_test_config):
        if 'present' in treasure_test_config:
            assert_equals(len(treasures) >= 1, treasure_test_config['present'])
        if 'count' in treasure_test_config:
            assert_equals(len(treasures), treasure_test_config['count'])

    def _verify_treasure_distance(self, gripper, treasures, treasure_test_config):
        distance = self._get_closest_treasure_distance(gripper, treasures)
        distance.y = -distance.y
        assert_true(MathUtils.in_range_approx(distance, treasure_test_config['approx_distance'], self.DISTANCE_ERROR_MARGIN))

    def _get_closest_treasure_distance(self, gripper, treasures):
        closest_treasure = min(treasures, key = lambda treasure: Segment(treasure.location, gripper.location).length)
        return (closest_treasure.location - gripper.location) / TreasurePickupDetector.CAMERA_PHYSICAL_SCALE

    TREASURE_PICKUP_TEST_SET_CONFIG = [
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-15-19h59m15s990.png", 'treasure': {'present': True, 'approx_distance': Vector2(0, 5.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h03m58s628.png", 'treasure': {'present': True, 'approx_distance': Vector2(0.7, 12)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h04m19s380.png", 'treasure': {'present': True, 'approx_distance': Vector2(-5.75, 10.75)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h04m29s883.png", 'treasure': {'present': True, 'approx_distance': Vector2(-2.75, 10)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h04m38s959.png", 'treasure': {'present': True, 'approx_distance': Vector2(0.4, 7)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h04m49s855.png", 'treasure': {'present': True, 'approx_distance': Vector2(3.5, 5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h04m58s860.png", 'treasure': {'present': True, 'approx_distance': Vector2(0, 5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h05m12s380.png", 'treasure': {'present': True, 'approx_distance': Vector2(0, 2.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h05m23s661.png", 'treasure': {'present': True, 'approx_distance': Vector2(0, 9.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h05m40s205.png", 'treasure': {'present': True, 'approx_distance': Vector2(-5, 9.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h05m49s596.png", 'treasure': {'present': True, 'approx_distance': Vector2(4, 9.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h05m57s474.png", 'treasure': {'present': True, 'approx_distance': Vector2(0.5, 7.25)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h06m07s252.png", 'treasure': {'present': True, 'approx_distance': Vector2(-0.5, 5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h06m33s463.png", 'treasure': {'present': True, 'approx_distance': Vector2(0, 3)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-28-15h08m18s143.png", 'treasure': {'present': True, 'approx_distance': Vector2(0, 3.75)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-29-10h01m51s703.png", 'treasure': {'present': True, 'approx_distance': Vector2(2, 5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-29-11h17m00s485.png", 'treasure': {'present': True, 'approx_distance': Vector2(-2.5, 8)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-29-17h18m08s761.jpg", 'treasure': {'present': True, 'approx_distance': Vector2(0-1.5, 4)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-03-30-11h07m42s813.jpg", 'treasure': {'present': False}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h21m55s839.png", 'treasure': {'present': True, 'approx_distance': Vector2(-6, 13)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h22m51s713.png", 'treasure': {'present': True, 'approx_distance': Vector2(-2.5, 13)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h23m29s824.png", 'treasure': {'present': True, 'approx_distance': Vector2(-1, 13)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h23m59s110.png", 'treasure': {'present': True, 'approx_distance': Vector2(1.75, 13)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h24m32s914.png", 'treasure': {'present': True, 'approx_distance': Vector2(2.8, 13)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h25m51s799.png", 'treasure': {'present': True, 'approx_distance': Vector2(4.75, 13)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h26m43s304.png", 'treasure': {'present': True, 'approx_distance': Vector2(7.25, 13)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h27m13s855.png", 'treasure': {'present': True, 'approx_distance': Vector2(9.5, 13)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h30m27s398.png", 'treasure': {'present': True, 'approx_distance': Vector2(-6, 10)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h31m10s866.png", 'treasure': {'present': True, 'approx_distance': Vector2(-4, 10)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h31m37s571.png", 'treasure': {'present': True, 'approx_distance': Vector2(-1.5, 10)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h32m08s361.png", 'treasure': {'present': True, 'approx_distance': Vector2(0, 10)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h32m35s750.png", 'treasure': {'present': True, 'approx_distance': Vector2(1, 10)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h33m04s231.png", 'treasure': {'present': True, 'approx_distance': Vector2(3, 10)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h33m27s946.png", 'treasure': {'present': True, 'approx_distance': Vector2(5.25, 10)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h33m54s444.png", 'treasure': {'present': True, 'approx_distance': Vector2(7, 10)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h34m13s762.png", 'treasure': {'present': True, 'approx_distance': Vector2(9.5, 10)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h34m31s631.png", 'treasure': {'present': True, 'approx_distance': Vector2(9.5, 10)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h34m49s743.png", 'treasure': {'present': True, 'approx_distance': Vector2(9.5, 7.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h35m25s547.png", 'treasure': {'present': True, 'approx_distance': Vector2(7.5, 7.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h35m49s096.png", 'treasure': {'present': True, 'approx_distance': Vector2(4.25, 7.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h36m11s895.png", 'treasure': {'present': True, 'approx_distance': Vector2(1.5, 7.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h36m39s382.png", 'treasure': {'present': True, 'approx_distance': Vector2(1, 7.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h41m15s127.png", 'treasure': {'present': True, 'approx_distance': Vector2(0, 7.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h41m34s108.png", 'treasure': {'present': True, 'approx_distance': Vector2(-1.5, 7.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h42m10s326.png", 'treasure': {'present': True, 'approx_distance': Vector2(-3.75, 7.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h44m35s982.png", 'treasure': {'present': True, 'approx_distance': Vector2(-6, 7.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h45m12s593.png", 'treasure': {'present': True, 'approx_distance': Vector2(-6.5, 5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h45m54s408.png", 'treasure': {'present': True, 'approx_distance': Vector2(-4.25, 5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h46m17s553.png", 'treasure': {'present': True, 'approx_distance': Vector2(-1.75, 5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h46m47s820.png", 'treasure': {'present': True, 'approx_distance': Vector2(-0.25, 5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h47m11s168.png", 'treasure': {'present': True, 'approx_distance': Vector2(1.5, 5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h47m37s368.png", 'treasure': {'present': True, 'approx_distance': Vector2(2.75, 5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h48m00s093.png", 'treasure': {'present': True, 'approx_distance': Vector2(4.75, 5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h48m31s324.png", 'treasure': {'present': True, 'approx_distance': Vector2(7.5, 5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h48m57s711.png", 'treasure': {'present': True, 'approx_distance': Vector2(9.5, 5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h49m39s818.png", 'treasure': {'present': True, 'approx_distance': Vector2(9, 3)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h50m11s692.png", 'treasure': {'present': True, 'approx_distance': Vector2(6.75, 3)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h50m30s074.png", 'treasure': {'present': True, 'approx_distance': Vector2(4.25, 3)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h50m46s327.png", 'treasure': {'present': True, 'approx_distance': Vector2(2, 3)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h51m02s315.png", 'treasure': {'present': True, 'approx_distance': Vector2(1, 3)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h51m17s801.png", 'treasure': {'present': True, 'approx_distance': Vector2(0, 3)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h51m35s735.png", 'treasure': {'present': True, 'approx_distance': Vector2(-1.5, 3)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h52m00s753.png", 'treasure': {'present': True, 'approx_distance': Vector2(-4, 3)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h52m44s143.png", 'treasure': {'present': True, 'approx_distance': Vector2(-6, 3)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h54m13s268.png", 'treasure': {'present': True, 'approx_distance': Vector2(-3.25, 1.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h54m40s914.png", 'treasure': {'present': True, 'approx_distance': Vector2(0.1, 1.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h54m56s288.png", 'treasure': {'present': True, 'approx_distance': Vector2(2, 1.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h55m21s961.png", 'treasure': {'present': True, 'approx_distance': Vector2(4.5, 1.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h55m55s403.png", 'treasure': {'present': True, 'approx_distance': Vector2(7.5, 1.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h57m08s387.png", 'treasure': {'present': True, 'approx_distance': Vector2(-2.25, 0.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h57m58s054.png", 'treasure': {'present': True, 'approx_distance': Vector2(-4.75, 0.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h58m25s286.png", 'treasure': {'present': True, 'approx_distance': Vector2(0, 0.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h58m45s117.png", 'treasure': {'present': True, 'approx_distance': Vector2(2.5, 0.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-01-20h59m24s042.png", 'treasure': {'present': True, 'approx_distance': Vector2(8.25, 0.5)}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-05-18h12m44s428.jpg", 'treasure': {'present': True}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-05-18h12m45s464.jpg", 'treasure': {'present': True}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-05-18h12m48s439.jpg", 'treasure': {'present': True}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-07-16h20m16s239.jpg", 'treasure': {'present': True}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-07-16h20m34s129.jpg", 'treasure': {'present': True}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-07-16h24m41s697.jpg", 'treasure': {'present': True}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-07-16h24m44s822.jpg", 'treasure': {'present': True}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-07-16h36m10s125.jpg", 'treasure': {'present': True}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-07-16h36m59s695.jpg", 'treasure': {'present': True}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-07-16h41m25s968.jpg", 'treasure': {'present': True}, 'gripper': {'present': True}},
        {'filename': "local_treasure_pickup/vlcsnap-2016-04-07-16h44m07s537.jpg", 'treasure': {'present': True}, 'gripper': {'present': True}}
        ]
    TREASURE_PICKUP_SUCCESS_TEST_SET_CONFIG = [
        # Success
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-01-21h16m17s594.png", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(261, 463)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-01-21h16m22s686.png", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(255, 461)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-01-21h16m27s524.png", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(256, 463)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-01-21h16m33s050.png", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(251, 456)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-01-21h16m38s063.png", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(252, 455)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-01-21h16m43s914.png", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(247, 458)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-01-21h16m48s517.png", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(258, 454)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-01-21h16m59s704.png", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(258, 458)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-01-21h17m04s508.png", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(252, 455)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-01-21h17m09s539.png", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(257, 453)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-05-18h12m59s636.jpg", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(248, 490)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-05-18h13m27s932.jpg", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(245, 495)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-05-19h19m17s501.jpg", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(242, 497)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-07-16h37m06s416.jpg", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(255, 514)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-07-16h37m51s320.jpg", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(252, 513)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-07-16h39m24s799.jpg", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(257, 511)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-07-16h43m38s050.jpg", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(255, 520)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-07-19h48m54s415.jpg", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(253, 506)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-07-21h01m32s993.jpg", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(254, 508)},
        {'filename': "local_treasure_pickup_success/vlcsnap-2016-04-07-21h01m34s795.jpg", 'treasure': {'present': True}, 'gripper_mock_location': Vector2(252, 508)},
        # Fail
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-03-15-19h57m06s970.png", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(249, 264)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-03-30-16h12m15s990.png", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(214, 270)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-01-21h15m52s309.png", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(255, 464)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-01-21h16m00s511.png", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(254, 465)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-01-21h16m07s371.png", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(247, 460)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-01-21h17m14s635.png", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(256, 462)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-07-16h12m32s202.jpg", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(245, 510)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-07-16h18m01s249.jpg", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(245, 510)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-07-16h18m02s374.jpg", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(245, 510)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-07-16h18m06s639.jpg", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(245, 510)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-07-16h18m19s151.jpg", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(245, 510)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-07-16h20m05s038.jpg", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(245, 510)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-07-16h41m14s576.jpg", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(251, 512)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-07-20h15m54s652.jpg", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(245, 510)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-07-20h15m55s728.jpg", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(245, 510)},
        {'filename': "local_treasure_pickup_fail/vlcsnap-2016-04-07-20h17m26s949.jpg", 'treasure': {'present': False}, 'gripper_mock_location': Vector2(245, 510)}
        ]
    END_ZONE_TREASURE_TEST_SET_CONFIG = [
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h26m55s091.png", 'treasure': {'count': 8}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(122.5, 88.5), 'point2': Vector2(524, 116.5)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h27m17s759.png", 'treasure': {'count': 8}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(89, 88), 'point2': Vector2(495, 116)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h27m40s727.png", 'treasure': {'count': 8}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(107.5, 85), 'point2': Vector2(497.5, 111)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h28m08s296.png", 'treasure': {'count': 8}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(102, 84.5), 'point2': Vector2(495.5, 111)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h28m29s237.png", 'treasure': {'count': 4}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(76, 85.5), 'point2': Vector2(470.5, 111)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h29m28s966.png", 'treasure': {'count': 0}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(109, 87), 'point2': Vector2(517, 116)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h31m26s149.png", 'treasure': {'count': 0}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(101.5, 91.5), 'point2': Vector2(514, 118)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h31m52s818.png", 'treasure': {'count': 7}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(103, 93), 'point2': Vector2(513.5, 118)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h32m33s078.png", 'treasure': {'count': 7}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(102.5, 90), 'point2': Vector2(515, 117.5)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h33m54s327.png", 'treasure': {'count': 0}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(88.5, 91), 'point2': Vector2(501.5, 116.5)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h36m52s399.png", 'treasure': {'count': 8}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(97.5, 83), 'point2': Vector2(511, 107.5)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h37m35s417.png", 'treasure': {'count': 0}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(80, 83.5), 'point2': Vector2(494.5, 106)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h38m16s796.png", 'treasure': {'count': 4}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(85.5, 84.5), 'point2': Vector2(497.5, 106.5)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h38m25s562.png", 'treasure': {'count': 1}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(84, 85), 'point2': Vector2(496.5, 105)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h38m29s947.png", 'treasure': {'count': 0}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(85, 83), 'point2': Vector2(495, 105)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h38m39s726.png", 'treasure': {'count': 0}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(86, 85), 'point2': Vector2(496.5, 104.5)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h39m20s620.png", 'treasure': {'count': 4}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(95, 84), 'point2': Vector2(501.5, 104.5)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h39m29s893.png", 'treasure': {'count': 4}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(93.5, 85), 'point2': Vector2(499.5, 105.5)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h39m37s380.png", 'treasure': {'count': 2}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(93, 84), 'point2': Vector2(501, 105)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h40m07s312.png", 'treasure': {'count': 0}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(94, 83), 'point2': Vector2(501.5, 104.5)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h40m13s459.png", 'treasure': {'count': 0}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(108, 83.5), 'point2': Vector2(515, 103.5)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h43m09s291.png", 'treasure': {'count': 6}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(104, 89.5), 'point2': Vector2(515, 114)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h43m29s195.png", 'treasure': {'count': 0}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(104.5, 90), 'point2': Vector2(515.5, 114)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h43m45s361.png", 'treasure': {'count': 1}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(103.5, 90.5), 'point2': Vector2(516, 114.5)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h43m49s796.png", 'treasure': {'count': 0}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(103, 91.5), 'point2': Vector2(518, 115)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-01-21h43m49s796.png", 'treasure': {'count': 0}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(103, 91.5), 'point2': Vector2(518, 115)}}},
        {'filename': "local_end_zone_treasures/vlcsnap-2016-04-11-19h05m55s914.jpg", 'treasure': {'count': 2}, 'playfield': {'present': True, 'delimiting_segment': {'point1': Vector2(68, 47), 'point2': Vector2(485, 73)}}}
        ]
 def setup(self, camera_arm_control_service_mock):
     self._camera_arm_control_service_mock_instance = camera_arm_control_service_mock.return_value
     self._camera_arm_control_service_mock_instance.movement_in_progress = False
     self._local_world_detector = LocalWorldDetector(self._camera_arm_control_service_mock_instance)
     self._results = {}