Ejemplo n.º 1
0
class CalibrationScreen(QtGui.QWidget):
    """
  The main window in this application.
  """
    def __init__(self, cfgfile, port):
        QtGui.QWidget.__init__(self, None)
        self.config_file = cfgfile
        self.config = furious.config.parse_config(self.config_file)
        self.board = FuriousBoard()
        if not port:
            port = self.board.probe()
        if not port:
            QtGui.QMessageBox.information(self, "Error",
                                          "Unable to detect a Furious board.",
                                          QtGui.QMessageBox.Ok)
            QtGui.qApp.exit(1)
            # For some reason, the app doesn't exit immediately after the call
            # to qApp.exit() above, so this next line is needed for a clean
            # shutdown.
            exit(1)

        self.board.open(port)

        if not self.board.is_ready():
            QtGui.QMessageBox.information(
                self, "Error",
                "Unable to connect to Furious board on %s." % port,
                QtGui.QMessageBox.Ok)
            QtGui.qApp.exit(1)

        quitBtn = QtGui.QPushButton("Quit")
        self.connect(quitBtn, QtCore.SIGNAL('clicked()'), QtGui.qApp,
                     QtCore.SLOT('quit()'))

        saveBtn = QtGui.QPushButton("Save")
        self.connect(saveBtn, QtCore.SIGNAL('clicked()'), self.saveConfig)

        buttons = QtGui.QHBoxLayout()
        buttons.addWidget(saveBtn)
        buttons.addWidget(quitBtn)

        layout = QtGui.QVBoxLayout()

        statusLbl = QtGui.QLabel("Connected on %s" % port)
        layout.addWidget(statusLbl)
        for sname in self.config['servo']:
            servo = self.config['servo'][sname]
            sc = ServoControl(self, sname, servo)
            layout.addWidget(sc)
        layout.addLayout(buttons)
        self.setLayout(layout)

    def __del__(self):
        self.board.close()

    def updateBoardState(self, servo_id, val):
        self.board.servos[int(servo_id)] = val
        self.board.update()

    def saveConfig(self):
        furious.config.save_config(self.config, self.config_file)
        QtGui.QMessageBox.information(
            self, "Message",
            "Your configuration has been saved to %s." % self.config_file,
            QtGui.QMessageBox.Ok)
Ejemplo n.º 2
0
class CalibrationScreen(QtGui.QWidget):
  """
  The main window in this application.
  """
  def __init__(self, cfgfile, port):
    QtGui.QWidget.__init__(self, None)
    self.config_file = cfgfile
    self.config = furious.config.parse_config(self.config_file)
    self.board = FuriousBoard()
    if not port:
      port = self.board.probe()
    if not port:
      QtGui.QMessageBox.information(
          self,
          "Error",
          "Unable to detect a Furious board.",
          QtGui.QMessageBox.Ok )
      QtGui.qApp.exit(1)
      # For some reason, the app doesn't exit immediately after the call
      # to qApp.exit() above, so this next line is needed for a clean
      # shutdown.
      exit(1)  

    self.board.open(port)

    if not self.board.is_ready():
      QtGui.QMessageBox.information(
          self,
          "Error",
          "Unable to connect to Furious board on %s." % port,
          QtGui.QMessageBox.Ok )
      QtGui.qApp.exit(1)

    quitBtn = QtGui.QPushButton("Quit")
    self.connect(quitBtn, QtCore.SIGNAL('clicked()'), 
        QtGui.qApp, QtCore.SLOT('quit()'))

    saveBtn = QtGui.QPushButton("Save")
    self.connect(saveBtn, QtCore.SIGNAL('clicked()'), self.saveConfig)

    buttons = QtGui.QHBoxLayout()
    buttons.addWidget(saveBtn)
    buttons.addWidget(quitBtn)

    layout = QtGui.QVBoxLayout()

    statusLbl = QtGui.QLabel("Connected on %s" % port)
    layout.addWidget(statusLbl)
    for sname in self.config['servo']:
      servo = self.config['servo'][sname]
      sc = ServoControl(self, sname, servo)
      layout.addWidget(sc)
    layout.addLayout(buttons)
    self.setLayout(layout)

  def __del__(self):
    self.board.close()

  def updateBoardState(self, servo_id, val):
    self.board.servos[int(servo_id)] = val
    self.board.update()

  def saveConfig(self):
    furious.config.save_config(self.config, self.config_file)
    QtGui.QMessageBox.information(
        self,
        "Message",
        "Your configuration has been saved to %s." % self.config_file,
        QtGui.QMessageBox.Ok )
Ejemplo n.º 3
0
class FuriousDriver(object):
  """
  This is the high-level class that encapsulates the devices from 
  L{furious.devices} and translates raw values from the Furious
  board into units that are meaningful to humans.
  """

  def __init__(self, config_file=None):
    """
    The constructor does some default configuration, but the driver
    usually needs to load a config file via L{load_config} to be 
    fully initialized.
    """
    self._board = FuriousBoard()
    self._servos = {}
    self._odometer = Odometer(self._board)
    self._logic_batt = Battery(self._board, port=7)
    self._motor_batt = Battery(self._board, port=6)
    self._dbg = None  # Observer object for debug messages

    if config_file:
      self.load_config(config_file)


  ### configuration ###

  def load_config(self, filename):
    """
    Configures the robot according to the settings in the given
    configuration file.
    @param filename: a filename containing configuration settings
    @type filename: string
    @return: None
    """
    # parse_config() takes care of the messiness of reading and cleaning
    # up the config file.
    config = parse_config(filename)
    for key in config:
      if key == "servo":
        for servo_name in config[key]:
          servo  = config[key][servo_name]
          id     = servo[0]
          min    = servo[1]
          center = servo[2]
          max    = servo[3]
          self._servos[servo_name] = Servo(self._board, id, min, center, max)

      elif key == "odometer":
        self._odometer = Odometer(self._board, config[key])

      # TODO: add battery level customizations


  ### connecting, disconnecting, etc ###

  def connect(self, port):
    """
    Attempts to establish a serial connection to the Furious board on
    the specified port (eg, "/dev/ttyACM0").
    """
    self._board.open(port)
    time.sleep(0.5)
    self.refresh()
    time.sleep(0.5)
    self.refresh()

  def disconnect(self):
    """
    Immediately stops all servos and closes the board's serial connection.
    """
    cmd = self.stop()
    self._board.close()
    return cmd

  def probe(self):
    """
    Probes the computer for a Furious board and returns the port that has
    one attached to it.  Returns None if no board can be found.  Note that 
    this does not connect the driver to the board; use L{open()} for that.
    """
    return self._board.probe()


  def is_ready(self):
    """
    Returns true if the robot is ready to accept commands.
    """
    return self._board.is_ready()


  ###  communicating with the board ###

  def stop(self):
    """
    Immediately stops all servos.  Good for emergencies and when you 
    reach your goal (or the end of your program).
    @return: the serial command string that was sent on this update,
      for debugging purposes
    """
    for i in range(len(self._board.servos)):
      self._board.servos[i] = 0
    return self.refresh()

  def refresh(self):
    """
    Sends all pending commands to and receives all updates from
    the board.
    @return: the serial command string that was sent on this update,
      for debugging purposes
    """
    # Update the board
    sent = ""
    try:
      sent = self._board.update()
    # Handle the case when a read or write is interrupted.
    except OSError, e:
      self.stop()
      if e.errno != errno.EINTR:  # if not interrupted system call
        raise e  # propagate the exception
    except select.error, e:
      self.stop()
      if e[0] != errno.EINTR:
        raise e