class DevelopmentWindow(): def __init__(self): self.worlds = [] ## Set up worlds fLocs1 = [(2,0),(-2,0),(0,2),(0,-2),(0,3),(0,-3),(3,0),(-3,0),(4,0),(-4,0),(0,4),(0,-4),(0,7),(7,0),(-7,0)] fLocs2 = [(1,1),(2,2),(3,3),(4,4),(3,5),(2,6),(1,7),(0,8),(-2,6),(-4,4),(-6,2),(-8,0),(-5,0),(-2,-3),(-5,-5)] fLocs3 = [(-2,2),(-1,0),(1,0),(-1,0),(2,-2),(3,5),(-5,5),(-8,8),(10,10),(-10,10),(10,-10),(0,-1),(0,-2),(0,-3),(0,-4)] fLocs4 = [(random.random()*20 - 20.0/2., random.random()*20 - 20.0/2.) for i in xrange(20)] fLocs5 = [(random.random()*20 - 20.0/2., random.random()*20 - 20.0/2.) for i in xrange(20)] self.worlds.append([1,15,20,fLocs1]) self.worlds.append([1,15,20,fLocs2]) self.worlds.append([1,15,20,fLocs3]) self.worlds.append([1,20,20,fLocs4]) self.worlds.append([1,20,20,fLocs5]) #parameters self.sP = SimParam.SimParam() self.sP.setWorld(1,self.worlds[0][0],self.worlds[0][1],self.worlds[0][2],self.worlds[0][3]) #change first index to change default world self.sP.setWorld(2,self.worlds[1][0],self.worlds[1][1],self.worlds[1][2],self.worlds[1][3]) self.sP.setWorld(3,self.worlds[2][0],self.worlds[2][1],self.worlds[2][2],self.worlds[2][3]) self.sP.setWorld(4,self.worlds[3][0],self.worlds[3][1],self.worlds[3][2],self.worlds[3][3]) self.sP.setWorld(5,self.worlds[4][0],self.worlds[4][1],self.worlds[4][2],self.worlds[4][3]) self.sP.setAnimParams(1,1,(0,0)) self.paused = True #paused? self.lastTime = 0 self.sim_msps = 0 self.dis_t = 1 #the t being displayed self.buff_t = 0 self.writeInterval = 100 self.simHistory = {} #this will fill with produced worlds from the simulations self.simEngine = SimulationEngine.SimulationEngine() self.developmentHistory = {} self.layoutHist = 300 #y value holder for new aniimat config button placement self.layoutList = [] # holds config/delete animat buttons and labels for any animats other than default #intialize TK self.root = tk.Tk() self.root.title("Development Simulation") self.canvas = tk.Canvas(self.root, width=1080, height=720) self.canvas.pack() #some general-purpose colors self.colorWhite = "#ffffff" self.colorGrey = "#dddddd" self.colorBlack = "#000000" self.colorLightBlue = "#ADD8E6" self.colorBlue = "#0000ff" self.colorRed = "#ff0000" #file options self.file_opt = options = {} options['defaultextension'] = '.netsim' options['filetypes'] = [('all files', '.*'), ('text files', '.txt'), ('Simulation Files', '.netsim')] #options['initialdir'] = 'C:\\' options['initialfile'] = '.netsim' options['parent'] = self.root options['title'] = 'Save Simulation As...' #set up menu bar menubar = tk.Menu(self.root) filemenu = tk.Menu(menubar, tearoff=0) filemenu.add_command(label="Start Simulation", command=self.startSimulation) filemenu.add_command(label="Save Current Development Simulation", command=self.saveCurrentSimulation) filemenu.add_command(label="Load Development from File", command=self.loadSimulationFromFile) filemenu.add_separator() filemenu.add_command(label="Load Results from Evolutionary Algorithm",command=self.loadEvo) filemenu.add_separator() filemenu.add_command(label="Exit",command=self.root.destroy) menubar.add_cascade(label="File", menu=filemenu) speedmenu = tk.Menu(menubar, tearoff=0) speedmenu.add_command(label="1ms", command=lambda:self.setWriteInterval(1)) speedmenu.add_command(label="25ms", command=lambda:self.setWriteInterval(25)) speedmenu.add_command(label="50ms", command=lambda:self.setWriteInterval(50)) speedmenu.add_command(label="100ms", command=lambda:self.setWriteInterval(100)) speedmenu.add_command(label="1s", command=lambda:self.setWriteInterval(1000)) speedmenu.add_command(label="Do not write") speedmenu.invoke(3) #default write interval is 100 editmenu = tk.Menu(menubar, tearoff=0) editmenu.add_command(label="Parameters",command = self.editParameters) editmenu.add_cascade(label="Write Interval", menu=speedmenu) menubar.add_cascade(label="Edit", menu=editmenu) self.root.config(menu=menubar) #Set up neuron graph and text log box and control bar self.neuronGraph = Graph(self.root, [75, 75, 475, 475], [-1.1, 1.1, -1.1, 1.1]) self.neuronGraph.plotCircle((2, 2), (0, 0), self.colorWhite) self.neuronGraph.title("Development") self.neuronGraph.xlabel("XAXIS") self.neuronGraph.ylabel("YAXIS") self.neuronGraph.draw(self.canvas) #Set up World Parameter Options self.animNum_sv = tk.StringVar() self.animNum_sv.set(str(self.sP.getAnimNum(1))) self.foodNum_sv = tk.StringVar() self.foodNum_sv.set(str(self.sP.getFoodNum(1))) self.arenaSize_sv = tk.StringVar() self.arenaSize_sv.set(str(self.sP.getWorldSize(1))) title = tk.Label(self.root, text="Parameter Settings",font="bold",relief="ridge",padx=5,pady=5) title.place(x=600,y=75) # animNum_l = tk.Label(self.root, text="Number of Animats:") # animNum_l.place(x=600,y=125) # animNum_e = tk.Entry(self.root, textvariable=self.animNum_sv) # animNum_e.place(x=750,y=125) foodNum_l = tk.Label(self.root, text="Number of Foods:") foodNum_l.place(x=600,y=125) foodNum_e = tk.Entry(self.root, textvariable=self.foodNum_sv) foodNum_e.place(x=750,y=125) arenaSize_l = tk.Label(self.root, text="World Size: ") arenaSize_l.place(x=600,y=150) arenaSize_e = tk.Entry(self.root, textvariable=self.arenaSize_sv) arenaSize_e.place(x=750,y=150) #button for retreiving parameters self.setParamButton = tk.Button(self.root, text="Set Parameters", command=self.saveParameters) self.setParamButton.place(x=675,y=175) title2 = tk.Label(self.root, text="Animat Settings", font="bold", relief="ridge",padx=5,pady=5) title2.place(x=600,y=250) defaultAnim_l = tk.Label(self.root, text="* Animat 1: ", font="bold") defaultAnim_l.place(x=600,y=300) #Animat Buttons animConfigButton = tk.Button(self.root, text="Configure Animat", command=lambda: self.configAnimat(0)) animConfigButton.place(x=700,y=300) newAnimButton = tk.Button(self.root, text="Add New Animat",bg='green', command=self.addAnimat) newAnimButton.place(x=750,y=250) self.videoBar = VideoBar(self.canvas, (100, 515, 500, 525), (0, 5000), self.timeClicked) #set up images playImage = ImageTk.PhotoImage(Image.open("play.png").resize((40, 40), Image.ANTIALIAS)) pauseImage = ImageTk.PhotoImage(Image.open("pause.png").resize((40,40), Image.ANTIALIAS)) stopImage = ImageTk.PhotoImage(Image.open("stop.png").resize((40,40), Image.ANTIALIAS)) restartImage = ImageTk.PhotoImage(Image.open("restart.png").resize((40,40), Image.ANTIALIAS)) step_fImage = ImageTk.PhotoImage(Image.open("step_f.png").resize((40,40), Image.ANTIALIAS)) step_bImage = ImageTk.PhotoImage(Image.open("step_b.png").resize((40,40), Image.ANTIALIAS)) #video control buttons self.playButton = tk.Button(self.root, command = self.play, image = playImage) self.playButton.place(x = 100,y=545) self.pauseButton = tk.Button(self.root, command = self.pause, image = pauseImage) self.pauseButton.place(x=155,y=545) self.stopButton = tk.Button(self.root, command = self.stop, image = stopImage) self.stopButton.place(x=210,y=545) self.restartButton = tk.Button(self.root, command = self.restart, image = restartImage) self.restartButton.place(x=265, y=545) self.step_bButton = tk.Button(self.root, command = self.step_b, image = step_bImage) self.step_bButton.place(x=320, y=545) self.step_fButton = tk.Button(self.root, command = self.step_f, image = step_fImage) self.step_fButton.place(x=375, y=545) #speed scale bar spdlabel = self.canvas.create_text(357, 615, text="Select Speed (ms/s)") self.speedScale = tk.Scale(self.root, from_=0, to=500, orient = "horizontal", length = 300) self.speedScale.place(x = 215, y = 625) self.root.after(0, self.refreshScreen) self.root.mainloop() def refreshScreen(self): #print(len(self.developmentHistory.keys())) if not self.paused: self.developmentHistory.update(self.simEngine.getNewDevelopments()) t = sorted(self.developmentHistory.keys())[len(self.developmentHistory.keys())-1] network = self.developmentHistory[t] self.neuronGraph.plotCircle((2, 2), (0, 0), self.colorWhite) for neuron in network.getNeurons(): self.neuronGraph.plotCircle((.05, .05), (neuron.X, neuron.Y), neuron.firing_color if neuron.isFiring() else neuron.color) self.neuronGraph.draw(self.canvas) self.root.after(1 if int(np.floor(1000/20)) < 1 else int(np.floor(1000/20)), self.refreshScreen) #Button Functions def play(self): self.simEngine.startNewDevelopmentSim() self.paused = False def pause(self): pass def stop(self): self.simEngine.stopSimulation() def restart(self): self.developmentHistory = {} self.simEngine.startNewDevelopmentSim() def step_b(self): pass def step_f(self): pass def timeClicked(self): pass def saveParameters(self): self.sP.setWorld((int)(self.animNum_sv.get()),self.foodNum_sv.get(),self.arenaSize_sv.get()) #self.parameters[0] = (int)(self.animNum_sv.get()) #self.parameters[1] = (int)(self.foodNum_sv.get()) #self.parameters[2] = (int)(self.arenaSize_sv.get()) saved = tk.Label(self.root, text="***SAVED***", font="bold",fg="red") saved.place(x=775,y=75) saved.after(2000,saved.destroy) def configAnimat(self,id): self.win = tk.Toplevel(height=600,width=700) self.win.title("Animat Configuration") title = tk.Label(self.win, text="Configure Animat", font="bold", relief="ridge",padx=5,pady=5) #set up entry variables self.type_sv = tk.StringVar() self.type_sv.set(str(self.sP.getType(id))) self.origin_sv = tk.StringVar() self.origin_sv.set(str(self.sP.getOrigin(id))) self.cal_sv = tk.StringVar() self.cal_sv.set(str(self.sP.getCalories(id))) self.inhibNum_sv = tk.StringVar() temp = self.sP.getInhib(id) self.inhibNum_sv.set(temp[0]) self.inhibA_sv = tk.StringVar() self.inhibA_sv.set(temp[1]) self.inhibB_sv = tk.StringVar() self.inhibB_sv.set(temp[2]) self.inhibC_sv = tk.StringVar() self.inhibC_sv.set(temp[3]) self.inhibD_sv = tk.StringVar() self.inhibD_sv.set(temp[4]) temp = self.sP.getExcit(id) self.excitNum_sv = tk.StringVar() self.excitNum_sv.set(temp[0]) self.excitA_sv = tk.StringVar() self.excitA_sv.set(temp[1]) self.excitB_sv = tk.StringVar() self.excitB_sv.set(temp[2]) self.excitC_sv = tk.StringVar() self.excitC_sv.set(temp[3]) self.excitD_sv = tk.StringVar() self.excitD_sv.set(temp[4]) #labels and entries type_l = tk.Label(self.win, text="Type: " ,font="bold") self.type_e = tk.Entry(self.win, textvariable=self.type_sv) origin_l = tk.Label(self.win, text="Origin: ", font="bold") self.origin_e = tk.Entry(self.win, textvariable=self.origin_sv) cal_l = tk.Label(self.win, text="Calories: ", font="bold") self.cal_e = tk.Entry(self.win, textvariable=self.cal_sv) inhibNum_l = tk.Label(self.win, text="Inhibitory Neurons:", font="bold") self.inhibNum_e = tk.Entry(self.win, textvariable=self.inhibNum_sv) inhibA_l = tk.Label(self.win, text="a:", font="bold") self.inhibA_e = tk.Entry(self.win, textvariable=self.inhibA_sv,width=4) inhibB_l = tk.Label(self.win, text="b:", font="bold") self.inhibB_e = tk.Entry(self.win, textvariable=self.inhibB_sv,width=4) inhibC_l = tk.Label(self.win, text="c:", font="bold") self.inhibC_e = tk.Entry(self.win, textvariable=self.inhibC_sv,width=4) inhibD_l = tk.Label(self.win, text="d:", font="bold") self.inhibD_e = tk.Entry(self.win, textvariable=self.inhibD_sv,width=4) excitNum_l = tk.Label(self.win, text="Excitatory Neurons:", font="bold") self.excitNum_e = tk.Entry(self.win, textvariable=self.excitNum_sv) excitA_l = tk.Label(self.win, text="a:", font="bold") self.excitA_e = tk.Entry(self.win, textvariable=self.excitA_sv,width=4) excitB_l = tk.Label(self.win, text="b:", font="bold") self.excitB_e = tk.Entry(self.win, textvariable=self.excitB_sv,width=4) excitC_l = tk.Label(self.win, text="c:", font="bold") self.excitC_e = tk.Entry(self.win, textvariable=self.excitC_sv,width=4) excitD_l = tk.Label(self.win, text="d:", font="bold") self.excitD_e = tk.Entry(self.win, textvariable=self.excitD_sv,width=4) #placements title.place(x=2,y=2) type_l.place(x=40,y=50) self.type_e.place(x=185,y=50) origin_l.place(x=40,y=75) self.origin_e.place(x=185,y=75) cal_l.place(x=40,y=100) self.cal_e.place(x=185,y=100) inhibNum_l.place(x=40,y=125) self.inhibNum_e.place(x=185,y=125) inhibA_l.place(x=260,y=125) self.inhibA_e.place(x=280,y=125) inhibB_l.place(x=310,y=125) self.inhibB_e.place(x=330,y=125) inhibC_l.place(x=360,y=125) self.inhibC_e.place(x=380,y=125) inhibD_l.place(x=410,y=125) self.inhibD_e.place(x=430,y=125) excitNum_l.place(x=40,y=150) self.excitNum_e.place(x=185,y=150) excitA_l.place(x=260,y=150) self.excitA_e.place(x=280,y=150) excitB_l.place(x=310,y=150) self.excitB_e.place(x=330,y=150) excitC_l.place(x=360,y=150) self.excitC_e.place(x=380,y=150) excitD_l.place(x=410,y=150) self.excitD_e.place(x=430,y=150) saveButton = tk.Button(self.win, text="Save Configuration", command=lambda:self.saveAnimat(id)) saveButton.place(x=200,y=200) def saveAnimat(self,id): self.sP.setType(id,self.type_e.get()) self.sP.setOrigin(id,(int(self.origin_e.get()[1]),int(self.origin_e.get()[4]))) self.sP.setCalories(id,int(self.cal_e.get())) inhib = [int(self.inhibNum_e.get()),float(self.inhibA_e.get()),float(self.inhibB_e.get()), float(self.inhibC_e.get()),float(self.inhibD_e.get())] excit = [int(self.excitNum_e.get()),float(self.excitA_e.get()),float(self.excitB_e.get()), float(self.excitC_e.get()),float(self.excitD_e.get())] self.sP.setInhib(id,inhib) self.sP.setExcit(id,excit) self.win.destroy() def addAnimat(self): self.sP.setAnimNum(1,self.sP.getAnimNum(1)+1) #self.parameters[0] += 1 #increase animatNum by 1 self.layoutHist += 50 #shift current y value down #id = self.sP.getAnimNum() - 1 #-1 beacause index = id-1 self.sP.setAnimParams(self.sP.getAnimNum(),"Wheel Animat",(1,0),10,[80,.02,.25,-65,2],[320,.02,.2,-65,8]) newLabel = tk.Label(self.root, text=("* Animat: " + str(self.sP.getAnimNum())), font="bold") newConfigButton = tk.Button(self.root, text="Configure Animat", command=lambda: self.configAnimat(id)) newDeleteButton = tk.Button(self.root, text="Remove Animat", command=lambda: self.deleteAnimat(id)) self.layoutList.append([newLabel,newConfigButton,newDeleteButton]) newLabel.place(x=600,y=self.layoutHist) newConfigButton.place(x=700,y=self.layoutHist) newDeleteButton.place(x=825,y=self.layoutHist) newConfigButton.invoke() ##NEED TO ADAPT TO simParam FIGURE OUT WORLD ANIM ID IMPLEMENTATION FIRST def deleteAnimat(self,id): pass # del self.animatParams[id] # self.layoutHist -= 50 # self.parameters[0] -= 1 # label,config,delete = self.layoutList[id-1] # label.destroy() # config.destroy() # delete.destroy() # del self.layoutList[id-1] #Menu Bar Functions def startSimulation(self): self.simWin = tk.Toplevel(self.root) self.root.withdraw() self.simEngine.stopSimulation() self.gui = GUIdriver.GUIDriver(self.simWin,self.root,self.sP) #NEED TO IMPLEMENT AFTER def loadEvo(self): #pass fn = tkFileDialog.askopenfilename() with open(fn,'r') as f: evoParams = json.load(f) # print evoParams self.sP.setAnimParams(1,1,evoParams[1],evoParams[2],evoParams[3],evoParams[4],evoParams[5]) self.sP.setAA(1,evoParams[6]) self.sP.setBB(1,evoParams[7]) self.simWin = tk.Toplevel(self.root) self.root.withdraw() self.simEngine.stopSimulation() self.gui = GUIdriver.GUIDriver(self.simWin,self.root,self.sP) def editParameters(self): paramWin = ParametersWindow.ParameterWindow() def saveCurrentSimulation(self): self.simEngine.stopSimulation() f = tkFileDialog.asksaveasfile(mode='w', **self.file_opt) cPickle.dump((self.simEngine.staticWorld, self.simHistory), f) if not f is None: f.close() def loadSimulationFromFile(self): f = tkFileDialog.askopenfile(mode='r', **self.file_opt) if f is None: return self.simEngine.loadSimulationFromFile(f) self.simHistory = {} self.dis_t = 0 self.buff_t = 0 self.videoBar.reset() self.paused = True def setWriteInterval(self,t): self.simEngine.setWriteInterval(t)
class GUIDriver: def __init__(self,master,devWin,simParams): self.sP = simParams #some parameters self.paused = False # whether simulation playback is paused self.simRunning = True # whether simulation is running - so buffering to GUI self.lastTime = 0 # the last time on the clock self.sim_msps = 0 # how many simulated milliseconds pass per second in display: i.e., a value of 1000 means real-time - useful for animat moving, but too fast to see neural activity self.dis_t = 1 #the time being currently displayed by the GUI self.buff_t = 0 #the time buffered by the Simulation Engine self.writeInterval = 25 # sets the interval between write states (in simulated ms); self.simHistory = {} # dictionary of time: dynamic world state self.tracked_data = collections.defaultdict(lambda: collections.defaultdict(lambda: collections.OrderedDict())) # not clear what this is; SH self.TRACK_NEURAL_FIRINGS = "Neural Firings" self.TRACK_ENERGY = "Energy" self.TRACK_POS = "Position" self.TRACK_LFP = "LFP" # probably should give this another name self.tracked_types = [] self.simEngine = SimulationEngine() #constructs a Simulation Engine self.world = 0 #placeholder for the World currently being displayed self.devWin = devWin # development window is parent; use this to set up parameters #some general-purpose colors self.colorWhite = "#ffffff" self.colorGrey = "#dddddd" self.colorBlack = "#000000" self.colorLightBlue = "#ADD8E6" self.colorBlue = "#0000ff" self.colorRed = "#ff0000" self.colorGreen = "#00ff00" #setting up Tk window self.root = master # window passed in self.root.title("Animat Simulation") self.canvas = tk.Canvas(self.root, width=1280, height=720) self.canvas.pack() #set up file options to save simulations self.file_opt = options = {} options['defaultextension'] = '.sim' options['filetypes'] = [('all files', '.*'), ('text files', '.txt'), ('Simulation Files', '.sim')] #options['initialdir'] = 'C:\\' options['initialfile'] = '.sim' options['parent'] = self.root options['title'] = 'Save Simulation As...' #set up menu bar self.menubar = tk.Menu(self.root) filemenu = tk.Menu(self.menubar, tearoff=0) filemenu.add_command(label="Save Current Simulation", command=self.saveCurrentSimulation) filemenu.add_command(label="Load Simulation from File", command=self.loadSimulationFromFile) filemenu.add_command(label="Calculate Benchmark", command=self.benchmark) filemenu.add_separator() filemenu.add_command(label="Exit",command=self.quit) self.menubar.add_cascade(label="File", menu=filemenu) speedmenu = tk.Menu(self.menubar, tearoff=0) speedCheckVar = tk.IntVar() speedmenu.add_radiobutton(label="1ms", variable = speedCheckVar, command=lambda:self.setWriteInterval(1)) speedmenu.add_radiobutton(label="25ms", variable = speedCheckVar, command=lambda:self.setWriteInterval(25)) speedmenu.add_radiobutton(label="50ms", variable = speedCheckVar, command=lambda:self.setWriteInterval(50)) speedmenu.add_radiobutton(label="100ms", variable = speedCheckVar, command=lambda:self.setWriteInterval(100)) speedmenu.add_radiobutton(label="1s", variable = speedCheckVar, command=lambda:self.setWriteInterval(1000)) speedmenu.add_radiobutton(label="Do not write", variable = speedCheckVar) speedmenu.invoke(1) #default write interval is 100 worldmenu = tk.Menu(self.menubar, tearoff=0) worldVar = tk.IntVar() #not used just required worldmenu.add_radiobutton(label="World 1", variable = worldVar, command=lambda:self.setWorldNum(1)) worldmenu.add_radiobutton(label="World 2", variable = worldVar, command=lambda:self.setWorldNum(2)) worldmenu.add_radiobutton(label="World 3", variable = worldVar, command=lambda:self.setWorldNum(3)) worldmenu.add_radiobutton(label="World 4", variable = worldVar, command=lambda:self.setWorldNum(4)) worldmenu.add_radiobutton(label="World 5", variable = worldVar, command=lambda:self.setWorldNum(5)) speedmenu.invoke(self.sP.worldToRun-1) #default write interval is 25 editmenu = tk.Menu(self.menubar, tearoff=0) editmenu.add_cascade(label="Write Interval", menu=speedmenu) editmenu.add_cascade(label="World to Run", menu=worldmenu) editmenu.add_command(label="Parameters", command=self.showDevWin) self.menubar.add_cascade(label="Edit", menu=editmenu) trackmenu = tk.Menu(self.menubar, tearoff=0) trackmenu.add_checkbutton(label="Neural Firings", command = lambda:self.track(self.TRACK_NEURAL_FIRINGS)) trackmenu.add_checkbutton(label="Energy", command = lambda:self.track(self.TRACK_ENERGY)) trackmenu.add_checkbutton(label="Position", command = lambda:self.track(self.TRACK_POS)) trackmenu.add_checkbutton(label="LFP", command = lambda:self.track(self.TRACK_LFP)) trackmenu.invoke(0) trackmenu.invoke(1) trackmenu.invoke(2) trackmenu.invoke(3) self.menubar.add_cascade(label="Track", menu = trackmenu) viewMenu = tk.Menu(self.menubar, tearoff=0) viewMenu.add_command(label="Internal Variables",command=self.varViewer) viewMenu.add_command(label="Connection Viewer",command=self.connectionViewer) self.menubar.add_cascade(label="View",menu=viewMenu) debugMenu = tk.Menu(self.menubar, tearoff=0) debugMenu.add_command(label="Print S",command = self.printS) debugMenu.add_command(label="Print RL",command = self.printRL) self.menubar.add_cascade(label="Debug",menu=debugMenu) self.root.config(menu=self.menubar) #initialize the graphs and video control bar self.worldGraph = Graph(self.root, [100, 50, 500, 475], [-10, 10, -10, 10]) self.worldGraph.title('World') self.worldGraph.xlabel('distance') self.neuron_graphs = {} self.neuron_box = TabBox(self.root, [600, 50, 1000, 475]) self.videoBar = VideoBar(self.canvas, (100, 515, 500, 525), (0, 15000), self.timeClicked) #some images--will probably eventually go in respective classes (static state) - can remove self.animatImage = Image.open("roomba.png") self.aImage = ImageTk.PhotoImage(self.animatImage) self.foodImage = Image.open("beer.png") self.fImage = ImageTk.PhotoImage(self.foodImage) playImage = ImageTk.PhotoImage(Image.open("play.png").resize((40, 40), Image.ANTIALIAS)) pauseImage = ImageTk.PhotoImage(Image.open("pause.png").resize((40,40), Image.ANTIALIAS)) stopImage = ImageTk.PhotoImage(Image.open("stop.png").resize((40,40), Image.ANTIALIAS)) restartImage = ImageTk.PhotoImage(Image.open("restart.png").resize((40,40), Image.ANTIALIAS)) step_fImage = ImageTk.PhotoImage(Image.open("step_f.png").resize((40,40), Image.ANTIALIAS)) step_bImage = ImageTk.PhotoImage(Image.open("step_b.png").resize((40,40), Image.ANTIALIAS)) continueImage = ImageTk.PhotoImage(Image.open("continue.png").resize((40,40), Image.ANTIALIAS)) #video control buttons self.playButton = tk.Button(self.root, command = self.play, image = playImage, relief='sunken') self.playButton.place(x = 100,y=545) self.pauseButton = tk.Button(self.root, command = self.pause, image = pauseImage, relief='raised') self.pauseButton.place(x=155,y=545) # self.stopButton = tk.Button(self.root, command = self.stop, image = stopImage) # self.stopButton.place(x=320, y=545) self.restartButton = tk.Button(self.root, command = self.restart, text="Start New Simulation") self.restartButton.place(x=320, y=575) self.step_bButton = tk.Button(self.root, command = self.step_b, image = step_bImage) self.step_bButton.place(x=210,y=545) self.step_fButton = tk.Button(self.root, command = self.step_f, image = step_fImage) self.step_fButton.place(x=265, y=545) # self.continueButton = tk.Button(self.root, command = self.continue_, image = continueImage) # self.continueButton.place(x=430, y=545) self.simCtrlButton = tk.Button(self.root, command=self.simCtrl, text="Stop Simulation",bg='red') self.simCtrlButton.place(x=320,y=545) # Buttons using images # self.playButton = tk.Button(self.root, command = self.play, text="Play", relief='sunken') # self.playButton.place(x = 100,y=545) # self.pauseButton = tk.Button(self.root, command = self.pause, text="Pause", relief='raised') # self.pauseButton.place(x=155,y=545) # # self.stopButton = tk.Button(self.root, command = self.stop, image = stopImage) # # self.stopButton.place(x=320, y=545) # self.restartButton = tk.Button(self.root, command = self.restart, text="Start New Simulation") # self.restartButton.place(x=320, y=575) # self.step_bButton = tk.Button(self.root, command = self.step_b, text = "Step <-") # self.step_bButton.place(x=210,y=545) # self.step_fButton = tk.Button(self.root, command = self.step_f, text = "Step ->") # self.step_fButton.place(x=265, y=545) # # self.continueButton = tk.Button(self.root, command = self.continue_, image = continueImage) # # self.continueButton.place(x=430, y=545) # self.simCtrlButton = tk.Button(self.root, command=self.simCtrl, text="Stop Simulation",bg='red') # self.simCtrlButton.place(x=320,y=545) #speed lock buttons self.speedButtons = tk.IntVar() rb1 = tk.Radiobutton(self.root, text="Real-Time", variable=self.speedButtons, value=1, command = self.realTime) rb1.place(x = 100, y = 600) rb2 = tk.Radiobutton(self.root, text="Synced", variable=self.speedButtons, value=2, command = self.synced) rb3 = tk.Radiobutton(self.root, text="Select:", variable=self.speedButtons, value=3, command = self.chooseSpeed) rb2.place(x = 100, y = 630) rb3.place(x = 100, y = 660) spdlabel = self.canvas.create_text(357, 635, text="Select Speed (ms/s)") self.speedScale = tk.Scale(self.root, from_=0, to=500, orient = "horizontal", length = 300) self.speedScale.place(x = 215, y = 645) rb3.invoke() #needs to be called after speed scale is created #Create legend for neuron map tk.Label(self.root,text="Neural Network Legend",font="bold",relief="ridge",padx=5,pady=5).place(x=1050,y=100) #inhib_t = tk.Label(self.root, text="Inhibitory Neuron: ") #inhib_t.place(x=1050,y=150) #inhib_c = self.canvas.create_oval(1175,150,1200,175, fill = "#b1b1ff") tk.Label(self.root, text="Excitatory Neuron: ").place(x=1050,y=150) self.canvas.create_oval(1200,150,1225,175, fill = NeuronModule.ExcitatoryNeuron(0,0,0).color) tk.Label(self.root, text="Hunger Neuron: ").place(x=1050,y=200) self.canvas.create_oval(1200,200,1225,225, fill = NeuronModule.HungerNeuron(0,0,0).color) tk.Label(self.root, text="Motor Neuron: ").place(x=1050,y=250) self.canvas.create_oval(1200,250,1225,275, fill = NeuronModule.MotorNeuron(0,0,0).color) tk.Label(self.root, text="Sensory Neuron A: ").place(x=1050,y=300) self.canvas.create_oval(1200,300,1225,325, fill = NeuronModule.SensoryNeuron_A(0,0,0).color) tk.Label(self.root, text="Sensory Neuron B: ").place(x=1050,y=350) self.canvas.create_oval(1200,350,1225,375, fill = NeuronModule.SensoryNeuron_B(0,0,0).color) #pack up the Frame and run mainContainer = tk.Frame(self.root) mainContainer.pack() self.run() #runs a simulation, for now self.root.mainloop() #starts the Tkinter event loop #called to start a new simulation def run(self): self.simEngine.startNewSim(self.sP) #starts a new simulation self.world = self.simEngine.staticWorld self.simEngine.setWriteInterval(self.writeInterval) #sets the write interval of the simulator self.worldGraph.set_numBounds(self.simEngine.staticWorld.numBounds) # bounds of box animat is contained self.makeStatMenu(3) self.root.after(0, self.refreshScreen) #adds task to refresh screen information - starts animation self.lastTime = time.clock() #clocks the start of the simulation #self.makeStatMenu(3) #right now hardcoded to 3 food items #main GUI refresh method def refreshScreen(self): # 1. The program needs to get the new states produced by the Simulation Engine since the last screen refresh. static, states = self.simEngine.getNewStates() #the Simulation Engine passes back new states and the static world self.simHistory.update(states) #updates the GUI's simulation history with the new states # 2. The program needs to figure out what time to display based on the selected speed and what has been recorded. systime = time.clock() #gets the system time elapsed_time = systime - self.lastTime #calculates the elapsed time from the last time the loop was run self.lastTime = systime #records new system time for the next loop if not self.paused and self.dis_t <= self.buff_t: #advances the displayed time, as long as it's not ahead of the simulation and is not paused self.dis_t += self.calculate_dis_dt(elapsed_time) dis_t_int = int(np.floor(self.dis_t/self.writeInterval) * self.writeInterval) #finds the displayed time based on the write interval: I.E., requests closest written time to the time that should be displayed # 3. If able to find the displayed time in recorded simulation history, the program needs to store and display the corresponding World graphically if dis_t_int in self.simHistory.keys(): # 3.a. loads ands stores the World static.loadDynamicState(self.simHistory[dis_t_int]) #loads the dynamic state at the displayed time into the static World object self.world = static #sets this loaded world as the GUI's world for other menus, etc # 3.b. displays the World on two Graph objects and draws them #plot the world: the Animat and food, for now for animat in self.world.animats: self.worldGraph.plotCircle((animat.radius*2,animat.radius*2), (animat.pos[0], animat.pos[1]), self.colorGrey) headPos = animat.pos[0]+(animat.radius)*np.cos(animat.direc), animat.pos[1]+(animat.radius)*np.sin(animat.direc) self.worldGraph.plotCircle((.2,.2), headPos, self.colorBlack) self.worldGraph.plotText(("Purisa", 6) , (animat.pos[0], animat.pos[1]), animat.id) if not (animat.id in self.neuron_graphs.iterkeys()): neuronGraph = Graph(self.root, self.neuron_box.content_bounds, [-1.3, 1.3, -1.3, 1.3]) self.neuron_graphs[animat.id] = neuronGraph self.neuron_box.add(neuronGraph, animat.id) neuronGraph = self.neuron_graphs[animat.id] neuronGraph.plotCircle((2, 2), (0, 0), self.colorWhite) neurons = animat.net.getNeurons() for neuron in neurons: neuronGraph.plotCircle((.05, .05), (neuron.X, neuron.Y), neuron.firing_color if neuron.isFiring() else neuron.color) neuronGraph.draw(self.canvas) for food in self.world.foods: #foodImage = self.worldGraph.size_up(Image.open(food.image), (1,1), 0) if food.amt > 0.0: self.worldGraph.plotCircle((1,1), food.getPos(), self.colorGreen) self.worldGraph.plotText(("Purisa", 6) , (food.getPos()[0], food.getPos()[1]), food.getType()) #self.worldGraph.plotCircle((1,1), food.pos, self.colorGreen) self.worldGraph.draw(self.canvas) for type in self.tracked_types: if type == self.TRACK_ENERGY: for t in sorted(states.keys()): static.loadDynamicState(states[t]) for animat in static.animats: self.tracked_data[animat.id][type][t] = animat.Energy elif type == self.TRACK_NEURAL_FIRINGS: for t in sorted(states.keys()): static.loadDynamicState(states[t]) for animat in static.animats: self.tracked_data[animat.id][type][t] = animat.net.get_neurons_firing() elif type == self.TRACK_POS: for t in sorted(states.keys()): static.loadDynamicState(states[t]) for animat in static.animats: self.tracked_data[animat.id][type][t] = animat.pos elif type == self.TRACK_LFP: continue for t in sorted(states.keys()): static.loadDynamicState(states[t]) for animat in static.animats: self.tracked_data[animat.id][type][t] = np.mean(animat.net.v.as_numpy_array()[animat.net.excitatoryNeurons]) # 4. Regardless of displaying a World, the program needs to make sure that the display time is reasonable and update the video control bar self.buff_t = sorted(self.simHistory.keys())[len(self.simHistory.keys())-1] #set the buffered time to the latest time in history if (self.dis_t > self.buff_t): self.dis_t = self.buff_t #sets the display time to the buffered time, if ahead if (self.dis_t < 0): self.dis_t = 0 #sets the display time to 0, if below 0 self.videoBar.update(dis_t_int, self.buff_t) #updates the video bar with the displayed time and the buffered time self.videoBar.draw() # 5. Reschedule another refresh! self.root.after(1 if int(np.floor(1000/10)) < 1 else int(np.floor(1000/10)), self.refreshScreen) #tells Tkinter to refresh the display again in 1/20 seconds #calculate the simulated time interval based on how many simulated ms per real-time seconds are supposed to be displayed def calculate_dis_dt(self, elapsedTime): if self.sim_msps == "synced": return self.buff_t - self.dis_t if self.sim_msps == "real-time": return int(round(elapsedTime * 1000)) self.sim_msps = self.speedScale.get() if self.sim_msps == 0: return 1 return int(round(float(self.sim_msps) * elapsedTime)) def play(self): self.paused = False self.playButton.config(relief='sunken') self.pauseButton.config(relief='raised') def pause(self): self.paused = True self.playButton.config(relief='raised') self.pauseButton.config(relief='sunken') def timeClicked(self, t): self.dis_t = t def simCtrl(self): if self.simRunning: self.simEngine.stopSimulation() self.simCtrlButton.config(text="Resume Simulation",bg='green') self.simRunning = False else: self.continue_() self.simCtrlButton.config(text="Stop Simulation",bg='red') self.simRunning = True def stop(self): self.simEngine.stopSimulation() def step_f(self): self.dis_t += self.writeInterval def step_b(self): self.dis_t -= self.writeInterval def realTime(self): self.sim_msps = "real-time" def synced(self): self.sim_msps = "synced" def chooseSpeed(self): self.sim_msps = self.speedScale.get() def saveCurrentSimulation(self): self.simEngine.stopSimulation() f = tkFileDialog.asksaveasfile(mode='w', **self.file_opt) cPickle.dump((self.simEngine.staticWorld, self.simHistory), f) if not f is None: f.close() def loadSimulationFromFile(self): f = tkFileDialog.askopenfile(mode='r', **self.file_opt) if f is None: return self.simEngine.loadSimulationFromFile(f) self.simHistory = {} self.dis_t = 0 self.buff_t = 0 self.videoBar.reset() self.paused = True ##MODIFY THISS!! def restart(self): self.dis_t = 0 self.buff_t = 0 self.paused = False self.simHistory = {} self.simEngine.startNewSim(self.sP) self.tracked_data = collections.defaultdict(lambda: collections.defaultdict(lambda: collections.OrderedDict())) self.lastTime = time.clock() self.videoBar.reset() self.simCtrlButton.config(text="Stop Simulation",bg='red') self.simRunning = True self.playButton.config(relief='sunken') self.pauseButton.config(relief='raised') def setWriteInterval(self, interval): self.writeInterval = interval self.simEngine.setWriteInterval(interval) def continue_(self): if len(self.simHistory) == 0 or self.simEngine.is_running(): return self.simEngine.continueSim(self.simHistory[self.buff_t], self.buff_t) def track(self, to_track): if to_track in self.tracked_types: return else: self.tracked_types.append(to_track) def quit(self): self.simEngine.stopSimulation() self.root.destroy() self.devWin.destroy() def makeStatMenu(self,foodNum): statMenu = tk.Menu(self.menubar,tearoff=0) animatMenu = tk.Menu(statMenu,tearoff=0) if self.world != 0: index = 0 for animat in self.world.animats: index += 1 animatMenu.add_command(label=("Animat " + str(index)), command=lambda:self.animatStatWindow(animat)) statMenu.add_cascade(label="Animats",menu=animatMenu) stimMenu = tk.Menu(statMenu,tearoff=0) foodMenu = tk.Menu(stimMenu,tearoff=0) for i in range(0,foodNum): foodMenu.add_command(label=("Food "+str(i+1)),command=self.foodStatWindow) stimMenu.add_cascade(label="Food",menu=foodMenu) statMenu.add_cascade(label="Stimuli",menu=stimMenu) self.menubar.add_cascade(label="Statistics",menu=statMenu) def animatStatWindow(self, anim): stats = anim.getStats() win = tk.Toplevel(height=600,width=700) #title and icon win.title("Animat Stats") # icon = tk.Label(win,image=self.aImage,relief="ridge") # icon.place(x=20,y=20) #stat list title = tk.Label(win,text="Stats for Animat: " + str(anim.id),font="bold",relief="ridge",padx=5,pady=5) type_l = tk.Label(win,text=("Type: ")) type_t = tk.Text(win,height=1,width=30,bg="grey") type_t.insert(tk.END,str(anim.__class__)) nrg_l = tk.Label(win,text=("Energy: ")) nrg_t = tk.Text(win,height=1,width=30,bg="grey") nrg_t.insert(tk.END,str(anim.Energy)) title2 = tk.Label(win,text="Internals",font="bold",relief="ridge",padx=5,pady=5) cme_l = tk.Label(win,text=("cMotionEnergy: ")) cme_t = tk.Text(win,height=1,width=30,bg="grey") cme_t.insert(tk.END,str(anim.cMotionEnergy)) kbe_l = tk.Label(win,text=("kBasalEnergy: ")) kbe_t = tk.Text(win,height=1,width=30,bg="grey") kbe_t.insert(tk.END,str(anim.kBasalEnergy)) tab_box = TabBox(win, [20, 250, 620, 550], toolbar=True) count = 1 for type in self.tracked_types: f = Figure(figsize=(5,4), dpi=50) a = f.add_subplot(111) t = self.tracked_data[anim.id][type].keys() s = self.tracked_data[anim.id][type].values() if type == self.TRACK_NEURAL_FIRINGS: t = [] s = [] for ti in self.tracked_data[anim.id][type].keys(): for si in self.tracked_data[anim.id][type][ti][0]: t.append(ti) s.append(si) if type == self.TRACK_POS: t = [] s = [] for ti in self.tracked_data[anim.id][type].keys(): t.append(self.tracked_data[anim.id][type][ti][0]) s.append(self.tracked_data[anim.id][type][ti][1]) if type == self.TRACK_NEURAL_FIRINGS: a.plot(t,s,'.k') else: a.plot(t,s,'-k') canvas = FigureCanvasTkAgg(f, master=win) tbcan = tab_box.add_canvas(canvas.get_tk_widget(), type) NavigationToolbar2TkAgg(canvas, tbcan) #placements title.place(x=300,y=20) type_l.place(x=300,y=60) type_t.place(x=390,y=60) nrg_l.place(x=300,y=90) nrg_t.place(x=390,y=90) title2.place(x=300,y=130) cme_l.place(x=300,y=170) cme_t.place(x=390,y=170) kbe_l.place(x=300,y=200) kbe_t.place(x=390,y=200) ## NEEDS IMPLEMENTATION def foodStatWindow(self): win = tk.Toplevel(height=600,width=700) #title and icon win.title("Food Stats") icon = tk.Label(win,image=self.fImage,relief="ridge") icon.place(x=20,y=20) #stat list title = tk.Label(win,text="Stats for Food 1",font="bold",relief="ridge",padx=5,pady=5) #placements title.place(x=300,y=20) def varViewer(self,time): win = tk.Toplevel(height=800,width=1100) win.title("Internal Variable Viewer") tBox = tk.Frame(win,height=500,width=700) h = len(self.simHistory[0].getS()) #get S because has highest number of rows w = len(self.simHistory[0].getA()) * 2 #get A because has highest number of columns vScroll = tk.Scrollbar(tBox,orient="vertical") hScroll = tk.Scrollbar(tBox,orient="horizontal") disBox = tk.Text(tBox,xscrollcommand=hScroll.set,yscrollcommand=vScroll.set) state = self.simHistory[time] #disBox.insert("INSERT",) #placements tBox.place(x=100,y=100) vScroll.pack(side="right",fill="y") hScroll.pack(side="bottom",fill="x") disBox.pack() def connectionViewer(self): win = tk.Toplevel(height=800,width=1100) win.title("Network Connection Viewer") fig = Figure(figsize=(10,10)) ax = fig.add_subplot(111,xlim=(-1.5, 1.5),ylim=(-1.5, 1.5)) netCircle = plt.Circle((0,0), radius = 1, fill = False ) ax.add_artist(netCircle) neurons = self.world.animats[0].net.getNeurons() locs = {} # used for storing neurons in index : location,color for neuron in neurons: ax.add_artist(plt.Circle((neuron.X,neuron.Y),radius=.025,facecolor=neuron.color,edgecolor='black')) locs[neuron.index] = (neuron.X,neuron.Y,neuron.color) for i,connectsFrom in enumerate(self.world.animats[0].net.S): startLoc = locs[i][0],locs[i][1]+.025 color = locs[i][2] for connectsTo in np.nonzero(connectsFrom)[0]: endLoc = locs[connectsTo][0],locs[connectsTo][1]-.025 weight = connectsFrom[connectsTo] ax.annotate("",xy=endLoc,xytext=startLoc,size=5, arrowprops=dict(arrowstyle="->", color=color)) #ax.annotate("",xy=(-1,0),xytext=(1,0),arrowprops=dict(arrowstyle="simple",connectionstyle="arc3,rad=0.3",alpha=0.3)) ax.add_artist(plt.Circle((1,1.35),radius=.025,facecolor=NeuronModule.ExcitatoryNeuron(0,0,0).color,edgecolor='black')) ax.add_artist(plt.Text(1.04,1.33,"Excitatory",size='small')) ax.add_artist(plt.Circle((1,1.25),radius=.025,facecolor=NeuronModule.SensoryNeuron_A(0,0,0).color,edgecolor='black')) ax.add_artist(plt.Text(1.04,1.23,"Sensory A",size='small')) ax.add_artist(plt.Circle((1,1.15),radius=.025,facecolor=NeuronModule.SensoryNeuron_B(0,0,0).color,edgecolor='black')) ax.add_artist(plt.Text(1.04,1.13,"Sensory B",size='small')) ax.add_artist(plt.Circle((1,1.05),radius=.025,facecolor=NeuronModule.MotorNeuron(0,0,0).color,edgecolor='black')) ax.add_artist(plt.Text(1.04,1.03,"Motor",size='small')) ax.add_artist(plt.Circle((1,0.95),radius=.025,facecolor=NeuronModule.HungerNeuron(0,0,0).color,edgecolor='black')) ax.add_artist(plt.Text(1.04,0.93,"Hunger",size='small')) ##Show plot canvas = FigureCanvasTkAgg(fig,master=win) canvas.show() canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) NavigationToolbar2TkAgg(canvas,win) #Used for debug, prints value of S to terminal def printS(self): S = self.world.animats[0].net.S print "S: \n" print "Excitatory Neurons" for i in self.world.animats[0].net.excitatoryNeurons: print S[i] print "Sensory A Neurons" for i in self.world.animats[0].net.senseNeurons_A: print S[i] print "Sensory B Neurons" for i in self.world.animats[0].net.senseNeurons_B: print S[i] print "Motor Neurons" for i in self.world.animats[0].net.motorNeurons: print S[i] print "Hunger Neurons" for i in self.world.animats[0].net.hungerNeurons: print S[i] def printRL(self): neurons = self.world.animats[0].net.getNeurons() print "Excitatory Neurons" for i in self.world.animats[0].net.excitatoryNeurons: print "R", neurons[i].r, "L", neurons[i].l print "Sensory A Neurons" for i in self.world.animats[0].net.senseNeurons_A: print "R", neurons[i].r, "L", neurons[i].l print "Sensory B Neurons" for i in self.world.animats[0].net.senseNeurons_B: print "R", neurons[i].r, "L", neurons[i].l print "Motor Neurons" for i in self.world.animats[0].net.motorNeurons: print "R", neurons[i].r, "L", neurons[i].l print "Hunger Neurons" for i in self.world.animats[0].net.hungerNeurons: print "R", neurons[i].r, "L", neurons[i].l def setWorldNum(self,num): self.sP.worldToRun = num def showDevWin(self): self.simEngine.stopSimulation() self.root.destroy() self.devWin.deiconify() def benchmark(self): for anim in self.world.animats: anim.calcBenchmark(self.buff_t,self.simEngine.getRunTime())
class GUIDriver: def __init__(self, master, devWin, simParams): self.sP = simParams #some parameters self.paused = False # whether simulation playback is paused self.simRunning = True # whether simulation is running - so buffering to GUI self.lastTime = 0 # the last time on the clock self.sim_msps = 0 # how many simulated milliseconds pass per second in display: i.e., a value of 1000 means real-time - useful for animat moving, but too fast to see neural activity self.dis_t = 1 #the time being currently displayed by the GUI self.buff_t = 0 #the time buffered by the Simulation Engine self.writeInterval = 25 # sets the interval between write states (in simulated ms); self.simHistory = {} # dictionary of time: dynamic world state self.tracked_data = collections.defaultdict( lambda: collections.defaultdict(lambda: collections.OrderedDict() )) # not clear what this is; SH self.TRACK_NEURAL_FIRINGS = "Neural Firings" self.TRACK_ENERGY = "Energy" self.TRACK_POS = "Position" self.TRACK_LFP = "LFP" # probably should give this another name self.tracked_types = [] self.simEngine = SimulationEngine() #constructs a Simulation Engine self.world = 0 #placeholder for the World currently being displayed self.devWin = devWin # development window is parent; use this to set up parameters #some general-purpose colors self.colorWhite = "#ffffff" self.colorGrey = "#dddddd" self.colorBlack = "#000000" self.colorLightBlue = "#ADD8E6" self.colorBlue = "#0000ff" self.colorRed = "#ff0000" self.colorGreen = "#00ff00" #setting up Tk window self.root = master # window passed in self.root.title("Animat Simulation") self.canvas = tk.Canvas(self.root, width=1280, height=720) self.canvas.pack() #set up file options to save simulations self.file_opt = options = {} options['defaultextension'] = '.sim' options['filetypes'] = [('all files', '.*'), ('text files', '.txt'), ('Simulation Files', '.sim')] #options['initialdir'] = 'C:\\' options['initialfile'] = '.sim' options['parent'] = self.root options['title'] = 'Save Simulation As...' #set up menu bar self.menubar = tk.Menu(self.root) filemenu = tk.Menu(self.menubar, tearoff=0) filemenu.add_command(label="Save Current Simulation", command=self.saveCurrentSimulation) filemenu.add_command(label="Load Simulation from File", command=self.loadSimulationFromFile) filemenu.add_command(label="Calculate Benchmark", command=self.benchmark) filemenu.add_separator() filemenu.add_command(label="Exit", command=self.quit) self.menubar.add_cascade(label="File", menu=filemenu) speedmenu = tk.Menu(self.menubar, tearoff=0) speedCheckVar = tk.IntVar() speedmenu.add_radiobutton(label="1ms", variable=speedCheckVar, command=lambda: self.setWriteInterval(1)) speedmenu.add_radiobutton(label="25ms", variable=speedCheckVar, command=lambda: self.setWriteInterval(25)) speedmenu.add_radiobutton(label="50ms", variable=speedCheckVar, command=lambda: self.setWriteInterval(50)) speedmenu.add_radiobutton(label="100ms", variable=speedCheckVar, command=lambda: self.setWriteInterval(100)) speedmenu.add_radiobutton(label="1s", variable=speedCheckVar, command=lambda: self.setWriteInterval(1000)) speedmenu.add_radiobutton(label="Do not write", variable=speedCheckVar) speedmenu.invoke(1) #default write interval is 100 worldmenu = tk.Menu(self.menubar, tearoff=0) worldVar = tk.IntVar() #not used just required worldmenu.add_radiobutton(label="World 1", variable=worldVar, command=lambda: self.setWorldNum(1)) worldmenu.add_radiobutton(label="World 2", variable=worldVar, command=lambda: self.setWorldNum(2)) worldmenu.add_radiobutton(label="World 3", variable=worldVar, command=lambda: self.setWorldNum(3)) worldmenu.add_radiobutton(label="World 4", variable=worldVar, command=lambda: self.setWorldNum(4)) worldmenu.add_radiobutton(label="World 5", variable=worldVar, command=lambda: self.setWorldNum(5)) speedmenu.invoke(self.sP.worldToRun - 1) #default write interval is 25 editmenu = tk.Menu(self.menubar, tearoff=0) editmenu.add_cascade(label="Write Interval", menu=speedmenu) editmenu.add_cascade(label="World to Run", menu=worldmenu) editmenu.add_command(label="Parameters", command=self.showDevWin) self.menubar.add_cascade(label="Edit", menu=editmenu) trackmenu = tk.Menu(self.menubar, tearoff=0) trackmenu.add_checkbutton( label="Neural Firings", command=lambda: self.track(self.TRACK_NEURAL_FIRINGS)) trackmenu.add_checkbutton( label="Energy", command=lambda: self.track(self.TRACK_ENERGY)) trackmenu.add_checkbutton(label="Position", command=lambda: self.track(self.TRACK_POS)) trackmenu.add_checkbutton(label="LFP", command=lambda: self.track(self.TRACK_LFP)) trackmenu.invoke(0) trackmenu.invoke(1) trackmenu.invoke(2) trackmenu.invoke(3) self.menubar.add_cascade(label="Track", menu=trackmenu) viewMenu = tk.Menu(self.menubar, tearoff=0) viewMenu.add_command(label="Internal Variables", command=self.varViewer) viewMenu.add_command(label="Connection Viewer", command=self.connectionViewer) self.menubar.add_cascade(label="View", menu=viewMenu) debugMenu = tk.Menu(self.menubar, tearoff=0) debugMenu.add_command(label="Print S", command=self.printS) debugMenu.add_command(label="Print RL", command=self.printRL) self.menubar.add_cascade(label="Debug", menu=debugMenu) self.root.config(menu=self.menubar) #initialize the graphs and video control bar self.worldGraph = Graph(self.root, [100, 50, 500, 475], [-10, 10, -10, 10]) self.worldGraph.title('World') self.worldGraph.xlabel('distance') self.neuron_graphs = {} self.neuron_box = TabBox(self.root, [600, 50, 1000, 475]) self.videoBar = VideoBar(self.canvas, (100, 515, 500, 525), (0, 15000), self.timeClicked) #some images--will probably eventually go in respective classes (static state) - can remove self.animatImage = Image.open("roomba.png") self.aImage = ImageTk.PhotoImage(self.animatImage) self.foodImage = Image.open("beer.png") self.fImage = ImageTk.PhotoImage(self.foodImage) playImage = ImageTk.PhotoImage( Image.open("play.png").resize((40, 40), Image.ANTIALIAS)) pauseImage = ImageTk.PhotoImage( Image.open("pause.png").resize((40, 40), Image.ANTIALIAS)) stopImage = ImageTk.PhotoImage( Image.open("stop.png").resize((40, 40), Image.ANTIALIAS)) restartImage = ImageTk.PhotoImage( Image.open("restart.png").resize((40, 40), Image.ANTIALIAS)) step_fImage = ImageTk.PhotoImage( Image.open("step_f.png").resize((40, 40), Image.ANTIALIAS)) step_bImage = ImageTk.PhotoImage( Image.open("step_b.png").resize((40, 40), Image.ANTIALIAS)) continueImage = ImageTk.PhotoImage( Image.open("continue.png").resize((40, 40), Image.ANTIALIAS)) #video control buttons self.playButton = tk.Button(self.root, command=self.play, image=playImage, relief='sunken') self.playButton.place(x=100, y=545) self.pauseButton = tk.Button(self.root, command=self.pause, image=pauseImage, relief='raised') self.pauseButton.place(x=155, y=545) # self.stopButton = tk.Button(self.root, command = self.stop, image = stopImage) # self.stopButton.place(x=320, y=545) self.restartButton = tk.Button(self.root, command=self.restart, text="Start New Simulation") self.restartButton.place(x=320, y=575) self.step_bButton = tk.Button(self.root, command=self.step_b, image=step_bImage) self.step_bButton.place(x=210, y=545) self.step_fButton = tk.Button(self.root, command=self.step_f, image=step_fImage) self.step_fButton.place(x=265, y=545) # self.continueButton = tk.Button(self.root, command = self.continue_, image = continueImage) # self.continueButton.place(x=430, y=545) self.simCtrlButton = tk.Button(self.root, command=self.simCtrl, text="Stop Simulation", bg='red') self.simCtrlButton.place(x=320, y=545) # Buttons using images # self.playButton = tk.Button(self.root, command = self.play, text="Play", relief='sunken') # self.playButton.place(x = 100,y=545) # self.pauseButton = tk.Button(self.root, command = self.pause, text="Pause", relief='raised') # self.pauseButton.place(x=155,y=545) # # self.stopButton = tk.Button(self.root, command = self.stop, image = stopImage) # # self.stopButton.place(x=320, y=545) # self.restartButton = tk.Button(self.root, command = self.restart, text="Start New Simulation") # self.restartButton.place(x=320, y=575) # self.step_bButton = tk.Button(self.root, command = self.step_b, text = "Step <-") # self.step_bButton.place(x=210,y=545) # self.step_fButton = tk.Button(self.root, command = self.step_f, text = "Step ->") # self.step_fButton.place(x=265, y=545) # # self.continueButton = tk.Button(self.root, command = self.continue_, image = continueImage) # # self.continueButton.place(x=430, y=545) # self.simCtrlButton = tk.Button(self.root, command=self.simCtrl, text="Stop Simulation",bg='red') # self.simCtrlButton.place(x=320,y=545) #speed lock buttons self.speedButtons = tk.IntVar() rb1 = tk.Radiobutton(self.root, text="Real-Time", variable=self.speedButtons, value=1, command=self.realTime) rb1.place(x=100, y=600) rb2 = tk.Radiobutton(self.root, text="Synced", variable=self.speedButtons, value=2, command=self.synced) rb3 = tk.Radiobutton(self.root, text="Select:", variable=self.speedButtons, value=3, command=self.chooseSpeed) rb2.place(x=100, y=630) rb3.place(x=100, y=660) spdlabel = self.canvas.create_text(357, 635, text="Select Speed (ms/s)") self.speedScale = tk.Scale(self.root, from_=0, to=500, orient="horizontal", length=300) self.speedScale.place(x=215, y=645) rb3.invoke() #needs to be called after speed scale is created #Create legend for neuron map tk.Label(self.root, text="Neural Network Legend", font="bold", relief="ridge", padx=5, pady=5).place(x=1050, y=100) #inhib_t = tk.Label(self.root, text="Inhibitory Neuron: ") #inhib_t.place(x=1050,y=150) #inhib_c = self.canvas.create_oval(1175,150,1200,175, fill = "#b1b1ff") tk.Label(self.root, text="Excitatory Neuron: ").place(x=1050, y=150) self.canvas.create_oval(1200, 150, 1225, 175, fill=NeuronModule.ExcitatoryNeuron(0, 0, 0).color) tk.Label(self.root, text="Hunger Neuron: ").place(x=1050, y=200) self.canvas.create_oval(1200, 200, 1225, 225, fill=NeuronModule.HungerNeuron(0, 0, 0).color) tk.Label(self.root, text="Motor Neuron: ").place(x=1050, y=250) self.canvas.create_oval(1200, 250, 1225, 275, fill=NeuronModule.MotorNeuron(0, 0, 0).color) tk.Label(self.root, text="Sensory Neuron A: ").place(x=1050, y=300) self.canvas.create_oval(1200, 300, 1225, 325, fill=NeuronModule.SensoryNeuron_A(0, 0, 0).color) tk.Label(self.root, text="Sensory Neuron B: ").place(x=1050, y=350) self.canvas.create_oval(1200, 350, 1225, 375, fill=NeuronModule.SensoryNeuron_B(0, 0, 0).color) #pack up the Frame and run mainContainer = tk.Frame(self.root) mainContainer.pack() self.run() #runs a simulation, for now self.root.mainloop() #starts the Tkinter event loop #called to start a new simulation def run(self): self.simEngine.startNewSim(self.sP) #starts a new simulation self.world = self.simEngine.staticWorld self.simEngine.setWriteInterval( self.writeInterval) #sets the write interval of the simulator self.worldGraph.set_numBounds(self.simEngine.staticWorld.numBounds ) # bounds of box animat is contained self.makeStatMenu(3) self.root.after( 0, self.refreshScreen ) #adds task to refresh screen information - starts animation self.lastTime = time.clock() #clocks the start of the simulation #self.makeStatMenu(3) #right now hardcoded to 3 food items #main GUI refresh method def refreshScreen(self): # 1. The program needs to get the new states produced by the Simulation Engine since the last screen refresh. static, states = self.simEngine.getNewStates( ) #the Simulation Engine passes back new states and the static world self.simHistory.update( states) #updates the GUI's simulation history with the new states # 2. The program needs to figure out what time to display based on the selected speed and what has been recorded. systime = time.clock() #gets the system time elapsed_time = systime - self.lastTime #calculates the elapsed time from the last time the loop was run self.lastTime = systime #records new system time for the next loop if not self.paused and self.dis_t <= self.buff_t: #advances the displayed time, as long as it's not ahead of the simulation and is not paused self.dis_t += self.calculate_dis_dt(elapsed_time) dis_t_int = int( np.floor(self.dis_t / self.writeInterval) * self.writeInterval ) #finds the displayed time based on the write interval: I.E., requests closest written time to the time that should be displayed # 3. If able to find the displayed time in recorded simulation history, the program needs to store and display the corresponding World graphically if dis_t_int in self.simHistory.keys(): # 3.a. loads ands stores the World static.loadDynamicState( self.simHistory[dis_t_int] ) #loads the dynamic state at the displayed time into the static World object self.world = static #sets this loaded world as the GUI's world for other menus, etc # 3.b. displays the World on two Graph objects and draws them #plot the world: the Animat and food, for now for animat in self.world.animats: self.worldGraph.plotCircle( (animat.radius * 2, animat.radius * 2), (animat.pos[0], animat.pos[1]), self.colorGrey) headPos = animat.pos[0] + (animat.radius) * np.cos( animat.direc), animat.pos[1] + (animat.radius) * np.sin( animat.direc) self.worldGraph.plotCircle((.2, .2), headPos, self.colorBlack) self.worldGraph.plotText( ("Purisa", 6), (animat.pos[0], animat.pos[1]), animat.id) if not (animat.id in self.neuron_graphs.iterkeys()): neuronGraph = Graph(self.root, self.neuron_box.content_bounds, [-1.3, 1.3, -1.3, 1.3]) self.neuron_graphs[animat.id] = neuronGraph self.neuron_box.add(neuronGraph, animat.id) neuronGraph = self.neuron_graphs[animat.id] neuronGraph.plotCircle((2, 2), (0, 0), self.colorWhite) neurons = animat.net.getNeurons() for neuron in neurons: neuronGraph.plotCircle( (.05, .05), (neuron.X, neuron.Y), neuron.firing_color if neuron.isFiring() else neuron.color) neuronGraph.draw(self.canvas) for food in self.world.foods: #foodImage = self.worldGraph.size_up(Image.open(food.image), (1,1), 0) if food.amt > 0.0: self.worldGraph.plotCircle((1, 1), food.getPos(), self.colorGreen) self.worldGraph.plotText( ("Purisa", 6), (food.getPos()[0], food.getPos()[1]), food.getType()) #self.worldGraph.plotCircle((1,1), food.pos, self.colorGreen) self.worldGraph.draw(self.canvas) for type in self.tracked_types: if type == self.TRACK_ENERGY: for t in sorted(states.keys()): static.loadDynamicState(states[t]) for animat in static.animats: self.tracked_data[animat.id][type][t] = animat.Energy elif type == self.TRACK_NEURAL_FIRINGS: for t in sorted(states.keys()): static.loadDynamicState(states[t]) for animat in static.animats: self.tracked_data[animat.id][type][ t] = animat.net.get_neurons_firing() elif type == self.TRACK_POS: for t in sorted(states.keys()): static.loadDynamicState(states[t]) for animat in static.animats: self.tracked_data[animat.id][type][t] = animat.pos elif type == self.TRACK_LFP: continue for t in sorted(states.keys()): static.loadDynamicState(states[t]) for animat in static.animats: self.tracked_data[animat.id][type][t] = np.mean( animat.net.v.as_numpy_array()[ animat.net.excitatoryNeurons]) # 4. Regardless of displaying a World, the program needs to make sure that the display time is reasonable and update the video control bar self.buff_t = sorted(self.simHistory.keys())[ len(self.simHistory.keys()) - 1] #set the buffered time to the latest time in history if (self.dis_t > self.buff_t): self.dis_t = self.buff_t #sets the display time to the buffered time, if ahead if (self.dis_t < 0): self.dis_t = 0 #sets the display time to 0, if below 0 self.videoBar.update( dis_t_int, self.buff_t ) #updates the video bar with the displayed time and the buffered time self.videoBar.draw() # 5. Reschedule another refresh! self.root.after( 1 if int(np.floor(1000 / 10)) < 1 else int(np.floor(1000 / 10)), self.refreshScreen ) #tells Tkinter to refresh the display again in 1/20 seconds #calculate the simulated time interval based on how many simulated ms per real-time seconds are supposed to be displayed def calculate_dis_dt(self, elapsedTime): if self.sim_msps == "synced": return self.buff_t - self.dis_t if self.sim_msps == "real-time": return int(round(elapsedTime * 1000)) self.sim_msps = self.speedScale.get() if self.sim_msps == 0: return 1 return int(round(float(self.sim_msps) * elapsedTime)) def play(self): self.paused = False self.playButton.config(relief='sunken') self.pauseButton.config(relief='raised') def pause(self): self.paused = True self.playButton.config(relief='raised') self.pauseButton.config(relief='sunken') def timeClicked(self, t): self.dis_t = t def simCtrl(self): if self.simRunning: self.simEngine.stopSimulation() self.simCtrlButton.config(text="Resume Simulation", bg='green') self.simRunning = False else: self.continue_() self.simCtrlButton.config(text="Stop Simulation", bg='red') self.simRunning = True def stop(self): self.simEngine.stopSimulation() def step_f(self): self.dis_t += self.writeInterval def step_b(self): self.dis_t -= self.writeInterval def realTime(self): self.sim_msps = "real-time" def synced(self): self.sim_msps = "synced" def chooseSpeed(self): self.sim_msps = self.speedScale.get() def saveCurrentSimulation(self): self.simEngine.stopSimulation() f = tkFileDialog.asksaveasfile(mode='w', **self.file_opt) cPickle.dump((self.simEngine.staticWorld, self.simHistory), f) if not f is None: f.close() def loadSimulationFromFile(self): f = tkFileDialog.askopenfile(mode='r', **self.file_opt) if f is None: return self.simEngine.loadSimulationFromFile(f) self.simHistory = {} self.dis_t = 0 self.buff_t = 0 self.videoBar.reset() self.paused = True ##MODIFY THISS!! def restart(self): self.dis_t = 0 self.buff_t = 0 self.paused = False self.simHistory = {} self.simEngine.startNewSim(self.sP) self.tracked_data = collections.defaultdict( lambda: collections.defaultdict(lambda: collections.OrderedDict())) self.lastTime = time.clock() self.videoBar.reset() self.simCtrlButton.config(text="Stop Simulation", bg='red') self.simRunning = True self.playButton.config(relief='sunken') self.pauseButton.config(relief='raised') def setWriteInterval(self, interval): self.writeInterval = interval self.simEngine.setWriteInterval(interval) def continue_(self): if len(self.simHistory) == 0 or self.simEngine.is_running(): return self.simEngine.continueSim(self.simHistory[self.buff_t], self.buff_t) def track(self, to_track): if to_track in self.tracked_types: return else: self.tracked_types.append(to_track) def quit(self): self.simEngine.stopSimulation() self.root.destroy() self.devWin.destroy() def makeStatMenu(self, foodNum): statMenu = tk.Menu(self.menubar, tearoff=0) animatMenu = tk.Menu(statMenu, tearoff=0) if self.world != 0: index = 0 for animat in self.world.animats: index += 1 animatMenu.add_command( label=("Animat " + str(index)), command=lambda: self.animatStatWindow(animat)) statMenu.add_cascade(label="Animats", menu=animatMenu) stimMenu = tk.Menu(statMenu, tearoff=0) foodMenu = tk.Menu(stimMenu, tearoff=0) for i in range(0, foodNum): foodMenu.add_command(label=("Food " + str(i + 1)), command=self.foodStatWindow) stimMenu.add_cascade(label="Food", menu=foodMenu) statMenu.add_cascade(label="Stimuli", menu=stimMenu) self.menubar.add_cascade(label="Statistics", menu=statMenu) def animatStatWindow(self, anim): stats = anim.getStats() win = tk.Toplevel(height=600, width=700) #title and icon win.title("Animat Stats") # icon = tk.Label(win,image=self.aImage,relief="ridge") # icon.place(x=20,y=20) #stat list title = tk.Label(win, text="Stats for Animat: " + str(anim.id), font="bold", relief="ridge", padx=5, pady=5) type_l = tk.Label(win, text=("Type: ")) type_t = tk.Text(win, height=1, width=30, bg="grey") type_t.insert(tk.END, str(anim.__class__)) nrg_l = tk.Label(win, text=("Energy: ")) nrg_t = tk.Text(win, height=1, width=30, bg="grey") nrg_t.insert(tk.END, str(anim.Energy)) title2 = tk.Label(win, text="Internals", font="bold", relief="ridge", padx=5, pady=5) cme_l = tk.Label(win, text=("cMotionEnergy: ")) cme_t = tk.Text(win, height=1, width=30, bg="grey") cme_t.insert(tk.END, str(anim.cMotionEnergy)) kbe_l = tk.Label(win, text=("kBasalEnergy: ")) kbe_t = tk.Text(win, height=1, width=30, bg="grey") kbe_t.insert(tk.END, str(anim.kBasalEnergy)) tab_box = TabBox(win, [20, 250, 620, 550], toolbar=True) count = 1 for type in self.tracked_types: f = Figure(figsize=(5, 4), dpi=50) a = f.add_subplot(111) t = self.tracked_data[anim.id][type].keys() s = self.tracked_data[anim.id][type].values() if type == self.TRACK_NEURAL_FIRINGS: t = [] s = [] for ti in self.tracked_data[anim.id][type].keys(): for si in self.tracked_data[anim.id][type][ti][0]: t.append(ti) s.append(si) if type == self.TRACK_POS: t = [] s = [] for ti in self.tracked_data[anim.id][type].keys(): t.append(self.tracked_data[anim.id][type][ti][0]) s.append(self.tracked_data[anim.id][type][ti][1]) if type == self.TRACK_NEURAL_FIRINGS: a.plot(t, s, '.k') else: a.plot(t, s, '-k') canvas = FigureCanvasTkAgg(f, master=win) tbcan = tab_box.add_canvas(canvas.get_tk_widget(), type) NavigationToolbar2TkAgg(canvas, tbcan) #placements title.place(x=300, y=20) type_l.place(x=300, y=60) type_t.place(x=390, y=60) nrg_l.place(x=300, y=90) nrg_t.place(x=390, y=90) title2.place(x=300, y=130) cme_l.place(x=300, y=170) cme_t.place(x=390, y=170) kbe_l.place(x=300, y=200) kbe_t.place(x=390, y=200) ## NEEDS IMPLEMENTATION def foodStatWindow(self): win = tk.Toplevel(height=600, width=700) #title and icon win.title("Food Stats") icon = tk.Label(win, image=self.fImage, relief="ridge") icon.place(x=20, y=20) #stat list title = tk.Label(win, text="Stats for Food 1", font="bold", relief="ridge", padx=5, pady=5) #placements title.place(x=300, y=20) def varViewer(self, time): win = tk.Toplevel(height=800, width=1100) win.title("Internal Variable Viewer") tBox = tk.Frame(win, height=500, width=700) h = len(self.simHistory[0].getS() ) #get S because has highest number of rows w = len(self.simHistory[0].getA() ) * 2 #get A because has highest number of columns vScroll = tk.Scrollbar(tBox, orient="vertical") hScroll = tk.Scrollbar(tBox, orient="horizontal") disBox = tk.Text(tBox, xscrollcommand=hScroll.set, yscrollcommand=vScroll.set) state = self.simHistory[time] #disBox.insert("INSERT",) #placements tBox.place(x=100, y=100) vScroll.pack(side="right", fill="y") hScroll.pack(side="bottom", fill="x") disBox.pack() def connectionViewer(self): win = tk.Toplevel(height=800, width=1100) win.title("Network Connection Viewer") fig = Figure(figsize=(10, 10)) ax = fig.add_subplot(111, xlim=(-1.5, 1.5), ylim=(-1.5, 1.5)) netCircle = plt.Circle((0, 0), radius=1, fill=False) ax.add_artist(netCircle) neurons = self.world.animats[0].net.getNeurons() locs = {} # used for storing neurons in index : location,color for neuron in neurons: ax.add_artist( plt.Circle((neuron.X, neuron.Y), radius=.025, facecolor=neuron.color, edgecolor='black')) locs[neuron.index] = (neuron.X, neuron.Y, neuron.color) for i, connectsFrom in enumerate(self.world.animats[0].net.S): startLoc = locs[i][0], locs[i][1] + .025 color = locs[i][2] for connectsTo in np.nonzero(connectsFrom)[0]: endLoc = locs[connectsTo][0], locs[connectsTo][1] - .025 weight = connectsFrom[connectsTo] ax.annotate("", xy=endLoc, xytext=startLoc, size=5, arrowprops=dict(arrowstyle="->", color=color)) #ax.annotate("",xy=(-1,0),xytext=(1,0),arrowprops=dict(arrowstyle="simple",connectionstyle="arc3,rad=0.3",alpha=0.3)) ax.add_artist( plt.Circle((1, 1.35), radius=.025, facecolor=NeuronModule.ExcitatoryNeuron(0, 0, 0).color, edgecolor='black')) ax.add_artist(plt.Text(1.04, 1.33, "Excitatory", size='small')) ax.add_artist( plt.Circle((1, 1.25), radius=.025, facecolor=NeuronModule.SensoryNeuron_A(0, 0, 0).color, edgecolor='black')) ax.add_artist(plt.Text(1.04, 1.23, "Sensory A", size='small')) ax.add_artist( plt.Circle((1, 1.15), radius=.025, facecolor=NeuronModule.SensoryNeuron_B(0, 0, 0).color, edgecolor='black')) ax.add_artist(plt.Text(1.04, 1.13, "Sensory B", size='small')) ax.add_artist( plt.Circle((1, 1.05), radius=.025, facecolor=NeuronModule.MotorNeuron(0, 0, 0).color, edgecolor='black')) ax.add_artist(plt.Text(1.04, 1.03, "Motor", size='small')) ax.add_artist( plt.Circle((1, 0.95), radius=.025, facecolor=NeuronModule.HungerNeuron(0, 0, 0).color, edgecolor='black')) ax.add_artist(plt.Text(1.04, 0.93, "Hunger", size='small')) ##Show plot canvas = FigureCanvasTkAgg(fig, master=win) canvas.show() canvas.get_tk_widget().pack(side=tk.TOP, fill=tk.BOTH, expand=1) NavigationToolbar2TkAgg(canvas, win) #Used for debug, prints value of S to terminal def printS(self): S = self.world.animats[0].net.S print "S: \n" print "Excitatory Neurons" for i in self.world.animats[0].net.excitatoryNeurons: print S[i] print "Sensory A Neurons" for i in self.world.animats[0].net.senseNeurons_A: print S[i] print "Sensory B Neurons" for i in self.world.animats[0].net.senseNeurons_B: print S[i] print "Motor Neurons" for i in self.world.animats[0].net.motorNeurons: print S[i] print "Hunger Neurons" for i in self.world.animats[0].net.hungerNeurons: print S[i] def printRL(self): neurons = self.world.animats[0].net.getNeurons() print "Excitatory Neurons" for i in self.world.animats[0].net.excitatoryNeurons: print "R", neurons[i].r, "L", neurons[i].l print "Sensory A Neurons" for i in self.world.animats[0].net.senseNeurons_A: print "R", neurons[i].r, "L", neurons[i].l print "Sensory B Neurons" for i in self.world.animats[0].net.senseNeurons_B: print "R", neurons[i].r, "L", neurons[i].l print "Motor Neurons" for i in self.world.animats[0].net.motorNeurons: print "R", neurons[i].r, "L", neurons[i].l print "Hunger Neurons" for i in self.world.animats[0].net.hungerNeurons: print "R", neurons[i].r, "L", neurons[i].l def setWorldNum(self, num): self.sP.worldToRun = num def showDevWin(self): self.simEngine.stopSimulation() self.root.destroy() self.devWin.deiconify() def benchmark(self): for anim in self.world.animats: anim.calcBenchmark(self.buff_t, self.simEngine.getRunTime())
class DevelopmentWindow(): def __init__(self): self.worlds = [] ## Set up worlds fLocs1 = [(1, -2), (-4, -6), (-6, 1), (-2, 0), (1, -3), (3, 9), (10, 3), (-3, 6), (-2, -6), (10, 6), (-9, 1), (1, -2), (2, -2), (3, -9), (5, -1)] # testing out non symetric world # fLocs1 = [(2,0),(-2,0),(0,2),(0,-2),(0,3),(0,-3),(3,0),(-3,0),(4,0),(-4,0),(0,4),(0,-4),(0,7),(7,0),(-7,0)] fLocs2 = [(1, 1), (2, 2), (3, 3), (4, 4), (3, 5), (2, 6), (1, 7), (0, 8), (-2, 6), (-4, 4), (-6, 2), (-8, 0), (-5, 0), (-2, -3), (-5, -5)] fLocs3 = [(-2, 2), (-1, 0), (1, 0), (-1, 0), (2, -2), (3, 5), (-5, 5), (-8, 8), (10, 10), (-10, 10), (10, -10), (0, -1), (0, -2), (0, -3), (0, -4)] fLocs4 = [(random.random() * 20 - 20.0 / 2., random.random() * 20 - 20.0 / 2.) for i in xrange(20)] fLocs5 = [(random.random() * 20 - 20.0 / 2., random.random() * 20 - 20.0 / 2.) for i in xrange(20)] self.worlds.append([1, 15, 20, fLocs1]) self.worlds.append([1, 15, 20, fLocs2]) self.worlds.append([1, 15, 20, fLocs3]) self.worlds.append([1, 20, 20, fLocs4]) self.worlds.append([1, 20, 20, fLocs5]) #parameters self.sP = SimParam.SimParam() self.sP.setWorld( 1, self.worlds[0][0], self.worlds[0][1], self.worlds[0][2], self.worlds[0][3]) #change first index to change default world self.sP.setWorld(2, self.worlds[1][0], self.worlds[1][1], self.worlds[1][2], self.worlds[1][3]) self.sP.setWorld(3, self.worlds[2][0], self.worlds[2][1], self.worlds[2][2], self.worlds[2][3]) self.sP.setWorld(4, self.worlds[3][0], self.worlds[3][1], self.worlds[3][2], self.worlds[3][3]) self.sP.setWorld(5, self.worlds[4][0], self.worlds[4][1], self.worlds[4][2], self.worlds[4][3]) self.sP.setAnimParams(1, 1, (0, 0)) self.paused = True #paused? self.lastTime = 0 self.sim_msps = 0 self.dis_t = 1 #the t being displayed self.buff_t = 0 self.writeInterval = 100 self.simHistory = { } #this will fill with produced worlds from the simulations self.simEngine = SimulationEngine.SimulationEngine() self.developmentHistory = {} self.layoutHist = 300 #y value holder for new aniimat config button placement self.layoutList = [ ] # holds config/delete animat buttons and labels for any animats other than default #intialize TK self.root = tk.Tk() self.root.title("Development Simulation") self.canvas = tk.Canvas(self.root, width=1080, height=720) self.canvas.pack() #some general-purpose colors self.colorWhite = "#ffffff" self.colorGrey = "#dddddd" self.colorBlack = "#000000" self.colorLightBlue = "#ADD8E6" self.colorBlue = "#0000ff" self.colorRed = "#ff0000" #file options self.file_opt = options = {} options['defaultextension'] = '.netsim' options['filetypes'] = [('all files', '.*'), ('text files', '.txt'), ('Simulation Files', '.netsim')] #options['initialdir'] = 'C:\\' options['initialfile'] = '.netsim' options['parent'] = self.root options['title'] = 'Save Simulation As...' #set up menu bar menubar = tk.Menu(self.root) filemenu = tk.Menu(menubar, tearoff=0) filemenu.add_command(label="Start Simulation", command=self.startSimulation) filemenu.add_command(label="Save Current Development Simulation", command=self.saveCurrentSimulation) filemenu.add_command(label="Load Development from File", command=self.loadSimulationFromFile) filemenu.add_separator() filemenu.add_command(label="Load Results from Evolutionary Algorithm", command=self.loadEvo) filemenu.add_separator() filemenu.add_command(label="Exit", command=self.root.destroy) menubar.add_cascade(label="File", menu=filemenu) speedmenu = tk.Menu(menubar, tearoff=0) speedmenu.add_command(label="1ms", command=lambda: self.setWriteInterval(1)) speedmenu.add_command(label="25ms", command=lambda: self.setWriteInterval(25)) speedmenu.add_command(label="50ms", command=lambda: self.setWriteInterval(50)) speedmenu.add_command(label="100ms", command=lambda: self.setWriteInterval(100)) speedmenu.add_command(label="1s", command=lambda: self.setWriteInterval(1000)) speedmenu.add_command(label="Do not write") speedmenu.invoke(3) #default write interval is 100 editmenu = tk.Menu(menubar, tearoff=0) editmenu.add_command(label="Parameters", command=self.editParameters) editmenu.add_cascade(label="Write Interval", menu=speedmenu) menubar.add_cascade(label="Edit", menu=editmenu) self.root.config(menu=menubar) #Set up neuron graph and text log box and control bar self.neuronGraph = Graph(self.root, [75, 75, 475, 475], [-1.1, 1.1, -1.1, 1.1]) self.neuronGraph.plotCircle((2, 2), (0, 0), self.colorWhite) self.neuronGraph.title("Development") self.neuronGraph.xlabel("XAXIS") self.neuronGraph.ylabel("YAXIS") self.neuronGraph.draw(self.canvas) #Set up World Parameter Options self.animNum_sv = tk.StringVar() self.animNum_sv.set(str(self.sP.getAnimNum(1))) self.foodNum_sv = tk.StringVar() self.foodNum_sv.set(str(self.sP.getFoodNum(1))) self.arenaSize_sv = tk.StringVar() self.arenaSize_sv.set(str(self.sP.getWorldSize(1))) title = tk.Label(self.root, text="Parameter Settings", font="bold", relief="ridge", padx=5, pady=5) title.place(x=600, y=75) # animNum_l = tk.Label(self.root, text="Number of Animats:") # animNum_l.place(x=600,y=125) # animNum_e = tk.Entry(self.root, textvariable=self.animNum_sv) # animNum_e.place(x=750,y=125) foodNum_l = tk.Label(self.root, text="Number of Foods:") foodNum_l.place(x=600, y=125) foodNum_e = tk.Entry(self.root, textvariable=self.foodNum_sv) foodNum_e.place(x=750, y=125) arenaSize_l = tk.Label(self.root, text="World Size: ") arenaSize_l.place(x=600, y=150) arenaSize_e = tk.Entry(self.root, textvariable=self.arenaSize_sv) arenaSize_e.place(x=750, y=150) #button for retreiving parameters self.setParamButton = tk.Button(self.root, text="Set Parameters", command=self.saveParameters) self.setParamButton.place(x=675, y=175) title2 = tk.Label(self.root, text="Animat Settings", font="bold", relief="ridge", padx=5, pady=5) title2.place(x=600, y=250) defaultAnim_l = tk.Label(self.root, text="* Animat 1: ", font="bold") defaultAnim_l.place(x=600, y=300) #Animat Buttons animConfigButton = tk.Button(self.root, text="Configure Animat", command=lambda: self.configAnimat(0)) animConfigButton.place(x=700, y=300) newAnimButton = tk.Button(self.root, text="Add New Animat", bg='green', command=self.addAnimat) newAnimButton.place(x=750, y=250) self.videoBar = VideoBar(self.canvas, (100, 515, 500, 525), (0, 5000), self.timeClicked) #set up images playImage = ImageTk.PhotoImage( Image.open("play.png").resize((40, 40), Image.ANTIALIAS)) pauseImage = ImageTk.PhotoImage( Image.open("pause.png").resize((40, 40), Image.ANTIALIAS)) stopImage = ImageTk.PhotoImage( Image.open("stop.png").resize((40, 40), Image.ANTIALIAS)) restartImage = ImageTk.PhotoImage( Image.open("restart.png").resize((40, 40), Image.ANTIALIAS)) step_fImage = ImageTk.PhotoImage( Image.open("step_f.png").resize((40, 40), Image.ANTIALIAS)) step_bImage = ImageTk.PhotoImage( Image.open("step_b.png").resize((40, 40), Image.ANTIALIAS)) #video control buttons self.playButton = tk.Button(self.root, command=self.play, image=playImage) self.playButton.place(x=100, y=545) self.pauseButton = tk.Button(self.root, command=self.pause, image=pauseImage) self.pauseButton.place(x=155, y=545) self.stopButton = tk.Button(self.root, command=self.stop, image=stopImage) self.stopButton.place(x=210, y=545) self.restartButton = tk.Button(self.root, command=self.restart, image=restartImage) self.restartButton.place(x=265, y=545) self.step_bButton = tk.Button(self.root, command=self.step_b, image=step_bImage) self.step_bButton.place(x=320, y=545) self.step_fButton = tk.Button(self.root, command=self.step_f, image=step_fImage) self.step_fButton.place(x=375, y=545) #speed scale bar spdlabel = self.canvas.create_text(357, 615, text="Select Speed (ms/s)") self.speedScale = tk.Scale(self.root, from_=0, to=500, orient="horizontal", length=300) self.speedScale.place(x=215, y=625) self.root.after(0, self.refreshScreen) self.root.mainloop() def refreshScreen(self): #print(len(self.developmentHistory.keys())) if not self.paused: self.developmentHistory.update(self.simEngine.getNewDevelopments()) t = sorted(self.developmentHistory.keys())[ len(self.developmentHistory.keys()) - 1] network = self.developmentHistory[t] self.neuronGraph.plotCircle((2, 2), (0, 0), self.colorWhite) for neuron in network.getNeurons(): self.neuronGraph.plotCircle( (.05, .05), (neuron.X, neuron.Y), neuron.firing_color if neuron.isFiring() else neuron.color) self.neuronGraph.draw(self.canvas) self.root.after( 1 if int(np.floor(1000 / 20)) < 1 else int(np.floor(1000 / 20)), self.refreshScreen) #Button Functions def play(self): self.simEngine.startNewDevelopmentSim() self.paused = False def pause(self): pass def stop(self): self.simEngine.stopSimulation() def restart(self): self.developmentHistory = {} self.simEngine.startNewDevelopmentSim() def step_b(self): pass def step_f(self): pass def timeClicked(self): pass def saveParameters(self): self.sP.setWorld((int)(self.animNum_sv.get()), self.foodNum_sv.get(), self.arenaSize_sv.get()) #self.parameters[0] = (int)(self.animNum_sv.get()) #self.parameters[1] = (int)(self.foodNum_sv.get()) #self.parameters[2] = (int)(self.arenaSize_sv.get()) saved = tk.Label(self.root, text="***SAVED***", font="bold", fg="red") saved.place(x=775, y=75) saved.after(2000, saved.destroy) def configAnimat(self, id): self.win = tk.Toplevel(height=600, width=700) self.win.title("Animat Configuration") title = tk.Label(self.win, text="Configure Animat", font="bold", relief="ridge", padx=5, pady=5) #set up entry variables self.type_sv = tk.StringVar() self.type_sv.set(str(self.sP.getType(id))) self.origin_sv = tk.StringVar() self.origin_sv.set(str(self.sP.getOrigin(id))) self.cal_sv = tk.StringVar() self.cal_sv.set(str(self.sP.getCalories(id))) self.inhibNum_sv = tk.StringVar() temp = self.sP.getInhib(id) self.inhibNum_sv.set(temp[0]) self.inhibA_sv = tk.StringVar() self.inhibA_sv.set(temp[1]) self.inhibB_sv = tk.StringVar() self.inhibB_sv.set(temp[2]) self.inhibC_sv = tk.StringVar() self.inhibC_sv.set(temp[3]) self.inhibD_sv = tk.StringVar() self.inhibD_sv.set(temp[4]) temp = self.sP.getExcit(id) self.excitNum_sv = tk.StringVar() self.excitNum_sv.set(temp[0]) self.excitA_sv = tk.StringVar() self.excitA_sv.set(temp[1]) self.excitB_sv = tk.StringVar() self.excitB_sv.set(temp[2]) self.excitC_sv = tk.StringVar() self.excitC_sv.set(temp[3]) self.excitD_sv = tk.StringVar() self.excitD_sv.set(temp[4]) #labels and entries type_l = tk.Label(self.win, text="Type: ", font="bold") self.type_e = tk.Entry(self.win, textvariable=self.type_sv) origin_l = tk.Label(self.win, text="Origin: ", font="bold") self.origin_e = tk.Entry(self.win, textvariable=self.origin_sv) cal_l = tk.Label(self.win, text="Calories: ", font="bold") self.cal_e = tk.Entry(self.win, textvariable=self.cal_sv) inhibNum_l = tk.Label(self.win, text="Inhibitory Neurons:", font="bold") self.inhibNum_e = tk.Entry(self.win, textvariable=self.inhibNum_sv) inhibA_l = tk.Label(self.win, text="a:", font="bold") self.inhibA_e = tk.Entry(self.win, textvariable=self.inhibA_sv, width=4) inhibB_l = tk.Label(self.win, text="b:", font="bold") self.inhibB_e = tk.Entry(self.win, textvariable=self.inhibB_sv, width=4) inhibC_l = tk.Label(self.win, text="c:", font="bold") self.inhibC_e = tk.Entry(self.win, textvariable=self.inhibC_sv, width=4) inhibD_l = tk.Label(self.win, text="d:", font="bold") self.inhibD_e = tk.Entry(self.win, textvariable=self.inhibD_sv, width=4) excitNum_l = tk.Label(self.win, text="Excitatory Neurons:", font="bold") self.excitNum_e = tk.Entry(self.win, textvariable=self.excitNum_sv) excitA_l = tk.Label(self.win, text="a:", font="bold") self.excitA_e = tk.Entry(self.win, textvariable=self.excitA_sv, width=4) excitB_l = tk.Label(self.win, text="b:", font="bold") self.excitB_e = tk.Entry(self.win, textvariable=self.excitB_sv, width=4) excitC_l = tk.Label(self.win, text="c:", font="bold") self.excitC_e = tk.Entry(self.win, textvariable=self.excitC_sv, width=4) excitD_l = tk.Label(self.win, text="d:", font="bold") self.excitD_e = tk.Entry(self.win, textvariable=self.excitD_sv, width=4) #placements title.place(x=2, y=2) type_l.place(x=40, y=50) self.type_e.place(x=185, y=50) origin_l.place(x=40, y=75) self.origin_e.place(x=185, y=75) cal_l.place(x=40, y=100) self.cal_e.place(x=185, y=100) inhibNum_l.place(x=40, y=125) self.inhibNum_e.place(x=185, y=125) inhibA_l.place(x=260, y=125) self.inhibA_e.place(x=280, y=125) inhibB_l.place(x=310, y=125) self.inhibB_e.place(x=330, y=125) inhibC_l.place(x=360, y=125) self.inhibC_e.place(x=380, y=125) inhibD_l.place(x=410, y=125) self.inhibD_e.place(x=430, y=125) excitNum_l.place(x=40, y=150) self.excitNum_e.place(x=185, y=150) excitA_l.place(x=260, y=150) self.excitA_e.place(x=280, y=150) excitB_l.place(x=310, y=150) self.excitB_e.place(x=330, y=150) excitC_l.place(x=360, y=150) self.excitC_e.place(x=380, y=150) excitD_l.place(x=410, y=150) self.excitD_e.place(x=430, y=150) saveButton = tk.Button(self.win, text="Save Configuration", command=lambda: self.saveAnimat(id)) saveButton.place(x=200, y=200) def saveAnimat(self, id): self.sP.setType(id, self.type_e.get()) self.sP.setOrigin( id, (int(self.origin_e.get()[1]), int(self.origin_e.get()[4]))) self.sP.setCalories(id, int(self.cal_e.get())) inhib = [ int(self.inhibNum_e.get()), float(self.inhibA_e.get()), float(self.inhibB_e.get()), float(self.inhibC_e.get()), float(self.inhibD_e.get()) ] excit = [ int(self.excitNum_e.get()), float(self.excitA_e.get()), float(self.excitB_e.get()), float(self.excitC_e.get()), float(self.excitD_e.get()) ] self.sP.setInhib(id, inhib) self.sP.setExcit(id, excit) self.win.destroy() def addAnimat(self): self.sP.setAnimNum(1, self.sP.getAnimNum(1) + 1) #self.parameters[0] += 1 #increase animatNum by 1 self.layoutHist += 50 #shift current y value down #id = self.sP.getAnimNum() - 1 #-1 beacause index = id-1 self.sP.setAnimParams(self.sP.getAnimNum(), "Wheel Animat", (1, 0), 10, [80, .02, .25, -65, 2], [320, .02, .2, -65, 8]) newLabel = tk.Label(self.root, text=("* Animat: " + str(self.sP.getAnimNum())), font="bold") newConfigButton = tk.Button(self.root, text="Configure Animat", command=lambda: self.configAnimat(id)) newDeleteButton = tk.Button(self.root, text="Remove Animat", command=lambda: self.deleteAnimat(id)) self.layoutList.append([newLabel, newConfigButton, newDeleteButton]) newLabel.place(x=600, y=self.layoutHist) newConfigButton.place(x=700, y=self.layoutHist) newDeleteButton.place(x=825, y=self.layoutHist) newConfigButton.invoke() ##NEED TO ADAPT TO simParam FIGURE OUT WORLD ANIM ID IMPLEMENTATION FIRST def deleteAnimat(self, id): pass # del self.animatParams[id] # self.layoutHist -= 50 # self.parameters[0] -= 1 # label,config,delete = self.layoutList[id-1] # label.destroy() # config.destroy() # delete.destroy() # del self.layoutList[id-1] #Menu Bar Functions def startSimulation(self): self.simWin = tk.Toplevel(self.root) self.root.withdraw() self.simEngine.stopSimulation() self.gui = GUIdriver.GUIDriver(self.simWin, self.root, self.sP) #NEED TO IMPLEMENT AFTER def loadEvo(self): #pass fn = tkFileDialog.askopenfilename() with open(fn, 'r') as f: evoParams = json.load(f) # print evoParams self.sP.setAnimParams(1, 1, evoParams[1], evoParams[2], evoParams[3], evoParams[4], evoParams[5]) self.sP.setAA(1, evoParams[6]) self.sP.setBB(1, evoParams[7]) self.simWin = tk.Toplevel(self.root) self.root.withdraw() self.simEngine.stopSimulation() self.gui = GUIdriver.GUIDriver(self.simWin, self.root, self.sP) def editParameters(self): paramWin = ParametersWindow.ParameterWindow() def saveCurrentSimulation(self): self.simEngine.stopSimulation() f = tkFileDialog.asksaveasfile(mode='w', **self.file_opt) cPickle.dump((self.simEngine.staticWorld, self.simHistory), f) if not f is None: f.close() def loadSimulationFromFile(self): f = tkFileDialog.askopenfile(mode='r', **self.file_opt) if f is None: return self.simEngine.loadSimulationFromFile(f) self.simHistory = {} self.dis_t = 0 self.buff_t = 0 self.videoBar.reset() self.paused = True def setWriteInterval(self, t): self.simEngine.setWriteInterval(t)