Esempio n. 1
0
class AzathothClient:
    def __init__(self):
        self.connected = False
        self.builder = gtk.Builder()
        self.builder.add_from_file('main.glade')
        self.mainWindow = self.builder.get_object('window_main')

        self.builder.connect_signals(self)
        
        # let's just add widgets as members programatically.
        widgets = ('btn_disconnect', 'btn_connect', 'statusbar', 'label_js_x',
            'label_js_y', 'rb_js_enable', 'rb_js_disable', 'eb_js_x', 'eb_js_y',
            'eb_drivestatus', 'label_drivestatus', 'label_drive_x', 'label_drive_y',
            'label_raw_x', 'label_raw_y', 'label_select_cmd', 'label_select_act',
            'eb_select_cmd', 'eb_select_act', 'label_estop_cmd', 'label_estop_act',
            'eb_estop_cmd', 'eb_estop_act')
        for wid in widgets:
            setattr(self, wid, self.builder.get_object(wid))

        self.context_id = self.statusbar.get_context_id("Azathoth")

        self.prev_x = 0
        self.prev_y = 0
        self.joystick = None
        self.joystick_x = 0
        self.joystick_y = 0
        self.joystick_enabled = False

        self.mainWindow.show_all()

    def connect(self, host, port=2024):
        log.msg(format="Connecting to host %(host)s on port %(port)d", host=host, port=port)
        self.statusbar.push(self.context_id, 'Connecting...')
        self.factory = ControlFactory(self)
        self.connection = reactor.connectTCP(host, port, self.factory)

    def disconnect(self):
        log.msg("Disconnecting")
        self.connection.disconnect()

    def setUiState(self, state):
        connected_controls = ('btn_disconnect', 'rb_js_enable', 'rb_js_disable',
            'btn_select', 'btn_deselect', 'tb_estop', 'tb_reset', 'tb_calibrate',
            'imi_calibration')
        if state == 'connecting':
            self.btn_disconnect.set_sensitive(True)
            self.btn_connect.set_sensitive(False)
        elif state == 'connected':
            for control in connected_controls:
                self.builder.get_object(control).set_sensitive(True)
        elif state == 'disconnected':
            if self.joystick_enabled:
                self.rb_js_enable.set_active(False)
                self.rb_js_disable.set_active(True)
                self.disableJoystick()
            for control in connected_controls:
                self.builder.get_object(control).set_sensitive(False)
                self.btn_connect.set_sensitive(True)

    def enableJoystick(self):
        self.joystick_enabled = True
        try:
            self.joystick = Joystick(1)
        except:
            self.joystick_enabled = False
            self.rb_js_enable.set_active(True)
            self.rb_js_disable.set_active(False)
            self.statusbar.push(self.context_id, 'Joystick device error')
            return
        self.js_handler = self.joystick.connect('axis', self.axis_event)
        self.factory.control.send_select_command(True)

    def disableJoystick(self):
        self.joystick_enabled = False
        self.rb_js_enable.set_active(True)
        self.rb_js_disable.set_active(False)
        if self.joystick is not None:
            self.joystick.disconnect(self.js_handler)
            self.joystick.shutdown()
            self.joystick = None
        self.factory.control.send_select_command(False)

    def onStartConnection(self):
        self.setUiState('connecting')

    def onConnect(self):
        self.statusbar.remove_all(self.context_id)
        self.statusbar.push(self.context_id, 'Connected')
        self.setUiState('connected')

    def onConnectionLost(self):
        self.setUiState('disconnected')
        self.statusbar.remove_all(self.context_id)
        self.statusbar.push(self.context_id, 'Disconnected')
        if self.calDlg is not None:
            self.calDlg.destroy()

    def onConnectionFailed(self, reason):
        self.setUiState('disconnected')
        self.statusbar.remove_all(self.context_id)
        self.statusbar.push(self.context_id, 'Connection failed!')

    def onUpdateAxis(self):
        if self.joystick_x != 0:
            self.eb_js_x.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color('#00FF00'))
        elif self.joystick_x == 0:
            self.eb_js_x.modify_bg(gtk.STATE_NORMAL, None)
        if self.joystick_y != 0:
            self.eb_js_y.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color('#00FF00'))
        elif self.joystick_y == 0:
            self.eb_js_y.modify_bg(gtk.STATE_NORMAL, None)

        self.label_js_x.set_label(str(self.joystick_x))
        self.label_js_y.set_label(str(self.joystick_y))
        self.factory.control.send_joystick_command(self.joystick_x, self.joystick_y)

    def onStatusUpdate(self, status, xpos, ypos, xval, yval):
        estop_act = (status & 0x01 == 0x01)
        estop_cmd = (status & 0x02 == 0x02)
        select_act = (status & 0x04 == 0x04)
        select_cmd = (status & 0x08 == 0x08)
        moving = (status & 0x10 == 0x10)
        if moving:
            self.label_drivestatus.set_label("MOVING")
            self.eb_drivestatus.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color('#00FF00'))
        else:
            self.label_drivestatus.set_label("STOPPED")
            self.eb_drivestatus.modify_bg(gtk.STATE_NORMAL, None)
        
        if estop_act:
            self.label_estop_act.set_label("RUN")
            self.eb_estop_act.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color('#00FF00'))
        else:
            self.label_estop_act.set_label("STOP")
            self.eb_estop_act.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color('#FF0000'))
        if estop_cmd:
            self.label_estop_cmd.set_label("RUN")
            self.eb_estop_cmd.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color('#00FF00'))
        else:
            self.label_estop_cmd.set_label("STOP")
            self.eb_estop_cmd.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color('#FF0000'))
        
        if select_act:
            self.label_select_act.set_label("ROBOT")
            self.eb_select_act.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color('#00FF00'))
        else:
            self.label_select_act.set_label("CHAIR")
            self.eb_select_act.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color('#00FFFF'))
        if select_cmd:
            self.label_select_cmd.set_label("ROBOT")
            self.eb_select_cmd.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color('#00FF00'))
        else:
            self.label_select_cmd.set_label("CHAIR")
            self.eb_select_cmd.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color('#00FFFF'))

        self.label_drive_x.set_label(str(xpos))
        self.label_drive_y.set_label(str(ypos))
        self.label_raw_x.set_label(str(xval))
        self.label_raw_y.set_label(str(yval))

    def on_window_main_delete_event(self, win, event):
        reactor.stop()

    def on_imi_quit_activate(self, widget):
        reactor.stop()

    def on_imi_calibration_activate(self, widget):
        self.calDlg = CalibrationDialog(self)

    def on_btn_connect_clicked(self, widget):
        host = self.builder.get_object('entry_host').get_text()
        self.connect(host)

    def on_btn_disconnect_clicked(self, widget):
        self.disconnect()

    def on_rb_js_enable_toggled(self, btn):
        if btn.get_active():
            self.enableJoystick()
        else: 
            self.disableJoystick()

    def on_btn_select_clicked(self, btn):
        self.factory.control.send_select_command(True)

    def on_btn_deselect_clicked(self, btn):
        self.factory.control.send_select_command(False)

    def on_tb_estop_clicked(self, btn):
        self.factory.control.send_estop_command()

    def on_tb_reset_clicked(self, btn):
        self.factory.control.send_reset_command()

    def on_tb_calibrate_clicked(self, btn):
        self.calDlg = CalibrationDialog(self)

    def axis_event(self, object, axis, value, init):
        if init == 128:
            # Ignore this event. One gets sent per axis when the joystick
            # is initialized. I should really find out why.
            return
        if axis == 0:
            # dividing by 256 scales the value to fit within a signed char
            self.prev_x = self.joystick_x
            self.joystick_x = value / 256
            if self.joystick_x == self.prev_x:
                return
        if axis == 1:
            # this axis needs to be inverted
            self.prev_y = self.joystick_y
            self.joystick_y = -value / 256
            if self.joystick_y == self.prev_y:
                return
        self.onUpdateAxis()

    def button_event(self, object, button, value, init):
        pass
Esempio n. 2
0
class JsController(Controller):
    
    def __init__(self, model, view, jsdevnum):
        Controller.__init__(self, model, view)
        self.jsdevnum = jsdevnum
        self.joystick = None
        self.joystick_x = 0
        self.joystick_y = 0

    def register_view(self, view):
        pass

    def register_adapters(self):
        a = Adapter(self.model, 'joy_x')
        a.connect_widget(self.view['label_js_x'], setter=self.joystick_setter)
        self.adapt(a)

        a = Adapter(self.model, 'joy_y')
        a.connect_widget(self.view['label_js_y'], setter=self.joystick_setter)
        self.adapt(a)

    def enableJoystick(self):
        logging.debug('enableJoystick')
        self.joystick_enabled = True
        try:
            self.joystick = Joystick(self.jsdevnum)
        except:
            self.joystick_enabled = False
            #self.view['rb_js_enable'].set_active(False)
            #self.view['rb_js_disable'].set_active(True)
            logging.error('could not enable joystick')
            return
        self.jsAxisHandler = self.joystick.connect('axis', self.on_axis_event)
        self.jsButtonHandler = self.joystick.connect('button', self.on_button_event)

    def disableJoystick(self):
        self.joystick_enabled = False
        #self.view['rb_js_enable'].set_active(True)
        #self.view['rb_js_disable'].set_active(False)
        if self.joystick is not None:
            self.joystick.disconnect(self.jsAxisHandler)
            self.joystick.disconnect(self.jsButtonHandler)
            self.joystick = None

    # signal handlers
    def on_rb_js_enable_toggled(self, btn):
        logging.debug('on_rb_js_enable_toggled')
        if btn.get_active():
            self.enableJoystick()
        else:
            self.disableJoystick()

    def on_tb_calibrate_clicked(self, btn):
        #TODO
        pass

    def on_axis_event(self, object, axis, value, init):
        if init == 128:
            # Ignore this event. One gets sent per axis when the joystick
            # is initialized. I should really find out why.
            return
        if axis == 0:
            # dividing by 256 scales the value to fit within a signed char
            self.prev_x = self.joystick_x
            self.joystick_x = value / 256
            if self.joystick_x == self.prev_x:
                return
        elif axis == 1:
            # this axis needs to be inverted
            self.prev_y = self.joystick_y
            self.joystick_y = -value / 256
            if self.joystick_y == self.prev_y:
                return
        else: # ignore other axises
            return
        self.model.driveModel.joystickCommand(self.joystick_x, self.joystick_y)

    def on_button_event(self, object, button, value, init):
        pass

    # special setters
    def joystick_setter(self, wid, val):
        if val != 0:
            color = gtk.gdk.Color('#00FF00')
        else:
            color = None
        wid.set_label(str(val))
        if wid == self.view['label_js_x']:
            self.view['eb_js_x'].modify_bg(gtk.STATE_NORMAL, color)
        else:
            self.view['eb_js_y'].modify_bg(gtk.STATE_NORMAL, color)