예제 #1
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()
예제 #2
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)
예제 #3
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
예제 #4
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()
예제 #5
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)
예제 #6
0
class ButtonDetector(object):
    debug = True
    bounce_start = np.zeros([ncontrollers, rc.MAX_INPUT_DOFS]) - 1
    was_pressed = np.zeros([ncontrollers, rc.MAX_INPUT_DOFS], dtype=bool)

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

    def load_config(self, config_file):
        self.config = SafeConfigParser()
        self.config.read(config_file)

    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

    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, 'ButtonDetector')
                else:
                    self.process_message(msg)

    def get_inputs(self):
        sections = self.config.sections()
        self.inputs = {}
        for sec in sections:
            if 'input ' in sec:
                tag = self.config.get(sec, 'tag')
                self.inputs[tag] = {}

    def process_message(self, msg):
        msg_type = msg.GetHeader().msg_type
        if msg_type == rc.MT_INPUT_DOF_DATA:
            mdf = rc.MDF_INPUT_DOF_DATA()
            copy_from_msg(mdf, msg)
            tag = mdf.tag
            if tag in self.inputs.keys():
                dof_vals = np.asarray(mdf.dof_vals[:], dtype=float)
                cid = int(mdf.tag[-1])
                pressed = ~self.was_pressed[cid] & (dof_vals > btn_threshold)
                started = self.bounce_start[cid] > 0

                # start timers on previously unstarted counters
                self.bounce_start[cid, pressed & ~started] = time.time()

                dt = time.time() - self.bounce_start[cid]
                held = dt > bounce_threshold
                valid_held = pressed & held

                for vh in np.flatnonzero(valid_held):
                    if vh in name_lookup.keys():
                        self.was_pressed[cid, vh] = True
                        self.send_btn_press(name_lookup[vh], cid)

                released = self.was_pressed[cid] & (dof_vals < btn_threshold)
                valid_released = released & held & ~valid_held

                for vr in np.flatnonzero(valid_released):
                    if vr in name_lookup.keys():
                        self.was_pressed[cid, vr] = False
                        self.send_btn_release(name_lookup[vr], cid)
                        self.bounce_start[cid, vr] = -1

    def send_btn_press(self, btn, controller_id):
        print "controller_id %d sending button press %s" % (controller_id, btn)
        btn_map = {'l1' : rc.PS3_B_L1,
                   'l2' : rc.PS3_B_L2,
                   'r1' : rc.PS3_B_R1,
                   'x'  : rc.PS3_B_X,
                   'sq' : rc.PS3_B_SQUARE,
                   'crc': rc.PS3_B_CIRCLE,
                   'trg': rc.PS3_B_TRIANGLE}
        mdf_out = rc.MDF_PS3_BUTTON_PRESS()
        mdf_out.whichButton = btn_map[btn]
        mdf_out.controllerId = controller_id
        # make outgoing message data
        msg_out = CMessage(rc.MT_PS3_BUTTON_PRESS)
        copy_to_msg(mdf_out, msg_out)
        self.mod.SendMessage(msg_out)

    def send_btn_release(self, btn, controller_id):
        print "controller_id %d sending button release %s" % (controller_id, btn)
        btn_map = {'l1' : rc.PS3_B_L1,
                   'l2' : rc.PS3_B_L2,
                   'r1' : rc.PS3_B_R1,
                   'x'  : rc.PS3_B_X,
                   'sq' : rc.PS3_B_SQUARE,
                   'crc': rc.PS3_B_CIRCLE,
                   'trg': rc.PS3_B_TRIANGLE}
        mdf_out = rc.MDF_PS3_BUTTON_RELEASE()
        mdf_out.whichButton = btn_map[btn]
        mdf_out.controllerId = controller_id
        msg_out = CMessage(rc.MT_PS3_BUTTON_RELEASE)
        copy_to_msg(mdf_out, msg_out)
        self.mod.SendMessage(msg_out)
예제 #7
0
class SampleGenerator(object):
    def __init__(self, config_file, server):
        self.serial_no = 2
        self.freq = 50  # Hz
        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)
        triggers = self.config.get('main', 'triggers').split()
        self.triggers = [eval('rc.MT_%s' % (x)) for x in triggers]
        if not triggers:
            freq = self.config.get('main', 'frequency')
            if freq != '':
                self.freq = self.config.getfloat('main', 'frequency')
            print "Freq: %.2f" % (self.freq)

    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):
        self.delta_time_calc = self.default_timer()  #time.time()
        while True:
            msg = CMessage()
            rcv = self.mod.ReadMessage(msg, 0.001)
            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.mod.SendSignal(rc.MT_EXIT_ACK)
                        self.mod.DisconnectFromMMM()
                        break
                elif msg_type == rc.MT_PING:
                    respond_to_ping(self.mod, msg, 'SampleGenerator')
                elif (msg_type == rc.MT_SPM_SPIKECOUNT):
                    msg_src_mod_id = hdr.src_mod_id
                    if msg_src_mod_id == rc.MID_SPM_MOD:
                        print "\n\n ** Detected SPM_SPIKECOUNT messages coming from SPM_MOD! Quitting..\n\n"
                        sys.exit(0)
                else:
                    if len(self.triggers) > 0:
                        self.process_msg(msg)
            else:
                # if no triggers...
                if len(self.triggers) == 0:
                    period = (1. / self.freq)
                    time_now = self.default_timer()
                    delta_time = period - (time_now - self.delta_time_calc)
                    #print "%f %f %f\n\n" % (time_now, self.delta_time_calc, delta_time)
                    if delta_time > 0:
                        time.sleep(delta_time)
                    self.delta_time_calc = self.delta_time_calc + period
                    self.send_sample_generated()

    def process_msg(self, msg):
        msg_type = msg.GetHeader().msg_type
        if msg_type in self.triggers:
            time_now = self.default_timer()  #time.time()
            delta_time = time_now - self.delta_time_calc
            self.delta_time_calc = time_now
            self.send_sample_generated()

    def send_sample_generated(self):
        sg = rc.MDF_SAMPLE_GENERATED()
        self.serial_no += 1
        sg.sample_header.SerialNo = self.serial_no
        sg.sample_header.Flags = 0
        sg.sample_header.DeltaTime = (1. / self.freq)
        sg.source_timestamp = self.default_timer()  #time.time()
        sg_msg = CMessage(rc.MT_SAMPLE_GENERATED)
        copy_to_msg(sg, sg_msg)
        self.mod.SendMessage(sg_msg)
        sys.stdout.write('|')
        sys.stdout.flush()