Beispiel #1
0
 def openSonarMonitor(self):
   if not self.sonarMonitor:
     if self.toolbar.buttons['eBot'].cget('relief') == SUNKEN:
       self.sonarMonitor = SonarMonitor(soar.outputs.eBot.EBOT_POINTS,
                                          self.sonarmon_geom)
     elif self.toolbar.buttons['Amigosimulator'].cget('relief') == SUNKEN:
       self.sonarMonitor = AmigoSonarMonitor(soar.outputs.amigo_simulator.ROBOT_POINTS,
                                            self.sonarmon_geom)
     elif self.toolbar.buttons['simulator'].cget('relief') == SUNKEN:
       self.sonarMonitor = SonarMonitor(soar.outputs.simulator.ROBOT_POINTS,
                                            self.sonarmon_geom)
     elif self.toolbar.buttons['pioneer'].cget('relief') == SUNKEN:
       self.sonarMonitor = AmigoSonarMonitor(soar.outputs.amigo_simulator.ROBOT_POINTS,
                                            self.sonarmon_geom)
   self.sonarMonitor.openWindow()
 def openSonarMonitor(self):
     if not self.sonarMonitor:
         if self.toolbar.buttons['eBot'].cget('relief') == SUNKEN:
             self.sonarMonitor = SonarMonitor(soar.outputs.eBot.EBOT_POINTS,
                                              self.sonarmon_geom)
         elif self.toolbar.buttons['Amigosimulator'].cget(
                 'relief') == SUNKEN:
             self.sonarMonitor = AmigoSonarMonitor(
                 soar.outputs.amigo_simulator.ROBOT_POINTS,
                 self.sonarmon_geom)
         elif self.toolbar.buttons['simulator'].cget('relief') == SUNKEN:
             self.sonarMonitor = SonarMonitor(
                 soar.outputs.simulator.ROBOT_POINTS, self.sonarmon_geom)
         elif self.toolbar.buttons['pioneer'].cget('relief') == SUNKEN:
             self.sonarMonitor = AmigoSonarMonitor(
                 soar.outputs.amigo_simulator.ROBOT_POINTS,
                 self.sonarmon_geom)
     self.sonarMonitor.openWindow()
class application(object):
    ENABLED = 0
    DISABLED = 1
    UNCHANGED = 2

    def __init__(self):
        app.soar = self
        self.top = app.top
        app.top.wm_title('soar' + soar.version.format_version())
        app.top.protocol('WM_DELETE_WINDOW', self.exit)

        self.initializeNamespace()
        self.userfn = UserFunctionIF()
        io.configure_io(self.namespace)
        self.soar_toolbar_commands = formulae.FormulaPool()
        self.flowtriplets = [(self.startstepper, self.step, self.stopstepper)]
        soar_dir = soar.__path__[0]
        self.readConfigFile()
        if self.main_geom:
            app.top.geometry(self.main_geom[self.main_geom.find('+'):])
        media_dir = soar_dir + '/media'
        self.toolbar = widgets.ToolbarFrame(app.top,
                                            self.soar_toolbar_commands)
        self.toolbar.pack(side=TOP)
        start_images = {'normal': media_dir + "/start.gif"}
        step_images = {'normal': media_dir + "/step.gif"}
        stop_images = {'normal': media_dir + "/stop.gif"}
        simulator_images = {'normal': media_dir + "/simulator.gif"}
        eBot_images = {'normal': media_dir + "/eBot.gif"}
        robot_images = {'normal': media_dir + "/robot.gif"}
        brain_images = {'normal': media_dir + "/brain.gif"}
        joystick_images = {'normal': media_dir + "/joystick.gif"}
        oscillo_images = {'normal': media_dir + "/oscillo.gif"}
        Amigo_simulator_images = {'normal': media_dir + "/simulator.gif"}
        # if we're on the mac, the buttons won't stay pushed, so
        # we have a different image to indicate active buttons
        self.use_active_button_images = (platform.system() == 'Darwin')
        if (self.use_active_button_images):
            start_images['active'] = media_dir + "/start_active.gif"
            stop_images['active'] = media_dir + "/stop_active.gif"
            simulator_images['active'] = media_dir + "/simulator_active.gif"
            eBot_images['active'] = media_dir + "/eBot_active.gif"
            robot_images['active'] = media_dir + "/robot_active.gif"
            brain_images['active'] = media_dir + "/brain_active.gif"
            joystick_images['active'] = media_dir + "/joystick_active.gif"
            oscillo_images['active'] = media_dir + "/oscillo_active.gif"
            Amigo_simulator_images[
                'active'] = media_dir + "/simulator_active.gif"
        self.soar_toolbar_commands.addFormula(
            ('start', self.startall, 'Start', start_images, lambda: []))
        self.soar_toolbar_commands.addFormula(
            ('step', self.stepall, 'Step', step_images, lambda: []))
        self.soar_toolbar_commands.addFormula(
            ('stop', self.stopall, 'Stop', stop_images, lambda: []))
        self.pushToolbarButton('stop')
        self.disableToolbarButton('start')
        self.disableToolbarButton('step')

        Label(self.toolbar, text="Outputs:").pack(side=LEFT)

        #self.simulator_dir_default = soar_dir + "/6.01/worlds"
        self.soar_toolbar_commands.addFormula(
            ('simulator', self.openSimulator, 'Simulator', simulator_images,
             self.openSimulatorDialog))
        self.soar_toolbar_commands.addFormula(
            ('Amigosimulator', self.openAmigoSimulator, 'AmigoSimulator',
             Amigo_simulator_images, self.openAmigoSimulatorDialog))
        #self.soar_toolbar_commands.addFormula(('pioneer', self.openPioneer,
        #                                       'Pioneer', robot_images,
        #                                       lambda: []))
        self.soar_toolbar_commands.addFormula(
            ('eBot', self.openEBot, 'eBot', eBot_images, lambda: []))

        #CHANGED: robot name
        self.soar_toolbar_commands.addFormula(
            ('pioneer', self.openPioneer, 'Amigobot', robot_images,
             lambda: []))

        Label(self.toolbar, text="Controls:").pack(side=LEFT)

        #self.brain_dir_default = '~'
        self.soar_toolbar_commands.addFormula(
            ('brain', self.openBrain, 'Brain', brain_images,
             self.openBrainDialog))
        self.disableToolbarButton('brain')

        #CHANGED: commented out
        #self.soar_toolbar_commands.addFormula(('joystick', self.openJoystick,
        #                                       'Joystick', joystick_images,
        #                                       lambda: []))
        #self.disableToolbarButton('joystick')

        #    self.soar_toolbar_commands.addFormula(('oscillo', self.openOscillo,
        #                                           '    Oscilloscope ', oscillo_images,
        #                                           lambda: []))

        self.minibuffer = widgets.MiniBuffer(app.mainframe,
                                             self.namespace,
                                             width=78)
        self.minibuffer.pack(side=TOP, fill=X, expand=1)

        self.stderrbuffer = None
        #    self.stderrframe = app.tabframe.addFrameWithHideCB("errors",
        #                                                       self.clearErrors)
        #    self.stderrframe = app.tabframe.addFrame("errors")
        self.stderrbuffer = widgets.OutputBufferFrame(
            app.mainframe)  #self.stderrframe)
        self.stderrbuffer.box_.config(foreground='red')
        self.stderrbuffer.pack(fill=BOTH, expand=1)
        sys.stderr = parallel.PipeSyndicator([sys.stderr, self.stderrbuffer])
        self.clearErrors()

        self.stdoutbuffer = None
        #    self.stdoutframe = app.tabframe.addFrameWithHideCB("standard output",
        #                                                       self.clearOutput)
        #    self.stdoutframe = app.tabframe.addFrame("standard output")
        self.stdoutbuffer = widgets.OutputBufferFrame(
            app.mainframe)  #self.stdoutframe)
        self.stdoutbuffer.pack(fill=BOTH, expand=1)
        sys.stdout = parallel.PipeSyndicator([sys.stdout, self.stdoutbuffer])
        self.clearOutput()

        self.reloadAllButton = Button(app.mainframe,
                                      text="Reload Brain and World",
                                      command=self.reloadAll)
        self.reloadAllButton.pack()
        self.disableButton(self.reloadAllButton)

        self.reloadBrainButton = Button(app.mainframe,
                                        text="Reload Brain",
                                        command=self.reloadBrain)
        self.reloadBrainButton.pack()
        self.brainfile = ""
        self.disableButton(self.reloadBrainButton)
        #self.reloadWorldButton = Button(app.mainframe, text="Reload World",
        #                                command = self.reloadWorld)
        #self.reloadWorldButton.pack()
        #self.disableButton(self.reloadWorldButton)
        self.sonarMonitor = None
        self.oscope = None
        self.control = None
        self.output = None
        self.readfile = False
        self.writefile = False

    def readConfigFile(self):
        # defaults for if no file exists
        self.simulator_dir_default = soar.__path__[0] + "/worlds"
        self.brain_dir_default = '~'
        self.main_geom = None
        self.simulator_geom = None
        self.scope_geom = None
        self.sonarmon_geom = None
        homedir = os.path.expanduser('~')
        homedir.replace('\\', '/')
        try:
            f = open(homedir + "/.soarc")
        except:
            # it's okay if there's no config file; we'll write one at the end
            return
        vars = {}
        for line in f.readlines():
            if '=' in line:
                key, value = map(str.strip, line.split('=', 1))
                vars[key] = value
        f.close()
        if vars.has_key('OPEN_PATH') and os.path.exists(vars['OPEN_PATH']):
            self.brain_dir_default = vars['OPEN_PATH']
        if vars.has_key('WORLD_PATH') and os.path.exists(vars['WORLD_PATH']):
            self.simulator_dir_default = vars['WORLD_PATH']
        # get geometry for the windows for each standard widget
        if vars.has_key('MAIN_GEOM'): self.main_geom = vars['MAIN_GEOM']
        if vars.has_key('SIM_GEOM'): self.simulator_geom = vars['SIM_GEOM']
        if vars.has_key('SCOPE_GEOM'): self.scope_geom = vars['SCOPE_GEOM']
        if vars.has_key('SONAR_MON_GEOM'):
            self.sonarmon_geom = vars['SONAR_MON_GEOM']

    def writeConfigFile(self):
        homedir = os.path.expanduser('~')
        homedir.replace('\\', '/')
        try:
            f = open(homedir + "/.soarc", "w")
            f.write('%s=%s\n' % ('OPEN_PATH', self.brain_dir_default))
            f.write('%s=%s\n' % ('WORLD_PATH', self.simulator_dir_default))
            f.write('%s=%s\n' % ('MAIN_GEOM', self.top.geometry()))
            if self.simulator_geom:
                f.write('%s=%s\n' % ('SIM_GEOM', self.simulator_geom))
            if self.scope_geom:
                f.write('%s=%s\n' % ('SCOPE_GEOM', self.scope_geom))
            if self.sonarmon_geom:
                f.write('%s=%s\n' % ('SONAR_MON_GEOM', self.sonarmon_geom))
        except:
            sys.stderr.write("Could not write soar config file .soarc\n")

    def exit(self):
        # askyesno seems to be broken in current Tk (always returns False)
        #answer = form.widgets.askyesno("Exit", "Are you sure you want to exit?")
        answer = form.widgets.askquestion("Exit",
                                          "Are you sure you want to exit?")
        if answer == 'no':
            return
        try:
            self.stopall()
        except:
            pass
        try:
            self.unloadModule(self.control)
        except:
            pass
        try:
            self.unloadModule(self.output)
        except:
            pass
        self.closeSonarMonitor()
        self.closeOscillo()
        self.writeConfigFile()
        form.main.tk.destroy()
        form.main.sys.exit(0)

    def clearErrors(self):
        self.stderrbuffer.clear()
        sys.stderr.write("Error output will appear in this window.\n")

    def clearOutput(self):
        self.stdoutbuffer.clear()
        print "Ordinary output will appear in this window."

    def openSimulator(self, world):
        import soar.outputs.simulator
        if (len(world) > 0):
            #self.enableButton(self.reloadWorldButton)
            # do this before we try to read the file so we can reload even
            # if there is an error in the file
            if self.control:
                self.enableButton(self.reloadAllButton)
            try:
                self.setOutput(lambda: \
                                 soar.outputs.simulator.Simulator(world,
                                                                  self.simulator_geom))
            except:
                sys.stderr.write(
                    "Error loading world.  Perhaps you accidentally chose a brain file?\n"
                )
                return
            self.pushToolbarButton('simulator')
            self.unpushToolbarButton('Amigosimulator')
            self.unpushToolbarButton('pioneer')
            self.unpushToolbarButton('eBot')
            self.unpushToolbarButton('brain')
            #CHANGED commented out
            #self.unpushToolbarButton('joystick')
            self.reloadBrain(True)

    def openAmigoSimulator(self, world):
        import soar.outputs.amigo_simulator
        if (len(world) > 0):
            #self.enableButton(self.reloadWorldButton)
            # do this before we try to read the file so we can reload even
            # if there is an error in the file
            if self.control:
                self.enableButton(self.reloadAllButton)
            try:
                self.setOutput(lambda: \
                                 soar.outputs.amigo_simulator.amigo_simulator(world,
                                                                  self.simulator_geom))
            except:
                sys.stderr.write(
                    "Error loading world.  Perhaps you accidentally chose a brain file?\n"
                )
                return
            self.pushToolbarButton('Amigosimulator')
            self.unpushToolbarButton('simulator')
            self.unpushToolbarButton('pioneer')
            self.unpushToolbarButton('eBot')
            self.unpushToolbarButton('brain')
            #CHANGED commented out
            #self.unpushToolbarButton('joystick')
            self.reloadBrain(True)

    def openEBot(self):
        import soar.outputs.eBot
        # allow pioneer button to be unpushed to disconnect
        if self.toolbar.buttons['eBot'].cget('relief') == SUNKEN:
            self.closeEBot(False)
        else:
            if self.setOutput(lambda: soar.outputs.eBot.eBot()):
                sys.stderr.write("Set output to eBot.\n")
                #self.disableButton(self.reloadWorldButton)
                self.disableButton(self.reloadAllButton)
                # allowing reinit to pioneer is most likely to cause crashing, so don't
                self.pushToolbarButton('eBot', self.ENABLED)
                self.enableToolbarButton('brain')
                #CHANGED commented out
                #self.enableToolbarButton('joystick')
                # can't step the real robot
                self.disableToolbarButton('step')
                if self.brainfile != "":
                    self.enableButton(self.reloadBrainButton)
                    self.enableButton(self.reloadAllButton)
            self.unpushToolbarButton('simulator')
            self.unpushToolbarButton('Amigosimulator')
            self.reloadBrain(True)
        # print "Hello"
        # import soar.outputs.eBotDemo
        #from soar.outputs.eBotDemo import eBotDemo
        #eBotDemo()

    def closeEBot(self, callUserFn=True):
        self.stopall(callUserFn)
        self.setOutput(lambda: None)
        self.unpushToolbarButton('eBot')
        # don't have output, so disable brain loading
        #CHANGED commented out
        #self.disableToolbarButton('joystick')
        self.disableToolbarButton('brain')
        self.disableButton(self.reloadBrainButton)
        self.disableButton(self.reloadAllButton)

    def openPioneer(self):
        import soar.outputs.pioneer
        # allow pioneer button to be unpushed to disconnect
        if self.toolbar.buttons['pioneer'].cget('relief') == SUNKEN:
            self.closePioneer(False)
        else:
            if self.setOutput(lambda: soar.outputs.pioneer.Pioneer()):
                #self.disableButton(self.reloadWorldButton)
                self.disableButton(self.reloadAllButton)
                # allowing reinit to pioneer is most likely to cause crashing, so don't
                self.pushToolbarButton('pioneer', self.ENABLED)
                self.enableToolbarButton('brain')
                #CHANGED commented out
                #self.enableToolbarButton('joystick')
                # can't step the real robot
                self.disableToolbarButton('step')
                if self.brainfile != "":
                    self.enableButton(self.reloadBrainButton)
                    self.enableButton(self.reloadAllButton)
            self.unpushToolbarButton('simulator')
            self.reloadBrain(True)

    def closePioneer(self, callUserFn=True):
        self.stopall(callUserFn)
        self.setOutput(lambda: None)
        self.unpushToolbarButton('pioneer')
        # don't have output, so disable brain loading
        #CHANGED commented out
        #self.disableToolbarButton('joystick')
        self.disableToolbarButton('brain')
        self.disableButton(self.reloadBrainButton)
        self.disableButton(self.reloadAllButton)

    def openBrain(self, brainfile, reload=False):
        import soar.controls.brain
        if (len(brainfile) > 0):
            # clear error, output windows
            self.clearOutput()
            self.clearErrors()
            if (reload):
                print "***Reloading Brain***"
            else:
                print "***Loading Brain***"
            print "'" + brainfile + "'"
            self.setControl(
                lambda: soar.controls.brain.Brain(brainfile, reload),
                not reload)
            if self.control:
                self.pushToolbarButton('brain', self.ENABLED)
                self.enableButton(self.reloadBrainButton)
                self.chooseStop(self.output != None)
                if self.output:
                    #CHANGED commented out
                    #self.unpushToolbarButton('joystick')
                    self.enableButton(self.reloadAllButton)
                print "Successfully loaded brain file"
                print "'" + brainfile + "'"
            else:
                #self.disableButton(self.reloadBrainButton)
                print "Failed to load brain file '" + brainfile + "'"

    def reloadAll(self):
        self.reloadWorld()
        self.reloadBrain()

    def reloadBrain(self, quiet=False):
        if self.brainfile == "" and not quiet:
            sys.stderr.write("No valid brain filename to reload.\n")
        if self.control is not None:
            try:
                self.control.reload()
            except AttributeError:
                # we must have tried to reload the joystick (yes, this is ugly)
                if self.brainfile != "":
                    self.openBrain(self.brainfile, True)
        # if we failed, and we have a brainfile, just try loading the brain
        # as opposed to REloading
        if self.control is None and self.brainfile != "":
            self.openBrain(self.brainfile, False)

    def reloadWorld(self):
        if self.output is not None:
            try:
                self.output.initGlobals(True)
            except AttributeError:
                pass

    def openSonarMonitor(self):
        if not self.sonarMonitor:
            if self.toolbar.buttons['eBot'].cget('relief') == SUNKEN:
                self.sonarMonitor = SonarMonitor(soar.outputs.eBot.EBOT_POINTS,
                                                 self.sonarmon_geom)
            elif self.toolbar.buttons['Amigosimulator'].cget(
                    'relief') == SUNKEN:
                self.sonarMonitor = AmigoSonarMonitor(
                    soar.outputs.amigo_simulator.ROBOT_POINTS,
                    self.sonarmon_geom)
            elif self.toolbar.buttons['simulator'].cget('relief') == SUNKEN:
                self.sonarMonitor = SonarMonitor(
                    soar.outputs.simulator.ROBOT_POINTS, self.sonarmon_geom)
            elif self.toolbar.buttons['pioneer'].cget('relief') == SUNKEN:
                self.sonarMonitor = AmigoSonarMonitor(
                    soar.outputs.amigo_simulator.ROBOT_POINTS,
                    self.sonarmon_geom)
        self.sonarMonitor.openWindow()

    def closeSonarMonitor(self):
        if self.sonarMonitor:
            self.sonarMonitor.closeWindow()
            self.sonarMonitor = None

    def openJoystick(self):
        import soar.controls.joystick
        self.setControl(lambda: soar.controls.joystick.Joystick())
        #CHANGED commented out
        #self.pushToolbarButton('joystick')
        self.unpushToolbarButton('brain')

    def closeOscillo(self):
        if self.oscope:
            self.oscope.closeWindow()
        self.oscope = None

    def openOscillo(self):
        if not self.oscope:
            self.oscope = Oscilloscope(self.scope_geom)
        self.oscope.openWindow()

    def addScopeProbeFunction(self, name, func):
        self.oscope.addProbeFunction(name, func)

    def clearScope(self):
        if self.oscope:
            self.oscope.clearProbes()
            self.oscope.closeWindow()

    def openSimulatorDialog(self):
        filename = widgets.askopenfilename(
            title="Open a World File...",
            initialdir=self.simulator_dir_default,
            filetypes=[("World Files", "*.py")])
        if (len(filename) > 0):
            self.simulator_dir_default = filename[0:filename.rfind("/")]
        return [filename]

    def openAmigoSimulatorDialog(self):
        filename = widgets.askopenfilename(
            title="Open a World File...",
            initialdir=self.simulator_dir_default,
            filetypes=[("World Files", "*.py")])
        if (len(filename) > 0):
            self.simulator_dir_default = filename[0:filename.rfind("/")]
        return [filename]

    def openBrainDialog(self):
        filename = widgets.askopenfilename(title="Open a Brain File...",
                                           initialdir=self.brain_dir_default,
                                           filetypes=[("Brain Files", "*.py")])
        self.brainfile = filename
        if (len(filename) > 0):
            self.brain_dir_default = filename[0:filename.rfind("/")]
            os.chdir(self.brain_dir_default)
            self.enableButton(self.reloadBrainButton)
        return [filename]

    def removeFlowTriplet(self, trip):
        self.flowtriplets.remove(trip)

    def addFlowTriplet(self, trip):
        self.flowtriplets.append(trip)

    def setReadLog(self, f):
        self.control.readfile = open(f, 'rb')

    def setWriteLog(self, f):
        self.control.writefile = open(f, 'wb')

    def enableToolbarButton(self, name):
        self.enableButton(self.toolbar.buttons[name])

    def disableToolbarButton(self, name):
        self.disableButton(self.toolbar.buttons[name])

    def pushToolbarButton(self, name, state=DISABLED):
        self.pushButton(self.toolbar.buttons[name], state)
        self.toolbar.buttonImage(name, 'active')

    def unpushToolbarButton(self, name, state=ENABLED):
        self.unpushButton(self.toolbar.buttons[name], state)
        self.toolbar.buttonImage(name, 'normal')

    def flashToolbarButton(self, name):
        self.toolbar.buttons[name].flash()

    def enableButton(self, button):
        button.config(state=NORMAL)

    def disableButton(self, button):
        button.config(state=DISABLED)

    def buttonState(self, button, state):
        if state == self.DISABLED:
            self.disableButton(button)
        elif state == self.ENABLED:
            self.enableButton(button)

    def pushButton(self, button, state=DISABLED):
        button.config(relief=SUNKEN)
        self.buttonState(button, state)

    def unpushButton(self, button, state=ENABLED):
        button.config(relief=RAISED)
        self.buttonState(button, state)

    def chooseStart(self):
        self.pushToolbarButton('start')
        self.unpushToolbarButton('stop')
        self.pushToolbarButton('step')
        # can't choose control or output while running
        self.disableToolbarButton('simulator')
        self.disableToolbarButton('pioneer')
        self.disableToolbarButton('brain')
        #CHANGED commented out
        #self.disableToolbarButton('joystick')
        self.disableButton(self.reloadBrainButton)
        self.disableButton(self.reloadAllButton)

    def chooseStop(self, allowStart=1):
        if (allowStart):
            self.unpushToolbarButton('start')
            self.unpushToolbarButton('step')
        else:
            self.unpushToolbarButton('start', self.DISABLED)
            self.unpushToolbarButton('step', self.DISABLED)
        self.unpushToolbarButton('stop', self.DISABLED)
        # now we can choose control and output again
        self.enableToolbarButton('simulator')
        self.enableToolbarButton('Amigosimulator')
        self.enableToolbarButton('pioneer')
        self.enableToolbarButton('brain')
        #CHANGED commented out
        #self.enableToolbarButton('joystick')
        if self.brainfile != "":
            self.enableButton(self.reloadBrainButton)
            self.enableButton(self.reloadAllButton)

    def disableStartStop(self):
        self.unpushToolbarButton('start', self.DISABLED)
        self.unpushToolbarButton('stop', self.DISABLED)
        self.unpushToolbarButton('step', self.DISABLED)

    def setControl(self, lazy_control, allow_start=1):
        if self.readfile:
            self.readfile.close()
        if self.writefile:
            self.writefile.close()
        self.unloadModule(self.control)
        # try to read in the brain file.  if it fails, unload the module
        try:
            self.control = lazy_control()
        except Exception, e:
            self.disableStartStop()
            self.unloadModule(self.control)
            self.control = None
            raise e
        self.readfile = False
        self.writefile = False
        # if we did read in the file, try to call the setup function
        # if the setup function fails, unload the module
        if self.control != None:
            try:
                self.userfn.callFunctions('setup')
                self.loadModule(self.control)
            except:
                self.unloadModule(self.control)
                self.control = None
        if ((self.output != None) and allow_start):
            self.chooseStop(True)
        elif (self.output is None):
            self.disableStartStop()
Beispiel #4
0
class application(object):
  ENABLED = 0
  DISABLED = 1
  UNCHANGED = 2
  def __init__(self):
    app.soar = self
    self.top = app.top
    app.top.wm_title('soar'+soar.version.format_version())
    app.top.protocol('WM_DELETE_WINDOW', self.exit)

    self.initializeNamespace()
    self.userfn = UserFunctionIF()
    io.configure_io(self.namespace)
    self.soar_toolbar_commands = formulae.FormulaPool()
    self.flowtriplets = [(self.startstepper, self.step, self.stopstepper)]
    soar_dir = soar.__path__[0]
    self.readConfigFile()
    if self.main_geom:
      app.top.geometry(self.main_geom[self.main_geom.find('+'):])
    media_dir = soar_dir + '/media'
    self.toolbar = widgets.ToolbarFrame(app.top, self.soar_toolbar_commands)
    self.toolbar.pack(side = TOP)
    start_images = {'normal' : media_dir + "/start.gif"}
    step_images = {'normal' : media_dir + "/step.gif"}
    stop_images = {'normal' : media_dir + "/stop.gif"}
    simulator_images = {'normal' : media_dir + "/simulator.gif"}
    eBot_images = {'normal' : media_dir + "/eBot.gif"}
    robot_images = {'normal' : media_dir + "/robot.gif"}
    brain_images = {'normal' : media_dir + "/brain.gif"}
    joystick_images = {'normal' : media_dir + "/joystick.gif"}
    oscillo_images = {'normal' : media_dir + "/oscillo.gif"}
    Amigo_simulator_images = {'normal' : media_dir + "/simulator.gif"}
    # if we're on the mac, the buttons won't stay pushed, so
    # we have a different image to indicate active buttons
    self.use_active_button_images = (platform.system() == 'Darwin')
    if (self.use_active_button_images):
      start_images['active'] = media_dir + "/start_active.gif"
      stop_images['active'] = media_dir + "/stop_active.gif"
      simulator_images['active'] = media_dir + "/simulator_active.gif"
      eBot_images['active'] = media_dir + "/eBot_active.gif"
      robot_images['active'] = media_dir + "/robot_active.gif"
      brain_images['active'] = media_dir + "/brain_active.gif"
      joystick_images['active'] = media_dir + "/joystick_active.gif"
      oscillo_images['active'] = media_dir + "/oscillo_active.gif"
      Amigo_simulator_images['active'] = media_dir + "/simulator_active.gif"
    self.soar_toolbar_commands.addFormula(('start', self.startall, 'Start',
                                            start_images, lambda: []))
    self.soar_toolbar_commands.addFormula(('step', self.stepall, 'Step',
                                           step_images, lambda: []))
    self.soar_toolbar_commands.addFormula(('stop', self.stopall, 'Stop',
                                           stop_images, lambda: []))
    self.pushToolbarButton('stop')
    self.disableToolbarButton('start')
    self.disableToolbarButton('step')

    Label(self.toolbar, text = "Outputs:").pack(side = LEFT)

    #self.simulator_dir_default = soar_dir + "/6.01/worlds"
    self.soar_toolbar_commands.addFormula(('simulator', self.openSimulator,
                                           'Simulator', simulator_images,
                                           self.openSimulatorDialog))
    self.soar_toolbar_commands.addFormula(('Amigosimulator', self.openAmigoSimulator,
                                           'AmigoSimulator', Amigo_simulator_images,
                                           self.openAmigoSimulatorDialog))
    #self.soar_toolbar_commands.addFormula(('pioneer', self.openPioneer,
    #                                       'Pioneer', robot_images,
    #                                       lambda: []))
    self.soar_toolbar_commands.addFormula(('eBot', self.openEBot,
                                           'eBot', eBot_images,
                                           lambda: []))

    #CHANGED: robot name
    self.soar_toolbar_commands.addFormula(('pioneer', self.openPioneer,
                                           'Amigobot', robot_images,
                                           lambda: []))


    Label(self.toolbar, text = "Controls:").pack(side = LEFT)

    #self.brain_dir_default = '~'
    self.soar_toolbar_commands.addFormula(('brain', self.openBrain, 'Brain',
                                           brain_images, self.openBrainDialog))
    self.disableToolbarButton('brain')


    #CHANGED: commented out
    #self.soar_toolbar_commands.addFormula(('joystick', self.openJoystick,
    #                                       'Joystick', joystick_images,
    #                                       lambda: []))
    #self.disableToolbarButton('joystick')


#    self.soar_toolbar_commands.addFormula(('oscillo', self.openOscillo,
#                                           '    Oscilloscope ', oscillo_images,
#                                           lambda: []))


    self.minibuffer = widgets.MiniBuffer(app.mainframe, self.namespace,
                                         width=78)
    self.minibuffer.pack(side = TOP, fill=X, expand=1)

    self.stderrbuffer = None
#    self.stderrframe = app.tabframe.addFrameWithHideCB("errors",
#                                                       self.clearErrors)
#    self.stderrframe = app.tabframe.addFrame("errors")
    self.stderrbuffer = widgets.OutputBufferFrame(app.mainframe)#self.stderrframe)
    self.stderrbuffer.box_.config(foreground='red')
    self.stderrbuffer.pack(fill=BOTH, expand=1)
    sys.stderr = parallel.PipeSyndicator([sys.stderr, self.stderrbuffer])
    self.clearErrors()

    self.stdoutbuffer = None
#    self.stdoutframe = app.tabframe.addFrameWithHideCB("standard output",
#                                                       self.clearOutput)
#    self.stdoutframe = app.tabframe.addFrame("standard output")
    self.stdoutbuffer = widgets.OutputBufferFrame(app.mainframe)#self.stdoutframe)
    self.stdoutbuffer.pack(fill=BOTH, expand=1)
    sys.stdout = parallel.PipeSyndicator([sys.stdout, self.stdoutbuffer])
    self.clearOutput()

    self.reloadAllButton = Button(app.mainframe, text="Reload Brain and World",
                                  command = self.reloadAll)
    self.reloadAllButton.pack()
    self.disableButton(self.reloadAllButton)

    self.reloadBrainButton = Button(app.mainframe, text="Reload Brain",
                                    command = self.reloadBrain)
    self.reloadBrainButton.pack()
    self.brainfile = ""
    self.disableButton(self.reloadBrainButton)
    #self.reloadWorldButton = Button(app.mainframe, text="Reload World",
    #                                command = self.reloadWorld)
    #self.reloadWorldButton.pack()
    #self.disableButton(self.reloadWorldButton)
    self.sonarMonitor = None
    self.oscope = None
    self.control = None
    self.output = None
    self.readfile = False
    self.writefile = False

  def readConfigFile(self):
    # defaults for if no file exists
    self.simulator_dir_default = soar.__path__[0] + "/worlds"
    self.brain_dir_default = '~'
    self.main_geom = None
    self.simulator_geom = None
    self.scope_geom = None
    self.sonarmon_geom = None
    homedir = os.path.expanduser('~')
    homedir.replace('\\', '/')
    try:
      f = open(homedir+"/.soarc")
    except:
      # it's okay if there's no config file; we'll write one at the end
      return
    vars = {}
    for line in f.readlines():
      if '=' in line:
        key,value = map(str.strip, line.split('=',1))
        vars[key] = value
    f.close()
    if vars.has_key('OPEN_PATH') and os.path.exists(vars['OPEN_PATH']):
      self.brain_dir_default = vars['OPEN_PATH']
    if vars.has_key('WORLD_PATH') and os.path.exists(vars['WORLD_PATH']):
      self.simulator_dir_default = vars['WORLD_PATH']
    # get geometry for the windows for each standard widget
    if vars.has_key('MAIN_GEOM'): self.main_geom = vars['MAIN_GEOM']
    if vars.has_key('SIM_GEOM'): self.simulator_geom = vars['SIM_GEOM']
    if vars.has_key('SCOPE_GEOM'): self.scope_geom = vars['SCOPE_GEOM']
    if vars.has_key('SONAR_MON_GEOM'):
      self.sonarmon_geom = vars['SONAR_MON_GEOM']

  def writeConfigFile(self):
    homedir = os.path.expanduser('~')
    homedir.replace('\\', '/')
    try:
      f = open(homedir+"/.soarc", "w")
      f.write('%s=%s\n' % ('OPEN_PATH', self.brain_dir_default))
      f.write('%s=%s\n' % ('WORLD_PATH', self.simulator_dir_default))
      f.write('%s=%s\n' % ('MAIN_GEOM', self.top.geometry()))
      if self.simulator_geom:
        f.write('%s=%s\n' % ('SIM_GEOM', self.simulator_geom))
      if self.scope_geom:
        f.write('%s=%s\n' % ('SCOPE_GEOM', self.scope_geom))
      if self.sonarmon_geom:
        f.write('%s=%s\n' % ('SONAR_MON_GEOM', self.sonarmon_geom))
    except:
      sys.stderr.write("Could not write soar config file .soarc\n")

  def exit(self):
    # askyesno seems to be broken in current Tk (always returns False)
    #answer = form.widgets.askyesno("Exit", "Are you sure you want to exit?")
    answer = form.widgets.askquestion("Exit", "Are you sure you want to exit?")
    if answer == 'no':
      return
    try:
      self.stopall()
    except:
      pass
    try:
      self.unloadModule(self.control)
    except:
      pass
    try:
      self.unloadModule(self.output)
    except:
      pass
    self.closeSonarMonitor()
    self.closeOscillo()
    self.writeConfigFile()
    form.main.tk.destroy()
    form.main.sys.exit(0)

  def clearErrors(self):
    self.stderrbuffer.clear()
    sys.stderr.write ("Error output will appear in this window.\n")

  def clearOutput(self):
    self.stdoutbuffer.clear()
    print "Ordinary output will appear in this window."

  def openSimulator(self, world):
    import soar.outputs.simulator
    if (len(world) > 0):
      #self.enableButton(self.reloadWorldButton)
      # do this before we try to read the file so we can reload even
      # if there is an error in the file
      if self.control:
        self.enableButton(self.reloadAllButton)
      try:
        self.setOutput(lambda: \
                         soar.outputs.simulator.Simulator(world,
                                                          self.simulator_geom))
      except:
        sys.stderr.write("Error loading world.  Perhaps you accidentally chose a brain file?\n")
        return
      self.pushToolbarButton('simulator')
      self.unpushToolbarButton('Amigosimulator')
      self.unpushToolbarButton('pioneer')
      self.unpushToolbarButton('eBot')
      self.unpushToolbarButton('brain')
      #CHANGED commented out
      #self.unpushToolbarButton('joystick')
      self.reloadBrain(True)

  def openAmigoSimulator(self, world):
    import soar.outputs.amigo_simulator
    if (len(world) > 0):
      #self.enableButton(self.reloadWorldButton)
      # do this before we try to read the file so we can reload even
      # if there is an error in the file
      if self.control:
        self.enableButton(self.reloadAllButton)
      try:
        self.setOutput(lambda: \
                         soar.outputs.amigo_simulator.amigo_simulator(world,
                                                          self.simulator_geom))
      except:
        sys.stderr.write("Error loading world.  Perhaps you accidentally chose a brain file?\n")
        return
      self.pushToolbarButton('Amigosimulator')
      self.unpushToolbarButton('simulator') 
      self.unpushToolbarButton('pioneer')
      self.unpushToolbarButton('eBot')
      self.unpushToolbarButton('brain')
      #CHANGED commented out
      #self.unpushToolbarButton('joystick')
      self.reloadBrain(True)

  def openEBot(self):
    import soar.outputs.eBot
    # allow pioneer button to be unpushed to disconnect
    if self.toolbar.buttons['eBot'].cget('relief') == SUNKEN:
      self.closeEBot(False)
    else:
      if self.setOutput(lambda: soar.outputs.eBot.eBot()):
        sys.stderr.write ("Set output to eBot.\n")
        #self.disableButton(self.reloadWorldButton)
        self.disableButton(self.reloadAllButton)
        # allowing reinit to pioneer is most likely to cause crashing, so don't
        self.pushToolbarButton('eBot', self.ENABLED)
        self.enableToolbarButton('brain')
        #CHANGED commented out
        #self.enableToolbarButton('joystick')
        # can't step the real robot
        self.disableToolbarButton('step')
        if self.brainfile != "":
          self.enableButton(self.reloadBrainButton)
          self.enableButton(self.reloadAllButton)
      self.unpushToolbarButton('simulator')
      self.unpushToolbarButton('Amigosimulator')
      self.reloadBrain(True)
    # print "Hello"
    # import soar.outputs.eBotDemo
    #from soar.outputs.eBotDemo import eBotDemo
    #eBotDemo()

  def closeEBot(self, callUserFn=True):
    self.stopall(callUserFn)
    self.setOutput(lambda: None)
    self.unpushToolbarButton('eBot')
    # don't have output, so disable brain loading
    #CHANGED commented out
    #self.disableToolbarButton('joystick')
    self.disableToolbarButton('brain')
    self.disableButton(self.reloadBrainButton)
    self.disableButton(self.reloadAllButton)

  def openPioneer(self):
    import soar.outputs.pioneer
    # allow pioneer button to be unpushed to disconnect
    if self.toolbar.buttons['pioneer'].cget('relief') == SUNKEN:
      self.closePioneer(False)
    else:
      if self.setOutput(lambda: soar.outputs.pioneer.Pioneer()):
        #self.disableButton(self.reloadWorldButton)
        self.disableButton(self.reloadAllButton)
        # allowing reinit to pioneer is most likely to cause crashing, so don't
        self.pushToolbarButton('pioneer', self.ENABLED)
        self.enableToolbarButton('brain')
        #CHANGED commented out
        #self.enableToolbarButton('joystick')
        # can't step the real robot
        self.disableToolbarButton('step')
        if self.brainfile != "":
          self.enableButton(self.reloadBrainButton)
          self.enableButton(self.reloadAllButton)
      self.unpushToolbarButton('simulator')
      self.reloadBrain(True)

  def closePioneer(self, callUserFn=True):
    self.stopall(callUserFn)
    self.setOutput(lambda: None)
    self.unpushToolbarButton('pioneer')
    # don't have output, so disable brain loading
    #CHANGED commented out
    #self.disableToolbarButton('joystick')
    self.disableToolbarButton('brain')
    self.disableButton(self.reloadBrainButton)
    self.disableButton(self.reloadAllButton)

  def openBrain(self, brainfile, reload=False):
    import soar.controls.brain
    if (len(brainfile) > 0):
      # clear error, output windows
      self.clearOutput()
      self.clearErrors()
      if ( reload ):
        print "***Reloading Brain***"
      else:
        print "***Loading Brain***"
      print "'" + brainfile + "'"
      self.setControl(lambda: soar.controls.brain.Brain(brainfile, reload),
                      not reload)
      if self.control:
        self.pushToolbarButton('brain', self.ENABLED)
        self.enableButton(self.reloadBrainButton)
        self.chooseStop(self.output != None)
        if self.output:
          #CHANGED commented out
          #self.unpushToolbarButton('joystick')
          self.enableButton(self.reloadAllButton)
        print "Successfully loaded brain file"
        print "'" + brainfile + "'"
      else:
        #self.disableButton(self.reloadBrainButton)
        print "Failed to load brain file '" + brainfile + "'"

  def reloadAll(self):
    self.reloadWorld()
    self.reloadBrain()

  def reloadBrain(self, quiet=False):
    if self.brainfile == "" and not quiet:
      sys.stderr.write("No valid brain filename to reload.\n")
    if self.control is not None:
      try:
        self.control.reload()
      except AttributeError:
        # we must have tried to reload the joystick (yes, this is ugly)
        if self.brainfile != "":
          self.openBrain(self.brainfile,True)
    # if we failed, and we have a brainfile, just try loading the brain
    # as opposed to REloading
    if self.control is None and self.brainfile != "":
      self.openBrain(self.brainfile,False)

  def reloadWorld(self):
    if self.output is not None:
      try:
        self.output.initGlobals(True)
      except AttributeError:
        pass

  def openSonarMonitor(self):
    if not self.sonarMonitor:
      if self.toolbar.buttons['eBot'].cget('relief') == SUNKEN:
        self.sonarMonitor = SonarMonitor(soar.outputs.eBot.EBOT_POINTS,
                                           self.sonarmon_geom)
      elif self.toolbar.buttons['Amigosimulator'].cget('relief') == SUNKEN:
        self.sonarMonitor = AmigoSonarMonitor(soar.outputs.amigo_simulator.ROBOT_POINTS,
                                             self.sonarmon_geom)
      elif self.toolbar.buttons['simulator'].cget('relief') == SUNKEN:
        self.sonarMonitor = SonarMonitor(soar.outputs.simulator.ROBOT_POINTS,
                                             self.sonarmon_geom)
      elif self.toolbar.buttons['pioneer'].cget('relief') == SUNKEN:
        self.sonarMonitor = AmigoSonarMonitor(soar.outputs.amigo_simulator.ROBOT_POINTS,
                                             self.sonarmon_geom)
    self.sonarMonitor.openWindow()

  def closeSonarMonitor(self):
    if self.sonarMonitor:
      self.sonarMonitor.closeWindow()
      self.sonarMonitor = None

  def openJoystick(self):
    import soar.controls.joystick
    self.setControl(lambda: soar.controls.joystick.Joystick())
    #CHANGED commented out
    #self.pushToolbarButton('joystick')
    self.unpushToolbarButton('brain')

  def closeOscillo(self):
    if self.oscope:
      self.oscope.closeWindow()
    self.oscope = None

  def openOscillo(self):
    if not self.oscope:
      self.oscope = Oscilloscope(self.scope_geom)
    self.oscope.openWindow()

  def addScopeProbeFunction(self, name, func):
    self.oscope.addProbeFunction(name, func)

  def clearScope(self):
    if self.oscope:
      self.oscope.clearProbes()
      self.oscope.closeWindow()

  def openSimulatorDialog(self):
    filename = widgets.askopenfilename(title = "Open a World File...",
                                       initialdir = self.simulator_dir_default,
                                       filetypes = [("World Files", "*.py")]);
    if (len(filename) > 0):
      self.simulator_dir_default = filename[0:filename.rfind("/")]
    return [filename]

  def openAmigoSimulatorDialog(self):
    filename = widgets.askopenfilename(title = "Open a World File...",
                                       initialdir = self.simulator_dir_default,
                                       filetypes = [("World Files", "*.py")]);
    if (len(filename) > 0):
      self.simulator_dir_default = filename[0:filename.rfind("/")]
    return [filename]
  def openBrainDialog(self):
    filename = widgets.askopenfilename(title = "Open a Brain File...",
                                       initialdir = self.brain_dir_default,
                                       filetypes = [("Brain Files", "*.py")]);
    self.brainfile = filename
    if (len(filename) > 0):
      self.brain_dir_default = filename[0:filename.rfind("/")]
      os.chdir(self.brain_dir_default)
      self.enableButton(self.reloadBrainButton)
    return [filename]

  def removeFlowTriplet(self, trip):
    self.flowtriplets.remove(trip)

  def addFlowTriplet(self, trip):
    self.flowtriplets.append(trip)

  def setReadLog(self, f):
    self.control.readfile = open(f, 'rb')

  def setWriteLog(self, f):
    self.control.writefile = open(f, 'wb')

  def enableToolbarButton(self, name):
    self.enableButton(self.toolbar.buttons[name])
  def disableToolbarButton(self, name):
    self.disableButton(self.toolbar.buttons[name])
  def pushToolbarButton(self, name, state=DISABLED):
    self.pushButton(self.toolbar.buttons[name], state)
    self.toolbar.buttonImage(name, 'active')
  def unpushToolbarButton(self, name, state=ENABLED):
    self.unpushButton(self.toolbar.buttons[name], state)
    self.toolbar.buttonImage(name, 'normal')
  def flashToolbarButton(self, name):
    self.toolbar.buttons[name].flash()

  def enableButton(self, button):
    button.config(state=NORMAL)
  def disableButton(self, button):
    button.config(state=DISABLED)
  def buttonState(self, button, state):
    if state == self.DISABLED:
      self.disableButton(button)
    elif state == self.ENABLED:
      self.enableButton(button)
  def pushButton(self, button, state=DISABLED):
    button.config(relief=SUNKEN)
    self.buttonState(button, state)
  def unpushButton(self, button, state=ENABLED):
    button.config(relief=RAISED)
    self.buttonState(button, state)

  def chooseStart(self):
    self.pushToolbarButton('start')
    self.unpushToolbarButton('stop')
    self.pushToolbarButton('step')
    # can't choose control or output while running
    self.disableToolbarButton('simulator')
    self.disableToolbarButton('pioneer')
    self.disableToolbarButton('brain')
    #CHANGED commented out
    #self.disableToolbarButton('joystick')
    self.disableButton(self.reloadBrainButton)
    self.disableButton(self.reloadAllButton)

  def chooseStop(self, allowStart=1):
    if (allowStart):
      self.unpushToolbarButton('start')
      self.unpushToolbarButton('step')
    else:
      self.unpushToolbarButton('start', self.DISABLED)
      self.unpushToolbarButton('step', self.DISABLED)
    self.unpushToolbarButton('stop', self.DISABLED)
    # now we can choose control and output again
    self.enableToolbarButton('simulator')
    self.enableToolbarButton('Amigosimulator')
    self.enableToolbarButton('pioneer')
    self.enableToolbarButton('brain')
    #CHANGED commented out
    #self.enableToolbarButton('joystick')
    if self.brainfile != "":
      self.enableButton(self.reloadBrainButton)
      self.enableButton(self.reloadAllButton)

  def disableStartStop(self):
    self.unpushToolbarButton('start', self.DISABLED)
    self.unpushToolbarButton('stop', self.DISABLED)
    self.unpushToolbarButton('step', self.DISABLED)

  def setControl(self, lazy_control, allow_start=1):
    if self.readfile:
      self.readfile.close()
    if self.writefile:
      self.writefile.close()
    self.unloadModule(self.control)
    # try to read in the brain file.  if it fails, unload the module
    try:
      self.control = lazy_control()
    except Exception, e:
      self.disableStartStop()
      self.unloadModule(self.control)
      self.control = None
      raise e
    self.readfile = False
    self.writefile = False
    # if we did read in the file, try to call the setup function
    # if the setup function fails, unload the module
    if self.control != None:
      try:
        self.userfn.callFunctions('setup')
        self.loadModule(self.control)
      except:
        self.unloadModule(self.control)
        self.control = None
    if ((self.output != None) and allow_start):
      self.chooseStop(True)
    elif (self.output is None):
      self.disableStartStop()