Ejemplo n.º 1
0
 def swapSlides(self):
     self.remaining = 0
     self.slide_index += 1
     self.slide_index %= self.SLIDE_NUMS
     self.slide_surface_prev = pygame.image.load(
         find_abs(f"bg_slide{(self.slide_index - 1) % self.SLIDE_NUMS}.png",
                  asset_locations()))
     self.slide_surface_next = pygame.image.load(
         find_abs(f"bg_slide{self.slide_index}.png", asset_locations()))
Ejemplo n.º 2
0
 def clickSimBots(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())
     ScreenObjectManager.instance.pushScreen(
         ScreenObjectManager.SCREEN_BOTS,
         batch_file=sim_path,
     )
Ejemplo n.º 3
0
def runFromConfig(config, shared):
    from ev3sim.robot import initialise_bot, RobotInteractor
    from ev3sim.file_helper import find_abs

    sl = ScriptLoader(**config.get("loader", {}))
    sl.setSharedData(shared)
    sl.active_scripts = []
    ev3sim.visual.utils.GLOBAL_COLOURS = config.get("colours", {})
    for index, robot in enumerate(config.get("robots", [])):
        robot_path = find_abs(robot,
                              allowed_areas=[
                                  "local", "local/robots/", "package",
                                  "package/robots/"
                              ])
        initialise_bot(config, robot_path, f"Robot-{index}")
    for opt in config.get("interactors", []):
        try:
            sl.active_scripts.append(fromOptions(opt))
        except Exception as exc:
            print(
                f"Failed to load interactor with the following options: {opt}. Got error: {exc}"
            )
    if sl.active_scripts:
        sl.startUp(**config.get("screen", {}))
        sl.loadElements(config.get("elements", []))
        for interactor in sl.active_scripts:
            if isinstance(interactor, RobotInteractor):
                interactor.connectDevices()
        sl.simulate()
    else:
        print("No interactors successfully loaded. Quitting...")
Ejemplo n.º 4
0
def batched_run(batch_file, bind_addr):
    from ev3sim.single_run import single_run as sim
    from ev3sim.attach import main as attach

    batch_path = find_abs(batch_file, allowed_areas=['local', 'local/batched_commands/', 'package', 'package/batched_commands/'])
    with open(batch_path, 'r') as f:
        config = yaml.safe_load(f)

    bot_paths = [x['name'] for x in config['bots']]
    sim_process = Process(target=sim, args=[config['preset_file'], bot_paths, bind_addr])

    script_processes = []
    for i, bot in enumerate(config['bots']):
        for script in bot.get('scripts', []):
            script_processes.append(Process(target=attach, kwargs={
                'passed_args': ['Useless', '--send_logs', '--simulator_addr', bind_addr, script, f"Robot-{i}"]
            }))

    sim_process.start()
    time.sleep(0.5) # Give the gRPC server 500ms to start
    for p in script_processes:
        p.start()

    # At the moment, just wait for the simulator to finish then kill all attach processes.
    # If any attach threads error out, then the stack trace is printed anyways so this is fine.
    sim_process.join()
    for p in script_processes:
        p.terminate()
Ejemplo n.º 5
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")
Ejemplo n.º 6
0
 def initWithKwargs(self, **kwargs):
     self.in_error = False
     self.first_launch = True
     batch = kwargs.get("batch_file", None)
     self.batch = batch
     if batch is None:
         # We are simply viewing the bots to edit or manage.
         self.bot_keys = []
     else:
         self.key_index = 0
         with open(batch, "r") as f:
             b_config = yaml.safe_load(f)
         preset = b_config["preset_file"]
         fname = find_abs(preset, allowed_areas=preset_locations())
         with open(fname, "r") as f:
             p_config = yaml.safe_load(f)
         self.bot_keys = p_config["bot_names"]
         self.bot_values = [None] * len(self.bot_keys)
         self.preview_images = [None] * len(self.bot_keys)
     self.bot_select_index = 0
     self.select_enable = False
     self.code_enable = False
     self.edit_enable = False
     self.remove_enable = False
     self.bot_index = -1
     self.next = kwargs.get("next", None)
     self.next_kwargs = kwargs.get("next_kwargs", {})
     super().initWithKwargs(**kwargs)
Ejemplo n.º 7
0
def onClickMapEditor(filename):
    from ev3sim.visual.manager import ScreenObjectManager

    ScreenObjectManager.instance.pushScreen(
        ScreenObjectManager.SCREEN_RESCUE_EDIT,
        batch_file=find_abs(f"{filename}.sim", batch_locations()),
    )
Ejemplo n.º 8
0
def run_sim(sim_path, edit=False):
    from ev3sim.validation.batch_files import BatchValidator

    if not BatchValidator.validate_file(sim_path):
        return raise_error(
            f"There is something wrong with the sim {sim_path}, and so it cannot be opened or used."
        )
    if not edit:
        return [ScreenObjectManager.SCREEN_SIM], [{
            "batch": sim_path,
        }]
    import importlib

    with open(sim_path, "r") as f:
        conf = yaml.safe_load(f)
    with open(find_abs(conf["preset_file"], preset_locations())) as f:
        preset = yaml.safe_load(f)
    if "visual_settings" not in preset:
        return raise_error("This preset cannot be edited.")
    mname, cname = preset["visual_settings"].rsplit(".", 1)
    klass = getattr(importlib.import_module(mname), cname)

    return [ScreenObjectManager.SCREEN_SETTINGS], [{
        "file": sim_path,
        "settings": klass,
        "allows_filename_change": True,
        "extension": "sim",
    }]
Ejemplo n.º 9
0
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...")
Ejemplo n.º 10
0
def simulate(batch_file, preset_filename, bot_paths, seed, override_settings,
             *queues_sizes):
    result_queue = queues_sizes[0][0]
    result_queue._internal_size = queues_sizes[0][1]
    StateHandler.instance.shared_info = {
        "result_queue": result_queue,
    }
    send_queues = [q for q, _ in queues_sizes[1::2]]
    for i, (_, size) in enumerate(queues_sizes[1::2]):
        send_queues[i]._internal_size = size
    recv_queues = [q for q, _ in queues_sizes[2::2]]
    for i, (_, size) in enumerate(queues_sizes[2::2]):
        recv_queues[i]._internal_size = size

    Randomiser.createGlobalRandomiserWithSeed(seed)

    preset_file = find_abs(preset_filename, allowed_areas=preset_locations())
    with open(preset_file, "r") as f:
        config = yaml.safe_load(f)
    config["settings"] = config.get("settings", {})
    recursive_merge(config["settings"], override_settings)

    config["robots"] = config.get("robots", []) + bot_paths

    initialiseFromConfig(config, send_queues, recv_queues)
Ejemplo n.º 11
0
 def clickSettings():
     ScreenObjectManager.instance.pushScreen(
         ScreenObjectManager.SCREEN_SETTINGS,
         file=find_abs("user_config.yaml", config_locations()),
         settings=main_settings,
     )
     ScreenObjectManager.instance.screens[
         ScreenObjectManager.SCREEN_SETTINGS].clearEvents()
Ejemplo n.º 12
0
    def clickSimSettings(self, preset):
        import importlib

        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())
        mname, cname = preset_config["visual_settings"].rsplit(".", 1)
        klass = getattr(importlib.import_module(mname), cname)
        ScreenObjectManager.instance.pushScreen(
            ScreenObjectManager.SCREEN_SETTINGS,
            file=sim_path,
            settings=klass,
            allows_filename_change=False,
            extension="sim",
        )
Ejemplo n.º 13
0
 def setCheckboxBg(self, value, obj):
     img = pygame.image.load(
         find_abs("ui/box_check.png" if value else "ui/box_clear.png",
                  allowed_areas=asset_locations()))
     if img.get_size() != obj.rect.size:
         img = pygame.transform.smoothscale(
             img, (obj.rect.width, obj.rect.height))
     obj.set_image(img)
Ejemplo n.º 14
0
    def image_path(self, value):
        from ev3sim.file_helper import find_abs

        self._image_path = find_abs(value,
                                    allowed_areas=[
                                        "local", "local/assets/", "package",
                                        "package/assets/"
                                    ])
        self.image = pygame.image.load(self._image_path)
Ejemplo n.º 15
0
 def startScreen(self):
     from ev3sim.file_helper import find_abs
     pygame.init()
     self.screen = pygame.display.set_mode((self.screen_width, self.screen_height), pygame.RESIZABLE)
     pygame.display.set_caption('MHS Robotics Club Simulator')
     img_path = find_abs('Logo.png', allowed_areas=['package/assets/'])
     img = pygame.image.load(img_path)
     img.set_colorkey((255, 255, 255))
     pygame.display.set_icon(img)
Ejemplo n.º 16
0
    def captureBotImage(self, directory, filename):
        self.resetVisualElements()
        from os.path import join
        from ev3sim.simulation.loader import ScriptLoader
        from ev3sim.robot import initialise_bot, RobotInteractor
        from ev3sim.simulation.randomisation import Randomiser

        Randomiser.createGlobalRandomiserWithSeed(0)
        ScriptLoader.instance.reset()
        ScriptLoader.instance.startUp()
        elems = {}
        initialise_bot(elems, find_abs(filename, [directory]), "", 0)
        ScriptLoader.instance.loadElements(elems.get("elements", []))
        for interactor in ScriptLoader.instance.active_scripts:
            if isinstance(interactor, RobotInteractor):
                interactor.connectDevices()
                interactor.initialiseDevices()
        for interactor in ScriptLoader.instance.active_scripts:
            interactor.startUp()
            interactor.tick(0)
            interactor.afterPhysics()
        screen = pygame.Surface((480, 480), pygame.SRCALPHA)
        custom_map = {
            "SCREEN_WIDTH": 480,
            "SCREEN_HEIGHT": 480,
            "MAP_WIDTH": 25,
            "MAP_HEIGHT": 25,
        }
        for elem in self.objects.values():
            elem.customMap = custom_map
            elem.calculatePoints()
        self.applyToScreen(screen, bg=pygame.Color(self.instance.background_colour))
        colorkey = pygame.Color(self.instance.background_colour)
        for x in range(480):
            for y in range(480):
                val = screen.get_at((x, y))
                val.a = 0 if (val.r == colorkey.r and val.g == colorkey.g and val.b == colorkey.b) else 255
                screen.set_at((x, y), val)
        self.resetVisualElements()
        ScriptLoader.instance.reset()
        config_path = join(find_abs(filename, [directory]), "config.bot")
        with open(config_path, "r") as f:
            config = yaml.safe_load(f)
        pygame.image.save(screen, join(find_abs(filename, [directory]), config.get("preview_path", "preview.png")))
Ejemplo n.º 17
0
def initialise_device(deviceData, parentObj, index, preview_mode=False):
    classes = find_abs("devices/classes.yaml")
    devices = yaml.safe_load(open(classes, "r"))
    name = deviceData["name"]
    if name not in devices:
        raise ValueError(f"Unknown device type {name}")
    fname = find_abs(devices[name], allowed_areas=device_locations())
    with open(fname, "r") as f:
        try:
            config = yaml.safe_load(f)
            utils.GLOBAL_COLOURS.update(config.get("colours", {}))
            mname, cname = config["class"].rsplit(".", 1)
            import importlib

            klass = getattr(importlib.import_module(mname), cname)
            relative_location = deviceData.get("position", [0, 0])
            relative_rotation = deviceData.get("rotation", 0) * np.pi / 180
            device = klass(parentObj, relative_location, relative_rotation)
            for i, opt in enumerate(config.get("interactors", [])):
                res = opt.get("kwargs", {})
                res.update({
                    "device": device,
                    "parent": parentObj,
                    "relative_location": relative_location,
                    "relative_rotation": relative_rotation,
                    "device_index": index,
                    "single_device_index": i,
                    "port": deviceData["port"],
                    "zPos": deviceData.get("zPos", 0),
                })
                if preview_mode:
                    for i in range(len(res.get("elements", []))):
                        res["elements"][i]["physics"] = True
                opt["kwargs"] = res
                interactor = fromOptions(opt)
                if not hasattr(parentObj, "device_interactors"):
                    parentObj.device_interactors = []
                parentObj.device_interactors.append(interactor)
                ScriptLoader.instance.addActiveScript(interactor)
        except yaml.YAMLError as exc:
            print(
                f"An error occurred while loading devices. Exited with error: {exc}"
            )
Ejemplo n.º 18
0
 def initFromKwargs(self, **kwargs):
     super().initFromKwargs(**kwargs)
     from ev3sim.file_helper import find_abs
     self.font_style = kwargs.get('font_style', "OpenSans-SemiBold.ttf")
     self.font_path = find_abs(self.font_style, allowed_areas=['local/assets/', 'local', 'package/assets/', 'package'])
     self.font_size = kwargs.get('font_size', 30)
     self.font = pygame.freetype.Font(self.font_path, self.font_size)
     self.hAlignment = kwargs.get('hAlignment', 'l')
     self.vAlignment = kwargs.get('vAlignment', 't')
     self.text = kwargs.get('text', 'Test')
Ejemplo n.º 19
0
    def image_path(self, value):
        from ev3sim.file_helper import find_abs

        image_path = find_abs(value, allowed_areas=asset_locations())
        if image_path != self._image_path:
            self._image_path = image_path
            self.image = pygame.image.load(self._image_path)
            try:
                self.calculatePoints()
            except:
                pass
Ejemplo n.º 20
0
        def action():
            import yaml
            """Go through and try fixing the bots."""
            for bot in old_bots:
                dirpath = os.path.join(path, bot[:-4])
                # Folder
                if os.path.isdir(dirpath):
                    import shutil

                    shutil.rmtree(dirpath)
                os.mkdir(dirpath)
                # config.bot
                with open(os.path.join(path, bot), "r") as f:
                    config = yaml.safe_load(f)
                bot_script = config.get("script", "code.py")
                preview_image = config.get("preview_path", "preview.png")
                for keyword in ["script", "preview_path"]:
                    if keyword in config:
                        del config[keyword]
                with open(os.path.join(dirpath, "config.bot"), "w") as f:
                    f.write(yaml.dump(config))
                # code.py
                try:
                    code_path = os.path.join(
                        find_abs_directory("workspace/code/"), bot_script)
                    with open(code_path, "r") as f:
                        code = f.read()
                except:
                    code = ""
                with open(os.path.join(dirpath, "code.py"), "w") as f:
                    f.write(code)
                # preview.png
                try:
                    preview = find_abs(preview_image, asset_locations())
                    with open(preview, "rb") as f:
                        preview_data = f.read()
                except:
                    preview_data = bytes()
                with open(os.path.join(dirpath, "preview.png"), "wb") as f:
                    f.write(preview_data)
                # Remove the old bot
                os.remove(os.path.join(path, bot))
            # Additionally, we need to update all sim files to no longer use the .bot prefix
            actual_dir = find_abs_directory("workspace/sims/")
            for file in os.listdir(actual_dir):
                if os.path.isfile(os.path.join(
                        actual_dir, file)) and file.endswith(".sim"):
                    with open(os.path.join(actual_dir, file), "r") as f:
                        config = yaml.safe_load(f)
                    for x in range(len(config.get("bots", []))):
                        if config["bots"][x].endswith(".bot"):
                            config["bots"][x] = config["bots"][x][:-4]
                    with open(os.path.join(actual_dir, file), "w") as f:
                        f.write(yaml.dump(config))
Ejemplo n.º 21
0
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)
Ejemplo n.º 22
0
 def updateFlipCheckbox(self):
     img = pygame.image.load(
         find_abs(
             "ui/box_check.png" if self.getSelectedAttribute("flip", False)
             else "ui/box_clear.png",
             allowed_areas=asset_locations(),
         ))
     if img.get_size() != self.flip_image.rect.size:
         img = pygame.transform.smoothscale(
             img, (self.flip_image.rect.width, self.flip_image.rect.height))
     self.flip_image.set_image(img)
Ejemplo n.º 23
0
    def generateVisual(self, size, container, manager, idx):
        self.container = container
        off = self.offset(size)

        label_size = ((size[0] - 40) / 2 - 10, 40)
        label_pos = (off[0] + 20, off[1])
        label = pygame_gui.elements.UILabel(
            relative_rect=pygame.Rect(*label_pos, *label_size),
            manager=manager,
            object_id=pygame_gui.core.ObjectID(f"{idx}-file-label",
                                               "entry-label"),
            container=container,
            text=self.title,
        )

        button_size = ((size[0] - 40) * 0.25 - 20, 44)
        button_size = [min(button_size[0], button_size[1])] * 2
        file_size = ((size[0] - 40) / 2 - button_size[0] - 30, 40)
        button_pos = (
            off[0] + 50 + label_size[0] + file_size[0],
            off[1] - 2,
        )
        file_pos = (off[0] + 40 + label_size[0], off[1])
        click = pygame_gui.elements.UIButton(
            relative_rect=pygame.Rect(*button_pos, *button_size),
            manager=manager,
            object_id=pygame_gui.core.ObjectID(f"{idx+2}-button",
                                               "file-button"),
            container=container,
            text="",
        )
        img = pygame.image.load(
            find_abs("ui/folder.png", allowed_areas=asset_locations()))
        if img.get_size() != button_size:
            img = pygame.transform.smoothscale(img, button_size)
        click_icon = pygame_gui.elements.UIImage(
            relative_rect=pygame.Rect(*button_pos, *button_size),
            manager=manager,
            object_id=pygame_gui.core.ObjectID(f"{idx+3}-image", "file-image"),
            container=container,
            image_surface=img,
        )

        self.filename = pygame_gui.elements.UILabel(
            relative_rect=pygame.Rect(*file_pos, *file_size),
            manager=manager,
            object_id=pygame_gui.core.ObjectID(f"{idx+1}-file-name",
                                               "entry-label"),
            container=container,
            text=self.current if self.current else "",
        )

        return [label, self.filename, click, click_icon]
Ejemplo n.º 24
0
def initialise_bot(topLevelConfig, robotFolder, prefix, path_index):
    # Returns the robot class, as well as a completed robot to add to the elements list.
    import yaml
    from os.path import join

    with open(join(robotFolder, "config.bot"), "r") as f:
        try:
            config = yaml.safe_load(f)
            mname, cname = config.get("robot_class",
                                      "ev3sim.robot.Robot").rsplit(".", 1)
            import importlib

            klass = getattr(importlib.import_module(mname), cname)
            bot_config = config["base_plate"]
            bot_config["type"] = "object"
            bot_config["physics"] = True
            add_devices(bot_config, config.get("devices", []))
            add_to_key(bot_config, prefix)
            add_to_zpos(bot_config, 10)
            # Append bot object to elements.
            topLevelConfig["elements"] = topLevelConfig.get("elements",
                                                            []) + [bot_config]
            robot = klass()
            ScriptLoader.instance.addActiveScript(
                RobotInteractor(
                    **{
                        "robot":
                        robot,
                        "base_key":
                        bot_config["key"],
                        "path_index":
                        path_index,
                        # Don't include directories here, since that shouldn't affect randomisation.
                        "filename":
                        robotFolder.replace("\\", "/").rsplit("/", 1)[-1],
                    }))
            robot.ID = prefix
            robot._follow_collider_offset = config.get("follow_collider",
                                                       [0, 0])
            ScriptLoader.instance.robots[prefix] = robot
            ScriptLoader.instance.outstanding_events[prefix] = []
            if config.get("type", "python") == "mindstorms":
                scriptname = config.get("script", "program.ev3")
            else:
                scriptname = config.get("script", "code.py")
            if scriptname is not None:
                scriptname = find_abs(scriptname, code_locations(robotFolder))
            ScriptLoader.instance.scriptnames[prefix] = scriptname

        except yaml.YAMLError as exc:
            print(
                f"An error occurred while loading robot preset {robotFolder}. Exited with error: {exc}"
            )
Ejemplo n.º 25
0
 def action(result):
     SettingsManager.instance.setMany(
         {"app": {
             "send_crash_reports": result,
         }})
     # Change user_config to have workspace_folder = ""
     config_file = find_abs("user_config.yaml", config_locations())
     with open(config_file, "r") as f:
         conf = yaml.safe_load(f)
     conf["app"]["send_crash_reports"] = result
     with open(config_file, "w") as f:
         f.write(yaml.dump(conf))
Ejemplo n.º 26
0
    def initFromKwargs(self, **kwargs):
        super().initFromKwargs(**kwargs)
        from ev3sim.file_helper import find_abs

        self.font_style = kwargs.get("font_style",
                                     "fonts/OpenSans-SemiBold.ttf")
        self.font_path = find_abs(self.font_style,
                                  allowed_areas=asset_locations())
        self.font_size = kwargs.get("font_size", 30)
        self.hAlignment = kwargs.get("hAlignment", "l")
        self.vAlignment = kwargs.get("vAlignment", "t")
        self.text = kwargs.get("text", "Test")
Ejemplo n.º 27
0
def initialise_device(deviceData, parentObj, index):
    classes = find_abs('devices/classes.yaml')
    devices = yaml.safe_load(open(classes, 'r'))
    name = deviceData['name']
    if name not in devices:
        raise ValueError(f"Unknown device type {name}")
    fname = find_abs(devices[name],
                     allowed_areas=['local/devices/', 'package/devices/'])
    with open(fname, 'r') as f:
        try:
            config = yaml.safe_load(f)
            utils.GLOBAL_COLOURS.update(config.get('colours', {}))
            mname, cname = config['class'].rsplit('.', 1)
            import importlib
            klass = getattr(importlib.import_module(mname), cname)
            relative_location = deviceData.get('position', [0, 0])
            relative_rotation = deviceData.get('rotation', 0) * np.pi / 180
            device = klass(parentObj, relative_location, relative_rotation)
            for i, opt in enumerate(config.get('interactors', [])):
                res = opt.get('kwargs', {})
                res.update({
                    'device': device,
                    'parent': parentObj,
                    'relative_location': relative_location,
                    'relative_rotation': relative_rotation,
                    'device_index': index,
                    'single_device_index': i,
                    'port': deviceData['port'],
                })
                opt['kwargs'] = res
                interactor = fromOptions(opt)
                if not hasattr(parentObj, 'device_interactors'):
                    parentObj.device_interactors = []
                parentObj.device_interactors.append(interactor)
                # Device interactors always act first.
                ScriptLoader.instance.active_scripts.insert(0, interactor)
        except yaml.YAMLError as exc:
            print(
                f"An error occured while loading devices. Exited with error: {exc}"
            )
Ejemplo n.º 28
0
    def initFromKwargs(self, **kwargs):
        super().initFromKwargs(**kwargs)
        from ev3sim.file_helper import find_abs

        self.font_style = kwargs.get("font_style", "OpenSans-SemiBold.ttf")
        self.font_path = find_abs(
            self.font_style, allowed_areas=["local/assets/", "local", "package/assets/", "package"]
        )
        self.font_size = kwargs.get("font_size", 30)
        self.font = pygame.freetype.Font(self.font_path, self.font_size)
        self.hAlignment = kwargs.get("hAlignment", "l")
        self.vAlignment = kwargs.get("vAlignment", "t")
        self.text = kwargs.get("text", "Test")
Ejemplo n.º 29
0
def fromOptions(options):
    if "filename" in options:
        import yaml

        fname = find_abs(options["filename"])
        with open(fname, "r") as f:
            config = yaml.safe_load(f)
            return fromOptions(config)
    if "class_path" not in options:
        raise ValueError(
            "Your options has no 'class_path' or 'filename' entry (Or the file you reference has no 'class_path' entry')"
        )
    import importlib

    if isinstance(options["class_path"], str):
        mname, cname = options["class_path"].rsplit(".", 1)

        klass = getattr(importlib.import_module(mname), cname)
    else:
        from importlib.machinery import SourceFileLoader

        module = SourceFileLoader(
            "not_main", find_abs(options["class_path"][0],
                                 preset_locations())).load_module()
        klass = getattr(module, options["class_path"][1])
    topObj = klass(*options.get("args", []), **options.get("kwargs", {}))
    # Add any settings for this interactor, if applicable.
    # This only works for package presets. Not workspace ones.
    if "settings_name" in options:
        name = options["settings_name"]
        if "settings_defn" not in options:
            raise ValueError(
                f"Expected a settings object to add with group name {name}")
        mname, cname = options["settings_defn"].rsplit(".", 1)
        obj = getattr(importlib.import_module(mname), cname)
        SettingsManager.instance.addSettingGroup(name, obj)
        # We need to remove this setting once the simulation ends, so save the name.
        topObj._settings_name = name
    return topObj
Ejemplo n.º 30
0
def single_run(preset_filename, robots, bind_addr):
    preset_file = find_abs(preset_filename, allowed_areas=['local', 'local/presets/', 'package', 'package/presets/'])
    with open(preset_file, 'r') as f:
        config = yaml.safe_load(f)

    config['robots'] = config.get('robots', []) + robots

    shared_data = {
        'tick': 0,                      # Current tick
        'write_stack': deque(),         # All write actions are processed through this
        'data_queue': {},               # Simulation data for each bot
        'active_count': {},             # Keeps track of which code connection each bot has.
        'bot_locks': {},                # Threading Locks and Conditions for each bot to wait for connection actions
        'bot_communications_data': {},  # Buffers and information for all bot communications
        'tick_updates': {},             # Simply a dictionary where the simulation tick will push static data, so the other methods are aware of when the simulation has exited.
    }

    result_bucket = Queue(maxsize=1)

    from threading import Thread
    from ev3sim.simulation.communication import start_server_with_shared_data

    def run(shared_data, result):
        try:
            runFromConfig(config, shared_data)
        except Exception as e:
            result.put(('Simulation', e))
            return
        result.put(True)

    comm_thread = Thread(target=start_server_with_shared_data, args=(shared_data, result_bucket, bind_addr), daemon=True)
    sim_thread = Thread(target=run, args=(shared_data, result_bucket), daemon=True)

    comm_thread.start()
    sim_thread.start()

    try:
        with result_bucket.not_empty:
            while not result_bucket._qsize():
                result_bucket.not_empty.wait(0.1)
        r = result_bucket.get()
        # Chuck it back on the queue so that other threads know we are quitting.
        result_bucket.put(r)
        if r is not True:
            print(f"An error occured in the {r[0]} thread. Raising an error now...")
            time.sleep(1)
            raise r[1]
    except KeyboardInterrupt:
        pass