예제 #1
0
 def setup_dragonfly(self, mm_ip):
     self.mod = Dragonfly_Module(0, 0)
     self.mod.ConnectToMMM(mm_ip)
     self.mod.Subscribe(MT_EXIT)
     self.mod.Subscribe(rc.MT_PING)
     self.mod.SendModuleReady()
     print "DrAQonfly: connected to dragonfly"
예제 #2
0
 def setup_dragonfly(self, server):
     self.mod = Dragonfly_Module(0, 0)
     self.mod.ConnectToMMM(server)
     self.mod.Subscribe(MT_EXIT)
     self.mod.Subscribe(rc.MT_PING)
     self.mod.Subscribe(rc.MT_INPUT_DOF_DATA)
     self.mod.SendModuleReady()
     print "Connected to Dragonfly at", server
예제 #3
0
 def setup_dragonfly(self, server):
     self.mod = Dragonfly_Module(rc.MID_SIMPLE_ARBITRATOR, 0)
     self.mod.ConnectToMMM(server)
     self.mod.Subscribe(MT_EXIT)
     for sub in subscriptions:
         self.mod.Subscribe(eval('rc.MT_%s' % (sub)))
     self.mod.SendModuleReady()
     print "Connected to Dragonfly at", server
예제 #4
0
 def setup_Dragonfly(self):
     server = self.config.get('Dragonfly', 'server')
     self.mod = Dragonfly_Module(0, 0)
     self.mod.ConnectToMMM(server)
     for i in self.msg_types:
         self.mod.Subscribe(eval('rc.MT_%s' % (i)))
     self.mod.SendModuleReady()
     print "Connected to Dragonfly at", server
예제 #5
0
 def setup_Dragonfly(self, mm_ip):
     self.mod = Dragonfly_Module(0, 0)
     self.mod.ConnectToMMM(mm_ip)
     self.mod.Subscribe(MT_EXIT)
     self.mod.Subscribe(rc.MT_PING)
     self.mod.Subscribe(self.in_msg_num)
     self.mod.Subscribe(rc.MT_MNOME_STATE)
     self.mod.SendModuleReady()
     print "Connected to Dragonfly at", mm_ip
예제 #6
0
 def setup_dragonfly(self, server):
     self.mod = Dragonfly_Module(0, 0)
     self.mod.ConnectToMMM(server)
     self.mod.Subscribe(MT_EXIT)
     self.mod.Subscribe(rc.MT_PING)
     for i in self.msg_types:
         self.mod.Subscribe(eval('rc.MT_%s' % (i)))
     self.mod.SendModuleReady()
     print "Connected to RTMA at", server
예제 #7
0
    def __init__(self):
        super(Display, self).__init__(180, 180, 180, 255)

        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM("everest:7111")
        self.mod.Subscribe(rc.MT_TASK_STATE_CONFIG)
        self.mod.Subscribe(rc.MT_INPUT_DOF_DATA)
        self.mod.Subscribe(rc.MT_COMBO_WAIT)
        self.mod.Subscribe(rc.MT_TRIAL_CONFIG)
        self.mod.Subscribe(rc.MT_END_TASK_STATE)
        self.mod.Subscribe(rc.MT_PING)

        self.msg = CMessage()
        
        self.timer_sec = 0
        self.timer_min = 0
        
        self.position_bar = Polygon(v=[(20, 455), (20, 565), (1260, 565), (1260, 455)], color=(0.05, 0.05, 0.05, 1), stroke=0)
        self.tgt_window   = Polygon(v=[(0, 0), (0, 0), (0, 0), (0, 0)], color=(0, 0.6, 0.2, 1), stroke=0)
        self.pos_fdbk     = Polygon(v=[(20, 405), (20, 615), (28, 615), (28, 405)], color=(0, 0.2, 1.0, 1), stroke=0)
        self.pos_fdbk_txt = pyglet.text.Label('',
                                      font_name='times new roman',
                                      font_size=32,
                                      color=(0,0,0,255),
                                      width=250,
                                      bold=True,
                                      x=1140, y=40)

        self.combo_wait_txt = pyglet.text.Label('',
                                      font_name='times new roman',
                                      font_size=32,
                                      color=(0,0,0,255),
                                      width=250,
                                      bold=True,
                                      x=478, y=840)
                                      
        self.score_txt = pyglet.text.Label('',
                                      font_name='times new roman',
                                      font_size=36,
                                      color=(0,0,0,255),
                                      width=250,
                                      bold=True,
                                      x=533, y=240)                                      

        self.reward_txt = pyglet.text.Label('',
                                      font_name='times new roman',
                                      font_size=22,
                                      color=(0,0,0,255),
                                      width=250,
                                      bold=True,
                                      x=475, y=120)                                      


        self.reset_score()

        self.schedule_interval(self.update, 0.01)
예제 #8
0
 def setup_dragonfly(self, server):
     subscriptions = [MT_EXIT, \
                      rc.MT_PING, \
                      rc.MT_POLARIS_POSITION]
     self.mod = Dragonfly_Module(0, 0)
     self.mod.ConnectToMMM(server)
     for sub in subscriptions:
         self.mod.Subscribe(sub)
     self.mod.SendModuleReady()
     print "Connected to Dragonfly at ", server
예제 #9
0
 def setup_dragonfly(self, server):
     subscriptions = [MT_EXIT, \
                      rc.MT_PING, \
                      rc.MT_DAQ_DATA, \
                      rc.MT_SAMPLE_GENERATED, \
                      rc.MT_TMS_TRIGGER]
     self.mod = Dragonfly_Module(0, 0)
     self.mod.ConnectToMMM(server)
     for sub in subscriptions:
         self.mod.Subscribe(sub)
     self.mod.SendModuleReady()
     print "Connected to Dragonfly at ", server
예제 #10
0
 def setup_dragonfly(self, server):
     subscriptions = [MT_EXIT, \
                      rc.MT_PING, \
                      rc.MT_FT_DATA, \
                      rc.MT_FT_COMPLETE, \
                      rc.MT_RTFT_CONFIG]
     self.mod = Dragonfly_Module(0, 0)
     self.mod.ConnectToMMM(server)
     for sub in subscriptions:
         self.mod.Subscribe(sub)
     self.mod.SendModuleReady()
     print "Connected to Dragonfly at ", server
예제 #11
0
    def setup_dragonfly(self, server):
        self.host_name = platform.uname()[1]
        self.host_os = platform.system()

        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(server)
        self.mod.Subscribe(rc.MT_APP_START)
        self.mod.Subscribe(rc.MT_PING)
        self.mod.Subscribe(MT_EXIT)
        self.mod.Subscribe(MT_KILL)

        self.mod.SendModuleReady()
        print "Connected to Dragonfly at", server
예제 #12
0
    def setup_dragonfly(self, server):
        self.mod = Dragonfly_Module(rc.MID_SAMPLE_GENERATOR, 0)
        self.mod.ConnectToMMM(server)
        self.mod.Subscribe(MT_EXIT)
        self.mod.Subscribe(rc.MT_PING)
        self.mod.Subscribe(rc.MT_SPM_SPIKECOUNT)
        for trigger in self.triggers:
            self.mod.Subscribe(trigger)
        self.mod.SendModuleReady()
        print "Connected to Dragonfly at", server

        if platform.system() == "Windows":
            # On Windows, the best timer is time.clock()
            self.default_timer = time.clock
        else:
            # On most other platforms the best timer is time.time()
            self.default_timer = time.time
    def run(self, config_file, server):
        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(server)
        for sub in self.subscriptions:
            self.mod.Subscribe(sub)
        self.mod.SendModuleReady()
        print "Connected to Dragonfly at", server

        self.config_file = config_file
        self.load_config()

        self.init_judge_display()
        self.init_plot()
        self.init_legend()

        self.timer = QtCore.QTimer(self)
        QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"),
                               self.timer_event)
        self.timer.start(10)
예제 #14
0
    def run(self, config_file, mm_ip):
        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(mm_ip)

        self.msg_types = [
            'TASK_STATE_CONFIG', 'ROBOT_CONTROL_SPACE_ACTUAL_STATE'
        ]
        self.msg_types.sort()
        self.mod.Subscribe(MT_EXIT)
        self.mod.Subscribe(rc.MT_PING)
        for i in self.msg_types:
            self.mod.Subscribe(eval('rc.MT_%s' % (i)))

        print "Connected to Dragonfly at", mm_ip
        #print "mod_id = ", self.mod.GetModuleID()

        self.timer = QtCore.QTimer()
        QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"),
                               self.timer_event)
        self.timer.start(50)
예제 #15
0
    def run(self, config_file, server):
        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(server)
        self.msg_types = ['END_TASK_STATE', 'SESSION_CONFIG', 'EM_DECODER_CONFIGURATION']
        self.msg_types.sort()
        self.mod.Subscribe(MT_EXIT)
        self.mod.Subscribe(rc.MT_PING)
        for i in self.msg_types:
            self.mod.Subscribe(eval('rc.MT_%s' % (i)))
        self.mod.SendModuleReady()
        print "Connected to Dragonfly at", server
        print "mod_id = ", self.mod.GetModuleID()

        self.config_file = config_file
        self.load_config()
        self.init_vars()
        self.init_plot()
        self.init_legend()

        timer = QtCore.QTimer(self)
        QtCore.QObject.connect(timer, QtCore.SIGNAL("timeout()"), self.timer_event)
        timer.start(10)
예제 #16
0
 def run(self):
     mod = Dragonfly_Module(self.mid, 0)
     mod.ConnectToMMM(self.server)
     for sub in self.subs:
         print "subscribing to %s" % (sub)
         mod.Subscribe(sub)
     mod.SendModuleReady()
     while (self.status()):
         msg = CMessage()
         rcv = mod.ReadMessage(msg, 0)
         if rcv == 1:
             if msg.GetHeader().msg_type in self.subs:
                 self.recv_msg(msg)
         sleep(.001)
class Display(ColorLayer):
    is_event_handler = True

    def __init__(self):
        super(Display, self).__init__(180, 180, 180, 255)

        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM("everest:7111")
        self.mod.Subscribe(rc.MT_TASK_STATE_CONFIG)
        self.mod.Subscribe(rc.MT_INPUT_DOF_DATA)
        self.mod.Subscribe(rc.MT_COMBO_WAIT)
        self.mod.Subscribe(rc.MT_TRIAL_CONFIG)
        self.mod.Subscribe(rc.MT_END_TASK_STATE)
        self.mod.Subscribe(rc.MT_PING)

        self.msg = CMessage()

        self.timer_sec = 0
        self.timer_min = 0

        self.blank_display = False

        self.position_bar = Polygon(v=[(20, 455), (20, 565), (1260, 565),
                                       (1260, 455)],
                                    color=(0.05, 0.05, 0.05, 1),
                                    stroke=0)
        self.tgt_window = Polygon(v=[(0, 0), (0, 0), (0, 0), (0, 0)],
                                  color=(0, 0.6, 0.2, 1),
                                  stroke=0)
        self.pos_fdbk = Polygon(v=[(20, 405), (20, 615), (28, 615), (28, 405)],
                                color=(0, 0.2, 1.0, 1),
                                stroke=0)
        self.pos_fdbk_txt = pyglet.text.Label('',
                                              font_name='times new roman',
                                              font_size=32,
                                              color=(0, 0, 0, 255),
                                              width=250,
                                              bold=True,
                                              x=1140,
                                              y=40)

        self.combo_wait_txt = pyglet.text.Label('',
                                                font_name='times new roman',
                                                font_size=32,
                                                color=(0, 0, 0, 255),
                                                width=250,
                                                bold=True,
                                                x=478,
                                                y=840)

        self.score_txt = pyglet.text.Label('',
                                           font_name='times new roman',
                                           font_size=36,
                                           color=(0, 0, 0, 255),
                                           width=250,
                                           bold=True,
                                           x=533,
                                           y=240)

        self.reward_txt = pyglet.text.Label('',
                                            font_name='times new roman',
                                            font_size=22,
                                            color=(0, 0, 0, 255),
                                            width=250,
                                            bold=True,
                                            x=475,
                                            y=120)

        self.reset_score()

        self.schedule_interval(self.update, 0.01)

    def timer_count_down(self, dt):
        self.timer_sec -= 1

        if self.timer_sec < 0:
            if self.timer_min > 0:
                self.timer_min -= 1
                self.timer_sec = 59
            else:
                self.unschedule(self.timer_count_down)
                self.combo_wait_txt.text = ''
                return

        self.combo_wait_txt.text = 'Relax Time   %d:%02d' % (self.timer_min,
                                                             self.timer_sec)

        if self.timer_min == 0 and self.timer_sec <= 5 and self.timer_sec > 0:
            winsound.PlaySound(
                os.path.join(os.environ.get('ROBOT_CONFIG'), 'default',
                             'gocue.wav'),
                winsound.SND_FILENAME | winsound.SND_ASYNC)

    def reset_score(self):
        self.score = 0
        self.score_force_level = 0
        self.score_target_dist = 999
        self.score_force_mult = 0
        self.score_target_mult = 0
        self.score_txt.text = "Score: %d" % self.score
        self.reward_txt.text = ""

    def update_reward(self):
        reward = self.score_force_mult * self.score_target_mult
        pts = "points"
        if reward == 1:
            pts = "point"
        self.reward_txt.text = "Current Reward: %d %s" % (reward, pts)

    def increment_score(self):
        self.score += self.score_force_mult * self.score_target_mult
        self.score_txt.text = "Score: %d" % self.score

    def update(self, dt):
        while True:
            rcv = self.mod.ReadMessage(self.msg, 0)
            if rcv == 1:
                hdr = self.msg.GetHeader()
                msg_type = hdr.msg_type

                if msg_type == rc.MT_PING:
                    self.reset_score()

                elif msg_type == rc.MT_INPUT_DOF_DATA:
                    mdf = rc.MDF_INPUT_DOF_DATA()
                    copy_from_msg(mdf, self.msg)

                    if mdf.tag == 'carduinoIO':
                        fdbk = 5 - mdf.dof_vals[
                            7]  # invert to match phyiscal setup
                        x_pos = int((fdbk * (MAX_WIDTH - 2 * OFFSET)) / 5.0)

                        self.pos_fdbk_txt.text = "%.2f V" % fdbk

                        self.pos_fdbk.v[0] = (x_pos, 405)
                        self.pos_fdbk.v[1] = (x_pos, 615)
                        self.pos_fdbk.v[2] = (x_pos + 8, 615)
                        self.pos_fdbk.v[3] = (x_pos + 8, 405)

    #                if msg_type == rc.MT_FORCE_SENSOR_DATA:
    #                    mdf = rc.MDF_FORCE_SENSOR_DATA()
    #                    copy_from_msg(mdf, self.msg)
    #
    #                    x_fdbk = mdf.data[0]
    #                    x_fdbk_width = int((x_fdbk / MAX_FDBK) * MAX_WIDTH)

                elif msg_type == rc.MT_COMBO_WAIT:
                    mdf = rc.MDF_COMBO_WAIT()
                    copy_from_msg(mdf, self.msg)

                    print mdf.duration

                    duration = mdf.duration / 1000  # convert to seconds
                    self.timer_sec = duration % 60
                    self.timer_min = duration / 60
                    self.schedule_interval(self.timer_count_down, 1)

                elif msg_type == rc.MT_TRIAL_CONFIG:
                    self.unschedule(self.timer_count_down)
                    self.combo_wait_txt.text = ''

                    # start displaying again
                    self.blank_display = False
                    self.color = (180, 180, 180)

                elif msg_type == rc.MT_END_TASK_STATE:
                    mdf = rc.MDF_END_TASK_STATE()
                    copy_from_msg(mdf, self.msg)

                    if (mdf.id == REWARD_TS) and (mdf.outcome == 1):
                        self.increment_score()

                    if (mdf.id in [2, 3, 4]) and (mdf.outcome == 0):
                        self.color = (0, 0, 0)
                        self.blank_display = True

                elif msg_type == rc.MT_TASK_STATE_CONFIG:
                    mdf = rc.MDF_TASK_STATE_CONFIG()
                    copy_from_msg(mdf, self.msg)

                    if mdf.background_color == 'gray':
                        self.color = (180, 180, 180)
                    elif mdf.background_color == 'red':
                        self.color = (150, 12, 12)
                    elif mdf.background_color == 'green':
                        self.color = (0, 150, 50)

                    if mdf.fdbk_display_color == 'gray':
                        self.tgt_window.color = (0.3, 0.3, 0.3, 1)
                    elif mdf.fdbk_display_color == 'yellow':
                        self.tgt_window.color = (0.5, 0.5, 0.0, 1)
                    elif mdf.fdbk_display_color == 'green':
                        self.tgt_window.color = (0.0, 0.6, 0.2, 1)
                    elif mdf.fdbk_display_color == 'red':
                        self.tgt_window.color = (0.6, 0.05, 0.05, 1)

                    if not (math.isnan(mdf.target[0])) and not (math.isnan(
                            mdf.target[1])):
                        x_tgt_lo = int(
                            (mdf.target[0] * (MAX_WIDTH - 2 * OFFSET)) / 5.0)
                        x_tgt_hi = int(
                            (mdf.target[1] * (MAX_WIDTH - 2 * OFFSET)) / 5.0)

                        self.tgt_window.v[0] = (x_tgt_lo, 430)
                        self.tgt_window.v[1] = (x_tgt_lo, 590)
                        self.tgt_window.v[2] = (x_tgt_hi, 590)
                        self.tgt_window.v[3] = (x_tgt_hi, 430)

                        # update multipliers during "ForceRamp" task state
                        if mdf.id == FORCERAMP_TS:
                            force_level = mdf.sep_threshold_f[1]
                            if force_level > self.score_force_level:
                                self.score_force_level = force_level
                                self.score_force_mult += 1

                                # new combo, reset target multipliers
                                self.score_target_mult = 0
                                self.score_target_dist = 999

                            target_level = mdf.target[1] - mdf.target[0]
                            if target_level < self.score_target_dist:
                                self.score_target_dist = target_level
                                self.score_target_mult += 1

                            self.update_reward()

                            #print mdf.id
                            #print force_level, self.score_force_level, self.score_force_mult
                            #print target_level, self.score_target_dist, self.score_target_mult
                            #print "\n"

            else:
                break

    #def on_key_release( self, keys, mod ):

    def draw(self):
        super(Display, self).draw()

        if not self.blank_display:
            self.position_bar.render()
            self.tgt_window.render()
            self.pos_fdbk.render()
            #self.pos_fdbk_txt.draw()
            self.combo_wait_txt.draw()
            self.score_txt.draw()
            self.reward_txt.draw()
예제 #18
0
class SimpleArbitrator(object):
    debug = True
    vel = np.zeros(rc.MAX_CONTROL_DIMS)
    #pos = np.zeros(rc.MAX_CONTROL_DIMS)
    autoVelControlFraction = \
        np.ones_like(rc.MDF_ROBOT_CONTROL_CONFIG().autoVelControlFraction)
    extrinsic_vel = np.zeros_like(rc.MDF_COMPOSITE_MOVEMENT_COMMAND().vel)
    intrinsic_vel = np.zeros_like(rc.MDF_COMPOSITE_MOVEMENT_COMMAND().vel)

    def __init__(self, config_file, server):
        self.load_config(config_file)
        self.setup_dragonfly(server)
        self.run()

    def load_config(self, config_file):
        self.config = SafeConfigParser()
        self.config.read(config_file)
        self.timer_tag = self.config.get('main', 'timer_tag')
        self.extrinsic_tags = self.config.get('main', 'extrinsic_tags').split()
        self.intrinsic_tags = self.config.get('main', 'intrinsic_tags').split()
        default_auto = float(self.config.get('main', 'default_auto'))
        self.autoVelControlFraction[:] = default_auto
        self.gate = 1.  # default value
        self.idle_gateable = 0.  # default value

    def setup_dragonfly(self, server):
        self.mod = Dragonfly_Module(rc.MID_SIMPLE_ARBITRATOR, 0)
        self.mod.ConnectToMMM(server)
        self.mod.Subscribe(MT_EXIT)
        for sub in subscriptions:
            self.mod.Subscribe(eval('rc.MT_%s' % (sub)))
        self.mod.SendModuleReady()
        print "Connected to Dragonfly at", server

    def run(self):
        while True:
            msg = CMessage()
            rcv = self.mod.ReadMessage(msg, 0.1)
            if rcv == 1:
                msg_type = msg.GetHeader().msg_type
                dest_mod_id = msg.GetHeader().dest_mod_id
                if msg_type == MT_EXIT:
                    if (dest_mod_id == 0) or (dest_mod_id
                                              == self.mod.GetModuleID()):
                        print 'Received MT_EXIT, disconnecting...'
                        self.mod.SendSignal(rc.MT_EXIT_ACK)
                        self.mod.DisconnectFromMMM()
                        break
                elif msg_type == rc.MT_PING:
                    respond_to_ping(self.mod, msg, 'SimpleArbitrator')
                else:
                    self.process_message(msg)

    def process_message(self, msg):
        '''
        Needs to:
        1) combine non-conflicting controlledDims e.g. from
        OPERATOR_MOVEMENT_COMMANDs, into either extrinsic or
        intrinsic commands
        2) combine intrinsic and extrinsic commands into final command
        '''
        msg_type = msg.GetHeader().msg_type
        if msg_type in [
                rc.MT_OPERATOR_MOVEMENT_COMMAND,
                rc.MT_PLANNER_MOVEMENT_COMMAND, rc.MT_EM_MOVEMENT_COMMAND,
                rc.MT_FIXTURED_MOVEMENT_COMMAND
        ]:

            if msg_type == rc.MT_OPERATOR_MOVEMENT_COMMAND:
                mdf = rc.MDF_OPERATOR_MOVEMENT_COMMAND()

            elif msg_type == rc.MT_PLANNER_MOVEMENT_COMMAND:
                mdf = rc.MDF_PLANNER_MOVEMENT_COMMAND()

            elif msg_type == rc.MT_EM_MOVEMENT_COMMAND:
                mdf = rc.MDF_EM_MOVEMENT_COMMAND()

            elif msg_type == rc.MT_FIXTURED_MOVEMENT_COMMAND:
                mdf = rc.MDF_FIXTURED_MOVEMENT_COMMAND()

            # MOVEMENT_COMMAND
            # ----------------
            # controlledDims
            # pos
            # sample_header
            # sample_interval
            # tag
            # vel
            # ----------------

            copy_from_msg(mdf, msg)
            tag = mdf.tag
            #if not tag in self.accepted_tags:
            #    return
            dim = np.asarray(mdf.controlledDims, dtype=bool)  #.astype(bool)
            if mdf.tag in self.intrinsic_tags:
                # intrinsic is AUTO command
                self.intrinsic_vel[dim] = np.asarray(mdf.vel, dtype=float)[dim]
                #print "intr_vel = " + " ".join(["%5.2f" % (x) for x in self.intrinsic_vel])
            elif mdf.tag in self.extrinsic_tags:
                #print "!"
                # extrinsic is non-AUTO, i.e. EM, command
                self.extrinsic_vel[dim] = np.asarray(mdf.vel, dtype=float)[dim]
                #self.extrinsic_vel[:8] *= self.gate

            if tag == self.timer_tag:
                self.send_output(mdf.sample_header)
        elif msg_type == rc.MT_ROBOT_CONTROL_CONFIG:
            mdf = rc.MDF_ROBOT_CONTROL_CONFIG()
            copy_from_msg(mdf, msg)
            self.autoVelControlFraction[:] = mdf.autoVelControlFraction
        elif msg_type == rc.MT_IDLE:
            mdf = rc.MDF_IDLE()
            copy_from_msg(mdf, msg)
            self.gate = float(np.asarray(mdf.gain, dtype=float).item())
        elif msg_type == rc.MT_IDLE_DETECTION_ENDED:
            self.gate = 1.0
        elif msg_type == rc.MT_TASK_STATE_CONFIG:
            mdf = rc.MDF_TASK_STATE_CONFIG()
            copy_from_msg(mdf, msg)
            self.idle_gateable = mdf.idle_gateable

    def get_combined_command(self):
        C = 1 - self.autoVelControlFraction  # extrinsic fraction
        d = self.intrinsic_vel
        u = self.extrinsic_vel
        combined = C * u + (1 - C) * d
        print "--------------------------------------"
        print "C" + " ".join(["%0.2f" % (x) for x in C])
        print "d" + " ".join(["%0.2f" % (x) for x in d])
        print "u" + " ".join(["%0.2f" % (x) for x in u])
        print "+" + " ".join(["%0.2f" % (x) for x in combined])
        print "gain: ", self.gate
        print "gateable: ", self.idle_gateable
        return combined

    def send_output(self, sample_header):
        mdf = rc.MDF_COMPOSITE_MOVEMENT_COMMAND()
        mdf.tag = 'composite'
        vel = np.zeros_like(mdf.vel)
        vel[:] = self.get_combined_command()
        if self.idle_gateable == 1:
            vel[:8] *= self.gate
        mdf.vel[:] = vel
        mdf.sample_header = sample_header
        msg = CMessage(rc.MT_COMPOSITE_MOVEMENT_COMMAND)
        copy_to_msg(mdf, msg)
        self.mod.SendMessage(msg)
예제 #19
0
class TrialStatus(object):
    def __init__(self, config_file, server):
        self.load_config(config_file)
        self.msg_nums = [eval('rc.MT_%s' % (x)) for x in self.msg_types]
        self.trial_sync = 0
        self.num_trials = 0
        self.num_trials_postcalib = 0
        self.num_trial_started_postcalib = 0
        self.num_trial_successful_postcalib = 0
        self.num_trial_givenup_postcalib = 0
        self.success_window = []
        self.started_window = []
        self.givenup_window = []
        self.shadow_num_trial_started_postcalib = 0
        self.shadow_num_trial_successful_postcalib = 0
        self.shadow_num_trial_givenup_postcalib = 0
        self.shadow_success_window = []
        self.shadow_started_window = []
        self.shadow_givenup_window = []

        self.last_time = time()
        self.setup_dragonfly(server)

        #self.rewards_given = 0
        #self.prev_rewards_given = 0
        self.run()

    def load_config(self, config_file):
        self.config = SafeConfigParser()
        self.config.read(config_file)
        self.msg_types = [
            'END_TASK_STATE', 'SESSION_CONFIG', 'EM_DECODER_CONFIGURATION'
        ]  #'GIVE_REWARD'
        self.msg_types.sort()
        self.window_len = self.config.getint('general', 'window_len')
        self.task_state_codes = {}
        for k, v in self.config.items('task state codes'):
            self.task_state_codes[k] = int(v)

    def setup_dragonfly(self, server):
        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(server)
        self.mod.Subscribe(MT_EXIT)
        self.mod.Subscribe(rc.MT_PING)
        for i in self.msg_types:
            self.mod.Subscribe(eval('rc.MT_%s' % (i)))
        self.mod.SendModuleReady()
        print "Connected to RTMA at", server

    def run(self):
        while True:
            msg = CMessage()
            rcv = self.mod.ReadMessage(msg, 0.1)
            if rcv == 1:
                msg_type = msg.GetHeader().msg_type
                dest_mod_id = msg.GetHeader().dest_mod_id
                if msg_type == MT_EXIT:
                    if (dest_mod_id == 0) or (dest_mod_id
                                              == self.mod.GetModuleID()):
                        print 'Received MT_EXIT, disconnecting...'
                        self.mod.SendSignal(rc.MT_EXIT_ACK)
                        self.mod.DisconnectFromMMM()
                        break
                elif msg_type == rc.MT_PING:
                    respond_to_ping(self.mod, msg, 'TrialStatus')
                else:
                    self.process_message(msg)

            this_time = time()
            self.diff_time = this_time - self.last_time
            if self.diff_time > 1.:
                self.last_time = this_time
                self.write()

    def reset_counters(self):
        self.trial_sync = 0
        self.num_trials_postcalib = 0
        self.num_trial_started_postcalib = 0
        self.num_trial_givenup_postcalib = 0
        self.num_trial_successful_postcalib = 0
        self.shadow_num_trial_started_postcalib = 0
        self.shadow_num_trial_givenup_postcalib = 0
        self.shadow_num_trial_successful_postcalib = 0
        self.started_window = []
        self.givenup_window = []
        self.success_window = []
        self.shadow_started_window = []
        self.shadow_givenup_window = []
        self.shadow_success_window = []

    def process_message(self, in_msg):
        msg_type = in_msg.GetHeader().msg_type
        if not msg_type in self.msg_nums:
            return

        # SESSION_CONFIG => start of session
        if msg_type == rc.MT_SESSION_CONFIG:
            self.num_trials = 0
            self.reset_counters()

        # EM_DECODER_CONFIGURATION => end of an adaptation round
        elif msg_type == rc.MT_EM_DECODER_CONFIGURATION:
            self.reset_counters()

        # END_TASK_STATE => end of a task
        elif msg_type == rc.MT_END_TASK_STATE:
            mdf = rc.MDF_END_TASK_STATE()
            copy_from_msg(mdf, in_msg)

            # need to know:
            #    begin task state code
            #    final task state code
            #    intertrial state code

            if (mdf.id == 1):
                self.trial_sync = 1
                self.shadow_started_window.append(0)

            if (mdf.id == self.task_state_codes['begin']) & (mdf.outcome == 1):
                if self.trial_sync:
                    #print "*** trial started ***"
                    #self.rewards_given += 1
                    self.shadow_num_trial_started_postcalib += 1
                    self.shadow_success_window.append(0)
                    self.shadow_givenup_window.append(0)
                    self.shadow_started_window[-1] = 1

            if mdf.reason == "JV_IDLE_TIMEOUT":
                if self.trial_sync:
                    self.shadow_num_trial_givenup_postcalib += 1
                    self.shadow_givenup_window[-1] = 1

            if (mdf.id == self.task_state_codes['final']) & (mdf.outcome == 1):
                if self.trial_sync:
                    #print "*** trial complete and successful"
                    self.shadow_num_trial_successful_postcalib += 1
                    self.shadow_success_window[-1] = 1

            if (mdf.id == self.task_state_codes['intertrial']):
                if self.trial_sync:
                    # do end-of-trial stuff here
                    self.num_trials += 1
                    self.num_trials_postcalib += 1
                    self.num_trial_started_postcalib = self.shadow_num_trial_started_postcalib
                    self.num_trial_successful_postcalib = self.shadow_num_trial_successful_postcalib
                    self.num_trial_givenup_postcalib = self.shadow_num_trial_givenup_postcalib

                    if len(self.shadow_success_window) > self.window_len:
                        self.shadow_success_window.pop(0)

                    if len(self.shadow_givenup_window) > self.window_len:
                        self.shadow_givenup_window.pop(0)

                    if len(self.shadow_started_window) > self.window_len:
                        self.shadow_started_window.pop(0)

                    self.success_window = copy.deepcopy(
                        self.shadow_success_window)
                    self.started_window = copy.deepcopy(
                        self.shadow_started_window)
                    self.givenup_window = copy.deepcopy(
                        self.shadow_givenup_window)

    def write(self):
        percent_start = percent_success = percent_givenup = 0
        percent_success_window = num_success_window = 0
        percent_started_window = num_started_window = 0
        percent_givenup_window = num_givenup_window = 0

        if self.num_trials_postcalib > 0:
            percent_start = 100 * self.num_trial_started_postcalib / self.num_trials_postcalib
            percent_givenup = 100 * self.num_trial_givenup_postcalib / self.num_trials_postcalib
            percent_success = 100 * self.num_trial_successful_postcalib / self.num_trials_postcalib

        if len(self.success_window) > 0:
            num_success_window = np.sum(self.success_window)
            percent_success_window = 100 * num_success_window / len(
                self.success_window)

        if len(self.started_window) > 0:
            num_started_window = np.sum(self.started_window)
            percent_started_window = 100 * num_started_window / len(
                self.started_window)

        if len(self.givenup_window) > 0:
            num_givenup_window = np.sum(self.givenup_window)
            percent_givenup_window = 100 * num_givenup_window / len(
                self.givenup_window)

        print "All trials : %d\n" % (self.num_trials_postcalib)
        print "Started trials  : %d (%0.0f%%)" % (
            self.num_trial_started_postcalib, percent_start)
        print "Given-up trials : %d (%0.0f%%)" % (
            self.num_trial_givenup_postcalib, percent_givenup)
        print "Success trials  : %d (%0.0f%%)\n" % (
            self.num_trial_successful_postcalib, percent_success)
        print "Started trials out of last %d\t\t: %d (%0.0f%%)" % (len(
            self.started_window), num_started_window, percent_started_window)
        print "Given-up trials out of last started %d\t: %d (%0.0f%%)" % (len(
            self.givenup_window), num_givenup_window, percent_givenup_window)
        print "Success trials out of last started %d\t: %d (%0.0f%%)" % (len(
            self.success_window), num_success_window, percent_success_window)
        print ""
예제 #20
0
class RandomGen(object):
    def __init__(self, config_file, mm_ip):
        daq_config = self.load_config(config_file)
        self.setup_daq(daq_config)
        self.setup_dragonfly(mm_ip)
        self.serial_no = 2
        self.variable = 0  # 0 and 1 cause problems for LogReader
        self.run()

    def load_config(self, config_file):
        cfg = SafeConfigParser()
        cfg.read(config_file)
        daq_config = Config()
        daq_config.minV = cfg.getfloat('main', 'minV')
        daq_config.maxV = cfg.getfloat('main', 'maxV')
        daq_config.nsamp = cfg.getint('main', 'nsamp_per_chan_per_second')
        daq_config.nchan = cfg.getint('main', 'nchan')
        daq_config.nirq = self.freq = cfg.getint('main', 'nirq_per_second')
        return daq_config

    def setup_daq(self, daq_config):
        self.daq_task = DAQInterface(self, daq_config)
        self.daq_task.register_callback(self.on_daq_callback)
        print "DrAQonfly: DAQ configured"

    def setup_dragonfly(self, mm_ip):
        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(mm_ip)
        self.mod.Subscribe(MT_EXIT)
        self.mod.Subscribe(rc.MT_PING)
        self.mod.SendModuleReady()
        print "DrAQonfly: connected to dragonfly"

    def on_daq_callback(self, data):
        mdf = rc.MDF_PLOT_POSITION()
        self.serial_no += 1
        mdf.tool_id = 0
        mdf.missing = 0
        self.variable += 1
        mdf.xyz[:] = np.array([self.variable] * 3)
        mdf.ori[:] = np.array(
            [self.variable] * 4
        )  # will work but need!!! reading modules to know the format of buffer
        #mdf.buffer[data.size:] = -1
        msg = CMessage(rc.MT_PLOT_POSITION)
        copy_to_msg(mdf, msg)
        self.mod.SendMessage(msg)
        print self.variable
        sys.stdout.write('|')
        sys.stdout.flush()

        # now check for exit message
        in_msg = CMessage()
        rcv = self.mod.ReadMessage(msg, 0)
        if rcv == 1:
            hdr = msg.GetHeader()
            msg_type = hdr.msg_type
            dest_mod_id = hdr.dest_mod_id
            if msg_type == MT_EXIT:
                if (dest_mod_id == 0) or (dest_mod_id
                                          == self.mod.GetModuleID()):
                    print "Received MT_EXIT, disconnecting..."
                    self.daq_task.StopTask()
                    self.mod.SendSignal(rc.MT_EXIT_ACK)
                    self.mod.DisconnectFromMMM()
                    self.stop()
            elif msg_type == rc.MT_PING:
                respond_to_ping(self.mod, msg, 'RandomGen')

    def run(self):
        self.daq_task.StartTask()
        print "!"
        while True:
            pass

    def stop(self):
        self.daq_task.StopTask()
        self.daq_task.ClearTask()
예제 #21
0
class MplCanvas(FigureCanvas):
    def __init__(self, parent=None, width=8, height=10, dpi=80):
        self.parent = parent
        self.redraw_yticks = True

        self.figure = Figure(figsize=(width, height), dpi=dpi, facecolor='#bbbbbb')
        FigureCanvas.__init__(self, self.figure)

        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,
                                   QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)


    def run(self, config_file, server):
        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(server)
        self.msg_types = ['END_TASK_STATE', 'SESSION_CONFIG', 'EM_DECODER_CONFIGURATION']
        self.msg_types.sort()
        self.mod.Subscribe(MT_EXIT)
        self.mod.Subscribe(rc.MT_PING)
        for i in self.msg_types:
            self.mod.Subscribe(eval('rc.MT_%s' % (i)))
        self.mod.SendModuleReady()
        print "Connected to Dragonfly at", server
        print "mod_id = ", self.mod.GetModuleID()

        self.config_file = config_file
        self.load_config()
        self.init_vars()
        self.init_plot()
        self.init_legend()

        timer = QtCore.QTimer(self)
        QtCore.QObject.connect(timer, QtCore.SIGNAL("timeout()"), self.timer_event)
        timer.start(10)


    def init_vars(self):
        self.num_trials = 0
        self.reset_counters()
        self.msg_cnt = 0
        self.console_disp_cnt = 0


    def reset_counters(self):
        self.trial_sync = 0
        self.num_trials_postcalib = 0
        self.num_trial_started_postcalib = 0
        self.num_trial_givenup_postcalib = 0
        self.num_trial_successful_postcalib = 0
        self.shadow_num_trial_started_postcalib = 0
        self.shadow_num_trial_givenup_postcalib = 0
        self.shadow_num_trial_successful_postcalib = 0
        self.started_window = []
        self.givenup_window = []
        self.success_window = []
        self.shadow_started_window = []
        self.shadow_givenup_window = []
        self.shadow_success_window = []
        self.percent_start = 0
        self.percent_success = 0
        self.percent_givenup = 0
        self.hist_narrow_SUR = []
        self.hist_narrow_GUR = []
        self.hist_narrow_STR = []

        self.hist_wide_SUR = []
        self.hist_wide_GUR = []
        self.hist_wide_STR = []

    def update_gui_label_data(self):
        self.parent.GALL.setText("%d" % self.num_trials_postcalib)
        self.parent.GSTR.setText("%d" % self.num_trial_started_postcalib) 
        self.parent.GGUR.setText("%d" % self.num_trial_givenup_postcalib) 
        self.parent.GSUR.setText("%d" % self.num_trial_successful_postcalib) 


    #def reload_config(self):
    #    self.load_config()
    #    for ax in self.figure.axes:
    #        self.figure.delaxes(ax)
    #    self.figure.clear()
    #    self.draw()
    #    self.init_plot(True)
    #    self.init_legend()
    #    self.redraw_yticks = True

    #def load_config(self):
    #    self.config = ConfigObj(self.config_file, unrepr=True)

    def load_config(self):
        self.config = SafeConfigParser()
        self.config.read(self.config_file)
        self.window_narrow = self.config.getint('general', 'window_narrow')
        self.window_wide = self.config.getint('general', 'window_wide')
        self.task_state_codes = {}
        for k, v in self.config.items('task state codes'):
            self.task_state_codes[k] = int(v)


    def init_plot(self, clear=False):
        self.nDims = 3

        self.figure.subplots_adjust(bottom=.05, right=.98, left=.08, top=.98, hspace=0.07)

        self.ax = []
        self.old_size = []
        self.ax_bkg = []
        self.lines = []

        ax = self.figure.add_subplot(1,1,1)

        box = ax.get_position()
        ax.set_position([box.x0, box.y0, box.width * 0.85, box.height])

        self.reset_axis(ax)
        self.draw()

        bbox_width = ax.bbox.width
        bbox_height = ax.bbox.height
        if clear == True:   # force to redraw
            bbox_width = 0
            bbox_height = 0

        self.old_size.append( (bbox_width, bbox_height) )
        self.ax_bkg.append(self.copy_from_bbox(ax.bbox))

        self.colors = ['k', 'r', 'g']
        self.styles = ['-', '-', '--']

        for d in range(self.nDims):
            for m in range(3):
                line, = ax.plot([], [], self.colors[d]+self.styles[m], lw=1.5, aa=True, animated=True)
                line.set_ydata([0, 0])
                line.set_xdata([0, 1])
                self.lines.append(line)
                self.draw()

        self.ax.append(ax)


    def reset_axis(self, ax): #, label):
        ax.grid(True)
        ax.set_ylim(-1, 101)
        ax.set_autoscale_on(False)
        ax.get_xaxis().set_ticks([])
        for tick in ax.get_yticklabels():
            tick.set_fontsize(9)


    def init_legend(self):
        legnd = []

        for d in range(self.nDims):
            for m in range(3):
                line = matplotlib.lines.Line2D([0,0], [0,0], color=self.colors[d], ls=self.styles[m], lw=1.5)
                legnd.append(line)

        legend_text = []
        legend_text.append('STR')
        legend_text.append('STR%d' % self.window_narrow)
        legend_text.append('STR%d' % self.window_wide)
        legend_text.append('GUR')
        legend_text.append('GUR%d' % self.window_narrow)
        legend_text.append('GUR%d' % self.window_wide)
        legend_text.append('SUR')
        legend_text.append('SUR%d' % self.window_narrow)
        legend_text.append('SUR%d' % self.window_wide)

        self.figure.legend(legnd, legend_text, loc = 'right', bbox_to_anchor=(1, 0.5),
                           frameon=False, labelspacing=1.5, prop={'size':'11'})
        self.draw()


    def timer_event(self):
        done = False
        while not done:
            msg = CMessage()
            rcv = self.mod.ReadMessage(msg, 0)
            if rcv == 1:
                msg_type = msg.GetHeader().msg_type

                # SESSION_CONFIG => start of session
                if msg_type == rc.MT_SESSION_CONFIG:
                    #self.msg_cnt += 1
                    self.num_trials = 0
                    self.reset_counters()
                    self.update_gui_label_data()


                # EM_DECODER_CONFIGURATION => end of an adaptation round
                elif msg_type == rc.MT_EM_DECODER_CONFIGURATION:
                    #self.msg_cnt += 1
                    self.reset_counters()
                    self.update_gui_label_data()

                # END_TASK_STATE => end of a task
                elif msg_type == rc.MT_END_TASK_STATE:
                    #self.msg_cnt += 1
                    mdf = rc.MDF_END_TASK_STATE()
                    copy_from_msg(mdf, msg)

                    # need to know:
                    #    begin task state code
                    #    final task state code
                    #    intertrial state code

                    if (mdf.id == 1):
                        self.trial_sync = 1
                        self.shadow_started_window.append(0)

                    if (mdf.id == self.task_state_codes['begin']) & (mdf.outcome == 1):
                        if self.trial_sync:
                            #print "*** trial started ***"
                            #self.rewards_given += 1
                            self.shadow_num_trial_started_postcalib += 1
                            self.shadow_success_window.append(0)
                            self.shadow_givenup_window.append(0)
                            self.shadow_started_window[-1] = 1

                    if mdf.reason == "JV_IDLE_TIMEOUT":
                        if self.trial_sync:
                            self.shadow_num_trial_givenup_postcalib += 1
                            self.shadow_givenup_window[-1] = 1

                    if (mdf.id == self.task_state_codes['final']) & (mdf.outcome == 1):
                        if self.trial_sync:
                            #print "*** trial complete and successful"
                            self.shadow_num_trial_successful_postcalib += 1
                            self.shadow_success_window[-1] = 1

                    if (mdf.id == self.task_state_codes['intertrial']):
                        if self.trial_sync:
                            # do end-of-trial stuff here
                            self.num_trials += 1
                            self.num_trials_postcalib += 1
                            self.num_trial_started_postcalib = self.shadow_num_trial_started_postcalib
                            self.num_trial_successful_postcalib = self.shadow_num_trial_successful_postcalib
                            self.num_trial_givenup_postcalib = self.shadow_num_trial_givenup_postcalib

                            if len(self.shadow_success_window) > self.window_wide: #self.window_narrow:
                                self.shadow_success_window.pop(0)

                            if len(self.shadow_givenup_window) > self.window_wide: #self.window_narrow:
                                self.shadow_givenup_window.pop(0)

                            if len(self.shadow_started_window) > self.window_wide: #self.window_narrow:
                                self.shadow_started_window.pop(0)

                            self.success_window = copy.deepcopy(self.shadow_success_window)
                            self.started_window = copy.deepcopy(self.shadow_started_window)
                            self.givenup_window = copy.deepcopy(self.shadow_givenup_window)

                            if self.num_trials_postcalib > 0:
                                self.percent_start = 100 * self.num_trial_started_postcalib / self.num_trials_postcalib
                                self.percent_givenup = 100 * self.num_trial_givenup_postcalib / self.num_trials_postcalib
                                self.percent_success = 100 * self.num_trial_successful_postcalib / self.num_trials_postcalib


                            percent_success_wide_window = np.NAN
                            if len(self.success_window) >= self.window_wide:
                                num_success_window = np.sum(self.success_window)
                                percent_success_wide_window = 100 * num_success_window / len(self.success_window)

                            percent_givenup_wide_window = np.NAN
                            if len(self.givenup_window) >= self.window_wide:
                                num_givenup_window = np.sum(self.givenup_window)
                                percent_givenup_wide_window = 100 * num_givenup_window / len(self.givenup_window)

                            percent_started_wide_window = np.NAN
                            if len(self.started_window) >= self.window_wide:
                                num_started_window = np.sum(self.started_window)
                                percent_started_wide_window = 100 * num_started_window / len(self.started_window)

                            percent_success_narrow_window = np.NAN
                            if len(self.success_window) >= self.window_narrow:
                                success_window_narrow = self.success_window[len(self.success_window)-self.window_narrow:]
                                num_success_window = np.sum(success_window_narrow)
                                percent_success_narrow_window = 100 * num_success_window / len(success_window_narrow)

                            percent_givenup_narrow_window = np.NAN
                            if len(self.givenup_window) >= self.window_narrow:
                                givenup_window_narrow = self.givenup_window[len(self.givenup_window)-self.window_narrow:]
                                num_givenup_window = np.sum(givenup_window_narrow)
                                percent_givenup_narrow_window = 100 * num_givenup_window / len(givenup_window_narrow)

                            if len(self.started_window) >= self.window_narrow:
                                started_window_narrow = self.started_window[len(self.started_window)-self.window_narrow:]
                                num_started_window = np.sum(started_window_narrow)
                                percent_started_narrow_window = 100 * num_started_window / len(started_window_narrow)
                                self.hist_narrow_STR.append(percent_started_narrow_window)
                                self.hist_narrow_SUR.append(percent_success_narrow_window)
                                self.hist_narrow_GUR.append(percent_givenup_narrow_window)

                                self.hist_wide_STR.append(percent_started_wide_window)
                                self.hist_wide_SUR.append(percent_success_wide_window)
                                self.hist_wide_GUR.append(percent_givenup_wide_window)

                            self.update_gui_label_data()


                elif msg_type == rc.MT_PING:
                    respond_to_ping(self.mod, msg, 'TrialStatusDisplay')

                elif msg_type == MT_EXIT:
                    self.exit()
                    done = True

            else:
                done = True

                self.console_disp_cnt += 1
                if self.console_disp_cnt == 50:
                    self.update_plot()
                    self.console_disp_cnt = 0


    def update_plot(self):

        #print "All trials : %d" % (self.num_trials_postcalib)
        #print ""
        #print "GSTR: ", self.percent_start
        #print "GGUR: ", self.percent_givenup
        #print "GSUR: ", self.percent_success
        #print ""
        #print "STR win: ", self.started_window
        #print "GUP win: ", self.givenup_window
        #print "SUC win: ", self.success_window
        #print ""
        #print "nSTR: ", self.hist_narrow_STR
        #print "nGUR: ", self.hist_narrow_GUR
        #print "nSUR :", self.hist_narrow_SUR
        #print ""
        #print "wSTR: ", self.hist_wide_STR
        #print "wGUR: ", self.hist_wide_GUR
        #print "wSUR :", self.hist_wide_SUR
        #print ""
        #print "Msg cnt    : %d" % (self.msg_cnt)
        #print "\n ----------------------- \n"

        i = 0
        ax = self.ax[i]
        current_size = ax.bbox.width, ax.bbox.height
        if self.old_size[i] != current_size:
            self.old_size[i] = current_size
            self.draw()
            self.ax_bkg[i] = self.copy_from_bbox(ax.bbox)
        self.restore_region(self.ax_bkg[i])

        #if len(self.hist_narrow_STR) > 1:
        if not self.hist_narrow_STR:
            self.lines[0].set_ydata([self.percent_start, self.percent_start])
            self.lines[0].set_xdata([0, 1])
            ax.draw_artist(self.lines[0])

            self.lines[3].set_ydata([self.percent_givenup, self.percent_givenup])
            self.lines[3].set_xdata([0, 1])
            ax.draw_artist(self.lines[3])

            self.lines[6].set_ydata([self.percent_success, self.percent_success])
            self.lines[6].set_xdata([0, 1])
            ax.draw_artist(self.lines[6])

        else:
            ax.set_xlim(0, len(self.hist_narrow_STR)-1)

            for k in range(0,9):
                self.lines[k].set_xdata(range(len(self.hist_narrow_STR)))

            self.lines[0].set_ydata([self.percent_start, self.percent_start])
            self.lines[0].set_xdata([0, len(self.hist_narrow_STR)])
            self.lines[1].set_ydata(self.hist_narrow_STR)
            self.lines[2].set_ydata(self.hist_wide_STR)

            ###

            self.lines[3].set_ydata([self.percent_givenup, self.percent_givenup])
            self.lines[3].set_xdata([0, len(self.hist_narrow_STR)])
            self.lines[4].set_ydata(self.hist_narrow_GUR)
            self.lines[5].set_ydata(self.hist_wide_GUR)

            ###

            self.lines[6].set_ydata([self.percent_success, self.percent_success])
            self.lines[6].set_xdata([0, len(self.hist_narrow_STR)])
            self.lines[7].set_ydata(self.hist_narrow_SUR)
            self.lines[8].set_ydata(self.hist_wide_SUR)

            for k in range(0,9):
                ax.draw_artist(self.lines[k])

        self.blit(ax.bbox)

        # need to redraw once to update y-ticks
        if self.redraw_yticks == True:
            self.draw()
            self.redraw_yticks = False


    def exit(self):
        print "exiting"
        self.parent.exit_app()

    def stop(self):
        print 'disconnecting'
        self.mod.SendSignal(rc.MT_EXIT_ACK)
        self.mod.DisconnectFromMMM()
class Display(ColorLayer):
    is_event_handler = True

    def __init__(self):
        super(Display, self).__init__(180, 180, 180, 255)

        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM()
        self.mod.Subscribe(rc.MT_TASK_STATE_CONFIG)
        self.mod.Subscribe(rc.MT_INPUT_DOF_DATA)
        self.mod.Subscribe(rc.MT_COMBO_WAIT)
        self.mod.Subscribe(rc.MT_TRIAL_CONFIG)
        self.mod.Subscribe(rc.MT_END_TASK_STATE)
        self.mod.Subscribe(rc.MT_PING)
        self.mod.Subscribe(rc.MT_RT_POSITION_FEEDBACK)

        self.msg = CMessage()

        self.timer_sec = 0
        self.timer_min = 0

        self.transformationType = 0

        dims = director.get_window_size()
        self.width = dims[0]
        self.height = dims[1]
        self.oldWidth = 1280
        self.oldHeight = 1024

        self.blank_display = False

        self.position_bar = Polygon(v=[(20, 455), (20, 565), (1260, 565),
                                       (1260, 455)],
                                    color=(0.05, 0.05, 0.05, 1),
                                    stroke=0)
        self.resizePolygon(self.position_bar)

        self.tgt_window = Polygon(v=[(0, 0), (0, 0), (0, 0), (0, 0)],
                                  color=(0, 0.6, 0.2, 1),
                                  stroke=0)
        self.resizePolygon(self.tgt_window)

        self.pos_fdbk = Polygon(v=[(20, 405), (20, 615), (28, 615), (28, 405)],
                                color=(0, 0.2, 1.0, 1),
                                stroke=0)
        self.resizePolygon(self.pos_fdbk)

        self.pos_fdbk_txt = pyglet.text.Label('',
                                              font_name='times new roman',
                                              font_size=32,
                                              color=(0, 0, 0, 255),
                                              width=250,
                                              bold=True,
                                              x=1140,
                                              y=40)

        self.combo_wait_txt = pyglet.text.Label('',
                                                font_name='times new roman',
                                                font_size=32,
                                                color=(255, 255, 255, 255),
                                                width=250,
                                                bold=True,
                                                x=478,
                                                y=840)

        self.score_txt = pyglet.text.Label('',
                                           font_name='times new roman',
                                           font_size=36,
                                           color=(0, 0, 0, 255),
                                           width=250,
                                           bold=True,
                                           x=500,
                                           y=240)

        self.reward_txt = pyglet.text.Label('',
                                            font_name='times new roman',
                                            font_size=22,
                                            color=(0, 0, 0, 255),
                                            width=250,
                                            bold=True,
                                            x=475,
                                            y=120)

        self.reset_score()

        self.schedule_interval(self.update, 0.01)


#     def timer_count_down(self, dt):
#         self.timer_sec -= 1
#
#         if self.timer_sec < 0:
#             if self.timer_min > 0:
#                 self.timer_min -= 1
#                 self.timer_sec = 59
#             else:
#                 self.unschedule(self.timer_count_down)
#                 self.combo_wait_txt.text = ''
#                 self.screen_on()
#                 return
#
#         self.combo_wait_txt.text = 'Relax Time   %d:%02d' % (self.timer_min, self.timer_sec)
#
#         if self.timer_min == 0 and self.timer_sec <= 5 and self.timer_sec > 0:
#             winsound.PlaySound(os.path.join(os.environ.get('ROBOT_CONFIG'), 'default', 'gocue.wav'), winsound.SND_FILENAME | winsound.SND_ASYNC)

    def resizePolygon(self, polygon):
        for i in xrange(4):
            polygon.v[i] = (polygon.v[i][0] * self.width / self.oldWidth,
                            polygon.v[i][1] * self.height / self.oldHeight)

    def reset_score(self):
        self.score = 0
        self.score_force_level = 0
        self.score_target_dist = 999
        self.score_force_mult = 0
        self.score_target_mult = 0
        self.score_txt.text = "Score: %d" % self.score
        self.reward_txt.text = ""

    def update_reward(self):
        reward = self.score_force_mult * self.score_target_mult
        pts = "points"
        if reward == 1:
            pts = "point"
        self.reward_txt.text = "Current Reward: %d %s" % (reward, pts)

    def increment_score(self):
        self.score += 1  #self.score_force_mult * self.score_target_mult
        self.score_txt.text = "Score: %d" % self.score

    def screen_off(self):
        self.color = (0, 0, 0)
        self.blank_display = True

    def screen_on(self):
        self.blank_display = False
        self.color = (180, 180, 180)

    def update(self, dt):
        while True:
            rcv = self.mod.ReadMessage(self.msg, 0)
            if rcv == 1:
                hdr = self.msg.GetHeader()
                msg_type = hdr.msg_type

                if msg_type == rc.MT_PING:
                    self.reset_score()

                elif msg_type == rc.MT_INPUT_DOF_DATA:
                    mdf = rc.MDF_INPUT_DOF_DATA()
                    copy_from_msg(mdf, self.msg)

                    if mdf.tag == 'carduinoIO':
                        fdbk = 5 - mdf.dof_vals[
                            7]  # invert to match phyiscal setup
                        x_pos = int((fdbk * (MAX_WIDTH - 2 * OFFSET)) / 5.0)

                        x_pos += 20

                        self.pos_fdbk_txt.text = "%.2f V" % fdbk

                        self.pos_fdbk.v[0] = (x_pos, 405)
                        self.pos_fdbk.v[1] = (x_pos, 615)
                        self.pos_fdbk.v[2] = (x_pos + 8, 615)
                        self.pos_fdbk.v[3] = (x_pos + 8, 405)

    #                if msg_type == rc.MT_FORCE_SENSOR_DATA:
    #                    mdf = rc.MDF_FORCE_SENSOR_DATA()
    #                    copy_from_msg(mdf, self.msg)
    #
    #                    x_fdbk = mdf.data[0]
    #                    x_fdbk_width = int((x_fdbk / MAX_FDBK) * MAX_WIDTH)

                elif msg_type == rc.MT_RT_POSITION_FEEDBACK:  # updates real time position of handle on screen receives messages from cube_sphere while loop
                    mdf = rc.MDF_RT_POSITION_FEEDBACK()
                    copy_from_msg(mdf, self.msg)

                    x_pos = mdf.distanceFromCenter

                    x_pos += 20

                    self.pos_fdbk.v[0] = (x_pos, 405)
                    self.pos_fdbk.v[1] = (x_pos, 615)
                    self.pos_fdbk.v[2] = (x_pos + 8, 615)
                    self.pos_fdbk.v[3] = (x_pos + 8, 405)
                    self.resizePolygon(self.pos_fdbk)
                    self.transformPolygon(self.pos_fdbk,
                                          self.transformationType)

                elif msg_type == rc.MT_COMBO_WAIT:
                    mdf = rc.MDF_COMBO_WAIT()
                    copy_from_msg(mdf, self.msg)

                    print mdf.duration

                    duration = mdf.duration / 1000  # convert to seconds
                    self.timer_sec = duration % 60
                    self.timer_min = duration / 60

                    self.screen_off()
                    self.schedule_interval(self.timer_count_down, 1)

                elif msg_type == rc.MT_TRIAL_CONFIG:
                    self.unschedule(self.timer_count_down)
                    self.combo_wait_txt.text = ''
                    self.screen_on()

                elif msg_type == rc.MT_END_TASK_STATE:
                    mdf = rc.MDF_END_TASK_STATE()
                    #copy_from_msg(mdf, self.msg)
                    read_msg_data(mdf, self.msg)

                    print mdf.id, mdf.outcome

                    if (mdf.id == REWARD_TS) and (mdf.outcome == 1):
                        self.increment_score()

                    if (mdf.id in [2, 3, 4]) and (mdf.outcome == 0):
                        print "screen off"
                        self.screen_off()

                elif msg_type == rc.MT_TASK_STATE_CONFIG:
                    mdf = rc.MDF_TASK_STATE_CONFIG()
                    copy_from_msg(mdf, self.msg)

                    if mdf.background_color == 'gray':
                        self.color = (180, 180, 180)
                    elif mdf.background_color == 'red':
                        self.color = (150, 12, 12)
                    elif mdf.background_color == 'green':
                        self.color = (0, 150, 50)

                    if mdf.fdbk_display_color == 'gray':
                        self.tgt_window.color = (0.3, 0.3, 0.3, 1)
                    elif mdf.fdbk_display_color == 'yellow':
                        self.increment_score()
                        self.tgt_window.color = (0.5, 0.5, 0.0, 1)
                    elif mdf.fdbk_display_color == 'green':
                        self.tgt_window.color = (0.0, 0.6, 0.2, 1)
                    elif mdf.fdbk_display_color == 'red':
                        self.tgt_window.color = (0.6, 0.05, 0.05, 1)

                    if not math.isnan(
                            mdf.direction) and mdf.direction in range(
                                -1, 3
                            ) and not mdf.direction == self.transformationType:
                        self.position_bar.v = [(20, 455), (20, 565),
                                               (1260, 565), (1260, 455)]
                        self.resizePolygon(self.position_bar)
                        self.transformPolygon(self.position_bar, mdf.direction)
                        self.transformPolygon(self.pos_fdbk, mdf.direction)
                        self.transformationType = mdf.direction

                    if not (math.isnan(mdf.target[0])) and not (math.isnan(
                            mdf.target[1])):
                        x_tgt_lo = mdf.target[0] + 20
                        x_tgt_hi = mdf.target[1] + 20

                        self.tgt_window.v[0] = (x_tgt_lo, 430)
                        self.tgt_window.v[1] = (x_tgt_lo, 590)
                        self.tgt_window.v[2] = (x_tgt_hi, 590)
                        self.tgt_window.v[3] = (x_tgt_hi, 430)
                        self.resizePolygon(self.tgt_window)
                        self.transformPolygon(self.tgt_window,
                                              self.transformationType)
            else:
                break

    def transformPolygon(self, polygon, transformationType):
        for i in xrange(4):
            polygon.v[i] = self.transformPoint(polygon.v[i],
                                               transformationType)

    def transformPoint(self, input_point, transformationType):
        # tt values are determined by adding XorYorZ and UpOrDown
        if transformationType == 0:  # goes from left to right XorYorZ=1 UpOrDown=-1
            return input_point
        elif transformationType == 2:  # goes from right to left XorYorZ=1 UpOrDown=1
            return (self.width - input_point[0], input_point[1])
        elif transformationType == -1:  # backward XorYorZ=0 UpOrDown=-1
            return (input_point[1], self.width - input_point[0])
        elif transformationType == 1:  # forwards XorYorZ=0 UpOrDown=1
            return (input_point[1], input_point[0])
        else:
            print "unknown transform type"

    #def on_key_release( self, keys, mod ):

    def draw(self):
        super(Display, self).draw()

        if not self.blank_display:
            self.position_bar.render()
            self.tgt_window.render()
            self.pos_fdbk.render()
            #self.pos_fdbk_txt.draw()
            self.score_txt.draw()
            self.reward_txt.draw()

        self.combo_wait_txt.draw()
    def __init__(self):
        super(Display, self).__init__(180, 180, 180, 255)

        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM()
        self.mod.Subscribe(rc.MT_TASK_STATE_CONFIG)
        self.mod.Subscribe(rc.MT_INPUT_DOF_DATA)
        self.mod.Subscribe(rc.MT_COMBO_WAIT)
        self.mod.Subscribe(rc.MT_TRIAL_CONFIG)
        self.mod.Subscribe(rc.MT_END_TASK_STATE)
        self.mod.Subscribe(rc.MT_PING)
        self.mod.Subscribe(rc.MT_RT_POSITION_FEEDBACK)

        self.msg = CMessage()

        self.timer_sec = 0
        self.timer_min = 0

        self.transformationType = 0

        dims = director.get_window_size()
        self.width = dims[0]
        self.height = dims[1]
        self.oldWidth = 1280
        self.oldHeight = 1024

        self.blank_display = False

        self.position_bar = Polygon(v=[(20, 455), (20, 565), (1260, 565),
                                       (1260, 455)],
                                    color=(0.05, 0.05, 0.05, 1),
                                    stroke=0)
        self.resizePolygon(self.position_bar)

        self.tgt_window = Polygon(v=[(0, 0), (0, 0), (0, 0), (0, 0)],
                                  color=(0, 0.6, 0.2, 1),
                                  stroke=0)
        self.resizePolygon(self.tgt_window)

        self.pos_fdbk = Polygon(v=[(20, 405), (20, 615), (28, 615), (28, 405)],
                                color=(0, 0.2, 1.0, 1),
                                stroke=0)
        self.resizePolygon(self.pos_fdbk)

        self.pos_fdbk_txt = pyglet.text.Label('',
                                              font_name='times new roman',
                                              font_size=32,
                                              color=(0, 0, 0, 255),
                                              width=250,
                                              bold=True,
                                              x=1140,
                                              y=40)

        self.combo_wait_txt = pyglet.text.Label('',
                                                font_name='times new roman',
                                                font_size=32,
                                                color=(255, 255, 255, 255),
                                                width=250,
                                                bold=True,
                                                x=478,
                                                y=840)

        self.score_txt = pyglet.text.Label('',
                                           font_name='times new roman',
                                           font_size=36,
                                           color=(0, 0, 0, 255),
                                           width=250,
                                           bold=True,
                                           x=500,
                                           y=240)

        self.reward_txt = pyglet.text.Label('',
                                            font_name='times new roman',
                                            font_size=22,
                                            color=(0, 0, 0, 255),
                                            width=250,
                                            bold=True,
                                            x=475,
                                            y=120)

        self.reset_score()

        self.schedule_interval(self.update, 0.01)
예제 #24
0
class PlotHead(HasTraits):
    scene = Instance(MlabSceneModel, ())

    # The layout of the panel created by Traits
    view = View(Item('scene',
                     editor=SceneEditor(),
                     resizable=True,
                     show_label=False),
                resizable=True)

    def __init__(self, config_file, server, parent):
        HasTraits.__init__(self)
        self.count = 0
        self.parent = parent
        self.pointer_position = np.zeros((1, 3))
        self.head_data = np.zeros((1, 3))
        self.load_config(config_file)
        self.init_plot()
        self.setup_dragonfly(server)

    def load_config(self, config_file):
        cfg = PyFileConfigLoader(config_file)
        cfg.load_config()
        self.config = cfg.config
        self.filename = self.config.head_model
        self.plate = self.config.tools.index('CB609')
        self.marker = self.config.tools.index('CT315')
        self.glasses = self.config.tools.index('ST568')
        self.pointer = self.config.tools.index('P717')
        self.pointer_Ti = np.array(self.config.tool_list[self.pointer].Ti)
        self.pointer_Qi = qa.norm(
            np.array(self.config.tool_list[self.pointer].Qi))
        self.pointer_Ni = np.array(self.config.tool_list[self.pointer].Ni)
        self.pointer_Xi = self.pointer_Ni - self.pointer_Ti
        self.tp = TP(self.pointer_Qi, self.pointer_Ni, self.pointer_Ti)

    def init_plot(self):
        '''
        # create a window with 14 plots (7 rows x 2 columns)
        ## create a window with 8 plots (4 rows x 2 columns)
        reader = tvtk.OBJReader()
        reader.file_name = self.filename
        mapper = tvtk.PolyDataMapper()
        mapper.input = reader.output
        actor = tvtk.Actor()
        mapper.color_mode = 0x000000
        actor.mapper = mapper
        actor.orientation = (-90,180,0)
        self.scene.add_actor(actor)
        '''
        self.plot = mlab.plot3d(0, 0, 0, color=(0, 0, 1))
        self.plot2 = mlab.plot3d(0, 0, 0, color=(1, 0, 0))
        self.pl = self.plot.mlab_source
        self.pl2 = self.plot2.mlab_source

        self.timer = wx.Timer(self.parent)
        self.timer.Start(50)
        self.parent.Bind(wx.EVT_TIMER, self.timer_event)

    def process_message(self, msg):
        # read a Dragonfly message
        msg_type = msg.GetHeader().msg_type
        dest_mod_id = msg.GetHeader().dest_mod_id
        if msg_type == MT_EXIT:
            if (dest_mod_id == 0) or (dest_mod_id == self.mod.GetModuleID()):
                print 'Received MT_EXIT, disconnecting...'
                self.mod.SendSignal(rc.MT_EXIT_ACK)
                self.mod.DisconnectFromMMM()
                return
        elif msg_type == rc.MT_PING:
            respond_to_ping(self.mod, msg, 'PlotHead')
        elif msg_type == rc.MT_POLARIS_POSITION:
            in_mdf = rc.MDF_POLARIS_POSITION()
            copy_from_msg(in_mdf, msg)
            positions = np.asarray(in_mdf.xyz[:])
            orientations = self.shuffle_q(np.asarray(in_mdf.ori[:]))
            if in_mdf.tool_id == (self.pointer + 1):
                Qf = qa.norm(orientations)
                Qr = qa.mult(Qf, qa.inv(self.pointer_Qi)).flatten()
                #find_nans(self.store_head, Qr, 'Qr')
                Tk = positions
                #find_nans(self.store_head, Tk, 'Tk')
                tip_pos = (qa.rotate(Qr, self.pointer_Xi) + Tk).flatten()
                self.pointer_position = np.append(self.pointer_position,
                                                  (tip_pos[np.newaxis, :]),
                                                  axis=0)
                #self.pl.reset(x=self.pointer_position[:,0], y=self.pointer_position[:,1], z=self.pointer_position[:,2])
                print("old=", tip_pos)
                print("new=", self.tp.get_pos(orientations, positions)[0])
            #elif in_mdf.tool_id == (self.glasses + 1):
            #    self.head_data = np.append(self.head_data, (head[np.newaxis,:]), axis=0)
            #    self.pl2.reset(x=self.head_data[:,0], y=self.head_data[:,1], z=self.head_data[:,2])

    def setup_dragonfly(self, server):
        subscriptions = [MT_EXIT, \
                         rc.MT_PING, \
                         rc.MT_POLARIS_POSITION]
        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(server)
        for sub in subscriptions:
            self.mod.Subscribe(sub)
        self.mod.SendModuleReady()
        print "Connected to Dragonfly at ", server

    def timer_event(self, parent):
        done = False
        sys.stdout.flush()
        while not done:
            msg = CMessage()
            rcv = self.mod.ReadMessage(msg, 0)
            if rcv == 1:
                self.process_message(msg)
            else:
                done = True

    def shuffle_q(self, q):
        return np.roll(q, -1, axis=0)
예제 #25
0
class PlotHead(threading.Thread):

    def __init__(self, parent, config_file, server):#, parent):
        #HasTraits.__init__(self)
        threading.Thread.__init__(self)
        self.daemon = True
        self.count = 0
        self.parent = parent
        self.plot_vertex_vec = np.array([3,-2,2])
        self.load_config(config_file)
        self.setup_dragonfly(server)
        self.start()
    
    def load_config(self, config_file):
        cfg = PyFileConfigLoader(config_file)
        cfg.load_config()
        self.config = cfg.config
        self.filename = self.config.head_model
        
    def process_message(self, msg):
        # read a Dragonfly message
        msg_type = msg.GetHeader().msg_type
        dest_mod_id = msg.GetHeader().dest_mod_id
        if  msg_type == MT_EXIT:
            if (dest_mod_id == 0) or (dest_mod_id == self.mod.GetModuleID()):
                print 'Received MT_EXIT, disconnecting...'
                self.mod.SendSignal(rc.MT_EXIT_ACK)
                self.mod.DisconnectFromMMM()
                return
        elif msg_type == rc.MT_PING:
            respond_to_ping(self.mod, msg, 'PlotHead')
        elif msg_type == rc.MT_PLOT_POSITION:
            in_mdf = rc.MDF_PLOT_POSITION()
            copy_from_msg(in_mdf, msg)
            tail = np.array(in_mdf.xyz[:])*0.127 + (self.plot_vertex_vec)#Hotspot position
            head = np.array(in_mdf.ori[:3])/4 #Vector head of coil, used to find ori
                 
            if np.any(np.isnan(tail)) == True:
                pass
            elif np.any(np.isnan(head)) == True:
                 pass
            elif np.any(np.isinf(tail)) == True:
                pass
            elif np.any(np.isinf(head)) == True:
                pass
            else:
                queue.put(np.vstack((head, tail)))
                self.count=+1
                print 'sent message'
        elif msg_type == rc.MT_MNOME_STATE:
            in_mdf = rc.MDF_MNOME_STATE()
            copy_from_msg(in_mdf, msg)
            if in_mdf.state == 0:
                print 'got clear'
                self.parent.reset = True
               
                
        
    def setup_dragonfly(self, server):
        subscriptions = [MT_EXIT, \
                         rc.MT_PING, \
                         rc.MT_PLOT_POSITION, \
                         rc.MT_MNOME_STATE]
        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(server)
        for sub in subscriptions:
            self.mod.Subscribe(sub)
        self.mod.SendModuleReady()
        print "Connected to Dragonfly at ", server
    
   # def timer_event(self, parent):
    def run(self):
        while True:
            msg = CMessage()
            rcv = self.mod.ReadMessage(msg, 0)
            if rcv == 1:
                self.process_message(msg)
예제 #26
0
class RTFT(object):
    def __init__(self, config_file, server):
        self.load_config(config_file)
        self.init_gui()
        self.setup_dragonfly(server)
        self.solo = True  #false if executed from demigod executive file
        self.RTFT_display = True  #default = True. if message from executive, then use that value
        self.state = -1  #-1= between trials 0 = outside target, 1 = close enough, waiting, 2 = close enough, hold time met
        self.start_hold = time.time()
        self.run()

    def load_config(self, config_file):  #Default config file is RTFT_CONFIG
        self.config = SafeConfigParser()
        self.config.read(config_file)
        self.rate = float(self.config.get('main', 'rate'))
        self.target_vector = [
            float(x)
            for x in self.config.get('main', 'target_vector').split(" ")
        ]
        self.target_color = [
            float(x)
            for x in self.config.get('main', 'target_color').split(" ")
        ]
        self.target_rad = float(self.config.get('main', 'target_radius'))
        self.ball_rad = float(self.config.get('main', 'cursor_radius'))
        self.ball_color = [
            float(x)
            for x in self.config.get('main', 'cursor_color').split(" ")
        ]
        self.max_factor = float(self.config.get('main', 'max_factor'))
        self.force_scale = float(self.config.get('main', 'force_scale'))
        self.threshold = float(self.config.get('main', 'threshold'))
        self.hold_time = float(self.config.get('main', 'hold_time'))

    def setup_dragonfly(self, server):
        subscriptions = [MT_EXIT, \
                         rc.MT_PING, \
                         rc.MT_FT_DATA, \
                         rc.MT_FT_COMPLETE, \
                         rc.MT_RTFT_CONFIG]
        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(server)
        for sub in subscriptions:
            self.mod.Subscribe(sub)
        self.mod.SendModuleReady()
        print "Connected to Dragonfly at ", server

    def init_gui(self):
        # Is the orientation matrix missing here????
        self.length = 100
        wallR = box(pos=vector(self.length / 2., 0, 0),
                    size=(0.2, self.length, self.length),
                    color=color.green)
        wallB = box(pos=vector(0, 0, -self.length / 2.),
                    size=(self.length, self.length, 0.2),
                    color=color.white)
        wallDown = box(pos=vector(0, -self.length / 2., 0),
                       size=(self.length, 0.2, self.length),
                       color=color.red)
        wallUp = box(pos=vector(0, self.length / 2., 0),
                     size=(self.length, 0.2, self.length),
                     color=color.white)
        wallL = box(pos=vector(-self.length / 2., 0, 0),
                    size=(0.2, self.length, self.length),
                    color=color.blue)

        self.unit_target = self.target_vector / np.linalg.norm(
            self.target_vector)
        self.target_position = np.array(
            self.unit_target) * self.max_factor * self.force_scale
        self.ball = sphere(pos=[0, 0, 0],
                           radius=self.ball_rad,
                           color=self.ball_color)
        self.target = sphere(pos=self.target_position,
                             radius=self.target_rad,
                             color=self.target_color)
        self.shadow_cursor = ring(pos=[0, -self.length / 2, 0],
                                  axis=(0, 10, 0),
                                  radius=self.ball_rad,
                                  thickness=1,
                                  color=[0.25, 0.25, 0.25])
        self.shadow_target = ring(pos=[
            self.target_position[0], -self.length / 2, self.target_position[2]
        ],
                                  axis=(0, 10, 0),
                                  radius=self.ball_rad,
                                  thickness=1,
                                  color=[0.25, 0.25, 0.25])

    def run(self):
        while True:
            msg = CMessage()
            rcv = self.mod.ReadMessage(msg, -1)
            if rcv == 1:
                msg_type = msg.GetHeader().msg_type
                dest_mod_id = msg.GetHeader().dest_mod_id
                if msg_type == MT_EXIT:
                    if (dest_mod_id == 0) or (dest_mod_id
                                              == self.mod.GetModuleID()):
                        print 'Received MT_EXIT, disconnecting...'
                        self.mod.SendSignal(rc.MT_EXIT_ACK)
                        self.mod.DisconnectFromMMM()
                        self.pi.ser.close()
                        break
                elif msg_type == rc.MT_PING:
                    respond_to_ping(self.mod, msg, 'RTFT_iso')
                else:
                    self.process_msg(msg)

    def process_msg(self, in_msg):
        header = in_msg.GetHeader()
        if header.msg_type == rc.MT_FT_DATA:
            mdf = rc.MDF_FT_DATA()
            copy_from_msg(mdf, in_msg)
            rate(self.rate)
            self.ball.pos = vector(mdf.F[0:3])
            self.shadow_cursor.pos = vector(
                [mdf.F[0], -self.length / 2, mdf.F[2]])
            self.unit_target = np.array(self.target_vector) / np.linalg.norm(
                self.target_vector)
            self.target_position = np.array(
                self.unit_target) * self.max_factor * self.force_scale
            self.target.pos = self.target_position
            self.shadow_target.pos = [
                self.target_position[0], -self.length / 2,
                self.target_position[2]
            ]
            distance = [a - b for a, b in zip(self.ball.pos, self.target.pos)]
            if (distance[0]**2 + distance[1]**2 + distance[2]**2)**(
                    1 / 2.) >= self.threshold and self.RTFT_display:
                self.ball.color = self.ball_color
                self.state = 0
            elif (distance[0]**2 + distance[1]**2 + distance[2]**2)**(
                    1 / 2.) < self.threshold and self.RTFT_display:
                if self.state == 0:  # if previous sample was outside radius, and now we're inside...
                    self.start_hold = time.time()
                    self.state = 1
                    self.ball.color = color.orange
                else:
                    if time.time() > (self.start_hold + self.hold_time):
                        self.ball.color = color.green
                        self.target.visible = False
                        self.shadow_target.visible = False
                        self.state = 2
                        out_mdf = rc.MDF_FT_COMPLETE()
                        out_mdf.FT_COMPLETE = self.state
                        out_mdf.sample_header = mdf.sample_header
                        msg = CMessage(rc.MT_FT_COMPLETE)
                        copy_to_msg(out_mdf, msg)
                        self.mod.SendMessage(msg)
                    else:
                        self.state = 1
                        self.ball.color = color.orange
            else:
                self.state = -1

            if self.state == 2 and self.solo:  #if no executive file
                self.target.pos = [
                    float(x) for x in [
                        np.random.rand(1, 1) * self.max_factor *
                        self.force_scale,
                        np.random.rand(1, 1) * self.max_factor *
                        self.force_scale,
                        np.random.rand(1, 1) * self.max_factor *
                        self.force_scale
                    ]
                ]
                self.shadow_target.pos = [
                    self.target.pos[0], -self.length / 2, self.target.pos[2]
                ]

            sys.stdout.write(
                "%7.4f, %5d, %16.2f\n" %
                (mdf.F[2], self.state,
                 (self.start_hold + self.hold_time) - time.time()))
            #msg_str = "%7.4f   " * 6 + "\n"
            #sys.stdout.write(msg_str % (mdf.F[0], mdf.F[1], mdf.F[2],
            #                            mdf.T[0], mdf.T[1], mdf.T[2]))
            sys.stdout.flush()

        elif header.msg_type == rc.MT_RTFT_CONFIG:
            mdf = rc.MDF_RTFT_CONFIG()
            copy_from_msg(mdf, in_msg)
            self.max_factor = mdf.max_factor
            self.RTFT_display = mdf.RTFT_display
            self.target_vector = mdf.target_vector[:]
            self.ball.visible = mdf.cursor_visible
            self.target.visible = mdf.target_visible
            self.shadow_target.visible = mdf.shadow_target_visible
            self.shadow_cursor.visible = mdf.shadow_cursor_visible
            self.ball_color = [1, 0, 0]
            self.solo = False
예제 #27
0
class Metronome(object):
    def __init__(self, config_file, mm_ip):
        self.load_config(config_file)
        self.count = 0
        self.pause_state = True
        self.setup_Dragonfly(mm_ip)
        self.calc_rates()
        self.run()

    def load_config(self, config_file):
        self.config = SafeConfigParser()
        self.config.read(config_file)
        self.pretrigger_time = self.config.getfloat('metronome',
                                                    'pretrigger time')
        self.metronome_period = self.config.getfloat('metronome',
                                                     'metronome period')
        self.in_msg_type = 'DAQ_DATA'  # trigger msg
        self.in_msg_num = eval('rc.MT_%s' % (self.in_msg_type.upper()))
        print self.in_msg_num, 'config load complete'

    def calc_rates(self):
        self.in_msg_freq = 1 / self.chk_msg()
        self.metronome_count = self.metronome_period * self.in_msg_freq
        if self.pretrigger_time > 0:  #negative pre-trigger fire after metronome
            self.trigger_out_count = self.metronome_count - self.pretrigger_time * self.in_msg_freq
        else:
            self.trigger_out_count = self.metronome_count + self.pretrigger_time * self.in_msg_freq
        print 'Got frequency! %d' % self.in_msg_freq
        print self.metronome_count, self.trigger_out_count

    def chk_msg(self):
        while True:
            in_msg = CMessage()
            rcv = self.mod.ReadMessage(in_msg, 0.1)
            if rcv == 1:
                msg_type = in_msg.GetHeader().msg_type
                if msg_type == MT_EXIT:
                    if (dest_mod_id == 0) or (dest_mod_id
                                              == self.mod.GetModuleID()):
                        print 'Received MT_EXIT, disconnecting...'
                        self.mod.SendSignal(rc.MT_EXIT_ACK)
                        self.mod.DisconnectFromMMM()
                        break
                elif msg_type == rc.MT_PING:
                    respond_to_ping(self.mod, in_msg, 'Metronome')
                elif msg_type == self.in_msg_num:
                    in_mdf = eval('rc.MDF_%s()' % (self.in_msg_type.upper()))
                    copy_from_msg(in_mdf, in_msg)
                    return in_mdf.sample_header.DeltaTime

    def setup_Dragonfly(self, mm_ip):
        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(mm_ip)
        self.mod.Subscribe(MT_EXIT)
        self.mod.Subscribe(rc.MT_PING)
        self.mod.Subscribe(self.in_msg_num)
        self.mod.Subscribe(rc.MT_MNOME_STATE)
        self.mod.SendModuleReady()
        print "Connected to Dragonfly at", mm_ip

    def run(self):
        while True:
            in_msg = CMessage()
            rcv = self.mod.ReadMessage(in_msg, 0.1)
            if rcv == 1:
                msg_type = in_msg.GetHeader().msg_type
                if msg_type == MT_EXIT:
                    if (dest_mod_id == 0) or (dest_mod_id
                                              == self.mod.GetModuleID()):
                        print 'Received MT_EXIT, disconnecting...'
                        self.mod.SendSignal(rc.MT_EXIT_ACK)
                        self.mod.DisconnectFromMMM()
                        break
                elif msg_type == rc.MT_PING:
                    respond_to_ping(self.mod, in_msg, 'Metronome')
                elif msg_type == rc.MT_MNOME_STATE:
                    print 'got message'
                    in_mdf = rc.MDF_MNOME_STATE()
                    copy_from_msg(in_mdf, in_msg)
                    if in_mdf.state == 0:
                        print 'got stop'
                        self.pause_state = True
                        self.count = 0
                    elif in_mdf.state == 1:
                        print 'got start'
                        self.pause_state = False
                        self.count = 0
                    elif in_mdf.state == 2:
                        print 'got pause'
                        self.pause_state = True
                        self.count = 0
                elif msg_type == self.in_msg_num:
                    if self.pause_state:
                        pass
                    else:
                        self.count += 1
                        if self.pretrigger_time > 0:
                            if self.count == self.metronome_count:
                                in_mdf = eval('rc.MDF_%s()' %
                                              (self.in_msg_type.upper()))
                                copy_from_msg(in_mdf, in_msg)
                                out_mdf = rc.MDF_TMS_TRIGGER()
                                out_mdf.sample_header = in_mdf.sample_header
                                out_msg = CMessage(rc.MT_TMS_TRIGGER)
                                copy_to_msg(out_mdf, out_msg)
                                self.mod.SendMessage(out_msg)
                                self.count = 0 - int(
                                    np.random.uniform(0, 1.5, 1)[0] *
                                    self.in_msg_freq)

                            if self.count == self.trigger_out_count:
                                sound_thread = threading.Thread(
                                    target=self.play_sound)
                                sound_thread.start()

                        else:
                            if self.count == self.trigger_out_count:
                                in_mdf = eval('rc.MDF_%s()' %
                                              (self.in_msg_type.upper()))
                                copy_from_msg(in_mdf, in_msg)
                                out_mdf = rc.MDF_TMS_TRIGGER()
                                out_mdf.sample_header = in_mdf.sample_header
                                out_msg = CMessage(rc.MT_TMS_TRIGGER)
                                copy_to_msg(out_mdf, out_msg)
                                self.mod.SendMessage(out_msg)

                            if self.count == self.metronome_count:
                                self.count = 0 - int(
                                    np.random.uniform(0, 1.5, 1)[0] *
                                    self.in_msg_freq)
                                sound_thread = threading.Thread(
                                    target=self.play_sound)
                                sound_thread.start()

    def play_sound(self):
        winsound.Beep(1500, 1000)
예제 #28
0
class BackgroundProcess(threading.Thread):
    
    def __init__(self, parent, config_file, server):
        threading.Thread.__init__(self)
        self.load_config(config_file)
        self.parent = parent
        self.collect_count = 0
        self.hotspot_count = 0
        self.TMS_trigger = False
        self.new_hotspot_data = False  
        self.new_collect_data = False
        self.ext_trig = False
        self.daemon = True
        self.setup_dragonfly(server)
        self.ext_trig = dit.DAQOut()
        self.setup_buffers()
        self.start()
     
    def load_config(self, config_file):
        cfg = SafeConfigParser()
        cfg.read(config_file)
        self.config = Config()
        #daq_config.minV  = cfg.getfloat('main', 'minV')
        #daq_config.maxV  = cfg.getfloat('main', 'maxV')
        self.config.nsamp = cfg.getint('main', 'nsamp_per_chan_per_second')
        self.config.nchan = cfg.getint('main', 'nchan')
        self.config.nemg = cfg.getint('main', 'nemg')
        self.config.nirq  = self.freq = cfg.getint('main', 'nirq_per_second')
        self.config.pre_trig = cfg.getfloat('main', 'pre_trigger')
        self.config.trig_chan = cfg.getfloat('main', 'trig_chan')
        self.config.perchan = self.config.nsamp / self.config.nirq
        self.config.npt   = self.config.nsamp * self.config.nchan / self.config.nirq
        self.config.pre_trig_samp = self.config.pre_trig * self.config.nsamp
        assert((self.config.nsamp * self.config.nchan) % self.config.nirq == 0)
        assert(self.config.nsamp % self.config.nirq == 0)
        
    
    def setup_dragonfly(self, server):
        subscriptions = [MT_EXIT, \
                         rc.MT_PING, \
                         rc.MT_DAQ_DATA, \
                         rc.MT_SAMPLE_GENERATED, \
                         rc.MT_TMS_TRIGGER]
        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(server)
        for sub in subscriptions:
            self.mod.Subscribe(sub)
        self.mod.SendModuleReady()
        print "Connected to Dragonfly at ", server
        
    def setup_buffers(self):
        self.cols = 2
        self.rows = self.config.nemg / self.cols
        self.npt = 2500 
        self.old_data = np.zeros((self.config.nchan, self.npt+300)) #  bigger to account for variable trig location in buffer
        self.new_data = np.zeros((self.config.nchan, self.npt+300))
        self.collect_data = np.zeros((self.config.nemg, self.npt))
        self.hotspot_data = np.zeros((self.config.nemg, self.npt))
        
        
    def run(self):
        while True:
            msg = CMessage()
            rcv = self.mod.ReadMessage(msg, 0)
            if rcv == 1:
                # read a Dragonfly message
                msg_type = msg.GetHeader().msg_type
                dest_mod_id = msg.GetHeader().dest_mod_id
                if  msg_type == MT_EXIT:
                    if (dest_mod_id == 0) or (dest_mod_id == self.mod.GetModuleID()):
                        print 'Received MT_EXIT, disconnecting...'
                        self.mod.SendSignal(rc.MT_EXIT_ACK)
                        self.mod.DisconnectFromMMM()
                        return
                elif msg_type == rc.MT_PING:
                    respond_to_ping(self.mod, msg, 'fast_display_rms')
                else:
                    self.process_message(msg)
                

    def process_message(self, msg):
        msg_type = msg.GetHeader().msg_type
        dest_mod_id = msg.GetHeader().dest_mod_id
        if msg_type == rc.MT_TMS_TRIGGER:
            self.ext_trig.run()
            self.TMS_trigger = True
            
        else:
            # if it is a NiDAQ message from channels 0-7, plot the data
            #self.counter += 1
            if msg_type == rc.MT_DAQ_DATA:
                #sys.stdout.write("*")
                #sys.stdout.flush()
                mdf = rc.MDF_DAQ_DATA()
                copy_from_msg(mdf, msg)
                # add data to data buffers (necessary, or just use graphics buffers?)
                # update plots to new data buffers
                buf = mdf.buffer
 
                self.new_data[:,:-self.config.perchan] = self.old_data[:,self.config.perchan:]
                for i in xrange(self.config.nchan):
                    #if i == 0:
                    #    print mdf.buffer[perchan * i:perchan * (i + 1)].size
                    self.new_data[i, -self.config.perchan:] = buf[i:self.config.nchan * self.config.perchan:self.config.nchan]
                self.old_data[:] = self.new_data[:]
                
        if self.parent.current_tab ==  'Collect':
            if self.TMS_trigger:
                if self.config.pre_trig_samp <= np.argmax(self.old_data[self.config.trig_chan, :] >= 3) <= (self.config.pre_trig_samp)+200:
                    self.trig_index = np.argmax(self.old_data[self.config.trig_chan, :] >= 3)
                    self.collect_data = self.old_data[:self.config.nemg, self.trig_index - self.config.pre_trig_samp:self.trig_index + self.npt - self.config.pre_trig_samp]
                    self.old_data = self.old_data * 0
                    self.new_data = self.new_data * 0
                    self.new_collect_data = True
                    self.TMS_trigger = False
                
        if self.parent.current_tab == 'Hotspot':
            if self.config.pre_trig_samp <= np.argmax(self.old_data[self.config.trig_chan, :] >= 3) <= self.config.pre_trig_samp+200:
                self.trig_index = np.argmax(self.old_data[self.config.trig_chan, :] >= 3)
                self.hotspot_data = self.old_data[:self.config.nemg, self.trig_index - self.config.pre_trig_samp:self.trig_index + self.npt - self.config.pre_trig_samp]
                self.new_hotspot_data = True
                self.old_data = self.old_data * 0
                self.new_data = self.new_data * 0
class MplCanvas(FigureCanvas):
    subscriptions = [
        rc.MT_PING, MT_EXIT, rc.MT_TASK_STATE_CONFIG, rc.MT_FORCE_SENSOR_DATA,
        rc.MT_FORCE_FEEDBACK, rc.MT_END_TASK_STATE
    ]

    def __init__(self, parent=None, width=8, height=10, dpi=80):
        self.parent = parent
        self.paused = False
        self.LiveData = None
        self.fdbk_actual_pos = None
        self.tsc_mdf = None
        self.ets_mdf = None
        self.redraw_yticks = True

        self.figure = Figure(figsize=(width, height),
                             dpi=dpi,
                             facecolor='#bbbbbb')
        FigureCanvas.__init__(self, self.figure)

        self.setParent(parent)

        FigureCanvas.setSizePolicy(self, QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

    def init_judge_display(self):
        N = self.config['config']['number_of_data_points']

        self.nAccumPoints = 0
        self.nScaleResetPoints = N * 2

        self.LiveData = {
            'ActualPos': {},
            'ThreshUpper': {},
            'ThreshLower': {},
            'JudgingMethod': {},
            'JudgingPolarity': {},
            'max_scale': {},
            'min_scale': {}
        }

        allDims = 6  # max possible number of dims

        for d in range(allDims):
            self.LiveData['ActualPos'][d] = np.zeros(N)
            self.LiveData['ThreshUpper'][d] = nan_array(N)
            self.LiveData['ThreshLower'][d] = nan_array(N)
            self.LiveData['JudgingMethod'][d] = nan_array(N)
            self.LiveData['JudgingPolarity'][d] = nan_array(N)
            self.LiveData['max_scale'][d] = np.finfo(float).eps
            self.LiveData['min_scale'][d] = -np.finfo(float).eps  #

        self.LiveData['TaskStateNo'] = np.zeros(N)
        self.LiveData['TaskStateVerdict'] = np.ones(N)

    def run(self, config_file, server):
        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(server)
        for sub in self.subscriptions:
            self.mod.Subscribe(sub)
        self.mod.SendModuleReady()
        print "Connected to Dragonfly at", server

        self.config_file = config_file
        self.load_config()

        self.init_judge_display()
        self.init_plot()
        self.init_legend()

        self.timer = QtCore.QTimer(self)
        QtCore.QObject.connect(self.timer, QtCore.SIGNAL("timeout()"),
                               self.timer_event)
        self.timer.start(10)

    def update_scales(self, d):
        min_data = np.nanmin(self.LiveData['ActualPos'][d])
        if min_data < self.LiveData['min_scale'][d]:
            self.LiveData['min_scale'][d] = min_data * 1.05
            # add 5%
            if self.auto_scale[d]:
                self.redraw_yticks = True
                #print 'update y lim - (', d, ')'

        max_data = np.nanmax(self.LiveData['ActualPos'][d])
        if max_data > self.LiveData['max_scale'][d]:
            self.LiveData['max_scale'][d] = max_data * 1.05
            # add 5%
            if self.auto_scale[d]:
                self.redraw_yticks = True
                #print 'update y lim + (', d, ')'

    def update_judging_data(self):

        #self.nAccumPoints += 1
        #if self.nAccumPoints == self.nScaleResetPoints:
        #    print 'global y lim update'
        #    self.nAccumPoints = 0
        #    for d in range(self.nDims):
        #        if self.auto_scale[d]:
        #            self.LiveData['max_scale'][d] = np.finfo(float).eps
        #            self.LiveData['min_scale'][d] = -np.finfo(float).eps

        # this loop is so we can update plot data even if we haven't received any TASK_STATE_CONFIG messages
        for i in range(self.nDims):
            d = self.dims[i] - 1
            actual_pos = self.fdbk_actual_pos[d]
            self.LiveData['ActualPos'][d] = self.add_to_windowed_array(
                self.LiveData['ActualPos'][d], actual_pos)
            self.update_scales(d)

        if self.tsc_mdf is None:
            return

        sep_threshold = np.array(self.tsc_mdf.sep_threshold, dtype=float)
        dofs_to_judge = np.where(~np.isnan(sep_threshold) == True)[0]

        #        for i in range(self.nDims):
        #            d = self.dims[i] - 1
        #
        #            threshU = np.NAN
        #            threshL = np.NAN
        #            method = np.NAN
        #            polarity = np.NAN
        #
        #            if np.where(dofs_to_judge == d)[0].size > 0:
        #                thresh = self.tsc_mdf.sep_threshold[d]
        #                method = 2 #self.tsc_mdf.sep_threshold_judging_method[d]
        #                polarity = self.tsc_mdf.sep_threshold_judging_polarity[d]
        #
        #                # invert polarities (because we plot "keep out" zones)
        #                if (polarity > 0) and (self.tsc_mdf.timed_out_conseq == 0):
        #                    polarity = ~polarity & 3;
        #
        #                ## judging_method: 1=distance (default), 2=absolute
        #                #if method == 1:  # dist
        #                #    target = self.tsc_mdf.target[d]
        #                #    threshU = target + thresh
        #                #    threshL = target - thresh
        #                #else:            # abs
        #                threshU = thresh
        #
        #            # insert new data to plotting arrays
        #            self.LiveData['ThreshUpper'][d] = self.add_to_windowed_array(self.LiveData['ThreshUpper'][d], threshU)
        #            self.LiveData['ThreshLower'][d] = self.add_to_windowed_array(self.LiveData['ThreshLower'][d], threshL)
        #            self.LiveData['JudgingMethod'][d] = self.add_to_windowed_array(self.LiveData['JudgingMethod'][d], method)
        #            self.LiveData['JudgingPolarity'][d] = self.add_to_windowed_array(self.LiveData['JudgingPolarity'][d], polarity)

        self.LiveData['TaskStateNo'] = self.add_to_windowed_array(
            self.LiveData['TaskStateNo'], self.tsc_mdf.id)

        if self.ets_mdf is not None:
            self.LiveData['TaskStateVerdict'][-2] = self.ets_mdf.outcome
            self.LiveData['TaskStateVerdict'][-1] = self.ets_mdf.outcome
            self.LiveData['TaskStateVerdict'] = self.add_to_windowed_array(
                self.LiveData['TaskStateVerdict'], self.ets_mdf.outcome)
            self.ets_mdf = None
        else:
            self.LiveData['TaskStateVerdict'] = self.add_to_windowed_array(
                self.LiveData['TaskStateVerdict'], 1)

    def add_to_windowed_array(self, arr, data):
        arr = np.append(arr, data)
        arr = np.delete(arr, 0)
        return arr

    def load_config(self):
        self.config = ConfigObj(self.config_file, unrepr=True)

    def reload_config(self):
        self.load_config()
        for ax in self.figure.axes:
            self.figure.delaxes(ax)
        self.figure.clear()
        self.draw()
        self.init_plot(True)
        self.init_legend()
        self.redraw_yticks = True

    def timer_event(self):
        done = False
        while not done:
            msg = CMessage()
            rcv = self.mod.ReadMessage(msg, 0)
            if rcv == 1:
                msg_type = msg.GetHeader().msg_type

                if msg_type == rc.MT_TASK_STATE_CONFIG:
                    self.tsc_mdf = rc.MDF_TASK_STATE_CONFIG()
                    copy_from_msg(self.tsc_mdf, msg)

                elif msg_type == rc.MT_FORCE_FEEDBACK:
                    mdf = rc.MDF_FORCE_FEEDBACK()
                    copy_from_msg(mdf, msg)

                    #self.fdbk_actual_pos = []
                    self.fdbk_actual_pos = [mdf.x, mdf.y, mdf.z, 0.0, 0.0, 0.0]

                    self.update_judging_data()

                elif msg_type == rc.MT_FORCE_SENSOR_DATA:
                    mdf = rc.MDF_FORCE_SENSOR_DATA()
                    copy_from_msg(mdf, msg)

                    self.fdbk_actual_pos = []
                    self.fdbk_actual_pos.extend(mdf.data)

                    self.update_judging_data()

                elif msg_type == rc.MT_END_TASK_STATE:
                    self.ets_mdf = rc.MDF_END_TASK_STATE()
                    copy_from_msg(self.ets_mdf, msg)

                elif msg_type == rc.MT_PING:
                    respond_to_ping(self.mod, msg, 'SimpleDisplay')

                elif msg_type == MT_EXIT:
                    self.exit()
                    done = True

            else:
                done = True

        self.update_plot()

    def init_plot(self, clear=False):
        self.figure.subplots_adjust(bottom=.05,
                                    right=.98,
                                    left=.08,
                                    top=.98,
                                    hspace=0.07)

        active_dims = 0
        if 'active_dims' in self.config['config']:
            active_dims = self.config['config']['active_dims']

        axis_labels = []
        self.dims = []
        if active_dims:
            active_labels = ['x', 'y', 'z', 'rx', 'ry', 'rz']
            for f in active_dims:
                if (f > 0) and (f <= 6):
                    self.dims.append(f)
                    axis_labels.extend(
                        ['#%d (%s)' % (f, active_labels[f - 1])])
                else:
                    print "Warning: invalid dim specified: %d, skipping.." % f

        self.nDims = len(active_dims)
        self.xN = self.config['config']['number_of_data_points']
        self.bg = self.config['marked_task_states'].keys()

        self.max_scale = self.config['config']['max_scale']
        self.min_scale = self.config['config']['min_scale']

        if 'auto_scale' in self.config['config']:
            self.auto_scale = self.config['config']['auto_scale']
        else:
            self.auto_scale = [0] * self.nDims

        self.ax = []
        self.old_size = []
        self.ax_bkg = []
        self.pos = []
        self.zones = {}
        self.zone_idx = []

        for d in range(self.nDims):
            ax = self.figure.add_subplot(self.nDims, 1, d + 1)
            self.reset_axis(ax, axis_labels[d])
            self.draw()

            bbox_width = ax.bbox.width
            bbox_height = ax.bbox.height
            if clear == True:
                # force to redraw
                bbox_width = 0
                bbox_height = 0

            self.old_size.append((bbox_width, bbox_height))
            self.ax_bkg.append(self.copy_from_bbox(ax.bbox))

            line, = ax.plot([], [], 'k-', lw=1.0, aa=None, animated=True)
            line.set_xdata(range(self.xN))
            line.set_ydata([0.0] * self.xN)
            self.pos.append(line)
            self.draw()

            self.zones[d] = []
            self.zone_idx.append(0)
            for z in range(60):
                patch = ax.add_patch(
                    Polygon(
                        [[0, 1e-12], [1e-12, 0], [1e-12, 1e-12], [0, 1e-12]],
                        fc='none',
                        ec='none',
                        fill=True,
                        closed=True,
                        aa=None,
                        animated=True))
                self.zones[d].append(patch)
                self.draw()

            self.ax.append(ax)

    def reset_axis(self, ax, label):
        ax.grid(True)
        ax.set_xlim(0, self.xN - 1)
        ax.set_autoscale_on(False)
        ax.set_ylabel(label, fontsize='small')
        ax.get_xaxis().set_ticks([])
        ax.yaxis.set_major_formatter(FormatStrFormatter('%.02f'))
        for tick in ax.get_yticklabels():
            tick.set_fontsize(9)

    def init_legend(self):
        legnd = []

        line = matplotlib.lines.Line2D([0, 0], [0, 0], color='k')
        legnd.append(line)

        for d in range(len(self.bg)):
            b_color = self.config['marked_task_states'][self.bg[d]]['color']
            patch = Polygon([[0, 0], [0, 0], [0, 0], [0, 0]],
                            fc=b_color,
                            ec='none',
                            fill=True,
                            closed=True,
                            alpha=0.65)
            legnd.append(patch)

        self.figure.legend(legnd, ['Position'] + self.bg,
                           loc='lower center',
                           frameon=False,
                           ncol=20,
                           prop={'size': '11'},
                           columnspacing=.5)
        self.draw()

    def plot_bg_mask(self, ax, idx, x, mask, ylim, fc, ec, hatch, alpha):
        # Find starts and ends of contiguous regions of true values in mask because
        # we want just one patch object per contiguous region
        _mask = np.asarray(np.insert(mask, 0, 0), dtype=int)
        begin_indices = np.where(np.diff(_mask) == 1)[0]

        _mask = np.asarray(np.append(mask, 0), dtype=int)
        end_indices = np.where(np.diff(_mask) == -1)[0]

        # Get DeltaX
        dx = np.mean(np.diff(x))

        # Get YLim if it was not given
        if len(ylim) == 0:
            ylim = ax.get_ylim()

        z = self.zones[idx]
        a = self.zone_idx[idx]

        for i in range(len(begin_indices)):
            b = begin_indices[i]
            e = end_indices[i]
            xb = x[b] - dx / 2
            xe = x[e] + dx / 2

            patch = z[a]
            patch.set_xy([[xb, ylim[0]], [xe, ylim[0]], [xe, ylim[1]],
                          [xb, ylim[1]]])
            patch.set_edgecolor(ec)
            patch.set_facecolor(fc)
            patch.set_hatch(hatch)
            patch.set_alpha(alpha)

            ax.draw_artist(patch)
            a = a + 1

        self.zone_idx[idx] = a

    def update_plot(self):
        if self.paused == False:
            LiveData = self.LiveData
        else:
            LiveData = self.PausedData

        for i in range(self.nDims):
            ax = self.ax[i]
            d = self.dims[i] - 1

            current_size = ax.bbox.width, ax.bbox.height
            if self.old_size[i] != current_size:
                self.old_size[i] = current_size
                self.draw()
                self.ax_bkg[i] = self.copy_from_bbox(ax.bbox)

            self.restore_region(self.ax_bkg[i])

            self.zone_idx[i] = 0

            min_scale = self.min_scale[i]
            max_scale = self.max_scale[i]

            if self.auto_scale[i]:
                min_scale = LiveData['min_scale'][d]
                max_scale = LiveData['max_scale'][d]

            ax.set_ylim(min_scale, max_scale)
            yLimG = ax.get_ylim()

            for b in range(len(self.bg)):
                b_id = self.config['marked_task_states'][self.bg[b]]['id']
                b_color = self.config['marked_task_states'][
                    self.bg[b]]['color']

                mask = np.where(LiveData['TaskStateNo'] == b_id, 1, 0)
                if np.sum(mask) > 0:
                    self.plot_bg_mask(ax, i, range(self.xN), mask, [], b_color,
                                      'none', None, 0.65)
                else:
                    # always draw patch for all colors so that they will always show up in the legend
                    z = self.zones[i]
                    patch = z[self.zone_idx[i]]
                    patch.set_xy([[0, 0], [0, 0], [0, 0], [0, 0]])
                    ax.draw_artist(patch)
                    self.zone_idx[i] = self.zone_idx[i] + 1

            # threshold_judging_method: 1=distance, 2=absolute
            # threshold_judging_polarity: 1 = <, 2 = >
            methods = ~np.isnan(LiveData['JudgingMethod'][d])
            if np.sum(methods) > 0:
                methods = np.unique(LiveData['JudgingMethod'][d][methods])
                for m in range(len(methods)):
                    method = methods[m]
                    met_mask = np.where(LiveData['JudgingMethod'][d] == method,
                                        True, False)
                    polaritys = np.unique(
                        LiveData['JudgingPolarity'][d][met_mask])

                    for p in range(len(polaritys)):
                        polarity = polaritys[p]
                        pol_mask = np.where(
                            LiveData['JudgingPolarity'][d] == polarity, True,
                            False)
                        mask = met_mask & pol_mask

                        yLimUs = np.unique(LiveData['ThreshUpper'][d][mask])

                        for b in range(len(yLimUs)):
                            yLimU = yLimUs[b]
                            submask = np.where(
                                LiveData['ThreshUpper'][d] == yLimU, True,
                                False) & mask

                            if method == 1:  # dist
                                yLimLs = np.unique(
                                    LiveData['ThreshLower'][d][submask])

                                for k in range(len(yLimLs)):
                                    yLimL = yLimLs[k]
                                    submask2 = np.where(
                                        LiveData['ThreshLower'][d] == yLimL,
                                        True, False) & submask

                                    if polarity == 1:  # <
                                        self.plot_bg_mask(
                                            ax, i, range(self.xN), submask2,
                                            [yLimL, yLimU], 'none', 'black',
                                            '//', 1)
                                    else:
                                        self.plot_bg_mask(
                                            ax, i, range(self.xN), submask2,
                                            [yLimG[0], yLimL], 'none', 'black',
                                            '//', 1)
                                        self.plot_bg_mask(
                                            ax, i, range(self.xN), submask2,
                                            [yLimU, yLimG[1]], 'none', 'black',
                                            '//', 1)

                            else:  # abs
                                if polarity == 1:  # <
                                    self.plot_bg_mask(ax, i, range(self.xN),
                                                      submask,
                                                      [yLimG[0], yLimU],
                                                      'none', 'black', '//', 1)
                                else:
                                    self.plot_bg_mask(ax, i, range(self.xN),
                                                      submask,
                                                      [yLimU, yLimG[1]],
                                                      'none', 'black', '//', 1)

            fail_mask = np.where(LiveData['TaskStateVerdict'] == 0, True,
                                 False)
            self.plot_bg_mask(ax, i, range(self.xN), fail_mask, [], 'red',
                              'none', None, 0.65)

            self.pos[i].set_ydata(LiveData['ActualPos'][d])
            ax.draw_artist(self.pos[i])

            self.blit(ax.bbox)

            if self.zone_idx[i] > 60:
                print "ERROR: too many zones! Increase number of preallocated patches"

        # need to redraw once to update y-ticks
        if self.redraw_yticks == True:
            self.draw()
            self.redraw_yticks = False

    def pause(self, pause_state):
        self.paused = pause_state
        self.PausedData = copy.deepcopy(self.LiveData)

    def exit(self):
        print "exiting"
        self.parent.exit_app()

    def stop(self):
        print 'disconnecting'
        self.timer.stop()
        self.mod.SendSignal(rc.MT_EXIT_ACK)
        self.mod.DisconnectFromMMM()
예제 #30
0
class AppStarter(object):
    def __init__(self, server):
        self.setup_dragonfly(server)
        self.run()

    def setup_dragonfly(self, server):
        self.host_name = platform.uname()[1]
        self.host_os = platform.system()

        self.mod = Dragonfly_Module(0, 0)
        self.mod.ConnectToMMM(server)
        self.mod.Subscribe(rc.MT_APP_START)
        self.mod.Subscribe(rc.MT_PING)
        self.mod.Subscribe(MT_EXIT)
        self.mod.Subscribe(MT_KILL)

        self.mod.SendModuleReady()
        print "Connected to Dragonfly at", server

    # this one is slightly different than the one in Common/python, leave this one here
    def respond_to_ping(self, msg, module_name):
        #print "PING received for '{0}'".format(p.module_name)

        dest_mod_id = msg.GetHeader().dest_mod_id
        p = rc.MDF_PING()
        copy_from_msg(p, msg)

        if (p.module_name.lower() == module_name.lower()) or (p.module_name == "*") or \
            (dest_mod_id == self.mod.GetModuleID()):
            mdf = rc.MDF_PING_ACK()
            mdf.module_name = module_name + ":" + self.host_name  # + ":" + self.host_os
            msg_out = CMessage(rc.MT_PING_ACK)
            copy_to_msg(mdf, msg_out)
            self.mod.SendMessage(msg_out)

    def run(self):
        while True:
            msg = CMessage()
            rcv = self.mod.ReadMessage(msg, 0.1)
            if rcv == 1:
                msg_type = msg.GetHeader().msg_type

                if msg_type == rc.MT_APP_START:

                    try:
                        mdf = rc.MDF_APP_START()
                        copy_from_msg(mdf, msg)
                        config = mdf.config

                        print "Config: %s" % config

                        # -- to do --
                        # get a list of all modules in appman.conf for this host
                        # see if any of the modules above are already/still running
                        # start non-running modules
                        # -- to do --

                        print "Creating scripts"
                        appman.create_script(config, self.host_name)
                        print "Starting modules on host: %s" % self.host_name
                        appman.run_script(self.host_name)

                        self.mod.SendSignal(rc.MT_APP_START_COMPLETE)

                    except Exception, e:
                        print "ERROR: %s" % (e)

                elif msg_type == rc.MT_PING:
                    print 'got ping'
                    self.respond_to_ping(msg, 'AppStarter')

                # we use this msg to stop modules individually
                elif msg_type == MT_EXIT:
                    print 'got exit'

                elif msg_type == MT_KILL:
                    print 'got kill'
                    appman.kill_modules()