コード例 #1
0
ファイル: app.py プロジェクト: rteshnizi/tethered-pair-v2
class TetheredPairApp(tk.Frame):
    def __init__(self):
        self._presetsDir = os.path.join(os.path.dirname(__file__), "..",
                                        "presets")
        self.master = tk.Tk()
        self.master.title("Tethered Pair Simulation")
        self.master.geometry("1100x850")
        super().__init__(self.master)
        self.pack()
        self.chosenPreset = tk.StringVar(master=self.master)
        self.chosenHeuristic = tk.StringVar(master=self.master)
        self._dbg = {
            # 'Print Mouse': tk.IntVar(master=self.master, value=0),
            'Test Vis Graph': tk.IntVar(master=self.master, value=0),
            'Test Triangulation': tk.IntVar(master=self.master, value=0),
            'Test Tighten Alg': tk.IntVar(master=self.master, value=0),
            'Debug Flag': tk.IntVar(master=self.master, value=0)
        }
        self.createDropdown()
        self.createButtons()
        self.createDebugOptions()
        self.canvas = Canvas(self.master, self)

    @property
    def debugFlag(self) -> bool:
        return self._dbg['Debug Flag'].get() == 1

    @property
    def shouldPrintMouse(self) -> bool:
        return False
        # return self._dbg['Print Mouse'].get() == 1

    @property
    def shouldDebugTriangulation(self) -> bool:
        return self._dbg['Test Triangulation'].get() == 1

    @property
    def shouldDebugTighten(self) -> bool:
        return self._dbg['Test Tighten Alg'].get() == 1

    @property
    def shouldDebugVisGraph(self) -> bool:
        return self._dbg['Test Vis Graph'].get() == 1

    def _getJsonPresets(self):
        isJson = lambda f: f.lower().endswith(".json")
        isNumbered = lambda f: f[:-5].isdigit()
        isStr = lambda f: not f[:-5].isdigit()
        # Get JSON files
        files = os.listdir(self._presetsDir)
        files = filter(isJson, files)
        # Separate numbered file names from string files names. They should be sorted separately
        numberedFiles = []
        stringFiles = []
        for fName in files:
            withoutExt = fName[:-5]  # Remove json from the end
            # I know this is not PyThOnIc. I don't need all these stupid exception b/c I actually have useful exceptions in my algorithm
            if withoutExt.isdigit():
                withoutExt = int(
                    withoutExt
                )  # convert to int or raise exception (meaning it's a string)
                numberedFiles.append(withoutExt)
            else:
                stringFiles.append(fName)
        # Sort files: string files names first, numbered test cases second
        numberedFiles = ["%d.json" % fName for fName in sorted(numberedFiles)]
        stringFiles = sorted(stringFiles)
        return stringFiles + numberedFiles

    def createDropdown(self):
        options = self._getJsonPresets()
        self.chosenPreset.set(options[0])
        self.presets = tk.OptionMenu(self.master, self.chosenPreset, *options)
        self.presets.pack(side=tk.TOP)

        self.loadPresetBtn = tk.Button(self)
        self.loadPresetBtn["text"] = "Load Preset"
        self.loadPresetBtn["command"] = self.loadPreset
        self.loadPresetBtn.pack(side=tk.TOP)

    def loadPreset(self):
        mapPath = self.chosenPreset.get()
        mapPath = os.path.join(self._presetsDir, mapPath)
        mapPath = os.path.abspath(mapPath)
        self.readMapJson(mapPath)

    def createButtons(self):
        self.browseBtn = tk.Button(self)
        self.browseBtn["text"] = "Select Map Json"
        self.browseBtn["command"] = self.selectMapFile
        self.browseBtn.pack(side=tk.TOP)

        heuristics = [
            "_heuristicNone", "_heuristicLineDist", "_heuristicShortestPath",
            "_heuristicTrmpp"
        ]
        self.chosenHeuristic.set(heuristics[2])
        self.heuristics = tk.OptionMenu(self.master, self.chosenHeuristic,
                                        *heuristics)
        self.heuristics.pack(side=tk.TOP)

        self.runBtn = tk.Button(self)
        self.runBtn["state"] = tk.DISABLED
        self.runBtn["text"] = "A*"
        self.runBtn["command"] = self.run
        self.runBtn.pack(side=tk.TOP)

        self.runDpBtn = tk.Button(self)
        self.runDpBtn["state"] = tk.DISABLED
        self.runDpBtn["text"] = "DP"
        self.runDpBtn["command"] = self.runDp
        self.runDpBtn.pack(side=tk.TOP)

    def selectMapFile(self):
        mapPath = filedialog.askopenfilename(
            initialdir=self._presetsDir,
            title="Select Map",
            filetypes=(
                ("JSON Files",
                 "*.json"), ))  # The trailing comma in filetypes is needed
        if (not mapPath):
            return
        mapPath = os.path.abspath(mapPath)
        self.readMapJson(mapPath)

    def readMapJson(self, absolutePath):
        if (not os.path.isfile(absolutePath)):
            return
        self.canvas.buildPreset(absolutePath)
        print("Max L = %.2f" % self.canvas.model.MAX_CABLE)
        self.runBtn["state"] = tk.NORMAL
        self.runDpBtn["state"] = tk.NORMAL

    def createDebugOptions(self):
        for (text, variable) in self._dbg.items():
            checkbox = tk.Checkbutton(master=self.master,
                                      text=text,
                                      variable=variable)
            checkbox.pack(side=tk.TOP)

    def run(self):
        if self.shouldDebugVisGraph:
            processReducedVisibilityGraph(True)
        elif not self.shouldDebugTighten and self.shouldDebugTriangulation:
            (cable, dest1, dest2) = (self.canvas.model.cable,
                                     self.canvas.model.robots[0].destination,
                                     self.canvas.model.robots[1].destination)
            (cable, dest1, dest2) = preprocessTheCable(cable, dest1, dest2)
            (cable, dest1,
             dest2) = pushCableAwayFromObstacles(cable, dest1, dest2)
            tri = testTriangulation(cable, dest1, dest2)
            print("triangles:", tri.triangleCount)
        elif self.shouldDebugTighten:
            cable = testTightenCable(self.shouldDebugTriangulation)
            self.canvas._renderCable(cable)
        else:
            solution = aStar(self.chosenHeuristic.get(), self.debugFlag)
            self.canvas.renderSolution(solution, True)
        # Disable the button to force a reset
        self.runBtn["state"] = tk.DISABLED
        self.runDpBtn["state"] = tk.DISABLED

    def runDp(self):
        solution = dynamicProg(self.chosenHeuristic.get(), self.debugFlag)
        self.canvas.renderSolution(solution, True)
        # Disable the button to force a reset
        self.runBtn["state"] = tk.DISABLED
        self.runDpBtn["state"] = tk.DISABLED