Example #1
0
def run_pinballview(width, height, configuration):
    """

        Changed from original Pierre-Luc Bacon implementation to reflect
        the visualization changes in the PinballView Class.

    """
    width, height = float(width), float(height)
    master = Tk()
    master.title('RLPY Pinball')
    screen = Canvas(master, width=500.0, height=500.0)
    screen.configure(background='LightGray')
    screen.pack()

    environment = PinballModel(configuration)
    environment_view = PinballView(screen, width, height, environment)

    actions = [
        PinballModel.ACC_X, PinballModel.DEC_Y, PinballModel.DEC_X,
        PinballModel.ACC_Y, PinballModel.ACC_NONE
    ]
    done = False
    while not done:
        user_action = np.random.choice(actions)
        environment_view.blit()
        if environment.episode_ended():
            done = True
        if environment.take_action(user_action) == environment.END_EPISODE:
            done = True

        environment_view.blit()
        screen.update()
Example #2
0
    def plot_results(self):
        grid_x = (self.canvas_width -
                  2 * self.canvas_margin) / (self.grid_size)
        grid_y = (self.canvas_height -
                  2 * self.canvas_margin) / (self.grid_size)
        pin_dx = grid_x / 6
        pin_dy = grid_y / 6

        master = Tk()

        w = Canvas(master, width=self.canvas_width, height=self.canvas_height)
        w.pack()

        for node in self.graph:
            i, j = self.id_to_coord(node)
            if node[-1] == 's':
                i += 0.5
                j += 0.5
            nx, ny = self.get_xy(i, j)
            if node[-1] == 's':
                fill_col = 'green'
                w.create_rectangle(nx - pin_dx,
                                   ny - pin_dy,
                                   nx + pin_dx,
                                   ny + pin_dy,
                                   fill=fill_col)
            else:
                fill_col = 'black'
                w.create_oval(nx - 2, ny - 2, nx + 2, ny + 2, fill=fill_col)

        self.draw_routes(w)

        w.update()
        w.postscript(file='sol35.ps', colormode='color')
        mainloop()
Example #3
0
class Wall(object):
    MIN_RED = MIN_GREEN = MIN_BLUE = 0x0
    MAX_RED = MAX_GREEN = MAX_BLUE = 0xFF

    PIXEL_WIDTH = 96

    def __init__(self, width, height):
        self.width = width
        self.height = height
        self._tk_init()
        self.pixels = [(0, 0, 0) for i in range(self.width * self.height)]

    def _tk_init(self):
        self.root = Tk()
        self.root.title("ColorWall %d x %d" % (self.width, self.height))
        self.root.resizable(0, 0)
        self.frame = Frame(self.root, bd=5, relief=SUNKEN)
        self.frame.pack()

        self.canvas = Canvas(self.frame,
                             width=self.PIXEL_WIDTH * self.width,
                             height=self.PIXEL_WIDTH * self.height,
                             bd=0, highlightthickness=0)
        self.canvas.pack()
        self.root.update()

    def set_pixel(self, x, y, hsv):
        self.pixels[self.width * y + x] = hsv

    def get_pixel(self, x, y):
        return self.pixels[self.width * y + x]

    def draw(self):
        self.canvas.delete(ALL)
        for x in range(len(self.pixels)):
            x_0 = (x % self.width) * self.PIXEL_WIDTH
            y_0 = (x / self.width) * self.PIXEL_WIDTH
            x_1 = x_0 + self.PIXEL_WIDTH
            y_1 = y_0 + self.PIXEL_WIDTH
            hue = "#%02x%02x%02x" % self._get_rgb(self.pixels[x])
            self.canvas.create_rectangle(x_0, y_0, x_1, y_1, fill=hue)
        self.canvas.update()

    def clear(self):
        for i in range(self.width * self.height):
            self.pixels[i] = (0, 0, 0)

    def _hsv_to_rgb(self, hsv):
        rgb = colorsys.hsv_to_rgb(*hsv)
        red = self.MAX_RED * rgb[0]
        green = self.MAX_GREEN * rgb[1]
        blue = self.MAX_BLUE * rgb[2]
        return (red, green, blue)

    def _get_rgb(self, hsv):
        red, green, blue = self._hsv_to_rgb(hsv)
        red = int(float(red) / (self.MAX_RED - self.MIN_RED) * 0xFF)
        green = int(float(green) / (self.MAX_GREEN - self.MIN_GREEN) * 0xFF)
        blue = int(float(blue) / (self.MAX_BLUE - self.MIN_BLUE) * 0xFF)
        return (red, green, blue)
Example #4
0
File: pok.py Project: sash13/diplom
class Example(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.x0=[x*0.1 for x in range(10, 15)]
        self.y0=[0 for x in range(10, 15)]
        #self.tet1 = [i for i in range(90)]
        #self.tet2 = [i for i in range(45, 135)]
        self.tet1_con = 0
        self.tet2_con = 0
        
        self.count1 = 0
        self.count2 = 0
        self.sign1 = 1
        self.sign2 = -1
        self.parent = parent
        self.initUI()
        self.parent.after(0, self.animation)
        
    def initUI(self):
        self.parent.title("Arm")        
        self.pack(fill=BOTH, expand=1)
        self.canvas = Canvas(self)
        #self.canvas.create_line(0, 0, 200, 100+self.count, width=arm_width)
        line = Line(self.canvas, points['1'], (800/2, 400))
        arms.append(line)
        line = Line(self.canvas, 90-(points['2']-points['1']), line.cor1)
        arms.append(line)
        
        self.canvas.pack(fill=BOTH, expand=1)
        
    def animation(self):
        self.canvas.delete("all")
        #self.canvas.create_line(0, 0, 200, 100+self.count, width=arm_width)
        '''if points['1'] > 90 and self.sign1 == 1:
            self.sign1 = -1
        elif points['1'] == 45 and self.sign1 == -1:
            self.sign1 = 1
        if points['2'] > 135 and self.sign2 == 1:
            self.sign2 = -1
        elif points['2'] == 90 and self.sign2 == -1:
            self.sign2 = 1
            
        points['2']+=self.sign2
        points['1']+=self.sign1'''
        if self.count1 >= len(self.x0) and self.sign1 == 1:
            self.sign1 = -1
        if self.count1 <= 0 and self.sign1 == -1:
            self.sign1 = 1

        self.count1+=self.sign1
        tet1, tet2 = getAngles(self.x0[self.count1-1], self.y0[self.count1-1])
	print tet1, tet2
        line = arms[0].draw(tet1)
        arms[1].draw(90-(tet2+tet1), line, 'red')
        #line = arms[0].draw(points['1'])
        #arms[1].draw(90-(points['2']-points['1']), line)

        self.canvas.update()
        #self.count +=1
        self.parent.after(50, self.animation)
Example #5
0
File: Pinball.py Project: MLDL/rlpy
def run_pinballview(width, height, configuration):
    """

        Changed from original Pierre-Luc Bacon implementation to reflect
        the visualization changes in the PinballView Class.

    """
    width, height = float(width), float(height)
    master = Tk()
    master.title('RLPY Pinball')
    screen = Canvas(master, width=500.0, height=500.0)
    screen.configure(background='LightGray')
    screen.pack()

    environment = PinballModel(configuration)
    environment_view = PinballView(screen, width, height, environment)

    actions = [
        PinballModel.ACC_X,
        PinballModel.DEC_Y,
        PinballModel.DEC_X,
        PinballModel.ACC_Y,
        PinballModel.ACC_NONE]
    done = False
    while not done:
        user_action = np.random.choice(actions)
        environment_view.blit()
        if environment.episode_ended():
            done = True
        if environment.take_action(user_action) == environment.END_EPISODE:
            done = True

        environment_view.blit()
        screen.update()
Example #6
0
def xGC_skew(seq, window=1000, zoom=100,
                         r=300, px=100, py=100):
    """Calculates and plots normal and accumulated GC skew (GRAPHICS !!!)."""
    from Tkinter import Scrollbar, Canvas, BOTTOM, BOTH, ALL, \
                        VERTICAL, HORIZONTAL, RIGHT, LEFT, X, Y
    yscroll = Scrollbar(orient=VERTICAL)
    xscroll = Scrollbar(orient=HORIZONTAL)
    canvas = Canvas(yscrollcommand=yscroll.set,
                    xscrollcommand=xscroll.set, background='white')
    win = canvas.winfo_toplevel()
    win.geometry('700x700')

    yscroll.config(command=canvas.yview)
    xscroll.config(command=canvas.xview)
    yscroll.pack(side=RIGHT, fill=Y)
    xscroll.pack(side=BOTTOM, fill=X)
    canvas.pack(fill=BOTH, side=LEFT, expand=1)
    canvas.update()

    X0, Y0 = r + px, r + py
    x1, x2, y1, y2 = X0 - r, X0 + r, Y0 - r, Y0 + r

    ty = Y0
    canvas.create_text(X0, ty, text='%s...%s (%d nt)' % (seq[:7], seq[-7:], len(seq)))
    ty += 20
    canvas.create_text(X0, ty, text='GC %3.2f%%' % (GC(seq)))
    ty += 20
    canvas.create_text(X0, ty, text='GC Skew', fill='blue')
    ty += 20
    canvas.create_text(X0, ty, text='Accumulated GC Skew', fill='magenta')
    ty += 20
    canvas.create_oval(x1, y1, x2, y2)

    acc = 0
    start = 0
    for gc in GC_skew(seq, window):
        r1 = r
        acc += gc
        # GC skew
        alpha = pi - (2*pi*start)/len(seq)
        r2 = r1 - gc*zoom
        x1 = X0 + r1 * sin(alpha)
        y1 = Y0 + r1 * cos(alpha)
        x2 = X0 + r2 * sin(alpha)
        y2 = Y0 + r2 * cos(alpha)
        canvas.create_line(x1, y1, x2, y2, fill='blue')
        # accumulated GC skew
        r1 = r - 50
        r2 = r1 - acc
        x1 = X0 + r1 * sin(alpha)
        y1 = Y0 + r1 * cos(alpha)
        x2 = X0 + r2 * sin(alpha)
        y2 = Y0 + r2 * cos(alpha)
        canvas.create_line(x1, y1, x2, y2, fill='magenta')

        canvas.update()
        start += window

    canvas.configure(scrollregion=canvas.bbox(ALL))
Example #7
0
def xGC_skew(seq, window = 1000, zoom = 100,
                         r = 300, px = 100, py = 100):
    """Calculates and plots normal and accumulated GC skew (GRAPHICS !!!)."""
    from Tkinter import Scrollbar, Canvas, BOTTOM, BOTH, ALL, \
                        VERTICAL, HORIZONTAL, RIGHT, LEFT, X, Y
    yscroll = Scrollbar(orient = VERTICAL)
    xscroll = Scrollbar(orient = HORIZONTAL)
    canvas = Canvas(yscrollcommand = yscroll.set,
                    xscrollcommand = xscroll.set, background = 'white')
    win = canvas.winfo_toplevel()
    win.geometry('700x700')

    yscroll.config(command = canvas.yview)
    xscroll.config(command = canvas.xview)
    yscroll.pack(side = RIGHT, fill = Y)
    xscroll.pack(side = BOTTOM, fill = X)
    canvas.pack(fill=BOTH, side = LEFT, expand = 1)
    canvas.update()

    X0, Y0 = r + px, r + py
    x1, x2, y1, y2 = X0 - r, X0 + r, Y0 -r, Y0 + r

    ty = Y0
    canvas.create_text(X0, ty, text = '%s...%s (%d nt)' % (seq[:7], seq[-7:], len(seq)))
    ty +=20
    canvas.create_text(X0, ty, text = 'GC %3.2f%%' % (GC(seq)))
    ty +=20
    canvas.create_text(X0, ty, text = 'GC Skew', fill = 'blue')
    ty +=20
    canvas.create_text(X0, ty, text = 'Accumulated GC Skew', fill = 'magenta')
    ty +=20
    canvas.create_oval(x1,y1, x2, y2)

    acc = 0
    start = 0
    for gc in GC_skew(seq, window):
        r1 = r
        acc+=gc
        # GC skew
        alpha = pi - (2*pi*start)/len(seq)
        r2 = r1 - gc*zoom
        x1 = X0 + r1 * sin(alpha)
        y1 = Y0 + r1 * cos(alpha)
        x2 = X0 + r2 * sin(alpha)
        y2 = Y0 + r2 * cos(alpha)
        canvas.create_line(x1,y1,x2,y2, fill = 'blue')
        # accumulated GC skew
        r1 = r - 50
        r2 = r1 - acc
        x1 = X0 + r1 * sin(alpha)
        y1 = Y0 + r1 * cos(alpha)
        x2 = X0 + r2 * sin(alpha)
        y2 = Y0 + r2 * cos(alpha)
        canvas.create_line(x1,y1,x2,y2, fill = 'magenta')

        canvas.update()
        start += window

    canvas.configure(scrollregion = canvas.bbox(ALL))
Example #8
0
class SimulationStrip(Strip):
    def __init__(self, length, row_length, led_size=DEFAULT_LED_SIZE):
        super(SimulationStrip, self).__init__(length)
        led_window = Tk()
        led_window.title('LED Simulator')
        MARGIN = 5
        led_size = min(
            (led_window.winfo_screenwidth() - 2 * MARGIN) / row_length,
            led_size)
        num_rows = math.ceil(length / row_length)
        height = num_rows * led_size + (1 + num_rows) * MARGIN
        width = led_size * row_length + 2 * MARGIN
        self.canvas = Canvas(led_window, width=width, height=height)
        self.canvas.pack()
        self.leds = [] * length
        self.leds = [
            self.create_rectangle(i, row_length, led_size, MARGIN)
            for i in xrange(length)
        ]
        self.canvas.update()

    def show(self):
        for i in xrange(self.length):
            color = '#%02x%02x%02x' % tuple([(255 * c) / MAX_BRIGHTNESS
                                             for c in self[i]])
            self.canvas.itemconfigure(self.leds[i], fill=color)
        self.canvas.update()
        time.sleep(SHOW_SLEEP_TIME)

    def create_rectangle(self, index, row_length, led_size, margin):
        #x0
        if (index / row_length) % 2 == 0:
            x0 = margin + (index % row_length) * led_size
        else:
            x0 = margin + (row_length - (index % row_length) - 1) * led_size

        #y0
        y0 = margin + (led_size + margin) * (index / row_length)

        #x1
        if (index / row_length) % 2 == 0:
            x1 = margin + ((index % row_length) + 1) * led_size
        else:
            x1 = margin + (row_length - (index % row_length)) * led_size

        #y1
        y1 = margin + (led_size + margin) * (index / row_length) + led_size

        return self.canvas.create_rectangle(x0, y0, x1, y1)
Example #9
0
class Animation:
    def __init__(self):
        root = Tk()
        self.canvas = Canvas(root, height=500, width=500)
        self.canvas.pack()

        self.canvas.create_rectangle(0, 0, 500, 500, fill="#0D4566", outline="#0D4566")  # space
        self.venus = Planet(250, 150, self.canvas, "red")
        self.earth = Planet(250, 100, self.canvas, "green")
        self.sun = Planet(250, 250, self.canvas, "yellow")

        self.start = time.time()
        self.ticks = 0
        self.done = False
        self.timer()
        root.mainloop()

    def rotate_body(self, body, amount):
        theta = math.degrees(amount)

        x = body.x - 250
        y = body.y - 250

        x, y = x * math.cos(theta) - y * math.sin(theta), x * math.sin(theta) + y * math.cos(theta)

        x += 250
        y += 250

        body.move_to(x, y)

        self.canvas.update()

    def timer(self):
        if self.done:
            print "Done after %2.2f seconds!" % (time.time() - self.start)
            return
        self.rotate_body(self.earth, math.pi / 36000 * 13.0)
        self.rotate_body(self.venus, math.pi / 36000 * 8.0)

        self.ticks += 1
        if self.ticks % 2 == 0:
            self.canvas.create_line(self.earth.x, self.earth.y, self.venus.x, self.venus.y, fill="white")
        if self.ticks > 1250:
            self.done = True

        self.canvas.after(5, self.timer)
Example #10
0
class Application(object):
    def __init__(self, root, grid_size):
        root.title("Diffusion-Limited Aggregation")
        self.cell_size = WINDOW / grid_size
        self.grid = Grid(grid_size)
        self.canvas = Canvas(root, width=WINDOW, height=WINDOW)
        self.canvas.create_rectangle(0, 0, WINDOW, WINDOW, fill=BACKGROUND)
        self.canvas.pack()
        self.colorizer = Colorizer()

    def fill(self, x, y, color):
        x *= self.cell_size
        y *= self.cell_size
        self.canvas.create_rectangle(x,
                                     y,
                                     x + self.cell_size,
                                     y + self.cell_size,
                                     fill=color)
        self.canvas.update()

    def mark(self, speck, color):
        grid = speck.grid
        grid[speck.x, speck.y] = True
        self.fill(speck.x, speck.y, color)

    def evolve(self):
        # Fill in center cell.
        self.mark(Speck(self.grid, (self.grid.size / 2, self.grid.size / 2)),
                  self.colorizer.next())

        # Fill until the edge.
        number = 0
        while True:
            speck = Speck(self.grid)
            self.fill(speck.x, speck.y, "red")
            while speck.on_grid() and not speck.stuck():
                speck.move()
            if speck.on_grid():
                print "%d,+%d" % (number, speck.steps)
                self.mark(speck, self.colorizer.next())
                if speck.on_edge():
                    break
            else:
                print "%d,-%d" % (number, speck.steps)
            number += 1
Example #11
0
class Application(object):

    def __init__(self, root, grid_size):
        root.title("Diffusion-Limited Aggregation")
        self.cell_size = WINDOW / grid_size
        self.grid = Grid(grid_size)
        self.canvas = Canvas(root, width=WINDOW, height=WINDOW)
        self.canvas.create_rectangle(0, 0, WINDOW, WINDOW, fill=BACKGROUND)
        self.canvas.pack()
        self.colorizer = Colorizer()

    def fill(self, x, y, color):
        x *= self.cell_size
        y *= self.cell_size
        self.canvas.create_rectangle(x, y,
                                     x + self.cell_size, y + self.cell_size,
                                     fill=color)
        self.canvas.update()

    def mark(self, speck, color):
        grid = speck.grid
        grid[speck.x, speck.y] = True
        self.fill(speck.x, speck.y, color)

    def evolve(self):
        # Fill in center cell.
        self.mark(Speck(self.grid, (self.grid.size/2, self.grid.size/2)),
                  self.colorizer.next())

        # Fill until the edge.
        number = 0
        while True:
            speck = Speck(self.grid)
            self.fill(speck.x, speck.y, "red")
            while speck.on_grid() and not speck.stuck():
                speck.move()
            if speck.on_grid():
                print "%d,+%d" % (number, speck.steps)
                self.mark(speck, self.colorizer.next())
                if speck.on_edge():
                    break
            else:
                print "%d,-%d" % (number, speck.steps)
            number += 1
Example #12
0
class SimulationStrip(Strip):
    def __init__(self, length, row_length, led_size=DEFAULT_LED_SIZE):
        super(SimulationStrip, self).__init__(length)
        led_window = Tk()
        led_window.title('LED Simulator')
        MARGIN = 5
        led_size = min((led_window.winfo_screenwidth() - 2 * MARGIN) / row_length, led_size)
        num_rows = math.ceil(length / row_length)
        height = num_rows * led_size + (1 + num_rows) * MARGIN
        width = led_size * row_length + 2 * MARGIN
        self.canvas = Canvas(led_window, width=width, height=height)
        self.canvas.pack()
        self.leds = [] * length
        self.leds = [self.create_rectangle(i, row_length, led_size, MARGIN) for i in xrange(length)]
        self.canvas.update()

    def show(self):
        for i in xrange(self.length):
            color = '#%02x%02x%02x' % tuple([(255 * c) / MAX_BRIGHTNESS for c in self[i]])
            self.canvas.itemconfigure(self.leds[i], fill=color)
        self.canvas.update()
        time.sleep(SHOW_SLEEP_TIME)

    def create_rectangle(self, index, row_length, led_size, margin):
        #x0
        if (index / row_length) % 2 == 0:
            x0 = margin + (index % row_length) * led_size
        else:
            x0 = margin + (row_length - (index % row_length) - 1) * led_size

        #y0
        y0 = margin + (led_size + margin) * (index / row_length)

        #x1
        if (index / row_length) % 2 == 0:
            x1 = margin + ((index % row_length) + 1) * led_size
        else:
            x1 = margin + (row_length - (index % row_length)) * led_size

        #y1
        y1 = margin + (led_size + margin) * (index / row_length) + led_size

        return self.canvas.create_rectangle(x0, y0, x1, y1)
Example #13
0
class Example(Frame):
    def __init__(self, parent):
        Frame.__init__(self, parent)
 
        self.x0, self.y0 = circle(-90, 90, 40)
        #self.x0, self.y0 = circle(-90, 90, 35)
        
        #print len(self.x0)
        #self.tet1 = [i for i in range(90)]
        #self.tet2 = [i for i in range(45, 135)]
        self.tet1_con = 0
        self.tet2_con = 0
        
        self.count1 = 0
        self.count2 = 0
        self.sign1 = 1
        self.sign2 = -1
        self.parent = parent
        self.initUI()
        self.parent.after(0, self.animation)
        
    def initUI(self):
        self.parent.title("Arm")        
        self.pack(fill=BOTH, expand=1)
        self.canvas = Canvas(self)
        #self.canvas.create_line(0, 0, 200, 100+self.count, width=arm_width)
        line = Line(self.canvas, points['1'], (width/2, hight/2))
        arms.append(line)
        line = Line(self.canvas, 90-(points['2']-points['1']), line.cor1)
        arms.append(line)
        
        self.canvas.pack(fill=BOTH, expand=1)
        
    def animation(self):
        self.canvas.delete("all")

        for i in range(0, len(self.x0), 2):
            self.canvas.create_line(width/2+self.x0[i], hight/2-self.y0[i],
                                    width/2+self.x0[i+1],hight/2-self.y0[i+1], width=2)


        tet1p, tet2p = getAngles(self.x0[self.count1], self.y0[self.count1])
        
        tet1 = 180-(tet1p)
        tet2 = 180-((tet2p)-tet1)+180

        text = '('+str(tet1p) +',' + str(tet2p) + ')'
        self.canvas.create_text((width/2, hight-100),text=text)

        
        line = arms[0].draw(tet1)
        arms[1].draw(tet2, line, 'red')
        
        self.count1+=self.sign1
        if self.count1 == (len(self.x0)-1) and self.sign1 == 1:
            #self.sign1 = -1
            self.count1 = 0
        if self.count1 <= 0 and self.sign1 == -1:
            self.sign1 = 1
            #self.x0=self.x01
            #self.y0=self.y01

        #line = arms[0].draw(points['1'])
        #arms[1].draw(90-(points['2']-points['1']), line)

        self.canvas.update()
        #self.count +=1
        self.parent.after(100, self.animation)
Example #14
0
class FourBarGUI(object):
    """
    GUI to model a 4-bar mechanism.
    """
    def __init__(self, wdw, r, c):
        """
        Determines layout of the canvas,
        number of rows and colums is r and c.
        """
        wdw.title('a 4-bar mechanism')
        self.fbr = FourBar()
        self.rows = r
        self.cols = c
        self.ox = c/3
        self.oy = 3*r/4
        # print "A =" , (self.ox, self.oy)
        self.togo = False
        # the canvas and start, stop, and clear buttons
        self.c = Canvas(wdw, width=self.cols, height=self.rows, bg='green')
        self.c.grid(row=1, column=2, columnspan=2)
        self.startbut = Button(wdw, text='start', command = self.start)
        self.startbut.grid(row=3, column=2, sticky=W+E)
        self.stopbut = Button(wdw, text='stop', command = self.stop)
        self.stopbut.grid(row=3, column=3, sticky=W+E)
        self.clearbut = Button(wdw, text='clear', command = self.clear)
        self.clearbut.grid(row=3, column=4, columnspan=3, sticky=W+E)
        # the length of the crank
        self.crank_lbl = Label(wdw, text='crank', justify=LEFT)
        self.crank_lbl.grid(row=0, column=0)
        self.crank_bar = IntVar()
        self.L = Scale(wdw, orient='vertical', from_=0, to=self.rows/2, \
            tickinterval=20, resolution=1, length=self.rows, \
            variable=self.crank_bar, command=self.draw_mechanism)
        self.L.set(self.fbr.crank)
        self.L.grid(row=1, column=0)
        # the angle that drives the crank
        self.angle_lbl = Label(wdw, text='angle', justify=LEFT)
        self.angle_lbl.grid(row=0, column=1)
        self.angle = DoubleVar()
        self.t = Scale(wdw, orient='vertical', from_=0, to=6.30, \
            tickinterval=0.30, resolution=0.01, length=self.rows, \
            variable=self.angle, command=self.draw_mechanism)
        self.t.grid(row=1, column=1)
        self.angle.set(self.fbr.angle)
        # the bar at the right
        self.right_bar_lbl = Label(wdw, text='right bar', justify=LEFT)
        self.right_bar_lbl.grid(row=0, column=4)
        self.right_bar = IntVar()
        self.r = Scale(wdw, orient='vertical', from_=0, to=self.rows/2, \
            tickinterval=20, resolution=1, length=self.rows, \
            variable=self.right_bar, command=self.draw_mechanism)
        self.r.grid(row=1, column=4)
        self.right_bar.set(self.fbr.right)
        # the top bar attached to the crank
        self.top_bar_lbl = Label(wdw, text='top bar', justify=LEFT)
        self.top_bar_lbl.grid(row=0, column=5)
        self.r_top_bar = IntVar()
        self.R = Scale(wdw, orient='vertical', from_=0, to=self.rows/2, \
            tickinterval=20, resolution=1, length=self.rows, \
            variable=self.r_top_bar, command=self.draw_mechanism)
        self.R.grid(row=1, column=5)
        self.r_top_bar.set(self.fbr.top)
        # the scale for the coupler bar
        self.coupler_bar_lbl = Label(wdw, text='coupler', justify=LEFT)
        self.coupler_bar_lbl.grid(row=0, column=6)
        self.coupler_bar = IntVar()
        self.cpl = Scale(wdw, orient='vertical', from_=0, to=self.rows/2, \
            tickinterval=20, resolution=1, length=self.rows, \
            variable=self.coupler_bar, command=self.draw_mechanism)
        self.cpl.grid(row=1, column=6)
        self.coupler_bar.set(self.fbr.coupler)
        # the horizontal bottom bar
        self.flat_lbl = Label(wdw, text='right joint', justify=RIGHT)
        self.flat_lbl.grid(row=2, column=1)
        self.flat = IntVar()
        self.f = Scale(wdw, orient='horizontal', from_=0, to=self.rows/2, \
            tickinterval=50, resolution=1, length=self.cols, \
            variable=self.flat, command=self.draw_mechanism)
        self.f.grid(row=2, column=2, columnspan=2)
        self.flat.set(self.fbr.flat)
        # coordinates of the coupler point appear on top
        self.ex = Entry(wdw) # for x value
        self.ex.grid(row=0, column=2)
        self.ex.insert(INSERT, "x = ")
        self.ey = Entry(wdw) # for y value
        self.ey.grid(row=0, column=3)
        self.ey.insert(INSERT,"y = ")
        # check button for drawing of coupler curve
        self.curve = IntVar()
        self.cb = Checkbutton(wdw, text='coupler', \
            variable=self.curve, onvalue=1, offvalue=0)
        self.curve.set(1)
        self.cb.grid(row=3, column=0)
        # draw the mechanism on canvas
        self.draw_mechanism(0)

    def update_values(self):
        """
        Takes all values of the scales and updates
        the data attributes of self.fbr.
        """
        self.fbr.flat = self.flat.get()
        self.fbr.crank = self.crank_bar.get()
        self.fbr.top = self.r_top_bar.get()
        self.fbr.right = self.right_bar.get()
        self.fbr.coupler = self.coupler_bar.get()
        self.fbr.angle = self.angle.get()
        #self.fbr.print_joints()

    def draw_coupler_point(self, p):
        """
        Draws coupler point with coordinates in p
        if the curve checkbox is on.
        Note that the previous values for the coordinates
        of the coupler point are stored in the entry fields.
        """
        if self.curve.get() == 1:
            px = self.ox + p[0]
            py = self.oy - p[1]
            eqx = self.ex.get()
            Lx = eqx.split('=')
            if Lx[1] == ' ':
                qx = 0.0
            else:
                qx = float(Lx[1])
            eqy = self.ey.get()
            Ly = eqy.split('=')
            if Ly[1] == ' ':
                qy = 0.0
            else:
                qy = float(Ly[1])
            if (qx != 0.0) and (qy != 0.0):
                qx = self.ox + qx
                qy = self.oy - qy
                self.c.create_line(qx, qy, px, py, width=1)

    def fill_entries(self, p):
        """
        Fills the entry fields with the coordinates
        of the coupler point in p.
        """
        sx = 'x = %f' % p[0]
        sy = 'y = %f' % p[1]
        self.ex.delete(0, END)
        self.ex.insert(INSERT, sx)
        self.ey.delete(0, END)
        self.ey.insert(INSERT, sy)

    def draw_link(self, p, q, s):
        """
        Draws the link from point with coordinates in p
        to the point with coordinates in q, using s as tag.
        """
        self.c.delete(s)
        px = self.ox + p[0]
        py = self.oy - p[1]
        qx = self.ox + q[0]
        qy = self.oy - q[1]
        self.c.create_line(px, py, qx, qy, width=2, tags=s)

    def draw_mechanism(self, v):
        """
        Fills the canvas with the current model
        of the planar 4-bar mechanism.
        Because this command is called by the sliders,
        the argument v is needed but not used.
        """
        self.update_values()
        L = self.fbr.joints()
        for i in range(0, len(L)):
            p = L[i]
            px = self.ox + p[0]
            py = self.oy - p[1]
            sj = 'joint%d' % i
            self.c.delete(sj)
            self.c.create_oval(px-6, py-6, px+6, py+6, width=1, \
                outline='black', fill='red', tags=sj)
        self.draw_link(L[0], L[2], 'link0')
        self.draw_link(L[1], L[3], 'link1')
        self.draw_link(L[2], L[3], 'link2')
        self.draw_link(L[2], L[4], 'link3')
        self.draw_coupler_point(L[4])
        self.fill_entries(L[4])

    def start(self):
        """
        Starts the animation, adding 0.01 to angle.
        """
        self.togo = True
        while self.togo:
            theta = self.angle.get()
            theta = theta + 0.01
            if theta > 6.28:
                theta = 0
            self.angle.set(theta)
            self.draw_mechanism(0)
            self.c.update()

    def stop(self):
        """
        Stops the animation.
        """
        self.togo = False

    def clear(self):
        """
        Clears the canvas.
        """
        self.c.delete(ALL)
Example #15
0
class Board:
    def __init__(self, width, height, title = "Boids"):
        """ A board for boids to explore """
        from Tkinter import Tk, Canvas, Toplevel
        self.colors = ["white", "black", "red", "yellow", "blue", "green", "purple", "pink", "cyan", "turquoise", "gray"]
        self.width = width
        self.height = height
        self.distance = 10
        self.boids = []
        self.oldVector = []
        self.title = title
        self.app = Tk()
        self.app.withdraw()
        self.win = Toplevel()
        self.win.wm_title(title)
        self.canvas = Canvas(self.win,
                             width=self.width,
                             height=self.height)
        self.canvas.pack(side = 'bottom', expand = "yes", anchor = "n",
                         fill = 'both')
        self.win.winfo_toplevel().protocol('WM_DELETE_WINDOW',self.close)
        #self.canvas.bind("<Configure>", self.changeSize)
        self.draw()

    def close(self):
        """ close the window """
        self.app.destroy()

    def draw(self):
        """ Initialize the board. You must do this if you ever want to see the path """
        print "Drawing...",
        self.canvas.delete("boid")
        for boid in self.boids:
            self.drawBoid( boid )
        self.canvas.update()
        print "Done!"

    def drawBoid(self, boid):
        size = 40
        angle = 80
        x = boid.x - size/2
        y = boid.y - size/2
        start = ((boid.dir + 180 + angle/2) - 55) % 360
        color = self.colors[boid.color]
        self.canvas.create_arc(x, y, x + size, y + size,
                               start = start, extent = angle/2,
                               fill = color, outline = color, tag = "boid")
        
    def addBoid(self, boid):
        self.boids.append( boid )
        self.oldVector.append( 0 )
        self.draw()

    def dist(self, x1, y1, x2, y2):
        return math.sqrt( (x1 - x2) ** 2 + (y1 - y2) ** 2)

    def angleTo(self, b1, b2):
        # figure out angle from boid1 to boid2
        # this is just a test!
        if self.boids[b1].x < self.boids[b2].x:
            return -10
        # return - if to the right, + if to the left
        else:
            return 10

    def avoid(self, num, radius):
        for i in range(len(self.boids)):
            if i != num:
                if self.dist(self.boids[i].x, self.boids[i].y,
                             self.boids[num].x, self.boids[num].y ) < radius:
                    return -self.angleTo( num, i)
        return 0.0
    
    def copy(self, num, radius):
        # if within radius, get closer to their angle
        # return - if to the right, + if to the left
        return 0

    def center(self, num, radius):
        # make yoru angle head toward center
        # return - if to the right, + if to the left
        return 0

    def view(self, num, radius):
        # try to have a clear view
        # return - if to the right, + if to the left
        return 0

    def adjustDirections(self, weights):
        radius = 40
        for boidNum in range(len(self.boids)):
            avoidVector = self.avoid( boidNum, radius )
            copyVector = self.copy( boidNum, radius )
            centerVector = self.center( boidNum, radius )
            viewVector = self.view( boidNum, radius )
            newVector = int(weights[0] * avoidVector + weights[1] * copyVector + weights[2] * centerVector + weights[3] * viewVector)
            self.boids[boidNum].dir += newVector
            self.oldVector[boidNum] = newVector

    def move(self):
        """ Make the boids move """
        self.adjustDirections([1., 1., 1., 1.]) # pass in weights: avoid, copy, center, view
        for boid in self.boids:
            boid.x += self.distance * math.cos( boid.dir / 180.0 * math.pi)
            boid.y -= self.distance * math.sin( boid.dir / 180.0 * math.pi)
            if boid.x > self.width:
                boid.x = 0
            if boid.x < 0:
                boid.x = self.width - 1
            if boid.y > self.height:
                boid.y = 0
            if boid.y < 0:
                boid.y = self.height - 1
        self.draw()
Example #16
0
class World(Tk):
    def __init__(self,filename=None,block=50,debug=True,delay=0.25,image=False,width=10,height=10):
#    def __init__(self,filename=None,block=50,debug=True,delay=0.25,image=True,width=10,height=10):
        Tk.__init__(self)
        self.title("")
        arg, self.width, self.height = block, width, height
#        self.photos = [PhotoImage(file=(k+".gif")) for k in ["east","north","west","south"]]
        self.beepers, self.ovals, self.numbers, self.robots, self.walls = {},{},{},{},{}
        self.m, self.n, self.t, self.delay = arg*(width+3), arg*(height+3), arg, delay
        self.debug, self.useImage = debug, image
        a, b, c = self.t+self.t/2, self.m-self.t-self.t/2, self.n-self.t-self.t/2
        self.canvas = Canvas(self, bg="white", width=self.m, height=self.n)
        self.canvas.pack()
        count = 1
        for k in range(2*self.t, max(self.m,self.n)-self.t, self.t):
            if k < b: 
                self.canvas.create_line(k, c, k, a, fill="red")
                self.canvas.create_text(k, c+self.t/2, text=str(count), font=("Times",max(-self.t*2/3,-15),""))
            if k < c: 
                self.canvas.create_line(b, k, a, k, fill="red")
                self.canvas.create_text(a-self.t/2, self.n-k, text=str(count), font=("Times",max(-self.t*2/3,-15),""))
            count += 1
        self.canvas.create_line(a, c, b, c, fill="black", width=3)
        self.canvas.create_line(a, a, a, c, fill="black", width=3)
        if filename is not None:
            self.readWorld(filename)
        self.refresh()

    def readWorld(self,filename):
        try:
            infile = open("worlds\\%s.wld" % filename, "r")
        except IOError:
           try:
               infile = open("worlds/%s.wld" % filename, "r")
           except IOError:
               infile = open(filename, "r")            
        text = infile.read().split("\n")
        infile.close()
        for t in text:
            if t.startswith("eastwestwalls"):
                s = t.split(" ")
                y, x = int(s[1]), int(s[2])
                self.addWall(x, y, -1, y)
            if t.startswith("northsouthwalls"):
                s = t.split(" ")
                x, y = int(s[1]), int(s[2])
                self.addWall(x, y, x, -1)
            if t.startswith("beepers"):
                s = t.split(" ")
                y, x, n = int(s[1]), int(s[2]), int(s[3])
                if n is infinity:
                    self.addInfiniteBeepers(x, y)
                else:
                    for k in range(n):
                        self.addBeeper(x, y)

    def pause(self):
        sleep(self.delay)

    def isBeeper(self,x,y):
        return (x,y) in self.beepers.keys() and not self.beepers[(x,y)] == 0

    def countRobots(self,x,y):
        if (x,y) not in self.robots.keys():
            return 0
        return len(self.robots[(x,y)])

    def crash(self,x1,y1,x2,y2):
        if 0 in (x1,y1,x2,y2):
            return True
        if (x2,y2) in self.walls.keys() and (x1,y1) in self.walls[(x2,y2)]:
            return True
        if (x1,y1) in self.walls.keys() and (x2,y2) in self.walls[(x1,y1)]:
            return True        
        return False

    def addInfiniteBeepers(self,x,y):
        flag = (x,y) not in self.beepers.keys() or self.beepers[(x,y)] is 0        
        self.beepers[(x,y)] = infinity
        text = "oo"
        a, b = self.t+x*self.t, self.n-(self.t+y*self.t)
        t = self.t/3
        if flag:
            self.ovals[(x,y)] = self.canvas.create_oval(a-t, b-t, a+t, b+t, fill="black")
            self.numbers[(x,y)] = self.canvas.create_text(a, b, text=text, fill="white", font=("Times",max(-self.t/2,-20),""))
        else:
            self.canvas.itemconfig(self.numbers[(x,y)], text=text)
        if (x,y) in self.robots.keys():
            for robot in self.robots[(x,y)]:
                robot.lift()

    def addBeeper(self,x,y):
        if (x,y) in self.beepers.keys() and self.beepers[(x,y)] is infinity:
            return
        flag = (x,y) not in self.beepers.keys() or self.beepers[(x,y)] is 0
        if flag:
            self.beepers[(x,y)] = 1
        else:
            self.beepers[(x,y)] += 1
        text = str(self.beepers[(x,y)])
        a, b = self.t+x*self.t, self.n-(self.t+y*self.t)
        t = self.t/3
        if flag:
            self.ovals[(x,y)] = self.canvas.create_oval(a-t, b-t, a+t, b+t, fill="black")
            self.numbers[(x,y)] = self.canvas.create_text(a, b, text=text, fill="white", font=("Times",max(-self.t/2,-20),""))
        else:
            self.canvas.itemconfig(self.numbers[(x,y)], text=text)
        if (x,y) in self.robots.keys():
            for robot in self.robots[(x,y)]:
                robot.lift()            

    def removeBeeper(self,x,y):
        if self.beepers[(x,y)] is infinity:
            return        
        self.beepers[(x,y)] -= 1
        flag = self.beepers[(x,y)] is 0        
        text = str(self.beepers[(x,y)])
        if flag:
            self.canvas.delete(self.ovals[(x,y)])
            self.canvas.delete(self.numbers[(x,y)])            
        else:
            self.canvas.itemconfig(self.numbers[(x,y)], text=text)
        if (x,y) in self.robots.keys():
            for robot in self.robots[(x,y)]:
                robot.lift()            

    def addWall(self,x1,y1,x2,y2):
        if not x1 == x2 and not y1 == y2:
            return
        if x1 == x2:
            y1, y2 = min(y1, y2), max(y1, y2)
            if y1 == -1:
                y1 = y2
            for k in range(y1, y2+1):
                self.walls.setdefault((x1,k), []).append((x1+1,k))
                a, b = self.t+x1*self.t+self.t/2, self.n-(self.t+k*self.t)+self.t/2
                c, d = self.t+x1*self.t+self.t/2, self.n-(self.t+k*self.t)-self.t/2
                self.canvas.create_line(a, b+1, c, d-1, fill="black", width=3)                
        else:
            x1, x2 = min(x1, x2), max(x1, x2)
            if x1 == -1:
                x1 = x2
            for k in range(x1, x2+1):
                self.walls.setdefault((k,y1), []).append((k,y1+1))
                a, b = self.t+k*self.t-self.t/2, self.n-(self.t+y1*self.t)-self.t/2
                c, d = self.t+k*self.t+self.t/2, self.n-(self.t+y1*self.t)-self.t/2
                self.canvas.create_line(a-1, b, c+1, d, fill="black", width=3)

    def draw(self,x,y,d,img):
#       if self.useImage:
#           if img is not None:
#               self.canvas.delete(img)
#           x, y = self.t+x*self.t, self.n-(self.t+y*self.t)
#           photo = self.photos[d/90]
#           img = self.canvas.create_image(x, y, image=photo)            
#           return img
#       else:
        t, angle = self.t/2, 120
        x, y = self.t+x*self.t, self.n-(self.t+y*self.t)
        x1, y1 = x+3**0.5*t/2*cos(radians(d)), y-3**0.5*t/2*sin(radians(d))
        x2, y2 = x+t*cos(radians(d+angle)), y-t*sin(radians(d+angle))
        x3, y3 = x+t/4*cos(radians(d+180)), y-t/4*sin(radians(d+180))
        x4, y4 = x+t*cos(radians(d-angle)), y-t*sin(radians(d-angle))
        if img is not None:
            self.canvas.delete(img)
        img = self.canvas.create_polygon(x1, y1, x2, y2, x3, y3, x4, y4, fill="blue")
        return img

    def erase(self,img):
        self.canvas.delete(img)

    def recordMove(self,count,x1,y1,x2,y2):
        for robot in self.robots[(x1,y1)]:
            if robot.count == count:
                self.robots[(x1,y1)].remove(robot)
                self.robots.setdefault((x2,y2), []).append(robot)                
                break

    def lift(self,img):
        self.canvas.lift(img)

    def refresh(self):
        self.canvas.update()
        self.pause()

    def register(self,x,y,robot):
        self.robots.setdefault((x,y), []).append(robot)

    def remove(self,x,y,robot):
        self.robots[(x,y)].remove(robot)
Example #17
0
File: Pinball.py Project: MLDL/rlpy
class Pinball(Domain):

    """
    The goal of this domain is to maneuver a small ball on a plate into a hole.
    The plate may contain obstacles which should be avoided.

    **STATE:**
        The state is given by a 4-dimensional vector, consisting of position and
        velocity of the ball.

    **ACTIONS:**
        There are 5 actions, standing for slanting the  plat in x or y direction
        or a horizontal position
        of the plate.

    **REWARD:**
        Slanting the plate costs -4 reward in addition to -1 reward for each timestep.
        When the ball reaches the hole, the agent receives 10000 units of reward.

    **REFERENCE:**

    .. seealso::
        G.D. Konidaris and A.G. Barto:
        *Skill Discovery in Continuous Reinforcement Learning Domains using Skill Chaining.*
        Advances in Neural Information Processing Systems 22, pages 1015-1023, December 2009.
    """
    #: default location of config files shipped with rlpy
    default_config_dir = os.path.join(
        __rlpy_location__,
        "Domains",
        "PinballConfigs")

    def __init__(self, noise=.1, episodeCap=1000,
                 configuration=os.path.join(default_config_dir, "pinball_simple_single.cfg")):
        """
        configuration:
            location of the configuration file
        episodeCap:
            maximum length of an episode
        noise:
            with probability noise, a uniformly random action is executed
        """
        self.NOISE = noise
        self.configuration = configuration
        self.screen = None
        self.episodeCap = episodeCap
        self.actions_num = 5
        self.actions = [
            PinballModel.ACC_X,
            PinballModel.DEC_Y,
            PinballModel.DEC_X,
            PinballModel.ACC_Y,
            PinballModel.ACC_NONE]
        self.statespace_limits = np.array(
            [[0.0, 1.0], [0.0, 1.0], [-2.0, 2.0], [-2.0, 2.0]])
        self.continuous_dims = [4]
        super(Pinball, self).__init__()
        self.environment = PinballModel(
            self.configuration,
            random_state=self.random_state)

    def showDomain(self, a):
        if self.screen is None:
            master = Tk()
            master.title('RLPY Pinball')
            self.screen = Canvas(master, width=500.0, height=500.0)
            self.screen.configure(background='LightGray')
            self.screen.pack()
            self.environment_view = PinballView(
                self.screen,
                500.0,
                500.0,
                self.environment)
        self.environment_view.blit()
        self.screen.pack()
        self.screen.update()

    def step(self, a):
        s = self.state
        [self.environment.ball.position[0],
         self.environment.ball.position[1],
         self.environment.ball.xdot,
         self.environment.ball.ydot] = s
        if self.random_state.random_sample() < self.NOISE:
            # Random Move
            a = self.random_state.choice(self.possibleActions())
        reward = self.environment.take_action(a)
        self.environment._check_bounds()
        state = np.array(self.environment.get_state())
        self.state = state.copy()
        return reward, state, self.isTerminal(), self.possibleActions()

    def s0(self):
        self.environment.ball.position[0], self.environment.ball.position[
            1] = self.environment.start_pos
        self.environment.ball.xdot, self.environment.ball.ydot = 0.0, 0.0
        self.state = np.array(
            [self.environment.ball.position[0], self.environment.ball.position[1],
             self.environment.ball.xdot, self.environment.ball.ydot])
        return self.state, self.isTerminal(), self.possibleActions()

    def possibleActions(self, s=0):
        return np.array(self.actions)

    def isTerminal(self):
        return self.environment.episode_ended()
Example #18
0
class Board:
    def __init__(self, width, height, title="Boids"):
        """ A board for boids to explore """
        from Tkinter import Tk, Canvas, Toplevel
        self.colors = [
            "white", "black", "red", "yellow", "blue", "green", "purple",
            "pink", "cyan", "turquoise", "gray"
        ]
        self.width = width
        self.height = height
        self.distance = 10
        self.boids = []
        self.oldVector = []
        self.title = title
        self.app = Tk()
        self.app.withdraw()
        self.win = Toplevel()
        self.win.wm_title(title)
        self.canvas = Canvas(self.win, width=self.width, height=self.height)
        self.canvas.pack(side='bottom', expand="yes", anchor="n", fill='both')
        self.win.winfo_toplevel().protocol('WM_DELETE_WINDOW', self.close)
        #self.canvas.bind("<Configure>", self.changeSize)
        self.draw()

    def close(self):
        """ close the window """
        self.app.destroy()

    def draw(self):
        """ Initialize the board. You must do this if you ever want to see the path """
        print "Drawing...",
        self.canvas.delete("boid")
        for boid in self.boids:
            self.drawBoid(boid)
        self.canvas.update()
        print "Done!"

    def drawBoid(self, boid):
        size = 40
        angle = 80
        x = boid.x - size / 2
        y = boid.y - size / 2
        start = ((boid.dir + 180 + angle / 2) - 55) % 360
        color = self.colors[boid.color]
        self.canvas.create_arc(x,
                               y,
                               x + size,
                               y + size,
                               start=start,
                               extent=angle / 2,
                               fill=color,
                               outline=color,
                               tag="boid")

    def addBoid(self, boid):
        self.boids.append(boid)
        self.oldVector.append(0)
        self.draw()

    def dist(self, x1, y1, x2, y2):
        return math.sqrt((x1 - x2)**2 + (y1 - y2)**2)

    def angleTo(self, b1, b2):
        # figure out angle from boid1 to boid2
        # this is just a test!
        if self.boids[b1].x < self.boids[b2].x:
            return -10
        # return - if to the right, + if to the left
        else:
            return 10

    def avoid(self, num, radius):
        for i in range(len(self.boids)):
            if i != num:
                if self.dist(self.boids[i].x, self.boids[i].y,
                             self.boids[num].x, self.boids[num].y) < radius:
                    return -self.angleTo(num, i)
        return 0.0

    def copy(self, num, radius):
        # if within radius, get closer to their angle
        # return - if to the right, + if to the left
        return 0

    def center(self, num, radius):
        # make yoru angle head toward center
        # return - if to the right, + if to the left
        return 0

    def view(self, num, radius):
        # try to have a clear view
        # return - if to the right, + if to the left
        return 0

    def adjustDirections(self, weights):
        radius = 40
        for boidNum in range(len(self.boids)):
            avoidVector = self.avoid(boidNum, radius)
            copyVector = self.copy(boidNum, radius)
            centerVector = self.center(boidNum, radius)
            viewVector = self.view(boidNum, radius)
            newVector = int(weights[0] * avoidVector +
                            weights[1] * copyVector +
                            weights[2] * centerVector +
                            weights[3] * viewVector)
            self.boids[boidNum].dir += newVector
            self.oldVector[boidNum] = newVector

    def move(self):
        """ Make the boids move """
        self.adjustDirections([1., 1., 1., 1.
                               ])  # pass in weights: avoid, copy, center, view
        for boid in self.boids:
            boid.x += self.distance * math.cos(boid.dir / 180.0 * math.pi)
            boid.y -= self.distance * math.sin(boid.dir / 180.0 * math.pi)
            if boid.x > self.width:
                boid.x = 0
            if boid.x < 0:
                boid.x = self.width - 1
            if boid.y > self.height:
                boid.y = 0
            if boid.y < 0:
                boid.y = self.height - 1
        self.draw()
    def initUI(self, tree, scaling):
        self.parent.title("MST")
        self.pack(fill=BOTH, expand=1)

        canvas = Canvas(self, width=10000, height=10000)
        #canvas.create_oval(10, 10, 15, 15, outline="red", fill="red", width=1)
        tempMax1 = 0
        tempMax2 = 0
        for node in tree.nodes:
            tempMax1 = max(tempMax1, node.GetLoc()[0])
            tempMax2 = max(tempMax2, node.GetLoc()[1])
        for x in range(tempMax1 + 1):
            for y in range(tempMax2 + 1):
                canvas.create_oval(scaling * (x + 1) - 1,
                                   scaling * (tempMax2 - y + 1) - 1,
                                   scaling * (x + 1) + 1,
                                   scaling * (tempMax2 - y + 1) + 1,
                                   outline="black",
                                   fill="black",
                                   width=1)

        for edge in tree.edges:
            point1 = edge.GetPoints()[0]
            point2 = edge.GetPoints()[1]
            point3 = edge.GetPoints()[2]
            canvas.create_oval(scaling * (point1[0] + 1) - 2,
                               scaling * (tempMax2 - point1[1] + 1) - 2,
                               scaling * (point1[0] + 1) + 2,
                               scaling * (tempMax2 - point1[1] + 1) + 2,
                               outline="red",
                               fill="red",
                               width=1)
            canvas.create_oval(scaling * (point2[0] + 1) - 2,
                               scaling * (tempMax2 - point2[1] + 1) - 2,
                               scaling * (point2[0] + 1) + 2,
                               scaling * (tempMax2 - point2[1] + 1) + 2,
                               outline="red",
                               fill="red",
                               width=1)
            if point3 != None:
                point3 = edge.GetPoints()[2]
                canvas.create_line(scaling * (point1[0] + 1),
                                   scaling * (tempMax2 - point1[1] + 1),
                                   scaling * (point3[0] + 1),
                                   scaling * (tempMax2 - point3[1] + 1),
                                   fill="red")
                canvas.create_line(scaling * (point2[0] + 1),
                                   scaling * (tempMax2 - point2[1] + 1),
                                   scaling * (point3[0] + 1),
                                   scaling * (tempMax2 - point3[1] + 1),
                                   fill="red")
            else:
                canvas.create_line(scaling * (point1[0] + 1),
                                   scaling * (tempMax2 - point1[1] + 1),
                                   scaling * (point2[0] + 1),
                                   scaling * (tempMax2 - point2[1] + 1),
                                   fill="red")
        canvas.pack(fill=BOTH, expand=1)

        canvas.update()
        canvas.postscript(file="graph.6.ps", colormode='color')
Example #20
0
class World(Tk):
    #    def __init__(self,filename=None,block=50,debug=True,delay=0.25,image=False,width=10,height=10):
    def __init__(self,
                 filename=None,
                 block=50,
                 debug=True,
                 delay=0.25,
                 image=True,
                 width=10,
                 height=10):
        Tk.__init__(self)
        self.title("")
        arg, self.width, self.height = block, width, height
        self.photos = [
            PhotoImage(file=(k + ".gif"))
            for k in ["east", "north", "west", "south"]
        ]
        self.beepers, self.ovals, self.numbers, self.robots, self.walls = {},{},{},{},{}
        self.m, self.n, self.t, self.delay = arg * (width + 3), arg * (
            height + 3), arg, delay
        self.debug, self.useImage = debug, image
        a, b, c = self.t + self.t / 2, self.m - self.t - self.t / 2, self.n - self.t - self.t / 2
        self.canvas = Canvas(self, bg="white", width=self.m, height=self.n)
        self.canvas.pack()
        count = 1
        for k in range(2 * self.t, max(self.m, self.n) - self.t, self.t):
            if k < b:
                self.canvas.create_line(k, c, k, a, fill="red")
                self.canvas.create_text(k,
                                        c + self.t / 2,
                                        text=str(count),
                                        font=("Times",
                                              max(-self.t * 2 / 3, -15), ""))
            if k < c:
                self.canvas.create_line(b, k, a, k, fill="red")
                self.canvas.create_text(a - self.t / 2,
                                        self.n - k,
                                        text=str(count),
                                        font=("Times",
                                              max(-self.t * 2 / 3, -15), ""))
            count += 1
        self.canvas.create_line(a, c, b, c, fill="black", width=3)
        self.canvas.create_line(a, a, a, c, fill="black", width=3)
        if filename is not None:
            self.readWorld(filename)
        self.refresh()

    def readWorld(self, filename):
        try:
            infile = open("worlds\\%s.wld" % filename, "r")
        except IOError:
            try:
                infile = open("worlds/%s.wld" % filename, "r")
            except IOError:
                infile = open(filename, "r")
        text = infile.read().split("\n")
        infile.close()
        for t in text:
            if t.startswith("eastwestwalls"):
                s = t.split(" ")
                y, x = int(s[1]), int(s[2])
                self.addWall(x, y, -1, y)
            if t.startswith("northsouthwalls"):
                s = t.split(" ")
                x, y = int(s[1]), int(s[2])
                self.addWall(x, y, x, -1)
            if t.startswith("beepers"):
                s = t.split(" ")
                y, x, n = int(s[1]), int(s[2]), int(s[3])
                if n is infinity:
                    self.addInfiniteBeepers(x, y)
                else:
                    for k in range(n):
                        self.addBeeper(x, y)

    def pause(self):
        sleep(self.delay)

    def isBeeper(self, x, y):
        return (x, y) in self.beepers.keys() and not self.beepers[(x, y)] == 0

    def countRobots(self, x, y):
        if (x, y) not in self.robots.keys():
            return 0
        return len(self.robots[(x, y)])

    def crash(self, x1, y1, x2, y2):
        if 0 in (x1, y1, x2, y2):
            return True
        if (x2, y2) in self.walls.keys() and (x1, y1) in self.walls[(x2, y2)]:
            return True
        if (x1, y1) in self.walls.keys() and (x2, y2) in self.walls[(x1, y1)]:
            return True
        return False

    def addInfiniteBeepers(self, x, y):
        flag = (x, y) not in self.beepers.keys() or self.beepers[(x, y)] is 0
        self.beepers[(x, y)] = infinity
        text = "oo"
        a, b = self.t + x * self.t, self.n - (self.t + y * self.t)
        t = self.t / 3
        if flag:
            self.ovals[(x, y)] = self.canvas.create_oval(a - t,
                                                         b - t,
                                                         a + t,
                                                         b + t,
                                                         fill="black")
            self.numbers[(x, y)] = self.canvas.create_text(
                a,
                b,
                text=text,
                fill="white",
                font=("Times", max(-self.t / 2, -20), ""))
        else:
            self.canvas.itemconfig(self.numbers[(x, y)], text=text)
        if (x, y) in self.robots.keys():
            for robot in self.robots[(x, y)]:
                robot.lift()

    def addBeeper(self, x, y):
        if (x, y) in self.beepers.keys() and self.beepers[(x, y)] is infinity:
            return
        flag = (x, y) not in self.beepers.keys() or self.beepers[(x, y)] is 0
        if flag:
            self.beepers[(x, y)] = 1
        else:
            self.beepers[(x, y)] += 1
        text = str(self.beepers[(x, y)])
        a, b = self.t + x * self.t, self.n - (self.t + y * self.t)
        t = self.t / 3
        if flag:
            self.ovals[(x, y)] = self.canvas.create_oval(a - t,
                                                         b - t,
                                                         a + t,
                                                         b + t,
                                                         fill="black")
            self.numbers[(x, y)] = self.canvas.create_text(
                a,
                b,
                text=text,
                fill="white",
                font=("Times", max(-self.t / 2, -20), ""))
        else:
            self.canvas.itemconfig(self.numbers[(x, y)], text=text)
        if (x, y) in self.robots.keys():
            for robot in self.robots[(x, y)]:
                robot.lift()

    def removeBeeper(self, x, y):
        if self.beepers[(x, y)] is infinity:
            return
        self.beepers[(x, y)] -= 1
        flag = self.beepers[(x, y)] is 0
        text = str(self.beepers[(x, y)])
        if flag:
            self.canvas.delete(self.ovals[(x, y)])
            self.canvas.delete(self.numbers[(x, y)])
        else:
            self.canvas.itemconfig(self.numbers[(x, y)], text=text)
        if (x, y) in self.robots.keys():
            for robot in self.robots[(x, y)]:
                robot.lift()

    def addWall(self, x1, y1, x2, y2):
        if not x1 == x2 and not y1 == y2:
            return
        if x1 == x2:
            y1, y2 = min(y1, y2), max(y1, y2)
            if y1 == -1:
                y1 = y2
            for k in range(y1, y2 + 1):
                self.walls.setdefault((x1, k), []).append((x1 + 1, k))
                a, b = self.t + x1 * self.t + self.t / 2, self.n - (
                    self.t + k * self.t) + self.t / 2
                c, d = self.t + x1 * self.t + self.t / 2, self.n - (
                    self.t + k * self.t) - self.t / 2
                self.canvas.create_line(a,
                                        b + 1,
                                        c,
                                        d - 1,
                                        fill="black",
                                        width=3)
        else:
            x1, x2 = min(x1, x2), max(x1, x2)
            if x1 == -1:
                x1 = x2
            for k in range(x1, x2 + 1):
                self.walls.setdefault((k, y1), []).append((k, y1 + 1))
                a, b = self.t + k * self.t - self.t / 2, self.n - (
                    self.t + y1 * self.t) - self.t / 2
                c, d = self.t + k * self.t + self.t / 2, self.n - (
                    self.t + y1 * self.t) - self.t / 2
                self.canvas.create_line(a - 1,
                                        b,
                                        c + 1,
                                        d,
                                        fill="black",
                                        width=3)

    def draw(self, x, y, d, img):
        if self.useImage:
            if img is not None:
                self.canvas.delete(img)
            x, y = self.t + x * self.t, self.n - (self.t + y * self.t)
            photo = self.photos[d / 90]
            img = self.canvas.create_image(x, y, image=photo)
            return img
        else:
            t, angle = self.t / 2, 120
            x, y = self.t + x * self.t, self.n - (self.t + y * self.t)
            x1, y1 = x + 3**0.5 * t / 2 * cos(
                radians(d)), y - 3**0.5 * t / 2 * sin(radians(d))
            x2, y2 = x + t * cos(radians(d + angle)), y - t * sin(
                radians(d + angle))
            x3, y3 = x + t / 4 * cos(radians(d + 180)), y - t / 4 * sin(
                radians(d + 180))
            x4, y4 = x + t * cos(radians(d - angle)), y - t * sin(
                radians(d - angle))
            if img is not None:
                self.canvas.delete(img)
            img = self.canvas.create_polygon(x1,
                                             y1,
                                             x2,
                                             y2,
                                             x3,
                                             y3,
                                             x4,
                                             y4,
                                             fill="blue")
            return img

    def erase(self, img):
        self.canvas.delete(img)

    def recordMove(self, count, x1, y1, x2, y2):
        for robot in self.robots[(x1, y1)]:
            if robot.count == count:
                self.robots[(x1, y1)].remove(robot)
                self.robots.setdefault((x2, y2), []).append(robot)
                break

    def lift(self, img):
        self.canvas.lift(img)

    def refresh(self):
        self.canvas.update()
        self.pause()

    def register(self, x, y, robot):
        self.robots.setdefault((x, y), []).append(robot)

    def remove(self, x, y, robot):
        self.robots[(x, y)].remove(robot)
Example #21
0
def main():   
    ImageFile.MAXBLOCK = 4096*2304 # this is only required for older PIL versions, if PILs output buffer is not large enough. see: https://mail.python.org/pipermail/image-sig/1999-August/000816.html
    
    parser = argparse.ArgumentParser(description='Simple Raytracer by Tilman Ginzel')
    parser.add_argument('-r', '--recursive', help='sets recursive depth, e.g. -r 3 (required)', nargs=1, type=checkPositiveInt, required=True, metavar='')
    parser.add_argument('-s', '--size', help='sets the size, e.g. -s 400 400', nargs=2, default=[400, 400], type=checkPositiveInt, required=False, metavar='')
    parser.add_argument('-v', '--verbose', help='enable live visualization while processing (slower)', required=False, action='store_true')
    parser.add_argument('-m', '--material', help='enable materials', required=False, action='store_true')
    parser.add_argument('-a', '--antialiasing', help='enables 4xSSAA (hence, 4 times slower)', required=False, action='store_true')
    parser.add_argument('-o', '--output', help='saves image to "./saves/"', required=False, action='store_true')
    parser.add_argument('-set', '--setting', help='choose a setting. -set 1 - 3', required=False, nargs=1, default=[1], type=int, metavar='')
    parser.add_argument('-nd', '--no-display', help='this should only be set if the script runs on a server without a $DISPLAY environment variable set!', required=False, action='store_true')
    
    try:
        args = vars(parser.parse_args())
    except:
        parser.print_help()
        sys.exit(1)

    settingId =  args['setting'][0]
    if settingId == 1: # default setting
        setting = DefaultSetting(width=args['size'][0], height=args['size'][1], recursiveDepth=args['recursive'][0], showMaterial=args['material'])
    elif settingId == 2: # space setting
        setting = SpaceSetting(width=args['size'][0], height=args['size'][1], recursiveDepth=args['recursive'][0], showMaterial=args['material'])
    elif settingId == 3: # room setting
        setting = RoomSetting(width=args['size'][0], height=args['size'][1], recursiveDepth=args['recursive'][0], showMaterial=args['material'])
    else: # default setting
        setting = DefaultSetting(width=args['size'][0], height=args['size'][1], recursiveDepth=args['recursive'][0], showMaterial=args['material'])

    # display is used to set whether you want to have a visual feedback in a graphical user interface.
    display = not args['no_display'] # easier to read and you do not have to negotiate it on every call 

    if display:
        window = Tk()
        window._root().wm_title('Raytracer - Tilman Ginzel (173388)')

        if args['verbose']:
            can = Canvas(window, width=setting.WIDTH, height=setting.HEIGHT)
        else:
            frame = Frame(window, width=setting.WIDTH, height=setting.HEIGHT)
            can = Canvas(frame, width=setting.WIDTH, height=setting.HEIGHT)
            frame = Frame(window)
        
        can.pack()

        # photoImage is used to show live changes while processing
        if args['verbose']:
            photoImage = PhotoImage(width=setting.WIDTH, height=setting.HEIGHT)
            can.create_image((setting.WIDTH/2, setting.HEIGHT/2), image=photoImage, state="normal")
    
    # pilImage is used to save the image after processing or if verbose is deactivated
    pilImage = Image.new("RGB", (setting.WIDTH, setting.HEIGHT), (0, 0, 0))
    
    start = time.clock()
    processor = Processor(setting, display=display, ssaa=args['antialiasing'])
    print 'start processing...'
    for pixel in processor.startProcessing():
        if display and args['verbose']:
            photoImage.put("#%02x%02x%02x" %((pixel[1][0], pixel[1][1], pixel[1][2])), (pixel[0][0], pixel[0][1]))
            if pixel[0][1] == setting.HEIGHT-1: # if y == bottom, update canvas
                can.update()
        
        pilImage.putpixel((pixel[0][0], pixel[0][1]), ((pixel[1][0], pixel[1][1], pixel[1][2])))
    
    end = time.clock()
    print 'done'
    print 'duration: %2.2f seconds' %(end-start)
    
    if display and not args['verbose']:
        tkImage = ImageTk.PhotoImage(pilImage)
        label = Label(image=tkImage)
        label.image = tkImage
        label.pack()
        can.pack()
        
    if args['output']:
        saveImage(pilImage, args)
    
    if display:
        window.mainloop()
Example #22
0
class Example(Frame):
    def __init__(self, parent, board):
        Frame.__init__(self, parent)
	self.board = board
        
	self.x0=[-x*10 for x in range(9, 13)]
        self.y0=[9*10  for x in range(9, 13)]

        self.x0=self.x0+[-13*10 for x in range(9, 13)]
        self.y0=self.y0+[x*10  for x in range(9, 13)]

        self.x0=self.x0+[-x*10 for x in [-i for i in range(-13,-8)]]
        self.y0=self.y0+[x*10  for x in [-i for i in range(-13,-8)]]

        #self.x0=self.x0+[-9*10 for x in [-i for i in range(-13,-8)]]
        #self.y0=self.y0+[x*10  for x in [-i for i in range(-13,-8)]]

        #self.x0=[-90 for x in range(70,210)]
        #self.y0=[x*1 for x in [-i for i in range(-200,-60)]]
        #print self.x0
        #self.x0=[5*10 for x in [-i for i in range(-20,-10)]]+self.x0
        #self.y0=[x*10  for x in [-i for i in range(-20,-10)]]+self.y0
        
	#self.x0=[-90+35*math.cos(x*math.pi/180) for x in range(1, 361,4)]
        #self.y0=[-35*math.sin(x*math.pi/180)+90  for x in range(1, 361,4)]
        
        print len(self.x0)
        #self.tet1 = [i for i in range(90)]
        #self.tet2 = [i for i in range(45, 135)]
        self.tet1_con = 0
        self.tet2_con = 0
        
        self.count1 = 0
        self.count2 = 0
        self.sign1 = 1
        self.sign2 = -1
        self.parent = parent
        self.initUI()
        self.parent.after(0, self.animation)
        
    def initUI(self):
        self.parent.title("Arm")        
        self.pack(fill=BOTH, expand=1)
        self.canvas = Canvas(self)
        #self.canvas.create_line(0, 0, 200, 100+self.count, width=arm_width)
        line = Line(self.canvas, points['1'], (width/2, hight/2))
        arms.append(line)
        line = Line(self.canvas, 90-(points['2']-points['1']), line.cor1)
        arms.append(line)
        
        self.canvas.pack(fill=BOTH, expand=1)
        
    def animation(self):
        self.canvas.delete("all")
        #self.canvas.create_line(0, 0, 200, 100+self.count, width=arm_width)
        '''if points['1'] > 90 and self.sign1 == 1:
            self.sign1 = -1
        elif points['1'] == 45 and self.sign1 == -1:
            self.sign1 = 1
        if points['2'] > 135 and self.sign2 == 1:
            self.sign2 = -1
        elif points['2'] == 90 and self.sign2 == -1:
            self.sign2 = 1
            
        points['2']+=self.sign2
        points['1']+=self.sign1'''
        #for i in range(0, len(self.x0), 2):
        #    self.canvas.create_line(width/2+self.x0[i], hight/2-self.y0[i],
        #                            width/2+self.x0[i+1],hight/2-self.y0[i+1], width=5)
	
        #print 800/2+self.x0[0], 300+self.y0[0], 800/2+self.x0[-1],300+self.y0[-1]
        tet1, tet2 = getAngles(self.x0[self.count1], self.y0[self.count1])
        #tet1, tet2 = getAngles(1.5, 0)
        #print (self.x0[self.count1], self.y0[self.count1])
        #print (tet1, tet2)
	print 'tet1:',tet1, 'tet2:', tet2
	#print 'tet2:', tet2
	tet2t = tet2
        tet1 = 180-(tet1)
        tet2 = 180-((tet2)-tet1)+180
        tet1 = tet1
        tet2 = tet2
	temp = 0
	if tet1 > 90:
	    temp = 0
	text = '('+str(tet1-10) +',' + str(180-(tet2-270)-10) + ')'
	print text
	self.canvas.create_text((width/2, hight-100),text=text)
	self.board.Servos.write(9, tet2t-10)
        self.board.Servos.write(11, tet1-10)
        #print (tet1, tet2)
        #line = arms[0].draw(tet1)
        #arms[1].draw(90-(tet2+tet1), line, 'red')
        
        line = arms[0].draw(tet1)
        arms[1].draw(tet2, line, 'red')
        
        self.count1+=self.sign1
        if self.count1 == (len(self.x0)-1) and self.sign1 == 1:
            #self.sign1 = -1
	    self.count1=0
        if self.count1 <= 0 and self.sign1 == -1:
            self.sign1 = 1
            #self.x0=self.x01
            #self.y0=self.y01

        #line = arms[0].draw(points['1'])
        #arms[1].draw(90-(points['2']-points['1']), line)

        self.canvas.update()
        #self.count +=1
        self.parent.after(50, self.animation)
class SurfaceManipulator(Frame):
    r"""
    A translation surface editor in tk.
    """
  
    # STATIC METHODS AND OBJECTS

    current = None
    # boolean variable to remember if the hook was run!
    _clear_hook_was_run = 0

    @staticmethod
    def launch(geometry = "800x700+10+10"):
        r"""Prefered way to gain access to a SurfaceManipulator window."""
        if SurfaceManipulator.current is None:
            SurfaceManipulator._clear_hook()
            root = Tk()
            root.geometry(geometry)
            SurfaceManipulator.current=SurfaceManipulator(root)
        return SurfaceManipulator.current
    
    @staticmethod
    def _window_destroyed(surface_manipulator):
        if SurfaceManipulator.current is surface_manipulator:
            SurfaceManipulator.current = None

    @staticmethod
    def _clear_hook():
        if not SurfaceManipulator._clear_hook_was_run:
            # Hack due to Nathan Dunfield (http://trac.sagemath.org/ticket/15152)
            import IPython.lib.inputhook as ih
            ih.clear_inputhook()
            SurfaceManipulator._clear_hook_was_run = 1

    # NORMAL METHODS


    def __init__(self, parent, surface=None, surfaces=[]):
        r"""
        INPUT:
        - ``surfaces`` -- a list of surfaces that the editor may modify
        - ``surface`` -- surface selected by default
        - ``parent`` -- parent Tk window
        """
        Frame.__init__(self, parent)   
        self._parent = parent
        self.pack(fill="both", expand=1)

        # Run something when closing
        self._parent.wm_protocol ("WM_DELETE_WINDOW", self.exit)

        # Surface currently being manipulated
        self._surface=None
        # List of surfaces in editor
        self._surfaces=[]
        # More variables to initialize
        self._currentActor=None
        # Initialization of GUI
        self._init_menu()
        self._init_gui()
        # Setup surface list
        for s in surfaces:
            self.add_surface(s)
        # Setup initial surface
        if surface is not None:
            self.add_surface(surface)
        self.set_surface(surface)

    def __repr__(self):
        return "Surface manipulator"

    def add_mega_wollmilchsau(self):
        from geometry.mega_wollmilchsau import MegaWollmilchsau
        s = MegaWollmilchsau()
        sm,sb = s.get_bundle()
        self.set_surface(sb)

    def add_octagon(self):
        from geometry.similarity_surface_generators import TranslationSurfaceGenerators
        ss=TranslationSurfaceGenerators.regular_octagon()
        ss.edit()

    def _init_menu(self):
        
        self._menubar = Menu(self._parent)
        menubar=self._menubar
        self._parent.config(menu=menubar)
        
        #new_menu = Menu(menubar, tearoff=0)
        #new_menu.add_command(label="Billiard Table", command=self.on_new_similarity_surface)
        
        file_menu = Menu(menubar, tearoff=0)
        #file_menu.add_cascade(label="New", menu=new_menu)
        file_menu.add_command(label="Octagon", command=self.add_octagon)
        file_menu.add_command(label="MegaWollmilchsau", command=self.add_mega_wollmilchsau)
        file_menu.add_separator()
        file_menu.add_command(label="About", command=self.on_about)
        file_menu.add_command(label="Export PostScript", command=self.on_export)
        file_menu.add_command(label="Exit", command=self.exit, accelerator="Alt+F4")
        menubar.add_cascade(label="File", underline=0, menu=file_menu)

        self._surface_menu = Menu(menubar, tearoff=0)
        self._selected_surface = IntVar()
        self._selected_surface.set(-1)
        menubar.add_cascade(label="Surface", underline=0, menu=self._surface_menu)
        self._surface_menu.add_radiobutton(label="None", 
            command=self.menu_select_surface, variable=self._selected_surface, 
            value=-1)

    def _init_gui(self):
        self._parent.title("FlatSurf Editor")

        self._canvas = Canvas(self, bg="#444", width=300, height=200)
        self._canvas.pack(fill="both", expand=1)
        
        self.bottom_text = Label(self, text="Welcome to FlatSurf.",
            anchor="w")
        self.bottom_text.pack(fill="x", expand=0)

        self.set_actor(None)

    def add_surface(self,newsurface):
        r"""
        Add a surface to the display list for the window.
        Returns the index of the new surface in the surface list.
        """
        if (newsurface==None):
            return -1
        i=0
        for s in self._surfaces:
            if (s==newsurface):
                return i
            i=i+1
        self._surfaces.append(newsurface)
        newsurface.zoom_fit_nice_boundary()
        self._reset_surface_menu()
        return len(self._surfaces)-1

    def exit(self):
        SurfaceManipulator._window_destroyed(self)
        self._parent.destroy()

    def find_bundle(self, surface):
        for surface_bundle in self._surfaces:
            if surface is surface_bundle.get_surface():
                return surface_bundle
        return None

    def get_bundle(self):
        return self._surface

    def get_bundles(self):
        return self._surfaces

    def get_canvas(self):
        return self._canvas

    def get_center(self):
        r"""
        Return the center of the canvas as a pair of integers.
        """
        return ( self.get_width()/2, self.get_height()/2 )

    def get_height(self):
        r"""
        Return the height of the canvas (an integer).
        """
        return self.get_canvas().winfo_height()

    def get_parent(self):
        return self._parent

    def get_surface_bundle(self):
        r"""
        Get the current surface bundle, or None if there is none.
        """
        return self._surface

    def get_width(self):
        r"""
        Return the width of the canvas (an integer).
        """
        return self.get_canvas().winfo_width()

    def menu_select_surface(self):
        r"""
        Called when a surface is selected from a menu.
        """
        i = self._selected_surface.get()
        if i == -1:
            self.set_surface(None)
        else:
            self.set_surface(self._surfaces[i])

    def on_about(self):
        self.set_text("Written by Vincent Delecroix and Pat Hooper.")

    def on_delete_junk(self):
        self._canvas.delete("junk")

    def on_export(self):
        r"""
        Export image as postscript file.
        """
        myFormats = [('PostScript','*.ps')]
        fileName = tkFileDialog.asksaveasfilename(parent=self,
            filetypes=myFormats , title="Save image as...")
        if len(fileName ) > 0:
            self._canvas.update() 
            self._canvas.postscript(file = fileName) 
            self.set_text("Wrote image to "+fileName)

#    def on_new_similarity_surface(self):  
#        s = CreateSimilaritySurfaceBundle(len(self._surfaces),self)
#        if s is not None:
#            i = self.set_surface(s)
#            self.set_text("Created new surface `"+self._surfaces[i].get_name()+"'.")

    def _on_no_surface(self):
        self._canvas.delete("all")

    def _on_zoom(self):
        self.set_actor(ZoomActor(self))

    def _on_zoom_box(self):
        self.set_actor(ZoomBoxActor(self))

    def _on_redraw_all(self):
        if self._surface is not None:
            self._surface.redraw_all()

    def _on_recenter(self):
        self.set_actor(RecenterActor(self))

    def _reset_menus(self):
        r"""
        Reset all menus except the file and surface menu
        """
        # The following loop removes all but the first two menus (File and Surface).
        num = len(self._menubar.children)
        for i in range(num,2,-1):
            self._menubar.delete(i)
        if self._surface!= None:
            self._surface.make_menus(self._menubar)

    def _reset_surface_menu(self):
        r"""
        Reset the surface menu.
        """
        ### This is a hack to get the number of items in the menu: 
        num = self._surface_menu.index(100)+1
        # First we remove everything but the first entry ("None")
        for i in range(num-1,0,-1):
            #print("removing a child2: "+str(i)+" of "+str(num))
            self._surface_menu.delete(i)
        # Add an entry for every surface in the list.
        for i in range( len(self._surfaces) ):
            surface = self._surfaces[i]
            self._surface_menu.add_radiobutton(label=surface.get_name(),
                command=self.menu_select_surface, variable=self._selected_surface,
                value=i)

    def set_text(self, text):
        self.bottom_text["text"]=text

    def set_actor(self, actor):
        r"""
        Set the current mode of user interaction.
        """
        if (actor != self._currentActor):
            if self._currentActor != None:
                self._currentActor.on_deactivate()
            if (actor==None):
                self.set_text("Nothing going on.")
                # Event bindings
                self._canvas.unbind('<Button-1>')
                self._canvas.unbind('<Button-2>')
                self._canvas.unbind('<Button-3>')
                self._canvas.unbind('<Double-Button-1>')
                self._canvas.unbind('<Shift-Button-1>')
                self._canvas.unbind('<Motion>')
                self.unbind('<FocusIn>')
                self.unbind('<FocusOut>')
                #self._canvas.unbind('<ButtonPress-1>')
                self._canvas.unbind('<ButtonRelease-1>')
                self._canvas.unbind('<B1-Motion>')
                self._parent.unbind('<Key>')
                self._parent.unbind('<KeyRelease>')
            else:
                # Event bindings
                self._canvas.bind('<Button-1>', actor.single_left_click)
                self._canvas.bind('<Double-Button-1>', actor.double_left_click)
                self._canvas.bind('<Triple-Button-1>', actor.double_left_click)
                self._canvas.bind('<Button-2>', actor.single_middle_click)
                self._canvas.bind('<Double-Button-2>', actor.double_middle_click)
                self._canvas.bind('<Triple-Button-2>', actor.double_middle_click)
                self._canvas.bind('<Button-3>', actor.single_right_click)
                self._canvas.bind('<Double-Button-3>', actor.double_right_click)
                self._canvas.bind('<Triple-Button-3>', actor.double_right_click)
                self._canvas.bind('<Shift-Button-1>', actor.shift_click)
                self._canvas.bind('<Motion>', actor.mouse_moved)
                #self._canvas.bind('<ButtonPress-1>', actor.left_mouse_pressed)
                self._canvas.bind('<ButtonRelease-1>', actor.left_mouse_released)
                self._canvas.bind('<B1-Motion>',actor.left_dragged)
                self.bind('<FocusIn>', actor.focus_in)
                self.bind('<FocusOut>', actor.focus_out)
                self._parent.bind('<Key>', actor.key_press)
                self._parent.bind('<KeyRelease>', actor.key_release)
                self._currentActor=actor
                self._currentActor.on_activate()

    def set_surface(self,surface_bundle):
        r"""
        Set the current surface to the one given by surface_bundle
        """
        i = self.add_surface(surface_bundle)
        if surface_bundle != self._surface:
            self._canvas.delete("all")
            self._surface=surface_bundle
            self._surface_menu.invoke(i+1)
            if i >= 0:
                self.set_text("Switched to `"+self._surface.get_name()+"'.")
                self._parent.title(self._surface.get_name())
                self._reset_menus()
                # stop the actor (was a bug).
                self.set_actor(None)
                if isinstance(self._surface, EditorRenderer):
                    self._surface.initial_render()
            else:
                self.set_text("No surface selected.")
                self._parent.title("FlatSurf Editor")
                self._reset_menus()
                self.set_actor(None)
        return i

    def surface_renamed(self):
        if self._surface is not None:
            self._parent.title(self._surface.get_name())
            self._reset_surface_menu()
class ConsumablePinball(Domain):

    """
    RL NOTES: Pinball Domain has a ballmodel and environment object. 
    Statespace augmentation will be only done in the _DOMAIN_.


    The goal of this domain is to maneuver a small ball on a plate into a hole.
    The plate may contain obstacles which should be avoided.

    **STATE:**
        The state is given by a 4-dimensional vector, consisting of position and
        velocity of the ball.

    **ACTIONS:**
        There are 5 actions, standing for slanting the  plat in x or y direction
        or a horizontal position
        of the plate.

    **REWARD:**
        Slanting the plate costs -4 reward in addition to -1 reward for each timestep.
        When the ball reaches the hole, the agent receives 10000 units of reward.

    **REFERENCE:**

    .. seealso::
        G.D. Konidaris and A.G. Barto:
        *Skill Discovery in Continuous Reinforcement Learning Domains using Skill Chaining.*
        Advances in Neural Information Processing Systems 22, pages 1015-1023, December 2009.
    """
    #: default location of config files shipped with rlpy
    default_config_dir = os.path.join(
        __rlpy_location__,
        "Domains",
        "PinballConfigs")
    # seems to only have one reasonable goalfn
    def __init__(self, goalArray,
                 noise=.1, episodeCap=1000,
                 configuration=os.path.join(default_config_dir, "pinball_simple_single.cfg"),
                 goalfn=None,
                 rewardFunction=None,
                 encodingFunction=allMarkovEncoding):
        """
        configuration:
            location of the configuration file
        episodeCap:
            maximum length of an episode
        noise:
            with probability noise, a uniformly random action is executed
        """
        self.NOISE = noise
        self.configuration = configuration
        self.screen = None
        self.episodeCap = episodeCap
        self.actions_num = 5
        self.actions = [
            PinballModel.ACC_X,
            PinballModel.DEC_Y,
            PinballModel.DEC_X,
            PinballModel.ACC_Y,
            PinballModel.ACC_NONE]
        self.statespace_limits = np.array(
            [[0.0, 1.0], [0.0, 1.0], [-2.0, 2.0], [-2.0, 2.0]])
        

        self.goalArray0 = np.array(goalArray)
        self.prev_states = []

        # TODO fix initial state

        # statespace augmentation
        self.encodingFunction = encodingFunction

        encodingLimits = []
        for i in range(0,len(self.encodingFunction(self.prev_states))):
            encodingLimits.append([0,1])

        self.statespace_limits = np.vstack((self.statespace_limits, encodingLimits))
        self.state_space_dims = len(self.statespace_limits)
        self.continuous_dims = np.arange(self.state_space_dims)

        self.DimNames = ["Dim: "+str(k) for k in range(0,2+len(self.encodingFunction(self.prev_states)))]

        self.rewardFunction = rewardFunction

        super(ConsumablePinball, self).__init__()
        self.environment = PinballModel(
            self.configuration,
            goalArray,
            goalfn=goalfn,
            random_state=self.random_state)

    def showDomain(self, a):
        if self.screen is None:
            master = Tk()
            master.title('RLPY Pinball')
            self.screen = Canvas(master, width=500.0, height=500.0)
            self.screen.configure(background='LightGray')
            self.screen.pack()
            self.environment_view = PinballView(
                self.screen,
                500.0,
                500.0,
                self.environment)
        self.environment_view.blit()
        self.screen.pack()
        self.screen.update()

    def step(self, a):
        s = self.state[:4]
        [self.environment.ball.position[0],
         self.environment.ball.position[1],
         self.environment.ball.xdot,
         self.environment.ball.ydot] = s
        if self.random_state.random_sample() < self.NOISE:
            # Random Move
            a = self.random_state.choice(self.possibleActions())
        reward = self.environment.take_action(a)
        self.environment._check_bounds()
        state = np.array(self.environment.get_state())

        self.prev_states.append(state[:4])

        state = self.augment_state(state)
        self.state = state

        terminal = self.isTerminal()
        if not terminal and self.rewardFunction:
            sr = self.environment.STEP_PENALTY
            gr = self.environment.END_EPISODE
            reward = reward + self.rewardFunction(self.prev_states, 
                                    self.goalArray(), 
                                    sr, 
                                    gr)

        return reward, state, terminal, self.possibleActions()

    def s0(self): #TODO reset this initial state; move logic into PinballModel
        self.environment.ball.position[0], self.environment.ball.position[
            1] = self.environment.start_pos
        self.environment.ball.xdot, self.environment.ball.ydot = 0.0, 0.0
        self.state = np.array(
            [self.environment.ball.position[0], self.environment.ball.position[1],
             self.environment.ball.xdot, self.environment.ball.ydot])


        self.prev_states = []
        self.state = self.augment_state(self.state)
        self.environment.goalArray = np.array(self.goalArray0)
        return self.state, self.isTerminal(), self.possibleActions()

    def possibleActions(self, s=0):
        return np.array(self.actions)

    def isTerminal(self):
        return self.environment.episode_ended() or len(self.prev_states) == self.episodeCap

    def augment_state(self, state):
        return np.concatenate((state, 
                            self.encodingFunction(self.prev_states)))

    def goalArray(self):
        return self.environment.goalArray
Example #25
0
class DiscreteTAMPViewer(object):
    def __init__(self,
                 rows,
                 cols,
                 width=500,
                 height=250,
                 side=25,
                 block_buffer=10,
                 title='Grid',
                 background='tan',
                 draw_fingers=False):
        assert (rows <= MAX_ROWS)
        assert (cols <= MAX_COLS)

        tk = Tk()
        tk.withdraw()
        top = Toplevel(tk)
        top.wm_title(title)
        top.protocol('WM_DELETE_WINDOW', top.destroy)

        self.width = width
        self.height = height
        self.rows = rows
        self.cols = cols
        self.canvas = Canvas(top,
                             width=self.width,
                             height=self.height,
                             background=background)
        self.canvas.pack()
        self.side = side
        self.block_buffer = block_buffer
        self.draw_fingers = draw_fingers
        self.cells = {}
        self.robot = []
        self.draw_environment()

    def transform_r(self, r):
        return self.table_y1 + r * (self.side + 2 * self.block_buffer
                                    ) + 2 * self.block_buffer + self.side / 2

    def transform_c(self, c):
        # assert r >= 0 and r < self.width
        return self.table_x1 + c * (self.side + 2 * self.block_buffer
                                    ) + 2 * self.block_buffer + self.side / 2

    def draw_environment(self, table_color='lightgrey', bin_color='grey'):
        table_width = self.cols * (
            self.side + 2 * self.block_buffer) + 2 * self.block_buffer
        table_height = self.rows * (
            self.side + 2 * self.block_buffer) + 2 * self.block_buffer

        border_buffer = 50
        #self.table_x1 = border_buffer
        self.table_y1 = self.height - table_height - border_buffer
        self.table_x1 = self.width / 2 - table_width / 2
        #self.table_y1 = self.height/2-table_height/2

        bin_width = 20
        self.environment = [
            self.canvas.create_rectangle(self.table_x1,
                                         self.table_y1,
                                         self.table_x1 + table_width,
                                         self.table_y1 + table_height,
                                         fill=table_color,
                                         outline='black',
                                         width=2),
            self.canvas.create_rectangle(self.table_x1 - bin_width,
                                         self.table_y1,
                                         self.table_x1,
                                         self.table_y1 + table_height,
                                         fill=bin_color,
                                         outline='black',
                                         width=2),
            self.canvas.create_rectangle(self.table_x1 + table_width,
                                         self.table_y1,
                                         self.table_x1 + table_width +
                                         bin_width,
                                         self.table_y1 + table_height,
                                         fill=bin_color,
                                         outline='black',
                                         width=2),
            self.canvas.create_rectangle(self.table_x1,
                                         self.table_y1 + table_height,
                                         self.table_x1 + table_width,
                                         self.table_y1 + table_height +
                                         bin_width,
                                         fill=bin_color,
                                         outline='black',
                                         width=2),
            self.canvas.create_rectangle(
                self.table_x1 - bin_width,
                self.table_y1 + table_height,
                self.table_x1 + table_width + bin_width,
                self.table_y1 + table_height + bin_width,
                fill=bin_color,
                outline='black',
                width=2),
        ]

        pose_radius = 2
        for r in range(self.rows):
            for c in range(self.cols):
                x = self.transform_c(c)
                y = self.transform_r(r)
                self.environment.append(
                    self.canvas.create_oval(x - pose_radius,
                                            y - pose_radius,
                                            x + pose_radius,
                                            y + pose_radius,
                                            fill='black'))

    def draw_robot(self, r, c, color='yellow'):
        # TODO - could also visualize as top grasps instead of side grasps
        grasp_buffer = 3  # 0 | 3 | 5
        finger_length = self.side + grasp_buffer  # + self.block_buffer
        finger_width = 10
        gripper_length = 20
        if self.draw_fingers:
            gripper_width = self.side + 2 * self.block_buffer + finger_width
        else:
            gripper_width = self.side
        stem_length = 50
        stem_width = 20

        x = self.transform_c(c)
        y = self.transform_r(
            r) - self.side / 2 - gripper_length / 2 - grasp_buffer
        finger_x = gripper_width / 2 - finger_width / 2
        self.robot = [
            self.canvas.create_rectangle(x - stem_width / 2.,
                                         y - stem_length,
                                         x + stem_width / 2.,
                                         y,
                                         fill=color,
                                         outline='black',
                                         width=2),
            self.canvas.create_rectangle(x - gripper_width / 2.,
                                         y - gripper_length / 2.,
                                         x + gripper_width / 2.,
                                         y + gripper_length / 2.,
                                         fill=color,
                                         outline='black',
                                         width=2),
        ]
        if self.draw_fingers:
            self.robot += [
                self.canvas.create_rectangle(x + finger_x - finger_width / 2.,
                                             y,
                                             x + finger_x + finger_width / 2.,
                                             y + finger_length,
                                             fill=color,
                                             outline='black',
                                             width=2),
                self.canvas.create_rectangle(x - finger_x - finger_width / 2.,
                                             y,
                                             x - finger_x + finger_width / 2.,
                                             y + finger_length,
                                             fill=color,
                                             outline='black',
                                             width=2),
            ]
        self.canvas.update()

    def draw_block(self, r, c, name='', color='red'):
        x = self.transform_c(c)
        y = self.transform_r(r)
        self.cells[(x, y)] = [
            self.canvas.create_rectangle(x - self.side / 2.,
                                         y - self.side / 2.,
                                         x + self.side / 2.,
                                         y + self.side / 2.,
                                         fill=color,
                                         outline='black',
                                         width=2),
            self.canvas.create_text(x, y, text=name),
        ]

    # def delete(self, (x, y)):
    #  if (x, y) in self.cells:
    #    self.canvas.delete(self.cells[(x, y)])

    def clear(self):
        self.canvas.delete('all')

    def save(self, filename):
        self.canvas.postscript(file='%s.ps' % filename, colormode='color')
        from PIL import ImageGrab
        ImageGrab.grab((0, 0, self.width, self.height)).save(filename + '.jpg')
Example #26
0
class DisplayQuadTree(object):
    def __init__(self, width, height, scale=1, show_grid=False):
        self._scale = scale
        self._grid_width = 1 if show_grid else 0
        self.size = (width*scale, height*scale)
        self._is_animate = False
        self._anime_time = 0.1

        self._tk_root = Tk()
        self._canvas = Canvas(self._tk_root, width=self.size[0], height=self.size[1])
        self._canvas.pack()

        self._button = Button(self._tk_root, text='Finished', command=self._stop_animate)
        self._button.configure(width=10, relief=FLAT)
        self._canvas.create_window(10, 10, anchor=NW, window=self._button)

        self._labelstr = StringVar()
        self._labelstr.set('0%')
        self._label = Label(self._tk_root, textvariable=self._labelstr)
        self._canvas.create_window(self.size[0] - 10,
                                   self.size[1] - 10,
                                   anchor=SE,
                                   window=self._label)

    def static(self, qtree):
        """ Draw the final output.
        """
        if qtree is None:
            return

        stack = [qtree]
        while len(stack):
            qnode = stack.pop()
            if qnode.children:
                for child in qnode.children:
                    stack.append(child)
            else:
                colour = '#{0:02x}{1:02x}{2:02x}'.format(*qnode.ave_color)
                self._canvas.create_rectangle(qnode.x * self._scale,
                                              qnode.y * self._scale,
                                              (qnode.x + qnode.width) * self._scale,
                                              (qnode.y + qnode.height) * self._scale,
                                              width=self._grid_width,
                                              outline='grey',
                                              fill=colour)
        self._labelstr.set('100%')

    def _stop_animate(self):
        """ Stop the animation. Called by the "Stop" button
        """
        self._is_animate = False
        self._button.configure(text='Finished')

    def animate(self, qtree):
        """ Animate the development of the quadtree as it was generated.
        Press the "Stop" to stop the animation
        """
        if qtree is None:
            return

        self._is_animate = True
        self._button.configure(text='Stop')

        q = Queue.Queue()
        q.put(qtree)
        count, max_qtrees = 0.0, qtree.sq_num
        while not q.empty() and self._is_animate:
            qnode = q.get()

            if qnode.children:
                for child in qnode.children:
                    q.put(child)

            count += 1.0
            colour = '#{0:02x}{1:02x}{2:02x}'.format(*qnode.ave_color)
            self._canvas.create_rectangle(qnode.x * self._scale,
                                          qnode.y * self._scale,
                                          (qnode.x + qnode.width) * self._scale,
                                          (qnode.y + qnode.height) * self._scale,
                                          width=self._grid_width,
                                          outline='grey',
                                          fill=colour)
            self._canvas.update()
            self._labelstr.set('{}%'.format(int(count/max_qtrees * 100)))
            time.sleep(self._anime_time)

        self._stop_animate()

    def show(self):
        """ Call this to start the display.
        """
        self._tk_root.mainloop()
Example #27
0
class Pinball(Domain):
    """
    The goal of this domain is to maneuver a small ball on a plate into a hole.
    The plate may contain obstacles which should be avoided.

    **STATE:**
        The state is given by a 4-dimensional vector, consisting of position and
        velocity of the ball.

    **ACTIONS:**
        There are 5 actions, standing for slanting the  plat in x or y direction
        or a horizontal position
        of the plate.

    **REWARD:**
        Slanting the plate costs -4 reward in addition to -1 reward for each timestep.
        When the ball reaches the hole, the agent receives 10000 units of reward.

    **REFERENCE:**

    .. seealso::
        G.D. Konidaris and A.G. Barto:
        *Skill Discovery in Continuous Reinforcement Learning Domains using Skill Chaining.*
        Advances in Neural Information Processing Systems 22, pages 1015-1023, December 2009.
    """
    #: default location of config files shipped with rlpy
    default_config_dir = os.path.join(__rlpy_location__, "Domains",
                                      "PinballConfigs")

    def __init__(self,
                 noise=.1,
                 episodeCap=1000,
                 configuration=os.path.join(default_config_dir,
                                            "pinball_simple_single.cfg")):
        """
        configuration:
            location of the configuration file
        episodeCap:
            maximum length of an episode
        noise:
            with probability noise, a uniformly random action is executed
        """
        self.NOISE = noise
        self.configuration = configuration
        self.screen = None
        self.episodeCap = episodeCap
        self.actions_num = 5
        self.actions = [
            PinballModel.ACC_X, PinballModel.DEC_Y, PinballModel.DEC_X,
            PinballModel.ACC_Y, PinballModel.ACC_NONE
        ]
        self.statespace_limits = np.array([[0.0, 1.0], [0.0, 1.0], [-2.0, 2.0],
                                           [-2.0, 2.0]])
        self.continuous_dims = [4]
        super(Pinball, self).__init__()
        self.environment = PinballModel(self.configuration,
                                        random_state=self.random_state)

    def showDomain(self, a):
        if self.screen is None:
            master = Tk()
            master.title('RLPY Pinball')
            self.screen = Canvas(master, width=500.0, height=500.0)
            self.screen.configure(background='LightGray')
            self.screen.pack()
            self.environment_view = PinballView(self.screen, 500.0, 500.0,
                                                self.environment)
        self.environment_view.blit()
        self.screen.pack()
        self.screen.update()

    def step(self, a):
        s = self.state
        [
            self.environment.ball.position[0],
            self.environment.ball.position[1], self.environment.ball.xdot,
            self.environment.ball.ydot
        ] = s
        if self.random_state.random_sample() < self.NOISE:
            # Random Move
            a = self.random_state.choice(self.possibleActions())
        reward = self.environment.take_action(a)
        self.environment._check_bounds()
        state = np.array(self.environment.get_state())
        self.state = state.copy()
        return reward, state, self.isTerminal(), self.possibleActions()

    def s0(self):
        self.environment.ball.position[0], self.environment.ball.position[
            1] = self.environment.start_pos
        self.environment.ball.xdot, self.environment.ball.ydot = 0.0, 0.0
        self.state = np.array([
            self.environment.ball.position[0],
            self.environment.ball.position[1], self.environment.ball.xdot,
            self.environment.ball.ydot
        ])
        return self.state, self.isTerminal(), self.possibleActions()

    def possibleActions(self, s=0):
        return np.array(self.actions)

    def isTerminal(self):
        return self.environment.episode_ended()
Example #28
0
class SimVis(object):
    """Defines the visualisation aspects of the program. Draws and updates all visuals."""

    SNAPSHOT_ENABLED = ENABLED = DEBUG_ID_ENABLED = HIGHLIGHT_COLLISIONS = SQUARESIZE = SNAPSHOT_HEIGHT = SNAPSHOT_WIDTH = None

    def __init__(self, width, height, squareSize):

        self.simRootPath = ""
        self.setSimRootPath(SimUtils.getRootPath())
        self.currentFolder = self.simRootPath
        self.simRun = 0;
        self.simRunFolder = ""
        self.__initImageFolder()
        self.__updateSimRunFolder()

        self.width = width
        self.height = height

        self.root = Tk()
        self.squareSize = squareSize
        self.CANVAS_WIDTH = (self.width * squareSize)
        self.CANVAS_HEIGHT = (self.height * squareSize) + CANVAS_TEXT_PADDING

        self.canvas = Canvas(self.root, width=self.CANVAS_WIDTH, height=self.CANVAS_HEIGHT, bg='white')
        self.canvas.pack()

        self.timeFont = ImageFont.truetype("Arialbd.ttf", CANVAS_TEXT_SIZE)
        self.time = 0.0
        self.timeMeasurement = "timesteps"
        self.timeStepsInMeasurement = 1
        self.timeText = None
        self.__updateTimeText()

        self.root.minsize(self.CANVAS_WIDTH, self.CANVAS_HEIGHT)
        self.root.geometry(str(self.CANVAS_WIDTH)+"x"+str(self.CANVAS_HEIGHT))

        self.world = None

        self.white = (255, 255, 255)
        # PIL image can be saved as .png .jpg .gif or .bmp file (among others)
        self.filenameJPG = None
        self.filename = None
        # PIL create an empty image and draw object to draw on
        # memory only, not visible
        self.image = Image.new("RGB", (self.CANVAS_WIDTH, self.CANVAS_HEIGHT), self.white)
        self.draw = ImageDraw.Draw(self.image)

    def __updateSimRunFolder(self) :
        if self.simRun > 0 :
            self.simRunFolder = SIM_RUN_DIR_PREFIX + str(self.simRun) + "/"
        else :
            self.simRunFolder = ""

        imageFolder = self.__getImageFolder()
        SimUtils.initFolder(folderName=imageFolder)

    def __updateTimeText(self) :
        self.timeText = TIME_TEXT_PREFIX + str(self.time) + " " + self.timeMeasurement

    def setTimeStepsInMeasurement(self, val):
        self.timeStepsInMeasurement = val
        self.__updateTimeText()

    def setTimeMeasurement(self, measurement):
        self.timeMeasurement = measurement
        self.__updateTimeText()

    def init(self, world, run=0) :
        self.canvas.delete("all")
        self.world = world
        self.setSimRun(run)

    def display(self):
        self.root.mainloop() # this method will hang until you close the TK (window), but is essential to display the window and canvas

    # Draw a 10 X 10 sqaure on the canvas with no border
    def drawSquare(self, x, y, color):
        if self.world[x][y].drawColor == color :
            return
        self.world[x][y].drawColor = color

        xPos = x * self.squareSize
        yPos = y * self.squareSize

        self.draw.rectangle([xPos , yPos, xPos + self.squareSize - 1, yPos + self.squareSize - 1], fill=color)

    # TODO: Remove this in final version?
    def __focusDebugDraw(self, x, y, id, colour):
        self.draw.text((x, y), str(id), fill=colour)

    #Draw an Epithelial Cell, the colour is set depandant on its state     
    def drawEpiCell(self, eCell):
        x = eCell.location.x
        y = eCell.location.y

        color = None

        if(eCell.State == EpithelialStates.HEALTHY) :
            color = "#FCFEF5"

        elif(eCell.State == EpithelialStates.CONTAINING):
            color = "#F9D423"

        elif(eCell.State == EpithelialStates.EXPRESSING):
            color = "#FC913A"

        elif(eCell.State == EpithelialStates.INFECTIOUS):
            color = "#C21A01"

        elif(eCell.State == EpithelialStates.NATURAL_DEATH or eCell.State == EpithelialStates.INFECTION_DEATH):
            color = "#000000"
        else:
             raise AttributeError('Illegal Epithelial Cell State')

        self.drawSquare(x, y, color)

        # TODO: Remove this in final version?
        if SimVis.DEBUG_ID_ENABLED:
            if eCell.focusId != None:
                if eCell.State == EpithelialStates.INFECTION_DEATH:
                    self.__focusDebugDraw(x * self.squareSize, y * self.squareSize, eCell.focusId, "#FFFFFF")
                else:
                    self.__focusDebugDraw(x * self.squareSize, y * self.squareSize, eCell.focusId, "#000000")
            
    def drawSimWorld(self, save, timesteps):
        if self.width == 0 and self.height == 0 :
            return

        #self.image = Image.new("RGB", (self.CANVAS_WIDTH, self.CANVAS_HEIGHT), self.white)
        #self.draw = ImageDraw.Draw(self.image)

        for x in xrange(0, self.width) :
            for y in xrange(0, self.height) :
                site = self.world[x][y]

                drawImmCell = False
                immCells = site.getImmCells()
                if len(immCells) > 0 :
                    mature = False
                    for immCell in immCells :
                        if immCell.State == ImmuneStates.MATURE :
                            self.drawImmCell(immCell)
                            drawImmCell = True
                            mature = True
                            break
                    if mature == False :
                        self.drawImmCell(immCell)
                        drawImmCell = True


                if drawImmCell == False :
                    eCell = site.getECell()
                    self.drawEpiCell(eCell)

        self.time = round(timesteps / self.timeStepsInMeasurement, 1)
        self.__updateTimeText()

        w, h = self.draw.textsize(self.timeText, self.timeFont)
        x = (self.CANVAS_WIDTH / 2) - (w/2)
        y = (self.CANVAS_HEIGHT - (CANVAS_TEXT_PADDING/2) - (h/2))
        self.draw.text((x, y), self.timeText, (0,0,0), font=self.timeFont)

        self.__savePILImageToFile(save)
        self.__updateCanvas(save)

        self.draw.rectangle([0, self.CANVAS_HEIGHT - CANVAS_TEXT_PADDING, 
                             self.CANVAS_WIDTH, self.CANVAS_HEIGHT], fill="white")

        #del self.draw
        #del self.image

    def drawImmCell(self, immCell):

        x = immCell.location.x
        y = immCell.location.y

        color = None

        if(immCell.State == ImmuneStates.VIRGIN) :
            color = "#C0D860"

        elif(immCell.State == ImmuneStates.MATURE):
            color = "#789048"

        else:
            raise AttributeError('Illegal Immune Cell State')

        self.drawSquare(x, y, color)

    def drawCollision(self, cell):
        self.drawSquare(cell.location.x, cell.location.y, "#5078F0")
        if SimVis.DEBUG_ID_ENABLED:
            self.__focusDebugDraw(cell.location.x * self.squareSize, cell.location.y * self.squareSize, str(cell.focusId), "#000000")

    def __initImageFolder(self):
        SimUtils.initFolder(folderParent=self.simRootPath, folderName=IMAGES_DIR_NAME, overwrite=True)
        SimUtils.initFolderPath(folderPath=self.__getTempFolder(), overwrite=True)

    def __getImageFolder(self):
        return self.simRootPath + IMAGES_DIR_NAME + self.simRunFolder

    def __getTempFolder(self):
        return self.simRootPath + IMAGES_DIR_NAME + TEMP_DIR_NAME

    def __savePILImageToFile(self, save):
        imageFolder = self.__getImageFolder()
        tempFolder = self.__getTempFolder()

        if save :
            self.filenameJPG = imageFolder + self.__getImageFileName()
            self.image.save(self.filenameJPG)
            
        self.filename = tempFolder + IMAGE_NAME_PREFIX + TEMP_IMAGE_EXTENSION
        self.image.save(self.filename)

    def __getImageFileName(self) :
        return IMAGE_NAME_PREFIX + "_" + str(int(self.time)) + self.timeMeasurement + "_" + str(self.height) + "x" + str(self.width) + IMAGE_EXTENSION

    def __updateCanvas(self, save):
        # draw PIL image to tkinter canvas
        self.canvas.background = PhotoImage(file=self.filename)
        self.canvas.create_image(2, 2, image=self.canvas.background, anchor="nw")

        self.canvas.update()

    def setSimRootPath(self, folderPath):
        if folderPath == "" :
            folderPath = "."
        if folderPath[len(folderPath) - 1] != '/' :
            folderPath += '/'
        self.simPathFolder = folderPath

    def setSimRun(self, run):
        self.simRun = run;
        self.__updateSimRunFolder();

    @staticmethod
    def Configure(settings):
        SimVis.ENABLED              = settings["bIsEnabled"]
        SimVis.SNAPSHOT_ENABLED     = settings["bSnapshotEnabled"]
        SimVis.SNAPSHOT_HEIGHT      = settings["iSnapshotHeight"]
        SimVis.SNAPSHOT_WIDTH       = settings["iSnapshotWidth"]
        SimVis.SQUARESIZE           = settings["iSquareSize"]
        SimVis.DEBUG_ID_ENABLED     = settings["bDebugFocusIdEnabled"]
        SimVis.HIGHLIGHT_COLLISIONS = settings["bHighlightCollisions"]
Example #29
0
class at_graph(Frame):

    def __init__(self, parent):
        Frame.__init__(self, parent)
        self.parent = parent
        self.u = utils('atoutput.pkl')
        self.km = dict()
        self.price = dict()
        self.km[0] = (min(self.u.all_km), max(self.u.all_km))
        self.price[0] = (min(self.u.all_price), max(self.u.all_price))
        self.zoom_level = 0
        try:
            self.parent.title("Auto trader results")
            self.is_standalone = True
        except:
            self.is_standalone = False
        self.style = Style()
        self.style.theme_use("classic")
        # Assume the parent is the root widget; make the frame take up the
        # entire widget size.
        print self.is_standalone
        if self.is_standalone:
            self.w, self.h = map(int,
                self.parent.geometry().split('+')[0].split('x'))
            self.w, self.h = 800, 800
        else:
            self.w, self.h = 600, 600
        self.c = None
        # Are they hovering over a data point?
        self.is_hovering = False
        # Filter the description strings: lower and whiten any non-matching
        # data point.
        self.filter = ''
        self.re = list()
        self.replot()

    def replot(self, zlfrac=None):
        """Replot the graph. If zlfrac is not None, then it should be a
        fractional value between 0 and 1; this is used to do smooth zooming,
        which doesn't plot the axes (it only redraws the car points)."""
        if self.c is not None:
            self.c.destroy()
        self.c = Canvas(self, height=self.h, width=self.w, bd=1, bg='#f3f5f9')
        self.c.grid(sticky=S, pady=1, padx=1)
        zl = self.zoom_level
        if zlfrac is not None:
            z1l, z1h = self.zoom_price_start
            z2l, z2h = self.zoom_price_end
            price_low = z1l + (z2l - z1l) * zlfrac
            price_high = z1h + (z2h - z1h) * zlfrac
            z1l, z1h = self.zoom_km_start
            z2l, z2h = self.zoom_km_end
            km_low = z1l + (z2l - z1l) * zlfrac
            km_high = z1h + (z2h - z1h) * zlfrac
            self.axis((price_low, price_high), 'y', draw=False)
            self.axis((km_low, km_high), 'x', draw=False)
            self.car_points(draw=False)
        else:
            self.axis(self.price[zl], 'y')
            self.axis(self.km[zl], 'x')
            self.car_points()
        self.pack(fill=BOTH, expand=1)

    def xyp(self, x, y):
        "Given x in km and y in $, return canvas position (xp, yp)."
        xp = int(math.floor((1.0 * x - self.x1) / (self.x2 - self.x1) \
            * (self.xp2 - self.xp1) + self.xp1 + 0.5))
        yp = int(math.floor((1.0 * y - self.y1) / (self.y2 - self.y1) \
            * (self.yp2 - self.yp1) + self.yp1 + 0.5))
        return (xp, yp)

    def axis(self, arange, ax, draw=True):
        "Add an axis ax='x' or 'y', with arange=(min, max) values."
        if draw:
            a1, a2, ast = self.u.axis(*arange)
        else:
            a1, a2 = arange
            ast = (a2 - a1) * 0.2
        nt = int(math.floor((a2 - a1) / ast + 0.5)) + 1
        st_offset = 50
        # Remember the min and max axis values, along with the canvas points
        # that correspond to each location (xp1 and xp2). This allows us to
        # calculate where on the canvas a particular (x, y) value falls.
        if ax == 'x':
            self.x1, self.x2 = a1, a2
            self.xp1, self.xp2 = st_offset, self.w - st_offset
            self.xtick = [a1 + i * ast for i in range(nt)]
            # Remember where the midpoint of the axis is, relative to canvas.
            self.xmid = (self.xp1 + self.xp2) / 2
        else:
            self.y1, self.y2 = a1, a2
            self.yp1, self.yp2 = self.h - st_offset, st_offset
            self.ytick = [a1 + i * ast for i in range(nt)]
            # Remember where the midpoint of the axis is, relative to canvas.
            self.ymid = (self.yp1 + self.yp2) / 2
        # Figure out tick labels.
        atick = ['%g' % ((a1 + i * ast) / 1000) for i in range(nt)]
        # Figure out maximum decimal places on all tick labels, and ensure
        # they all have that many decimal places.
        max_dec = max(map(lambda x: 0 if '.' not in x
            else len(x.split('.')[1]), atick))
        if max_dec > 0:
            atick = map(lambda x: x + '.' + '0'*max_dec if '.' not in x
                else x + '0'*(max_dec - len(x.split('.')[1])), atick)
        yst, xst = self.h - st_offset, st_offset
        # Draw axis line proper, and axis label.
        if draw:
            if ax == 'x':
                self.c.create_line(xst, yst, self.w - st_offset, yst)
                xp = (xst + self.w - st_offset) / 2
                self.c.create_text(xp, yst + 30, text='Mileage (km x 1000)')
            else:
                self.c.create_line(xst, yst, xst, st_offset)
                self.c.create_text(xst, st_offset - 30, text='Price')
                self.c.create_text(xst, st_offset - 15, text='($000)')
        tick_anchor = [N, E][ax == 'y']
        tick_x, tick_y = xst, yst
        tick_step = ([self.w, self.h][ax == 'y'] - st_offset * 2 * 1.0) / \
            (nt - 1)
        label_offset = 3
        for i1, tick in enumerate(atick):
            x_of, y_of = -label_offset, label_offset
            if ax == 'y':
                y_of = int(-i1 * tick_step)
            else:
                x_of = int(i1 * tick_step)
            if draw:
                self.c.create_text(tick_x + x_of, tick_y + y_of,
                    text=tick, anchor=tick_anchor)
            x_mini, y_mini = 0, 0
            x_maxi, y_maxi = 0, 0
            if ax == 'y':
                x_of += label_offset
                x_mini, x_maxi = 8, self.w - st_offset * 2
                # Remember what y coord this grid line is at.
                if i1 == 0:
                    self.y_grid = []
                self.y_grid.append(tick_y + y_of)
            else:
                y_of -= label_offset
                y_mini, y_maxi = -8, st_offset * 2 - self.h
                # Remember what x coord this grid line is at.
                if i1 == 0:
                    self.x_grid = []
                self.x_grid.append(tick_x + x_of)
            if draw:
                # Draw the little solid tick, next to the axis.
                self.c.create_line(tick_x + x_of, tick_y + y_of,
                    tick_x + x_of + x_mini, tick_y + y_of + y_mini)
                # Draw a dashed grid line, across the entire graph.
                self.c.create_line(tick_x + x_of, tick_y + y_of,
                    tick_x + x_of + x_maxi, tick_y + y_of + y_maxi,
                    dash=(1, 3))

    def car_points(self, draw=True):
        "Plot the cars themselves."
        # 199 215 151 151 199 224 230 162 157 250 224 167 178 165 192 249 200 216 204 204 204 191 173 158
        color_order = ['#c7d797', '#97c7e0', '#e6a29d', '#fae0a7', '#b2a5c0',
            '#f9c8d8', '#bfad9e', '#cccccc']
        #color_order = ['#98df8a', '#dbdb8d', '#aec7e8', '#c9acd4', '#f7b6d2',
        #    '#ffbb80', '#dc9b8d', '#e9ab17', '#dddddd']
        # Those colors above aren't saturated enough. Saturate them more.
        color_order = map(lambda x: resaturate(x, -80), color_order)
        # Change color depending on year.
        cy = dict()
        for i1, year in enumerate(reversed(sorted(set(self.u.all_year)))):
            cy[year] = color_order[-1]
            if i1 < len(color_order):
                cy[year] = color_order[i1]
        i1 = -1
        # Tuples of (index into self.u.all_* arrays, x position, y position).
        self.ov_dict = dict()
        if draw:
            self.c.focus_set()
            self.c.bind('<Button-1>', func=self.zoom)
            self.c.bind('<Button-2>', func=self.unzoom)
            self.c.bind('<Left>', func=self.left_key)
            self.c.bind('<Right>', func=self.right_key)
            self.c.bind('<Up>', func=self.up_key)
            self.c.bind('<Down>', func=self.down_key)
        legend = set()
        osz = 3 + self.zoom_level * 1
        # Total vehicle count, and vehicles which pass the filter count.
        self.vcount = self.fcount = 0
        for year, km, price in zip(self.u.all_year, self.u.all_km,
            self.u.all_price):
            x, y = self.xyp(km, price)
            i1 += 1
            if x < self.x_grid[0] or x > self.x_grid[-1] or \
                y > self.y_grid[0] or y < self.y_grid[-1]:
                continue
            self.vcount += 1
            legend.add((year, cy[year]))
            filtered = False
            if not re.search(self.filter, self.u.all_descr[i1], re.I):
                filtered = True
            # If a data point is filtered out, make its outline reflect its
            # model year, and fill it with white.
            #
            # Else, make its outline and fill color reflect the model year, and
            # upon mouseover, make it entirely red.
            ov = self.c.create_oval(x-osz, y-osz, x+osz, y+osz,
                outline=cy[year],
                activeoutline=['red', cy[year]][filtered],
                fill=[cy[year], 'white'][filtered],
                activefill=['red', 'white'][filtered],
            )
            self.ov_dict[ov] = (i1, x, y, cy[year], filtered)
            # If a data point is filtered out, mousing over it does nothing,
            # and also, lower it behind everything else.
            if filtered:
                self.c.lower(ov)
            else:
                self.fcount += 1
                if draw:
                    use_tag = 'Tag %d' % i1
                    self.c.addtag_withtag(use_tag, ov)
                    self.c.tag_bind(use_tag, sequence='<Enter>',
                        func=self.mouseover)
                    self.c.tag_bind(use_tag, sequence='<Leave>',
                        func=self.mouseoff)
                    self.c.tag_bind(use_tag, sequence='<Button-1>',
                        func=self.select)
        if draw:
            # OK, add a legend for every year that's displayed.
            i1 = 0
            for yr, color in reversed(sorted(legend)):
                xp, yp = self.x_grid[-1] + 10, self.y_grid[-1] + 15 * i1
                self.c.create_oval(xp-osz, yp-osz, xp+osz, yp+osz,
                    outline=color, fill=color)
                self.c.create_text(xp + 8, yp, text=str(yr), anchor=W)
                i1 += 1
            # And, add a title.
            tistr = 'Vehicle count: %d' % self.vcount
            if self.fcount != self.vcount:
                tistr = 'Filtered vehicle count: %d' % self.fcount
            xp = (self.x_grid[0] + self.x_grid[-1]) / 2
            yp = self.y_grid[-1] - 30
            self.c.create_text(xp, yp, text=tistr, font=('Helvetica', '16'))
            zstr1 = 'Click on a blank graph location to zoom in'
            zstr2 = 'Right click to zoom out'
            if self.zoom_level == 0:
                zstr = zstr1
            elif self.zoom_level == 2:
                zstr = zstr2
            else:
                zstr = zstr1 + ', or r' + zstr2[1:]
            self.c.create_text(xp, yp + 16, text=zstr, font=('Helvetica', '14'))

    def mouseover(self, event):
        oval = event.widget.find_closest(event.x, event.y)[0]
        # XXX Sometimes, the closest widget is an axis grid line, not an oval.
        # Need to handle this correctly eventually.
        if oval not in self.ov_dict:
            return
        self.is_hovering = True
        ind, x, y, color, filtered = self.ov_dict[oval]
        # Figure out how high the box needs to be by creating the text off-
        # graph, then getting its bbox and deleting it.
        w = 200
        de_text = self.u.all_descr[ind]
        deobj = self.c.create_text(self.w + 3, self.h + 3, text=de_text,
            anchor=N+W, width=w-6, font=('Helvetica', '14'))
        bbox = self.c.bbox(deobj)
        self.c.delete(deobj)
        h = 18 + bbox[3] - bbox[1]
        border = 5
        if x > self.xmid:
            x -= (w + border)
        else:
            x += border
        if y > self.ymid:
            y -= (h + border)
        else:
            y += border
        self.re = list()
        self.re.append(self.c.create_rectangle(x, y, x + w, y + h,
            fill=resaturate(color, 50)))
        pr_text = '$%s' % self.u.commafy(self.u.all_price[ind])
        self.re.append(self.c.create_text(x + 3, y + 3, text=pr_text,
            anchor=N+W, font=('Helvetica', '10')))
        km_text = '%skm' % self.u.commafy(self.u.all_km[ind])
        self.re.append(self.c.create_text(x + w - 3, y + 3, text=km_text,
            anchor=N+E, font=('Helvetica', '10')))
        wh_text = self.u.all_wherestr[ind]
        if wh_text[0].isdigit():
            wh_text += ' away'
        self.re.append(self.c.create_text(x + w/2, y + 3, text=wh_text,
            anchor=N, font=('Helvetica', '10')))
        self.re.append(self.c.create_text(x + 3, y + 16, text=de_text,
            anchor=N+W, width=w-6, font=('Helvetica', '14')))

    def set_filter(self, st):
        "Given a string 'st', filter ovals whose description doesn't match."
        self.filter = st
        self.replot()

    def mouseoff(self, event):
        "Code for mousing off a data point."
        # The tooptip rectangle and all its sub-objects need to be destroyed.
        map(self.c.delete, self.re)
        # Also, need to note that we're no longer over an oval -- that way,
        # Button-1 events will cause a zoom, rather than launching a web page.
        self.is_hovering = False

    def _zoom_animation(self):
        import time
        from math import tanh
        scale = 5
        for i1 in range(-scale, scale+1):
            self.replot(zlfrac=0.5 + 0.5*tanh(i1*2.0/scale)/tanh(2.0))
            self.c.update()

    def zoom(self, event):
        # Only zoom in if we're actually within the graph boundaries.
        if event.x <= self.x_grid[0] or event.x > self.x_grid[-1]:
            return
        if event.y >= self.y_grid[0] or event.y < self.y_grid[-1]:
            return
        # Don't zoom if we're hovering over a data point: let the web browser
        # event handler operate.
        if self.is_hovering:
            return
        # Don't zoom in more than twice.
        if self.zoom_level >= 2:
            return
        # Find the grid square which we're inside.
        for i1 in range(len(self.x_grid) - 1):
            if event.x <= self.x_grid[i1 + 1]:
                xgrid = i1 + 1
                break
        for i1 in range(len(self.y_grid) - 1):
            if event.y >= self.y_grid[i1 + 1]:
                ygrid = i1 + 1
                break
        self.zoom_level += 1
        zl = self.zoom_level
        # Make the limits of the new graph be those of the grid square which
        # was clicked inside.
        self.km[zl] = (self.xtick[xgrid-1], self.xtick[xgrid])
        self.price[zl] = (self.ytick[ygrid-1], self.ytick[ygrid])
        if zl == 1:
            self.zoom_price_start = self.u.axis(*self.price[0])[:2]
            self.zoom_km_start = self.u.axis(*self.km[0])[:2]
        else:
            self.zoom_price_start = self.price[zl - 1]
            self.zoom_km_start = self.km[zl - 1]
        self.zoom_price_end = self.price[zl]
        self.zoom_km_end = self.km[zl]
        self._zoom_animation()
        self.replot()

    def unzoom(self, event):
        # If already at maximum zoom, nothing to be done.
        if self.zoom_level == 0:
            return
        # If not clicking inside graph boundaries, don't unzoom.
        if event.x <= self.x_grid[0] or event.x > self.x_grid[-1]:
            return
        if event.y >= self.y_grid[0] or event.y < self.y_grid[-1]:
            return
        self.zoom_level -= 1
        zl = self.zoom_level
        self.zoom_price_start = self.price[zl + 1]
        self.zoom_km_start = self.km[zl + 1]
        if zl == 0:
            self.zoom_price_end = self.u.axis(*self.price[0])[:2]
            self.zoom_km_end = self.u.axis(*self.km[0])[:2]
        else:
            self.zoom_price_end = self.price[zl]
            self.zoom_km_end = self.km[zl]
        self._zoom_animation()
        self.replot()

    def left_key(self, event):
        zl = self.zoom_level
        if zl == 0:
            return
        # If at left edge already, don't scroll.
        kz = self.km[zl]
        if self.km[0][0] > kz[0]:
            return
        self.zoom_price_start = self.zoom_price_end = self.price[zl]
        self.zoom_km_start = kz
        self.km[zl] = (kz[0] - (kz[1] - kz[0]), kz[0])
        self.zoom_km_end = self.km[zl]
        self._zoom_animation()
        self.replot()

    def right_key(self, event):
        zl = self.zoom_level
        if zl == 0:
            return
        # If at right edge already, don't scroll.
        kz = self.km[zl]
        if self.km[0][1] < kz[1]:
            return
        self.zoom_price_start = self.zoom_price_end = self.price[zl]
        self.zoom_km_start = kz
        self.km[zl] = (kz[1], kz[1] + (kz[1] - kz[0]))
        self.zoom_km_end = self.km[zl]
        self._zoom_animation()
        self.replot()

    def down_key(self, event):
        zl = self.zoom_level
        if zl == 0:
            return
        # If at bottom edge already, don't scroll.
        pz = self.price[zl]
        if self.price[0][0] > pz[0]:
            return
        self.zoom_km_start = self.zoom_km_end = self.km[zl]
        self.zoom_price_start = pz
        self.price[zl] = (pz[0] - (pz[1] - pz[0]), pz[0])
        self.zoom_price_end = self.price[zl]
        self._zoom_animation()
        self.replot()

    def up_key(self, event):
        zl = self.zoom_level
        if zl == 0:
            return
        # If at top edge already, don't scroll.
        pz = self.price[zl]
        if self.price[0][1] < pz[1]:
            return
        self.zoom_km_start = self.zoom_km_end = self.km[zl]
        self.zoom_price_start = pz
        self.price[zl] = (pz[1], pz[1] + (pz[1] - pz[0]))
        self.zoom_price_end = self.price[zl]
        self._zoom_animation()
        self.replot()


    def select(self, event):
        "Open a web page, when a data point has been clicked on."
        oval = event.widget.find_closest(event.x, event.y)[0]
        # XXX As above, sometimes the closest widget is a grid line, not an
        # oval. Need to handle this correctly, eventually.
        if oval not in self.ov_dict:
            return
        ind, xp, yp, color, filtered = self.ov_dict[oval]
        webbrowser.open(self.u.all_alink[ind])
Example #30
0
class SurfaceManipulator(Frame):
    r"""
    A translation surface editor in tk.
    """

    # STATIC METHODS AND OBJECTS

    current = None
    # boolean variable to remember if the hook was run!
    _clear_hook_was_run = 0

    @staticmethod
    def launch(geometry="800x700+10+10"):
        r"""Prefered way to gain access to a SurfaceManipulator window."""
        if SurfaceManipulator.current is None:
            SurfaceManipulator._clear_hook()
            root = Tk()
            root.geometry(geometry)
            SurfaceManipulator.current = SurfaceManipulator(root)
        return SurfaceManipulator.current

    @staticmethod
    def _window_destroyed(surface_manipulator):
        if SurfaceManipulator.current is surface_manipulator:
            SurfaceManipulator.current = None

    @staticmethod
    def _clear_hook():
        if not SurfaceManipulator._clear_hook_was_run:
            # Hack due to Nathan Dunfield (http://trac.sagemath.org/ticket/15152)
            import IPython.lib.inputhook as ih
            ih.clear_inputhook()
            SurfaceManipulator._clear_hook_was_run = 1

    # NORMAL METHODS

    def __init__(self, parent, surface=None, surfaces=[]):
        r"""
        INPUT:
        - ``surfaces`` -- a list of surfaces that the editor may modify
        - ``surface`` -- surface selected by default
        - ``parent`` -- parent Tk window
        """
        Frame.__init__(self, parent)
        self._parent = parent
        self.pack(fill="both", expand=1)

        # Run something when closing
        self._parent.wm_protocol("WM_DELETE_WINDOW", self.exit)

        # Surface currently being manipulated
        self._surface = None
        # List of surfaces in editor
        self._surfaces = []
        # More variables to initialize
        self._currentActor = None
        # Initialization of GUI
        self._init_menu()
        self._init_gui()
        # Setup surface list
        for s in surfaces:
            self.add_surface(s)
        # Setup initial surface
        if surface is not None:
            self.add_surface(surface)
        self.set_surface(surface)

    def __repr__(self):
        return "Surface manipulator"

    def add_mega_wollmilchsau(self):
        from geometry.mega_wollmilchsau import MegaWollmilchsau
        s = MegaWollmilchsau()
        sm, sb = s.get_bundle()
        self.set_surface(sb)

    def add_octagon(self):
        from geometry.similarity_surface_generators import TranslationSurfaceGenerators
        ss = TranslationSurfaceGenerators.regular_octagon()
        ss.edit()

    def _init_menu(self):

        self._menubar = Menu(self._parent)
        menubar = self._menubar
        self._parent.config(menu=menubar)

        #new_menu = Menu(menubar, tearoff=0)
        #new_menu.add_command(label="Billiard Table", command=self.on_new_similarity_surface)

        file_menu = Menu(menubar, tearoff=0)
        #file_menu.add_cascade(label="New", menu=new_menu)
        file_menu.add_command(label="Octagon", command=self.add_octagon)
        file_menu.add_command(label="MegaWollmilchsau",
                              command=self.add_mega_wollmilchsau)
        file_menu.add_separator()
        file_menu.add_command(label="About", command=self.on_about)
        file_menu.add_command(label="Export PostScript",
                              command=self.on_export)
        file_menu.add_command(label="Exit",
                              command=self.exit,
                              accelerator="Alt+F4")
        menubar.add_cascade(label="File", underline=0, menu=file_menu)

        self._surface_menu = Menu(menubar, tearoff=0)
        self._selected_surface = IntVar()
        self._selected_surface.set(-1)
        menubar.add_cascade(label="Surface",
                            underline=0,
                            menu=self._surface_menu)
        self._surface_menu.add_radiobutton(label="None",
                                           command=self.menu_select_surface,
                                           variable=self._selected_surface,
                                           value=-1)

    def _init_gui(self):
        self._parent.title("FlatSurf Editor")

        self._canvas = Canvas(self, bg="#444", width=300, height=200)
        self._canvas.pack(fill="both", expand=1)

        self.bottom_text = Label(self, text="Welcome to FlatSurf.", anchor="w")
        self.bottom_text.pack(fill="x", expand=0)

        self.set_actor(None)

    def add_surface(self, newsurface):
        r"""
        Add a surface to the display list for the window.
        Returns the index of the new surface in the surface list.
        """
        if (newsurface == None):
            return -1
        i = 0
        for s in self._surfaces:
            if (s == newsurface):
                return i
            i = i + 1
        self._surfaces.append(newsurface)
        newsurface.zoom_fit_nice_boundary()
        self._reset_surface_menu()
        return len(self._surfaces) - 1

    def exit(self):
        SurfaceManipulator._window_destroyed(self)
        self._parent.destroy()

    def find_bundle(self, surface):
        for surface_bundle in self._surfaces:
            if surface is surface_bundle.get_surface():
                return surface_bundle
        return None

    def get_bundle(self):
        return self._surface

    def get_bundles(self):
        return self._surfaces

    def get_canvas(self):
        return self._canvas

    def get_center(self):
        r"""
        Return the center of the canvas as a pair of integers.
        """
        return (self.get_width() / 2, self.get_height() / 2)

    def get_height(self):
        r"""
        Return the height of the canvas (an integer).
        """
        return self.get_canvas().winfo_height()

    def get_parent(self):
        return self._parent

    def get_surface_bundle(self):
        r"""
        Get the current surface bundle, or None if there is none.
        """
        return self._surface

    def get_width(self):
        r"""
        Return the width of the canvas (an integer).
        """
        return self.get_canvas().winfo_width()

    def menu_select_surface(self):
        r"""
        Called when a surface is selected from a menu.
        """
        i = self._selected_surface.get()
        if i == -1:
            self.set_surface(None)
        else:
            self.set_surface(self._surfaces[i])

    def on_about(self):
        self.set_text("Written by Vincent Delecroix and Pat Hooper.")

    def on_delete_junk(self):
        self._canvas.delete("junk")

    def on_export(self):
        r"""
        Export image as postscript file.
        """
        myFormats = [('PostScript', '*.ps')]
        fileName = tkFileDialog.asksaveasfilename(parent=self,
                                                  filetypes=myFormats,
                                                  title="Save image as...")
        if len(fileName) > 0:
            self._canvas.update()
            self._canvas.postscript(file=fileName)
            self.set_text("Wrote image to " + fileName)

#    def on_new_similarity_surface(self):
#        s = CreateSimilaritySurfaceBundle(len(self._surfaces),self)
#        if s is not None:
#            i = self.set_surface(s)
#            self.set_text("Created new surface `"+self._surfaces[i].get_name()+"'.")

    def _on_no_surface(self):
        self._canvas.delete("all")

    def _on_zoom(self):
        self.set_actor(ZoomActor(self))

    def _on_zoom_box(self):
        self.set_actor(ZoomBoxActor(self))

    def _on_redraw_all(self):
        if self._surface is not None:
            self._surface.redraw_all()

    def _on_recenter(self):
        self.set_actor(RecenterActor(self))

    def _reset_menus(self):
        r"""
        Reset all menus except the file and surface menu
        """
        # The following loop removes all but the first two menus (File and Surface).
        num = len(self._menubar.children)
        for i in range(num, 2, -1):
            self._menubar.delete(i)
        if self._surface != None:
            self._surface.make_menus(self._menubar)

    def _reset_surface_menu(self):
        r"""
        Reset the surface menu.
        """
        ### This is a hack to get the number of items in the menu:
        num = self._surface_menu.index(100) + 1
        # First we remove everything but the first entry ("None")
        for i in range(num - 1, 0, -1):
            #print("removing a child2: "+str(i)+" of "+str(num))
            self._surface_menu.delete(i)
        # Add an entry for every surface in the list.
        for i in range(len(self._surfaces)):
            surface = self._surfaces[i]
            self._surface_menu.add_radiobutton(
                label=surface.get_name(),
                command=self.menu_select_surface,
                variable=self._selected_surface,
                value=i)

    def set_text(self, text):
        self.bottom_text["text"] = text

    def set_actor(self, actor):
        r"""
        Set the current mode of user interaction.
        """
        if (actor != self._currentActor):
            if self._currentActor != None:
                self._currentActor.on_deactivate()
            if (actor == None):
                self.set_text("Nothing going on.")
                # Event bindings
                self._canvas.unbind('<Button-1>')
                self._canvas.unbind('<Button-2>')
                self._canvas.unbind('<Button-3>')
                self._canvas.unbind('<Double-Button-1>')
                self._canvas.unbind('<Shift-Button-1>')
                self._canvas.unbind('<Motion>')
                self.unbind('<FocusIn>')
                self.unbind('<FocusOut>')
                #self._canvas.unbind('<ButtonPress-1>')
                self._canvas.unbind('<ButtonRelease-1>')
                self._canvas.unbind('<B1-Motion>')
                self._parent.unbind('<Key>')
                self._parent.unbind('<KeyRelease>')
            else:
                # Event bindings
                self._canvas.bind('<Button-1>', actor.single_left_click)
                self._canvas.bind('<Double-Button-1>', actor.double_left_click)
                self._canvas.bind('<Triple-Button-1>', actor.double_left_click)
                self._canvas.bind('<Button-2>', actor.single_middle_click)
                self._canvas.bind('<Double-Button-2>',
                                  actor.double_middle_click)
                self._canvas.bind('<Triple-Button-2>',
                                  actor.double_middle_click)
                self._canvas.bind('<Button-3>', actor.single_right_click)
                self._canvas.bind('<Double-Button-3>',
                                  actor.double_right_click)
                self._canvas.bind('<Triple-Button-3>',
                                  actor.double_right_click)
                self._canvas.bind('<Shift-Button-1>', actor.shift_click)
                self._canvas.bind('<Motion>', actor.mouse_moved)
                #self._canvas.bind('<ButtonPress-1>', actor.left_mouse_pressed)
                self._canvas.bind('<ButtonRelease-1>',
                                  actor.left_mouse_released)
                self._canvas.bind('<B1-Motion>', actor.left_dragged)
                self.bind('<FocusIn>', actor.focus_in)
                self.bind('<FocusOut>', actor.focus_out)
                self._parent.bind('<Key>', actor.key_press)
                self._parent.bind('<KeyRelease>', actor.key_release)
                self._currentActor = actor
                self._currentActor.on_activate()

    def set_surface(self, surface_bundle):
        r"""
        Set the current surface to the one given by surface_bundle
        """
        i = self.add_surface(surface_bundle)
        if surface_bundle != self._surface:
            self._canvas.delete("all")
            self._surface = surface_bundle
            self._surface_menu.invoke(i + 1)
            if i >= 0:
                self.set_text("Switched to `" + self._surface.get_name() +
                              "'.")
                self._parent.title(self._surface.get_name())
                self._reset_menus()
                # stop the actor (was a bug).
                self.set_actor(None)
                if isinstance(self._surface, EditorRenderer):
                    self._surface.initial_render()
            else:
                self.set_text("No surface selected.")
                self._parent.title("FlatSurf Editor")
                self._reset_menus()
                self.set_actor(None)
        return i

    def surface_renamed(self):
        if self._surface is not None:
            self._parent.title(self._surface.get_name())
            self._reset_surface_menu()
Example #31
0
class ConsumablePinball(Domain):
    """
    RL NOTES: Pinball Domain has a ballmodel and environment object. 
    Statespace augmentation will be only done in the _DOMAIN_.


    The goal of this domain is to maneuver a small ball on a plate into a hole.
    The plate may contain obstacles which should be avoided.

    **STATE:**
        The state is given by a 4-dimensional vector, consisting of position and
        velocity of the ball.

    **ACTIONS:**
        There are 5 actions, standing for slanting the  plat in x or y direction
        or a horizontal position
        of the plate.

    **REWARD:**
        Slanting the plate costs -4 reward in addition to -1 reward for each timestep.
        When the ball reaches the hole, the agent receives 10000 units of reward.

    **REFERENCE:**

    .. seealso::
        G.D. Konidaris and A.G. Barto:
        *Skill Discovery in Continuous Reinforcement Learning Domains using Skill Chaining.*
        Advances in Neural Information Processing Systems 22, pages 1015-1023, December 2009.
    """
    #: default location of config files shipped with rlpy
    default_config_dir = os.path.join(__rlpy_location__, "Domains",
                                      "PinballConfigs")

    # seems to only have one reasonable goalfn
    def __init__(self,
                 goalArray,
                 noise=.1,
                 episodeCap=1000,
                 configuration=os.path.join(default_config_dir,
                                            "pinball_simple_single.cfg"),
                 goalfn=None,
                 rewardFunction=None,
                 encodingFunction=allMarkovEncoding):
        """
        configuration:
            location of the configuration file
        episodeCap:
            maximum length of an episode
        noise:
            with probability noise, a uniformly random action is executed
        """
        self.NOISE = noise
        self.configuration = configuration
        self.screen = None
        self.episodeCap = episodeCap
        self.actions_num = 5
        self.actions = [
            PinballModel.ACC_X, PinballModel.DEC_Y, PinballModel.DEC_X,
            PinballModel.ACC_Y, PinballModel.ACC_NONE
        ]
        self.statespace_limits = np.array([[0.0, 1.0], [0.0, 1.0], [-2.0, 2.0],
                                           [-2.0, 2.0]])

        self.goalArray0 = np.array(goalArray)
        self.prev_states = []

        # TODO fix initial state

        # statespace augmentation
        self.encodingFunction = encodingFunction

        encodingLimits = []
        for i in range(0, len(self.encodingFunction(self.prev_states))):
            encodingLimits.append([0, 1])

        self.statespace_limits = np.vstack(
            (self.statespace_limits, encodingLimits))
        self.state_space_dims = len(self.statespace_limits)
        self.continuous_dims = np.arange(self.state_space_dims)

        self.DimNames = [
            "Dim: " + str(k)
            for k in range(0, 2 + len(self.encodingFunction(self.prev_states)))
        ]

        self.rewardFunction = rewardFunction

        super(ConsumablePinball, self).__init__()
        self.environment = PinballModel(self.configuration,
                                        goalArray,
                                        goalfn=goalfn,
                                        random_state=self.random_state)

    def showDomain(self, a):
        if self.screen is None:
            master = Tk()
            master.title('RLPY Pinball')
            self.screen = Canvas(master, width=500.0, height=500.0)
            self.screen.configure(background='LightGray')
            self.screen.pack()
            self.environment_view = PinballView(self.screen, 500.0, 500.0,
                                                self.environment)
        self.environment_view.blit()
        self.screen.pack()
        self.screen.update()

    def step(self, a):
        s = self.state[:4]
        [
            self.environment.ball.position[0],
            self.environment.ball.position[1], self.environment.ball.xdot,
            self.environment.ball.ydot
        ] = s
        if self.random_state.random_sample() < self.NOISE:
            # Random Move
            a = self.random_state.choice(self.possibleActions())
        reward = self.environment.take_action(a)
        self.environment._check_bounds()
        state = np.array(self.environment.get_state())

        self.prev_states.append(state[:4])

        state = self.augment_state(state)
        self.state = state

        terminal = self.isTerminal()
        if not terminal and self.rewardFunction:
            sr = self.environment.STEP_PENALTY
            gr = self.environment.END_EPISODE
            reward = reward + self.rewardFunction(self.prev_states,
                                                  self.goalArray(), sr, gr)

        return reward, state, terminal, self.possibleActions()

    def s0(self):  #TODO reset this initial state; move logic into PinballModel
        self.environment.ball.position[0], self.environment.ball.position[
            1] = self.environment.start_pos
        self.environment.ball.xdot, self.environment.ball.ydot = 0.0, 0.0
        self.state = np.array([
            self.environment.ball.position[0],
            self.environment.ball.position[1], self.environment.ball.xdot,
            self.environment.ball.ydot
        ])

        self.prev_states = []
        self.state = self.augment_state(self.state)
        self.environment.goalArray = np.array(self.goalArray0)
        return self.state, self.isTerminal(), self.possibleActions()

    def possibleActions(self, s=0):
        return np.array(self.actions)

    def isTerminal(self):
        return self.environment.episode_ended() or len(
            self.prev_states) == self.episodeCap

    def augment_state(self, state):
        return np.concatenate((state, self.encodingFunction(self.prev_states)))

    def goalArray(self):
        return self.environment.goalArray
Example #32
0
class Wall(object):
    MIN_RED = MIN_GREEN = MIN_BLUE = 0x0
    MAX_RED = MAX_GREEN = MAX_BLUE = 0xFF

    PIXEL_WIDTH = 50

    def __init__(self, width, height):
        self.width = width
        self.height = height
        self._tk_init()
        self.pixels = [(0, 0, 0) for i in range(self.width * self.height)]

    def _tk_init(self):
        self.root = Tk()
        self.root.title("ColorWall %d x %d" % (self.width, self.height))
        self.root.resizable(0, 0)
        self.frame = Frame(self.root, bd=5, relief=SUNKEN)
        self.frame.pack()

        self.canvas = Canvas(self.frame,
                             width=self.PIXEL_WIDTH * self.width,
                             height=self.PIXEL_WIDTH * self.height,
                             bd=0,
                             highlightthickness=0)
        self.canvas.pack()
        self.root.update()

    def set_pixel(self, x, y, hsv):
        self.pixels[self.width * y + x] = hsv

    def get_pixel(self, x, y):
        return self.pixels[self.width * y + x]

    def draw(self):
        self.canvas.delete(ALL)
        for x in range(len(self.pixels)):
            x_0 = (x % self.width) * self.PIXEL_WIDTH
            y_0 = (x / self.width) * self.PIXEL_WIDTH
            x_1 = x_0 + self.PIXEL_WIDTH
            y_1 = y_0 + self.PIXEL_WIDTH
            hue = "#%02x%02x%02x" % self._get_rgb(self.pixels[x])
            self.canvas.create_rectangle(x_0, y_0, x_1, y_1, fill=hue)
        self.canvas.update()

    def clear(self):
        for i in range(self.width * self.height):
            self.pixels[i] = (0, 0, 0)

    def _hsv_to_rgb(self, hsv):
        rgb = colorsys.hsv_to_rgb(*hsv)
        red = self.MAX_RED * rgb[0]
        green = self.MAX_GREEN * rgb[1]
        blue = self.MAX_BLUE * rgb[2]
        return (red, green, blue)

    def _get_rgb(self, hsv):
        red, green, blue = self._hsv_to_rgb(hsv)
        red = int(float(red) / (self.MAX_RED - self.MIN_RED) * 0xFF)
        green = int(float(green) / (self.MAX_GREEN - self.MIN_GREEN) * 0xFF)
        blue = int(float(blue) / (self.MAX_BLUE - self.MIN_BLUE) * 0xFF)
        return (red, green, blue)