コード例 #1
0
ファイル: loader.py プロジェクト: TheVinhLuong102/ev3sim
def initialiseFromConfig(config, send_queues, recv_queues):
    from collections import defaultdict
    from ev3sim.robot import initialise_bot, RobotInteractor

    ev3sim.visual.utils.GLOBAL_COLOURS = config.get("colours", {})
    # Keep track of index w.r.t. filename.
    robot_paths = defaultdict(lambda: 0)
    for index, robot in enumerate(config.get("robots", [])):
        robot_path = find_abs(robot, allowed_areas=bot_locations())
        initialise_bot(config, robot_path, f"Robot-{index}",
                       robot_paths[robot_path])
        robot_paths[robot_path] += 1
        ScriptLoader.instance.setRobotQueues(f"Robot-{index}",
                                             send_queues[index],
                                             recv_queues[index])
    for opt in config.get("interactors", []):
        try:
            ScriptLoader.instance.addActiveScript(fromOptions(opt))
        except Exception as exc:
            print(
                f"Failed to load interactor with the following options: {opt}. Got error: {exc}"
            )
    SettingsManager.instance.setMany(config["settings"])
    if ScriptLoader.instance.active_scripts:
        ScriptLoader.instance.startUp()
        ScriptLoader.instance.loadElements(config.get("elements", []))
        for interactor in ScriptLoader.instance.active_scripts:
            if isinstance(interactor, RobotInteractor):
                interactor.connectDevices()
        for interactor in ScriptLoader.instance.active_scripts:
            interactor.startUp()
    else:
        print("No interactors successfully loaded. Quitting...")
コード例 #2
0
 def action():
     with open(
             os.path.join(
                 find_abs(sim_config["bots"][index],
                          bot_locations()), fname),
             "w") as f:
         f.write("# Put your code here!\n")
コード例 #3
0
    def clickBots(self):
        # Shouldn't happen but lets be safe.
        if self.batch_index == -1:
            return
        from ev3sim.visual.manager import ScreenObjectManager

        sim_path = self.available_batches[self.batch_index][1]

        with open(sim_path, "r") as f:
            sim_config = yaml.safe_load(f)

        complete_path = find_abs(sim_config["bots"][0], bot_locations())
        relative_dir, relative_path = make_relative(complete_path,
                                                    bot_locations())

        return ScreenObjectManager.instance.pushScreen(
            ScreenObjectManager.SCREEN_BOT_EDIT,
            bot_file=complete_path,
            bot_dir_file=(relative_dir, relative_path),
        )
コード例 #4
0
ファイル: entry.py プロジェクト: TheVinhLuong102/ev3sim
def run_code(script_name):
    real = find_abs("examples/robots/default_testing", ["package"])
    rel_dir, rel_path = make_relative(real, bot_locations())
    with open(join(real, "config.bot"), "r") as f:
        bot_config = yaml.safe_load(f)
    bot_config["script"] = script_name
    bot_config["type"] = "mindstorms" if script_name.endswith(
        ".ev3") else "python"
    with open(join(real, "config.bot"), "w") as f:
        f.write(yaml.dump(bot_config))

    sim_path = find_abs("presets/testing.sim", ["package"])
    with open(sim_path, "r") as f:
        test_config = yaml.safe_load(f)

    test_config["bots"] = [rel_path]
    with open(sim_path, "w") as f:
        f.write(yaml.dump(test_config))

    return run_sim(sim_path)
コード例 #5
0
    def playSim(self, preset):
        abs_path = find_abs(preset, allowed_areas=preset_locations())
        with open(abs_path, "r") as f:
            preset_config = yaml.safe_load(f)
        sim_path = find_abs(preset_config["sim_location"],
                            allowed_areas=batch_locations())
        with open(sim_path, "r") as f:
            sim_config = yaml.safe_load(f)
        to_remove = []
        for index in range(len(sim_config["bots"])):
            # Try loading this bot.
            try:
                with open(
                        os.path.join(
                            find_abs(sim_config["bots"][index],
                                     bot_locations()), "config.bot"),
                        "r") as f:
                    bot_config = yaml.safe_load(f)
                if not BotValidator.validate_json(bot_config):
                    to_remove.append(index)
                if bot_config.get("type", "python") == "python":
                    fname = bot_config.get("script", "code.py")
                else:
                    fname = bot_config.get("script", "program.ev3")
                if not os.path.exists(
                        os.path.join(
                            find_abs(sim_config["bots"][index],
                                     bot_locations()), fname)):

                    def action():
                        with open(
                                os.path.join(
                                    find_abs(sim_config["bots"][index],
                                             bot_locations()), fname),
                                "w") as f:
                            f.write("# Put your code here!\n")

                    ScreenObjectManager.instance.forceCloseError(
                        f"Your bot {sim_config['bots'][index]} does not contain the file {fname}. You may have renamed or deleted it by accident. In order to use this bot, you need to add this file back. Click \"Add {fname}\" to create this file, or do it manually.",
                        (f"Add {fname}", action),
                    )
                    return
            except:
                to_remove.append(index)
        if to_remove:
            for index in to_remove[::-1]:
                del sim_config["bots"][index]
            with open(sim_path, "w") as f:
                f.write(yaml.dump(sim_config))
        if not sim_config["bots"]:
            # We cannot play, there no are valid bots.
            return ScreenObjectManager.instance.pushScreen(
                ScreenObjectManager.SCREEN_BOTS,
                batch_file=sim_path,
                next=ScreenObjectManager.instance.SCREEN_SIM,
                next_kwargs={"batch": sim_path},
            )
        return ScreenObjectManager.instance.pushScreen(
            ScreenObjectManager.instance.SCREEN_SIM,
            batch=sim_path,
        )
コード例 #6
0
    def generateObjects(self):
        # First, find all bot files.
        if not self.in_error:
            self.available_bots = []
            error_bots = []
            for rel_dir in bot_locations():
                try:
                    actual_dir = find_abs_directory(rel_dir)
                except:
                    continue
                for bot in BotValidator.all_valid_in_dir(actual_dir):
                    try:
                        # Show everything except dir and .bot
                        with open(os.path.join(actual_dir, bot, "config.bot"),
                                  "r") as f:
                            config = yaml.safe_load(f)
                        # If we are hidden, or in edit mode with hidden_edit, then don't show.
                        if not config.get("hidden", False) and not (
                                config.get("hidden_edit", False)
                                and len(self.bot_keys) == 0):
                            self.available_bots.append(
                                (bot, os.path.join(actual_dir,
                                                   bot), rel_dir, bot))
                    except Exception as e:
                        sentry_sdk.capture_exception(e)
                        error_bots.append(os.path.join(actual_dir, bot))
            if self.first_launch and error_bots:
                self.first_launch = False
                self.in_error = True
                self.addErrorDialog(
                    'A problem occured loading the following bots:<br><br><font color="#cc0000">'
                    + "<br>".join(bot for bot in error_bots) + "</font>")
                return

        self.bg = pygame_gui.elements.UIPanel(
            relative_rect=pygame.Rect(0, 0, *self._size),
            starting_layer_height=-1,
            manager=self,
            object_id=pygame_gui.core.ObjectID("background"),
        )
        self._all_objs.append(self.bg)

        # Scrolling container
        old_y = getattr(getattr(self, "scrolling_container", None), "cur_y", 0)
        self.scrolling_container = CustomScroll(
            relative_rect=pygame.Rect(0, 0, *self._size),
            manager=self,
            object_id=pygame_gui.core.ObjectID("scroll_container"),
        )
        self.scrolling_container.num_elems = len(self.available_bots)
        scrolling_size = (self._size[0] / 4 + self._size[0] / 5,
                          self._size[1] * 0.9 - min(self._size[1] / 6, 90))
        # Setting dimensions and positions on a UIScrollingContainer seems buggy. This works.
        self.scrolling_container.set_dimensions(scrolling_size)
        self.scrolling_container.set_position(scrolling_size)
        self.scrolling_container.cur_y = old_y
        self.scrolling_container.set_scroll(old_y)
        self._all_objs.append(self.scrolling_container)

        button_size = self._size[0] / 4, 60
        info_size = self._size[0] / 4 - 20, 15
        bot_rect = lambda i: (self._size[0] / 10, self._size[1] / 10 + i *
                              button_size[1] * 1.5)
        info_rect = lambda b_r: (
            b_r[0] + button_size[0] - info_size[0] - 10,
            b_r[1] + button_size[1] - info_size[1] - 5,
        )
        self.bot_buttons = []
        self.bot_descriptions = []
        for i, (show, bot, rel_dir,
                filename) in enumerate(self.available_bots):
            self.bot_buttons.append(
                pygame_gui.elements.UIButton(
                    relative_rect=pygame.Rect(*bot_rect(i), *button_size),
                    text=show,
                    manager=self,
                    container=self.scrolling_container,
                    object_id=pygame_gui.core.ObjectID(
                        show + "-" + str(i), "list_button_highlighted"
                        if i == self.bot_index else "list_button"),
                ))
            self.addButtonEvent(show + "-" + str(i), self.setBotIndex, i)
            self.bot_descriptions.append(
                pygame_gui.elements.UILabel(
                    relative_rect=pygame.Rect(*info_rect(bot_rect(i)),
                                              *info_size),
                    text=rel_dir,
                    manager=self,
                    container=self.scrolling_container,
                    object_id=pygame_gui.core.ObjectID(
                        show + "-dir-" + str(i), "button_info_selected"
                        if i == self.bot_index else "button_info"),
                ))
        self._all_objs.extend(self.bot_buttons)
        self._all_objs.extend(self.bot_descriptions)

        preview_size = self._size[0] / 4, self._size[1] / 4
        preview_size = (
            min(preview_size[0], (preview_size[1] * 4) // 3),
            min(preview_size[1], (preview_size[0] * 3) // 4),
        )
        try:
            if self.bot_index >= len(self.available_bots):
                self.bot_index = -1
            if self.bot_index == -1:
                image = pygame.Surface(preview_size)
                image.fill(pygame.Color(self.bg.background_colour))
            else:
                with open(
                        os.path.join(self.available_bots[self.bot_index][1],
                                     "config.bot"), "r") as f:
                    config = yaml.safe_load(f)
                bot_preview = os.path.join(
                    self.available_bots[self.bot_index][1],
                    config.get("preview_path", "preview.png"))
                image = pygame.image.load(bot_preview)
        except Exception as e:
            sentry_sdk.capture_exception(e)
            self.setBotIndex(-1)
            self.addErrorDialog(
                '<font color="#cc0000">The bot you have selected has some internal errors EV3Sim cannot resolve.</font><br><br>'
                +
                "If you'd like to fix this, then try manually editing the bot file in a text editor."
            )
            return
        if image.get_size() != preview_size:
            image = pygame.transform.smoothscale(
                image, [int(v) for v in preview_size])
        self.preview_image = pygame_gui.elements.UIImage(
            relative_rect=pygame.Rect(self._size[0] * 0.9 - preview_size[0],
                                      self._size[1] * 0.1, *preview_size),
            image_surface=image,
            manager=self,
            object_id=pygame_gui.core.ObjectID("preview-image"),
        )
        self._all_objs.append(self.preview_image)

        if len(self.bot_keys) == 0:
            code_size = preview_size[0] * 0.4, preview_size[1] * 0.4
            code_button_pos = (
                self._size[0] * 0.9 - code_size[0] - 10,
                self._size[1] * 0.1 + preview_size[1] + 10,
            )
            code_icon_size = code_size[1] * 0.6, code_size[1] * 0.6
            self.code_button = pygame_gui.elements.UIButton(
                relative_rect=pygame.Rect(*code_button_pos, *code_size),
                text="",
                manager=self,
                object_id=pygame_gui.core.ObjectID("bot-code",
                                                   "settings_buttons"),
            )
            self.addButtonEvent("bot-code", self.clickCode)
            if not self.code_enable:
                self.code_button.disable()
            code_icon_path = find_abs("ui/code.png",
                                      allowed_areas=asset_locations())
            self.code_icon = pygame_gui.elements.UIImage(
                relative_rect=pygame.Rect(
                    *self.iconPos(code_button_pos, code_size, code_icon_size),
                    *code_icon_size),
                image_surface=pygame.image.load(code_icon_path),
                manager=self,
                object_id=pygame_gui.core.ObjectID("code-icon"),
            )
            self._all_objs.append(self.code_button)
            self._all_objs.append(self.code_icon)

            edit_button_pos = (
                self._size[0] * 0.9 - preview_size[0],
                self._size[1] * 0.1 + preview_size[1] + 10,
            )
            self.edit_button = pygame_gui.elements.UIButton(
                relative_rect=pygame.Rect(*edit_button_pos, *code_size),
                text="",
                manager=self,
                object_id=pygame_gui.core.ObjectID("bot-edit",
                                                   "settings_buttons"),
            )
            self.addButtonEvent("bot-edit", self.clickEdit)
            if not self.edit_enable:
                self.edit_button.disable()
            edit_icon_path = find_abs("ui/edit.png",
                                      allowed_areas=asset_locations())
            self.edit_icon = pygame_gui.elements.UIImage(
                relative_rect=pygame.Rect(
                    *self.iconPos(edit_button_pos, code_size, code_icon_size),
                    *code_icon_size),
                image_surface=pygame.image.load(edit_icon_path),
                manager=self,
                object_id=pygame_gui.core.ObjectID("edit-icon"),
            )
            self._all_objs.append(self.edit_button)
            self._all_objs.append(self.edit_icon)

            new_size = self._size[0] / 8, min(self._size[1] / 6, 90)
            new_icon_size = new_size[1] * 0.6, new_size[1] * 0.6
            new_bot_pos = (bot_rect(0)[0] + button_size[0] - new_size[0],
                           self._size[1] * 0.9 - new_size[1])
            self.new_bot = pygame_gui.elements.UIButton(
                relative_rect=pygame.Rect(*new_bot_pos, *new_size),
                text="",
                manager=self,
                object_id=pygame_gui.core.ObjectID("new_bot", "action_button"),
            )
            self.addButtonEvent("new_bot", self.clickNew)
            new_bot_path = find_abs("ui/add.png",
                                    allowed_areas=asset_locations())
            self.new_icon = pygame_gui.elements.UIImage(
                relative_rect=pygame.Rect(
                    *self.iconPos(new_bot_pos, new_size, new_icon_size),
                    *new_icon_size),
                image_surface=pygame.image.load(new_bot_path),
                manager=self,
                object_id=pygame_gui.core.ObjectID("new_bot-icon"),
            )
            self._all_objs.append(self.new_bot)
            self._all_objs.append(self.new_icon)

            remove_bot_pos = (bot_rect(0)[0],
                              self._size[1] * 0.9 - new_size[1])
            self.remove_bot = pygame_gui.elements.UIButton(
                relative_rect=pygame.Rect(*remove_bot_pos, *new_size),
                text="",
                manager=self,
                object_id=pygame_gui.core.ObjectID("remove_bot",
                                                   "cancel-changes"),
            )
            self.addButtonEvent("remove_bot", self.clickRemove)
            if not self.remove_enable:
                self.remove_bot.disable()
            remove_bot_path = find_abs("ui/bin.png",
                                       allowed_areas=asset_locations())
            self.remove_icon = pygame_gui.elements.UIImage(
                relative_rect=pygame.Rect(
                    *self.iconPos(remove_bot_pos, new_size, new_icon_size),
                    *new_icon_size),
                image_surface=pygame.image.load(remove_bot_path),
                manager=self,
                object_id=pygame_gui.core.ObjectID("remove_bot-icon"),
            )
            self._all_objs.append(self.remove_bot)
            self._all_objs.append(self.remove_icon)
            super().generateObjects()
        else:
            # Bot key locations, for selecting bots in batch files.
            self.bot_loc_spots = []
            for i in range(len(self.bot_keys)):
                if i == self.key_index:
                    self.bot_loc_spots.append(
                        self.createBotImage(i, bg=pygame.Color("#80b918")))
                else:
                    self.bot_loc_spots.append(self.createBotImage(i))
                self.sizeBotImage(i, big_mode=len(self.bot_keys) == 1)
                img = self.preview_images[i]
                if img is None:
                    continue
                if img.get_size() != self.bot_loc_spots[i].rect.size:
                    img = pygame.transform.smoothscale(
                        img, (self.bot_loc_spots[i].rect.width,
                              self.bot_loc_spots[i].rect.height))
                self.bot_loc_spots[i].set_image(img)
            self._all_objs.extend(self.bot_loc_spots)

            select_size = (self._size[0] / 4 - 20) / 2, min(
                self._size[1] / 4, 120)
            select_button_pos = (self._size[0] * 0.9 - select_size[0] * 2 - 15,
                                 self._size[1] * 0.9 - select_size[1])
            self.select_button = pygame_gui.elements.UIButton(
                relative_rect=pygame.Rect(*select_button_pos, *select_size),
                text="SELECT",
                manager=self,
                object_id=pygame_gui.core.ObjectID("select-bot",
                                                   "action_button"),
            )
            self.addButtonEvent("select-bot", self.clickSelect)
            if not self.select_enable:
                self.select_button.disable()
            self._all_objs.append(self.select_button)

            done_size = (self._size[0] / 4 - 20) / 2, min(
                self._size[1] / 4, 120)
            done_button_pos = (self._size[0] * 0.9 - select_size[0] - 5,
                               self._size[1] * 0.9 - select_size[1])
            self.done_button = pygame_gui.elements.UIButton(
                relative_rect=pygame.Rect(*done_button_pos, *done_size),
                text="DONE",
                manager=self,
                object_id=pygame_gui.core.ObjectID("select-done",
                                                   "action_button"),
            )
            self.addButtonEvent("select-done", self.clickDone)
            if self.key_index == 0:
                self.done_button.disable()
            self._all_objs.append(self.done_button)
            super().generateObjects()
コード例 #7
0
ファイル: entry.py プロジェクト: TheVinhLuong102/ev3sim
def run_bot(bot_folder, script_name=None, edit=False):
    from ev3sim.validation.bot_files import BotValidator

    if not exists(join(bot_folder, "config.bot")):
        return raise_error(
            f"The bot {bot_folder} has been messed with, it is missing config.bot. If it has been deleted, please put it back there."
        )

    with open(join(bot_folder, "config.bot"), "r") as f:
        config = yaml.safe_load(f)
    if script_name is not None:
        config["script"] = script_name
        config["type"] = "mindstorms" if script_name.endswith(
            ".ev3") else "python"
        with open(join(bot_folder, "config.bot"), "w") as f:
            f.write(yaml.dump(config))

    if not BotValidator.validate_file(bot_folder):
        return raise_error(
            f"There is something wrong with the robot {bot_folder}, and so it cannot be opened or used."
        )

    try:
        relative_dir, relative_path = make_relative(bot_folder, ["workspace"])
        if relative_path.startswith("robots"):
            raise ValueError()
        sim_paths = [join(dirname(bot_folder), "sim.sim")]
    except:
        relative_dir, relative_path = make_relative(bot_folder,
                                                    bot_locations())
        sim_paths = [
            find_abs("presets/soccer.sim", ["package"]),
            find_abs("presets/rescue.sim", ["package"]),
        ]

    if not edit:
        found = False
        for sim in sim_paths:
            with open(sim, "r") as f:
                config = yaml.safe_load(f)
            for botpath in config["bots"]:
                if botpath == relative_path:
                    found = True
                    break
            if found:
                return run_sim(sim)
        # Not in the predefined presets.
        # Use the testing preset.
        sim_path = find_abs("presets/testing.sim", ["package"])
        with open(sim_path, "r") as f:
            test_config = yaml.safe_load(f)

        test_config["bots"] = [relative_path]
        with open(sim_path, "w") as f:
            f.write(yaml.dump(test_config))

        return run_sim(sim_path)
    else:
        return [ScreenObjectManager.SCREEN_BOT_EDIT], [{
            "bot_file":
            bot_folder,
            "bot_dir_file": (relative_dir, relative_path),
        }]