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()
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)
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
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()
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)
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)
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()