Exemplo n.º 1
0
    def compute_board_size(self, corners):

        min_x, min_y, max_x, max_y = self.find_min_max(corners)

        # Compute board size
        self.board.width = max_x - min_x
        self.board.height = max_y - min_y

        ExtentTracker.get_instance().board = Extent.from_rectangle(0, 0, self.board.width, self.board.height)
        logger.info('board has been set to {}'.format(ExtentTracker.get_instance().board))
Exemplo n.º 2
0
    def __init__(self, config, ui_root: UIElement, ll_communicator):

        self.config = config
        self.extent_tracker = ExtentTracker.get_instance()
        self.landscape_lab = ll_communicator
        self.ui_root = ui_root

        # get ticker thresholds from config
        self.min_distance = config.get("tracker_thresholds", "min_distance")
        self.external_min_appeared = config.get("tracker_thresholds",
                                                "external_min_appeared")
        self.external_max_disappeared = config.get("tracker_thresholds",
                                                   "external_max_disappeared")
        self.internal_min_appeared = config.get("tracker_thresholds",
                                                "internal_min_appeared")
        self.internal_max_disappeared = config.get("tracker_thresholds",
                                                   "internal_max_disappeared")

        # we initialize it with all available configurations
        # as soon as an external game mode is choosen it should change accordingly
        # FIXME: this should maybe move in a change_gamemode()
        self.allowed_tokens: List[Token] = []
        brick_colors = config.get("brick_colors")
        for color in brick_colors:
            for shape in BrickShape:
                token = Token(shape, color)
                self.allowed_tokens.append(token)

        # Initialize a flag for changes in the map extent
        self.extent_changed = False
Exemplo n.º 3
0
    def __init__(self, config):

        # call super()
        threading.Thread.__init__(self)
        self.name = "[LabTable] {}".format(__name__)

        self.config = config
        self.extent_tracker = ExtentTracker.get_instance()
        self._ssl_context = None

        # if ssl is configured load the pem file
        s = ""
        if self.ssl_pem_file:
            self._ssl_context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
            try:
                self._ssl_context.load_verify_locations(self.ssl_pem_file)
                s = "s"
            except FileNotFoundError:
                logger.fatal("SSL file configured but not found: {}".format(
                    self.ssl_pem_file))
                raise ConfigError(
                    "SSL file configured but not found: {}".format(
                        self.ssl_pem_file))

        self._uri = URL.format(s=s, host=self.ip, port=self.port)
        logger.info("configured remote URL to {}".format(self._uri))

        # start the listener thread
        self.start()

        # store singleton reference
        communicator_singletons[type(self).__name__] = self
    def __init__(self, config: Configurator, program_stage: CurrentProgramStage):

        # call super()
        self.ip = config.get("landscapelab", "ip")
        self.port = config.get("landscapelab", "port")
        super().__init__(config)

        self.extent_tracker = ExtentTracker.get_instance()
        self.program_stage = program_stage

        # set the callback functions for the received messages from the LL
        self.keyword_callbacks = {
            SEND_REC_CREATE_OBJECT_MSG["keyword"]: self.create_local_brick,
            SEND_REC_UPDATE_OBJECT_MSG["keyword"]: self.update_local_brick,
            SEND_REC_REMOVE_OBJECT_MSG["keyword"]: self.remove_local_brick,
            REC_GAMESTATE_INFO_MSG["keyword"]: self.game_mode_change,
            REC_UPDATE_SCORE_MSG["keyword"]: self.update_local_score,
            REC_PLAYER_POSITION_MSG["keyword"]: self.update_player_position
        }

        self.provided_tokens = []
        for color in config.get("brick_colors"):
            for shape in BrickShape:
                if shape.value > 0:
                    self.provided_tokens.append({"color": color, "shape": shape.name})
Exemplo n.º 5
0
    def __init__(self, config: Configurator, name: str, extent: Extent,
                 zoom_limits: Tuple[int, int], resolution: Tuple[int, int]):

        self.name = name
        self.config = config
        self.extent_tracker = ExtentTracker.get_instance()
        self.min_zoom, self.max_zoom = zoom_limits

        # set resolution
        self.resolution_x, self.resolution_y = resolution

        # initialize two black images
        self.map_image = [
            ImageHandler.ensure_alpha_channel(
                np.ones((self.resolution_y, self.resolution_x, 3), np.uint8) *
                255),
            ImageHandler.ensure_alpha_channel(
                np.ones(
                    (self.resolution_y, self.resolution_x, 3), np.uint8) * 255)
        ]
        self.current_image = 0

        # crs is initialized with a local configuration but overwritten once a connection with the LL is established
        self.crs = config.get("map_settings", "coordinate_reference_system")
        extent.fit_to_ratio(self.resolution_y / self.resolution_x)
        self.current_extent: Extent = extent

        # set extent modifiers
        pan_up_modifier = np.array([0, 1, 0, 1])
        pan_down_modifier = np.array([0, -1, 0, -1])
        pan_left_modifier = np.array([-1, 0, -1, 0])
        pan_right_modifier = np.array([1, 0, 1, 0])
        self.zoom_in_modifier = np.array([1, 1, -1, -1])
        self.zoom_out_modifier = np.array([-1, -1, 1, 1])

        # get navigation settings
        pan_distance = config.get('map_settings', 'pan_distance')
        zoom_strength = config.get('map_settings', 'zoom_strength')

        # these functions can be used to interact with the map
        # by calling these functions one can pan and zoom on the map
        # the functions will automatically request a new rendered map extent from the QGIS plugin
        # they need accept an unused brick parameter to make it possible to call these functions via UICallback
        self.pan_up = partial(self.modify_extent, pan_up_modifier,
                              pan_distance)
        self.pan_down = partial(self.modify_extent, pan_down_modifier,
                                pan_distance)
        self.pan_left = partial(self.modify_extent, pan_left_modifier,
                                pan_distance)
        self.pan_right = partial(self.modify_extent, pan_right_modifier,
                                 pan_distance)
        self.zoom_in = partial(self.modify_extent, self.zoom_in_modifier,
                               zoom_strength)
        self.zoom_out = partial(self.modify_extent, self.zoom_out_modifier,
                                zoom_strength)
    def set_screen_config_info(config):

        monitors = screeninfo.get_monitors()

        config.set("screen_resolution", "width", monitors[0].width)
        config.set("screen_resolution", "height", monitors[0].height)
        config.set("screen_resolution", "pos_x", monitors[0].x - 1)
        config.set("screen_resolution", "pos_y", monitors[0].y - 1)

        beamer_id = config.get("beamer_resolution", "screen_id")
        if beamer_id >= 0:
            # if beamer-id out of bounds use last screen
            beamer_id = min(beamer_id, len(monitors) - 1)

            beamer = monitors[beamer_id]
            config.set("beamer_resolution", "width", beamer.width)
            config.set("beamer_resolution", "height", beamer.height)
            config.set("beamer_resolution", "pos_x", beamer.x - 1)
            config.set("beamer_resolution", "pos_y", beamer.y - 1)

            ExtentTracker.get_instance().beamer = Extent(0, 0, beamer.width, beamer.height)
    def __init__(self,
                 map_handler: MainMap,
                 ui_root: UIElement,
                 callback_manager: CallbackManager,
                 tracker: Tracker,
                 config: Configurator,
                 board: Board,
                 program_stage: CurrentProgramStage,
                 video_output_name=None):

        self.config = config
        self.callback_manager = callback_manager
        self.extent_tracker = ExtentTracker.get_instance()
        self.board = board
        self.program_stage = program_stage

        self.active_channel = TableOutputChannel.CHANNEL_BOARD_DETECTION
        self.active_window = TableOutputStream.WINDOW_NAME_DEBUG

        # create a store of the last images of each channel
        self.channel_images = {}
        for channel in TableOutputChannel:
            self.channel_images[channel.name] = np.empty((1, 1))

        # create debug window
        cv2.namedWindow(TableOutputStream.WINDOW_NAME_DEBUG, cv2.WINDOW_NORMAL)
        cv2.resizeWindow(TableOutputStream.WINDOW_NAME_DEBUG, config.get("screen_resolution", "width"),
                         config.get("screen_resolution", "height"))

        # create beamer window
        beamer_id = self.config.get("beamer_resolution", "screen_id")
        if beamer_id >= 0:
            pos_x = config.get("beamer_resolution", "pos_x")
            pos_y = config.get("beamer_resolution", "pos_y")

            logger.info("beamer coords: {} {}".format(pos_x, pos_y))

            cv2.namedWindow(TableOutputStream.WINDOW_NAME_BEAMER, cv2.WND_PROP_FULLSCREEN)
            cv2.moveWindow(TableOutputStream.WINDOW_NAME_BEAMER, pos_x, pos_y)
            cv2.setWindowProperty(TableOutputStream.WINDOW_NAME_BEAMER, cv2.WND_PROP_FULLSCREEN, cv2.WINDOW_FULLSCREEN)
        else:
            cv2.namedWindow(TableOutputStream.WINDOW_NAME_BEAMER, cv2.WINDOW_AUTOSIZE)

        cv2.setMouseCallback(TableOutputStream.WINDOW_NAME_BEAMER, self.beamer_mouse_callback)

        if video_output_name:
            # Define the codec and create VideoWriter object. The output is stored in .avi file.
            # Define the fps to be equal to 10. Also frame size is passed.
            self.video_handler = cv2.VideoWriter(video_output_name, cv2.VideoWriter_fourcc('M', 'J', 'P', 'G'),
                                                 10, (config.get('video_resolution', 'width'),
                                                      config.get('video_resolution', 'height')))
        else:
            self.video_handler = None

        self.last_frame = None

        # set ui_root and map handler, create empty variable for tracker
        self.ui_root = ui_root
        self.map_handler = map_handler
        self.tracker: Tracker = tracker

        # create image handler to load images
        self.image_handler = ImageHandler(config)

        # load qr code images
        qr_size = self.config.get("qr_code", "size")
        # TODO calc optimal size on draw instead of scaling down to fixed size
        self.qr_bottom_left = self.image_handler.load_image("qr_bottom_left", (qr_size, qr_size))
        self.qr_bottom_right = self.image_handler.load_image("qr_bottom_right", (qr_size, qr_size))
        self.qr_top_left = self.image_handler.load_image("qr_top_left", (qr_size, qr_size))
        self.qr_top_right = self.image_handler.load_image("qr_top_right", (qr_size, qr_size))

        # load brick overlay images
        self.brick_outdated = self.image_handler.load_image("outdated_brick")
        self.brick_unknown = self.image_handler.load_image("unknown_brick")
        self.brick_internal = self.image_handler.load_image("internal_brick")

        # load and initialize icon lists
        self.brick_icons = {}
        self.virtual_icons = {}
        self.brick_icons["windmill_icon"] = self.image_handler.load_image("windmill_brick")
        self.brick_icons["pv_icon"] = self.image_handler.load_image("pv_brick")
        self.virtual_icons["windmill_icon"] = self.image_handler.load_image("windmill_icon")
        self.virtual_icons["pv_icon"] = self.image_handler.load_image("pv_icon")