def __init__(self, param=DefaultParam): self.param = param self.experiment = self.param['experiment'] self.experiment_time = self.param['experiment_time'] self.time_start = time.time() # Set up Phidget channels self.aout_channel_yaw = 0 self.aout_channel_x = 1 self.aout_channel_yaw_gain = 2 self.aout_channel_y = 3 self.aout_max_volt = 10.0 self.aout_min_volt = 0.0 # Setup analog output YAW self.aout_yaw = VoltageOutput() self.aout_yaw.setChannel(self.aout_channel_yaw) self.aout_yaw.openWaitForAttachment(5000) self.aout_yaw.setVoltage(0.0) # Setup analog output X self.aout_x = VoltageOutput() self.aout_x.setChannel(self.aout_channel_x) self.aout_x.openWaitForAttachment(5000) self.aout_x.setVoltage(0.0) # Setup analog output YAW gain self.aout_yaw_gain = VoltageOutput() self.aout_yaw_gain.setChannel(self.aout_channel_yaw_gain) self.aout_yaw_gain.openWaitForAttachment(5000) self.aout_yaw_gain.setVoltage(0.0) # Setup analog output Y self.aout_y = VoltageOutput() self.aout_y.setChannel(self.aout_channel_y) self.aout_y.openWaitForAttachment(5000) self.aout_y.setVoltage(0.0) self.print = True # Set up socket info self.HOST = '127.0.0.1' # The (receiving) host IP address (sock_host) self.PORT = 65432 # The (receiving) host port (sock_port) self.done = False self.gain_yaw = 1 self.heading_with_gain = 0 self.jump = True self.time_between_jumps = 90 self.jump_size = 0 #set up logger to save hd5f file self.logger = H5Logger( filename=self.param['logfile_name'], auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param)
def __init__(self, param=DefaultParam): self.param = param self.experiment = self.param['experiment'] self.experiment_time = self.param['experiment_time'] self.time_start = time.time( ) # get the current time and use it as a ref for elapsed time #get gain for the panels and wind self.gain_panels = self.param['gain_panels'] self.gain_wind = self.param['gain_wind'] # Set up Phidget serial numbers for using two devices self.phidget_vision = 525577 # written on the back of the Phidget self.phidget_wind = 589946 # for sending the position of the motor to NI-DAQ # Set up Phidget channels in device 1 for vision (0-index) self.aout_channel_yaw = 0 self.aout_channel_x = 1 self.aout_channel_yaw_gain = 2 self.aout_channel_y = 3 self.aout_max_volt = 10.0 self.aout_min_volt = 0.0 # Setup analog output YAW self.aout_yaw = VoltageOutput() self.aout_yaw.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw.setChannel(self.aout_channel_yaw) self.aout_yaw.openWaitForAttachment(5000) self.aout_yaw.setVoltage(0.0) # Setup analog output X self.aout_x = VoltageOutput() self.aout_x.setDeviceSerialNumber(self.phidget_vision) self.aout_x.setChannel(self.aout_channel_x) self.aout_x.openWaitForAttachment(5000) self.aout_x.setVoltage(0.0) # Setup analog output YAW gain self.aout_yaw_gain = VoltageOutput() self.aout_yaw_gain.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw_gain.setChannel(self.aout_channel_yaw_gain) self.aout_yaw_gain.openWaitForAttachment(5000) self.aout_yaw_gain.setVoltage(0.0) # Setup analog output Y self.aout_y = VoltageOutput() self.aout_y.setDeviceSerialNumber(self.phidget_vision) self.aout_y.setChannel(self.aout_channel_y) self.aout_y.openWaitForAttachment(5000) self.aout_y.setVoltage(0.0) # Set up Phidget channels in device 2 for wind (0-index) self.aout_channel_motor = 0 self.aout_channel_wind_valve = 2 # Setup analog output motor self.aout_motor = VoltageOutput() self.aout_motor.setDeviceSerialNumber(self.phidget_wind) self.aout_motor.setChannel(self.aout_channel_motor) self.aout_motor.openWaitForAttachment(5000) self.aout_motor.setVoltage(0.0) # Setup analog output wind valve self.aout_wind_valve = VoltageOutput() self.aout_wind_valve.setDeviceSerialNumber(self.phidget_wind) self.aout_wind_valve.setChannel(self.aout_channel_wind_valve) self.aout_wind_valve.openWaitForAttachment(5000) self.aout_wind_valve.setVoltage(0.0) self.print = True # Set up socket info for connecting with the FicTrac self.HOST = '127.0.0.1' # The (receiving) host IP address (sock_host) self.PORT = 65432 # The (receiving) host port (sock_port) # Set up Arduino connection self.COM = 'COM4' # serial port self.baudrate = 115200 # 9600 self.serialTimeout = 0.001 # blocking timeout for readline() # flag for indicating when the trial is done self.done = False #initialize heading with respect to panels to be starting position self.motor_command = 0 self.bar_position = np.deg2rad(360 - self.param['offset']) self.jump = True self.time_between_jumps = 90 # [s] self.jump_mag = 90 # [deg] jump magnitude self.jump_size = 0 # default value is zero #set up logger to save hd5f file self.logger_fictrac = H5Logger( filename=self.param['logfile_name'], auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #set up logger to save hd5f file self.logger_arduino = H5Logger( filename=(self.param['logfile_name']).replace( '.hdf5', '_arduino.hdf5'), auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #specify a variable for the first message being read self.first_time_in_loop = True
def endheatersignal(): voltageOutput0 = VoltageOutput() voltageOutput0.close()
class SocketClient(object): DefaultParam = { 'experiment': 1, 'experiment_time': 30, 'logfile_name': 'Z:/Wilson Lab/Mel/FlyOnTheBall/data', 'logfile_auto_incr': True, 'logfile_auto_incr_format': '{0:06d}', 'logfile_dt': 0.01, 'offset': 0 } def __init__(self, param=DefaultParam): self.param = param self.experiment = self.param['experiment'] self.experiment_time = self.param['experiment_time'] self.time_start = time.time( ) # get the current time and use it as a ref for elapsed time #get gain for the panels and wind self.gain_panels = self.param['gain_panels'] self.gain_wind = self.param['gain_wind'] # Set up Phidget serial numbers for using two devices self.phidget_vision = 525577 # written on the back of the Phidget self.phidget_wind = 589946 # for sending the position of the motor to NI-DAQ # Set up Phidget channels in device 1 for vision (0-index) self.aout_channel_yaw = 0 self.aout_channel_x = 1 self.aout_channel_yaw_gain = 2 self.aout_channel_y = 3 self.aout_max_volt = 10.0 self.aout_min_volt = 0.0 # Setup analog output YAW self.aout_yaw = VoltageOutput() self.aout_yaw.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw.setChannel(self.aout_channel_yaw) self.aout_yaw.openWaitForAttachment(5000) self.aout_yaw.setVoltage(0.0) # Setup analog output X self.aout_x = VoltageOutput() self.aout_x.setDeviceSerialNumber(self.phidget_vision) self.aout_x.setChannel(self.aout_channel_x) self.aout_x.openWaitForAttachment(5000) self.aout_x.setVoltage(0.0) # Setup analog output YAW gain self.aout_yaw_gain = VoltageOutput() self.aout_yaw_gain.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw_gain.setChannel(self.aout_channel_yaw_gain) self.aout_yaw_gain.openWaitForAttachment(5000) self.aout_yaw_gain.setVoltage(0.0) # Setup analog output Y self.aout_y = VoltageOutput() self.aout_y.setDeviceSerialNumber(self.phidget_vision) self.aout_y.setChannel(self.aout_channel_y) self.aout_y.openWaitForAttachment(5000) self.aout_y.setVoltage(0.0) # Set up Phidget channels in device 2 for wind (0-index) self.aout_channel_motor = 0 self.aout_channel_wind_valve = 2 # Setup analog output motor self.aout_motor = VoltageOutput() self.aout_motor.setDeviceSerialNumber(self.phidget_wind) self.aout_motor.setChannel(self.aout_channel_motor) self.aout_motor.openWaitForAttachment(5000) self.aout_motor.setVoltage(0.0) # Setup analog output wind valve self.aout_wind_valve = VoltageOutput() self.aout_wind_valve.setDeviceSerialNumber(self.phidget_wind) self.aout_wind_valve.setChannel(self.aout_channel_wind_valve) self.aout_wind_valve.openWaitForAttachment(5000) self.aout_wind_valve.setVoltage(0.0) self.print = True # Set up socket info for connecting with the FicTrac self.HOST = '127.0.0.1' # The (receiving) host IP address (sock_host) self.PORT = 65432 # The (receiving) host port (sock_port) # Set up Arduino connection self.COM = 'COM4' # serial port self.baudrate = 115200 # 9600 self.serialTimeout = 0.001 # blocking timeout for readline() # flag for indicating when the trial is done self.done = False #initialize heading with respect to panels to be starting position self.motor_command = 0 self.bar_position = np.deg2rad(360 - self.param['offset']) self.jump = True self.time_between_jumps = 90 # [s] self.jump_mag = 90 # [deg] jump magnitude self.jump_size = 0 # default value is zero #set up logger to save hd5f file self.logger_fictrac = H5Logger( filename=self.param['logfile_name'], auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #set up logger to save hd5f file self.logger_arduino = H5Logger( filename=(self.param['logfile_name']).replace( '.hdf5', '_arduino.hdf5'), auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #specify a variable for the first message being read self.first_time_in_loop = True def run(self): # connect to socket via UDP, not TCP! # connect to Arduino via serial with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock,\ serial.Serial(self.COM, self.baudrate, timeout=self.serialTimeout) as ser: sock.bind((self.HOST, self.PORT)) # takes one argument, give it as a tuple sock.setblocking(False) # make it non-blocking # Keep receiving data from socket until FicTrac closes data = "" timeout_in_seconds = 1 while not self.done: # main loop self.aout_wind_valve.setVoltage( 5.0) # keep the wind on for the duration of the trial motor_pos = np.nan self.motor_pos_rad = np.nan # default value before receiving the data # listening to Arduino msg = ser.readline() # read from serial until there's a \n self.time_arduino = time.time() - self.time_start # (s) if msg: # received a non-empty message try: arduino_line = msg.decode( 'utf-8')[:-2] # decode and remove \r and \n #motor_info = arduino_line.split(", ") #log_arduino = str("{:.7f}".format(time_now)) + "," + motor_info[0] + "\n" # first element is the current motor position (0-360 deg) #f_arduino.writelines(log_arduino) motor_pos = int( arduino_line) # current motor position (0-360 deg) self.motor_pos_rad = np.deg2rad(motor_pos) # Set analog output voltage of Phidget so that it could be recorded using NI-DAQ output_voltage_motor = self.motor_pos_rad * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_motor.setVoltage(output_voltage_motor) # write to HDF5 file self.write_logfile_arduino() except: print("message from Arduino is not a number:", msg) # ask the OS whether the socket is readable # give 3 lists of sockets for reading, writing, and checking for errors; we only care about the first one # https://docs.python.org/3/howto/sockets.html#socket-programming-howto ready = select.select( [sock], [], [], timeout_in_seconds ) # returns the subset of sockets that are actually readable # Only try to receive data if there is data waiting if ready[0]: # Receive one data frame new_data = sock.recv( 1024 ) # buffer size, should be a relatively small power of 2 # Uh oh? if not new_data: break # Decode received data data += new_data.decode('UTF-8') self.time_elapsed = time.time() - self.time_start # (s) # Find the first frame of data endline = data.find("\n") line = data[:endline] # copy first frame data = data[endline + 1:] # delete first frame # Tokenise toks = line.split(", ") # Check that we have sensible tokens if ((len(toks) < 24) | (toks[0] != "FT")): print('Bad read') continue # Extract FicTrac variables # (see https://github.com/rjdmoore/fictrac/blob/master/doc/data_header.txt for descriptions) self.frame = int(toks[1]) # frame counter self.posx = float(toks[15]) # integrated x position (rad) self.posy = float(toks[16]) # integrated y position (rad) self.intx = float( toks[20] ) # integrated x position (rad) of the sphere in lab coord neglecting heading self.inty = float( toks[21] ) # integrated y position (rad) of the sphere in lab coord neglecting heading self.timestamp = float( toks[22]) # frame capture time (ms) since epoch # calculate delta heading by comparing it to the previous value if self.first_time_in_loop: self.prev_heading = float(toks[17]) self.first_time_in_loop = False else: self.prev_heading = self.heading self.heading = float( toks[17] ) # integrated heading direction of the animal in lab coords (rad) self.deltaheading = self.heading - self.prev_heading # Set analog output voltage YAW_gain #set value depending on how much time has elapsed if ((self.time_elapsed > 1) and ((math.floor(self.time_elapsed) % self.time_between_jumps) == 0) and (self.jump == True)): #choose randomly between -120 and 120 jumps self.jump_size = random.choice([ np.deg2rad(-self.jump_mag), np.deg2rad(self.jump_mag) ]) self.jump = False else: self.jump_size = 0 #reset self.jump 1 sec before the gain change if (((math.floor(self.time_elapsed + 1) % self.time_between_jumps) == 0) and (self.jump == False)): self.jump = True # send the heading signal to Arduino self.motor_command = (self.motor_command + self.deltaheading + self.jump_size) % (2 * np.pi) #animal_heading_360 = int(self.heading * (360 / (2 * np.pi))) # convert from rad to deg arduino_str = "H " + str( 360 - np.rad2deg(self.motor_command) ) + "\n" # "H is a command used in the Arduino code to indicate heading arduino_byte = arduino_str.encode( ) # convert unicode string to byte string ser.write(arduino_byte) # send to serial port ## Set Phidget voltages using FicTrac data # Set analog output voltage X wrapped_intx = (self.intx % (2 * np.pi)) output_voltage_x = wrapped_intx * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_x.setVoltage(output_voltage_x) # Set analog output voltage YAW self.bar_position = (self.bar_position + self.deltaheading * self.gain_panels ) % (2 * np.pi) # wrap around self.output_voltage_yaw = (self.bar_position) * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_yaw.setVoltage(self.output_voltage_yaw) self.aout_yaw_gain.setVoltage(self.output_voltage_yaw) # Set analog output voltage Y wrapped_inty = self.inty % (2 * np.pi) output_voltage_y = wrapped_inty * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_y.setVoltage(output_voltage_y) # Save fictrac data in HDF5 file self.write_logfile_fictrac() # Display status message if self.print: print(f'time elapsed: {self.time_elapsed: 1.3f}', end='') print( f' motor command: {np.rad2deg(self.motor_command):3.0f}', end='') print(f' motor pos: {motor_pos:3.0f}', end='') print( f' bar pos: {np.rad2deg(self.bar_position):3.0f}') #print(f' delta heading: {np.rad2deg(self.deltaheading):3.0f}') if self.time_elapsed > self.experiment_time: self.done = True break # go back to 0 deg at the end of the trial arduino_str = "H " + str( 0 ) + "\n" # "H is a command used in the Arduino code to indicate heading arduino_byte = arduino_str.encode( ) # convert unicode string to byte string ser.write(arduino_byte) # send to serial port self.aout_wind_valve.setVoltage( 0.0) # turn the wind off at the end of the trial print('Trial finished - quitting!') #define function to log data to hdf5 file def write_logfile_fictrac(self): log_data = { 'time': self.time_elapsed, 'frame': self.frame, 'posx': self.posx, 'posy': self.posy, 'intx': self.intx, 'inty': self.inty, 'heading': self.heading, 'deltaheading': self.deltaheading, 'motor': self.motor_pos_rad, 'motor_command': self.motor_command, 'bar_position': self.bar_position, 'out_voltage_yaw': self.output_voltage_yaw } self.logger_fictrac.add(log_data) def write_logfile_arduino(self): log_data = {'time': self.time_arduino, 'motor': self.motor_pos_rad} self.logger_arduino.add(log_data)
class PneumaticFrame2: def __init__(self, master, initial_name, top_name, color, sol, reg_pwr, reg_set, reg_get, PSI): self.frame = Frame(master, borderwidth=2, relief=SUNKEN, bg=color) self.frame.pack() self.master = master self.frame_name = StringVar() self.frame_name.set(initial_name) self.state = 0 self.fontType = "Comic Sans" self.activeColor = 'SpringGreen4' self.frameColor = color self.pressure = IntVar() self.lock_flag = IntVar() self.pressure.set("") self.power = Button(self.frame, text="PWR", activebackground=self.activeColor, command=lambda: self.toggle_pwr()) self.set_label = Button(self.frame, text="SET LABEL", font=(self.fontType, 7), command=lambda: self.get_label_input()) self.observed_pressure = Entry(self.frame, width=5, state="readonly", textvariable=self.pressure) if self.frame_name.get() == "Hydro": self.set_pressure_scale = Scale(self.frame, orient=HORIZONTAL, from_=0, to=92, resolution=0.5, bg=color, label="Set Pressure (PSI)", highlightthickness=0, command=self.set_pressure) else: self.set_pressure_scale = Scale(self.frame, orient=HORIZONTAL, from_=0, to=50, resolution=0.5, bg=color, label="Set Pressure (PSI)", highlightthickness=0, command=self.set_pressure) self.custom_label = Label(self.frame, textvariable=self.frame_name, font=(self.fontType, 14), bg=color) self.label = Label(self.frame, text=initial_name, bg=color) self.lock = Checkbutton(self.frame, text="LOCK", bg=color, variable=self.lock_flag, command=self.lock) self.frame_name.set(top_name) # Init the pressure scale to the default value. self.set_pressure_scale.set(PSI) # Lock hydo at startup if initial_name == "Hydro": self.lock.select() self.set_pressure_scale.config(state="disabled") self.power.config(state="disable") self.frame.rowconfigure(0, minsize=30) self.custom_label.grid(row=0, column=0, columnspan=2, sticky=S) self.set_label.grid(column=0, row=1, columnspan=2) self.frame.rowconfigure(2, minsize=50) self.power.grid(column=0, row=2) self.observed_pressure.grid(column=1, row=2) self.set_pressure_scale.grid(column=0, row=3, columnspan=2, padx=20) self.frame.rowconfigure(4, minsize=5) self.label.grid(column=0, row=5) self.lock.grid(column=1, row=5) # Connect to Phidget Solid State Relay for solinoid control if self.frame_name.get() == "Hydro": self.solenoid_switch = DigitalOutput() self.solenoid_switch.setDeviceSerialNumber(sol[0]) self.solenoid_switch.setIsHubPortDevice(False) self.solenoid_switch.setHubPort(sol[1]) self.solenoid_switch.setChannel(sol[2]) self.solenoid_switch.openWaitForAttachment(5000) #Connect to Phidget Solid State Relay for regulator power control self.reg_switch = DigitalOutput() self.reg_switch.setDeviceSerialNumber(reg_pwr[0]) self.reg_switch.setIsHubPortDevice(False) self.reg_switch.setHubPort(reg_pwr[1]) self.reg_switch.setChannel(reg_pwr[2]) self.reg_switch.openWaitForAttachment(5000) #Connect to Phidget Voltage Ouptut for pressure control self.pressure_ctrl = VoltageOutput() self.pressure_ctrl.setDeviceSerialNumber(reg_set[0]) self.pressure_ctrl.setIsHubPortDevice(False) self.pressure_ctrl.setHubPort(reg_set[1]) self.pressure_ctrl.setChannel(reg_set[2]) self.pressure_ctrl.openWaitForAttachment(5000) #Connect to Phidget Analog Input for pressure reading self.pressure_reading = VoltageRatioInput() self.pressure_reading.setDeviceSerialNumber(reg_get[0]) #One of the VINT Hubs on the SBC is used and needs special configuration if reg_get[0] == SBCH: self.pressure_reading.setIsHubPortDevice(True) self.pressure_reading.setHubPort(0) self.pressure_reading.setChannel(reg_get[1]) self.pressure_reading.openWaitForAttachment(5000) def toggle_pwr(self): #Turn on air channel if self.state == 0: #Turn on power to regulator and show active button color self.power.config(bg=self.activeColor) self.reg_switch.setState(True) if self.frame_name.get() == "Hydro": self.solenoid_switch.setState(True) #Start monitoring air pressure self.update_pressure() #Change state of air channel self.state = 1 #Turn off air channel elif self.state == 1: remember_state = self.set_pressure_scale.get() if self.frame_name.get() != "Hydro": messagebox.showinfo( self.frame_name.get() + " Warning", "Pressure will be set to zero. Acknowledge that " + self.frame_name.get() + " is in a safe configuration") # Change pressure to zero self.set_pressure_scale.set(0) self.set_pressure(0) time.sleep(0.5) self.frame.update() self.reg_switch.setState(False) time.sleep(0.5) self.set_pressure_scale.set(remember_state) if self.frame_name.get() == "Hydro": self.solenoid_switch.setState(False) self.lock.select() self.set_pressure_scale.config(state="disabled") self.power.config(state="disable") #Turn off power to reguluator and remove active button color self.power.config(bg="SystemButtonFace") #Update air channel state self.state = 0 def get_label_input(self): self.window = popupWindow(self.master) self.set_label.config(state=DISABLED) self.master.wait_window(self.window.top) self.set_label.config(state=NORMAL) #If the user does not enter a value exception will be produced try: if len(self.window.value) > 12: self.frame_name.set("SET ERROR") else: self.frame_name.set(self.window.value) except: self.frame_name.set("SET ERROR") def set_pressure(self, val): # Pressure Range range = MAXPR - MINPR # Calculate volts/PSI ratio = 5 / range self.pressure_ctrl.setVoltage(float(val) * ratio) def update_pressure(self): if self.reg_switch.getState(): try: val = float(self.pressure_reading.getSensorValue()) PSI = val * 165.63 - 30.855 PSI = round(PSI, 2) self.pressure.set(PSI) #Low pressure check if PSI < (self.set_pressure_scale.get() - 3): if self.frame.cget('bg') == "Red": self.frame.config(bg=self.frameColor) self.set_pressure_scale.config(bg=self.frameColor) self.custom_label.config(bg=self.frameColor) self.label.config(bg=self.frameColor) self.lock.config(bg=self.frameColor) else: self.frame.config(bg='Red') self.set_pressure_scale.config(bg="Red") self.custom_label.config(bg="Red") self.label.config(bg="Red") self.lock.config(bg="Red") if PSI > (self.set_pressure_scale.get() - 3): if self.frame.cget('bg') == "Red": self.frame.config(bg=self.frameColor) self.set_pressure_scale.config(bg=self.frameColor) self.custom_label.config(bg=self.frameColor) self.label.config(bg=self.frameColor) self.lock.config(bg=self.frameColor) except: print("Init Air Pressure") root.after(200, self.update_pressure) else: self.pressure.set("") def lock(self): if self.lock_flag.get() == True: self.set_pressure_scale.config(state="disabled") self.power.config(state="disable") elif self.lock_flag.get() == False: self.set_pressure_scale.config(state="normal") self.power.config(state="normal")
class SocketClient(object): DefaultParam = { 'experiment': 1, 'stim_speed': 20, 'turn_type': 'clockwise', 'bar_offset': 0, 'experiment_time': 30, 'logfile_name': 'Z:/Wilson Lab/Mel/FlyOnTheBall/data', 'logfile_auto_incr': True, 'logfile_auto_incr_format': '{0:06d}', 'logfile_dt': 0.01, } def __init__(self, param=DefaultParam): self.param = param self.experiment = self.param['experiment'] self.stim_speed = self.param['stim_speed'] self.turn_type = self.param['turn_type'] self.bar_offset = self.param[ 'bar_offset'] # bar relative to wind [deg] self.experiment_time = self.param['experiment_time'] self.time_start = time.time( ) # get the current time and use it as a ref for elapsed time self.stim_dir = 0 self.offset_adjust = 15 # use this offset to make bars perfectly aligned to wind, hard coded (deg) self.fly_heading = 0 # for calculating heading of the fly (rad) self.first_time_in_loop = True self.print = True # for printing the current values on the console # specify the time epochs in the experiment self.time_baseline = 10 # [s] baseline period self.epoch_dur = 200 # [s] duration of an individual epoch self.epoch_num = 6 # total number of epochs # set voltage range for Phidget self.aout_max_volt = 10.0 self.aout_min_volt = 0.0 # set up two Phidgets self.phidget_vision = 525577 # for writing Fictrac x, y, and panels (yaw_gain) self.phidget_wind = 589946 # for sending the position of the motor to NI-DAQ, actual animal yaw # Set up Phidget channels in device 1 for vision (0-index) self.aout_channel_ydimension = 0 self.aout_channel_x = 1 self.aout_channel_y = 3 self.aout_channel_yaw_gain = 2 # Setup analog output X self.aout_x = VoltageOutput() self.aout_x.setDeviceSerialNumber(self.phidget_vision) self.aout_x.setChannel(self.aout_channel_x) self.aout_x.openWaitForAttachment(5000) self.aout_x.setVoltage(0.0) # Setup analog output Y self.aout_y = VoltageOutput() self.aout_y.setDeviceSerialNumber(self.phidget_vision) self.aout_y.setChannel(self.aout_channel_y) self.aout_y.openWaitForAttachment(5000) self.aout_y.setVoltage(0.0) # Setup analog output YAW (use this channel to turn panels on and off) self.aout_ydim = VoltageOutput() self.aout_ydim.setDeviceSerialNumber(self.phidget_vision) self.aout_ydim.setChannel(self.aout_channel_ydimension) self.aout_ydim.openWaitForAttachment(5000) self.aout_ydim.setVoltage(0.0) # Setup analog output YAW gain (use this channel to control panel bar position) self.aout_yaw_gain = VoltageOutput() self.aout_yaw_gain.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw_gain.setChannel(self.aout_channel_yaw_gain) self.aout_yaw_gain.openWaitForAttachment(5000) self.aout_yaw_gain.setVoltage(0.0) # Set up Phidget channels in device 2 for wind (0-index) self.aout_channel_motor = 0 self.aout_channel_yaw = 1 # for recording the actual yaw of the fly self.aout_channel_wind_valve = 2 # Setup analog output motor self.aout_motor = VoltageOutput() self.aout_motor.setDeviceSerialNumber(self.phidget_wind) self.aout_motor.setChannel(self.aout_channel_motor) self.aout_motor.openWaitForAttachment(5000) self.aout_motor.setVoltage(0.0) # Setup analog output for yaw self.aout_yaw = VoltageOutput() self.aout_yaw.setDeviceSerialNumber(self.phidget_wind) self.aout_yaw.setChannel(self.aout_channel_yaw) self.aout_yaw.openWaitForAttachment(5000) self.aout_yaw.setVoltage(0.0) # Setup analog output wind valve self.aout_wind_valve = VoltageOutput() self.aout_wind_valve.setDeviceSerialNumber(self.phidget_wind) self.aout_wind_valve.setChannel(self.aout_channel_wind_valve) self.aout_wind_valve.openWaitForAttachment(5000) self.aout_wind_valve.setVoltage(0.0) # Set up socket info for connecting with the FicTrac self.HOST = '127.0.0.1' # The (receiving) host IP address (sock_host) self.PORT = 65432 # The (receiving) host port (sock_port) # Set up Arduino connection self.COM = 'COM4' # serial port self.baudrate = 115200 # 9600 self.serialTimeout = 0.001 # blocking timeout for readline() # flag for indicating when the trial is done self.done = False #set up logger to save hd5f file self.logger_fictrac = H5Logger( filename=self.param['logfile_name'], auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #set up logger to save hd5f file self.logger_arduino = H5Logger( filename=(self.param['logfile_name']).replace( '.hdf5', '_arduino.hdf5'), auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) def run(self, gain_x=1): # connect to socket via UDP, not TCP! # connect to Arduino via serial with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock,\ serial.Serial(self.COM, self.baudrate, timeout=self.serialTimeout) as ser: sock.bind((self.HOST, self.PORT)) # takes one argument, give it as a tuple sock.setblocking(False) # make it non-blocking # Keep receiving data from socket until FicTrac closes data = "" timeout_in_seconds = 1 self.time_end = time.time() #initialize turn time while not self.done: # main loop motor_pos = np.nan self.motor_pos_rad = np.nan # default value before receiving the data # listening to Arduino msg = ser.readline() # read from serial until there's a \n self.time_arduino = time.time() - self.time_start # (s) if msg: # received a non-empty message try: arduino_line = msg.decode( 'utf-8')[:-2] # decode and remove \r and \n motor_pos = int( arduino_line) # current motor position (0-360 deg) self.motor_pos_rad = np.deg2rad(motor_pos) # Set analog output voltage of Phidget for recording the current motor position output_voltage_motor = self.motor_pos_rad * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_motor.setVoltage(output_voltage_motor) # write to HDF5 file self.write_logfile_arduino() except: print("message from Arduino is not a number:", msg) # ask the OS whether the socket is readable # give 3 lists of sockets for reading, writing, and checking for errors; we only care about the first one # https://docs.python.org/3/howto/sockets.html#socket-programming-howto ready = select.select( [sock], [], [], timeout_in_seconds ) # returns the subset of sockets that are actually readable # Only try to receive data if there is data waiting if ready[0]: # Receive one data frame new_data = sock.recv( 1024 ) # buffer size, should be a relatively small power of 2 if not new_data: break # Decode received data data += new_data.decode('UTF-8') self.time_elapsed = time.time() - self.time_start # (s) # Find the first frame of data endline = data.find("\n") line = data[:endline] # copy first frame data = data[endline + 1:] # delete first frame # Tokenise toks = line.split(", ") # Check that we have sensible tokens if ((len(toks) < 24) | (toks[0] != "FT")): print('Bad read') continue # Extract FicTrac variables # (see https://github.com/rjdmoore/fictrac/blob/master/doc/data_header.txt for descriptions) self.frame = int(toks[1]) # frame counter self.posx = float(toks[15]) # integrated x position (rad) self.posy = float(toks[16]) # integrated y position (rad) #self.heading = float(toks[17]) # integrated heading direction of the animal in lab coords (rad) self.intx = float( toks[20] ) # integrated x position (rad) of the sphere in lab coord neglecting heading self.inty = float( toks[21] ) # integrated y position (rad) of the sphere in lab coord neglecting heading self.timestamp = float( toks[22]) # frame capture time (ms) since epoch self.time_step = time.time( ) - self.time_end # difference between now and the previous time step [s] if self.turn_type == 'clockwise': self.stim_dir = ( self.stim_dir + (self.time_step * self.stim_speed)) % 360 elif self.turn_type == 'counterclockwise': self.stim_dir = ( self.stim_dir - (self.time_step * self.stim_speed)) % 360 self.time_end = time.time() # save the current time step # prepare the outputs based on the epoch if self.time_elapsed < self.time_baseline: self.epoch_counter = 0 else: self.epoch_counter = int(( (self.time_elapsed - self.time_baseline) // self.epoch_dur) + 1) if self.epoch_counter == 0: # baseline wind_voltage = 0.0 # wind off self.current_wind_dir = 0 # wind tube stationary at 0 deg y_dim_voltage = 5.0 # bar off self.current_bar_pos = 0 elif self.epoch_counter == 1: # bar only wind_voltage = 0.0 # wind off self.current_wind_dir = 0 # wind tube stationary at 0 deg y_dim_voltage = 9.0 # bar on self.current_bar_pos = self.stim_dir elif self.epoch_counter == 2: # wind only wind_voltage = 5.0 # wind on self.current_wind_dir = self.stim_dir y_dim_voltage = 5.0 # bar off self.current_bar_pos = 0 # bar is off anyways elif self.epoch_counter == 3: # both rotating in sync wind_voltage = 5.0 # wind on self.current_wind_dir = self.stim_dir y_dim_voltage = 9.0 # bar on self.current_bar_pos = self.stim_dir elif self.epoch_counter == 4: wind_voltage = 5.0 # wind on self.current_wind_dir = 0 # wind tube stationary at 0 deg y_dim_voltage = 9.0 # bar on self.current_bar_pos = self.stim_dir elif self.epoch_counter == 5: # both rotating in sync wind_voltage = 5.0 # wind on self.current_wind_dir = self.stim_dir y_dim_voltage = 9.0 # bar on self.current_bar_pos = self.stim_dir elif self.epoch_counter == 6: # stationary bar wind_voltage = 5.0 # wind on self.current_wind_dir = self.stim_dir y_dim_voltage = 9.0 # bar on self.current_bar_pos = 0 else: self.done = True # end of the experiment # configure the outputs self.aout_ydim.setVoltage(y_dim_voltage) self.aout_wind_valve.setVoltage( wind_voltage ) # turn the wind off at the end of the trial # send the wind direction to Arduino arduino_str = "H " + str( self.current_wind_dir ) + "\n" # "H is a command used in the Arduino code to indicate heading arduino_byte = arduino_str.encode( ) # convert unicode string to byte string ser.write(arduino_byte) # send to serial port # set analog output voltage of Phidget so that the motor position could be recorded on NI-DAQ output_voltage_motor = (self.current_wind_dir / 360) * ( self.aout_max_volt - self.aout_min_volt ) # convert from deg to V self.aout_motor.setVoltage(output_voltage_motor) # open-loop bar: set analog output voltage YAW GAIN (note the sign flip) self.current_bar_pos_adjusted = ( 360 - self.current_bar_pos - self.bar_offset + self.offset_adjust) % 360 output_voltage_yaw = self.current_bar_pos_adjusted * ( self.aout_max_volt - self.aout_min_volt) / 360 self.aout_yaw_gain.setVoltage( output_voltage_yaw) # yaw gain, not yaw! ## Write FicTrac data to Phidget # Set analog output voltage X wrapped_intx = (self.intx % (2 * np.pi)) output_voltage_x = wrapped_intx * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_x.setVoltage(output_voltage_x) # Set analog output voltage Y wrapped_inty = self.inty % (2 * np.pi) output_voltage_y = wrapped_inty * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_y.setVoltage(output_voltage_y) # Set analog output voltage YAW (on the wind Phidget, not vision Phidget) if self.first_time_in_loop: self.prev_heading = float(toks[17]) self.first_time_in_loop = False else: self.prev_heading = self.heading self.heading = float( toks[17] ) # integrated heading direction of the animal in lab coords (rad) self.deltaheading = self.heading - self.prev_heading self.fly_heading = (self.fly_heading + self.deltaheading ) % (2 * np.pi) # wrap around self.output_voltage_yaw = (self.fly_heading) * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_yaw.setVoltage(self.output_voltage_yaw) # Save fictrac data in HDF5 file self.write_logfile_fictrac() # Display status message if self.print: print(f'epoch: {self.epoch_counter}', end='') print(f'\t time elapsed: {self.time_elapsed: 1.3f} s', end='') print(f'\t wind dir: {self.current_wind_dir:3.0f} deg', end='') print(f'\t bar pos: {self.current_bar_pos:3.0f} deg', end='') print(f'\t y_dim: {y_dim_voltage:3.0f} V') # go back to 0 deg at the end of the trial arduino_str = "H " + str( 0 ) + "\n" # "H is a command used in the Arduino code to indicate heading arduino_byte = arduino_str.encode( ) # convert unicode string to byte string ser.write(arduino_byte) # send to serial port self.aout_wind_valve.setVoltage( 0.0) # turn the wind off at the end of the trial print('Trial finished - quitting!') #define function to log data to hdf5 file def write_logfile_fictrac(self): log_data = { 'time': self.time_elapsed, 'frame': self.frame, 'posx': self.posx, 'posy': self.posy, 'intx': self.intx, 'inty': self.inty, 'heading': self.heading, 'motor': self.motor_pos_rad } self.logger_fictrac.add(log_data) def write_logfile_arduino(self): log_data = {'time': self.time_arduino, 'motor': self.motor_pos_rad} self.logger_arduino.add(log_data)
class SocketClientCueDisappears(object): DefaultParam = { 'experiment': 1, 'experiment_time': 30, 'logfile_name': 'Z:/Wilson Lab/Mel/FlyOnTheBall/data', 'logfile_auto_incr': True, 'logfile_auto_incr_format': '{0:06d}', 'logfile_dt': 0.01, 'offset': 0 } def __init__(self, param=DefaultParam): self.param = param self.experiment = self.param['experiment'] self.experiment_time = self.param['experiment_time'] self.time_start = time.time() # Set up Phidget channels self.aout_channel_ydimension = 0 self.aout_channel_x = 1 self.aout_channel_yaw_gain = 2 self.aout_channel_y = 3 self.aout_max_volt = 10.0 self.aout_min_volt = 0.0 # Set up Phidget serial numbers for using two devices self.phidget_vision = 525577 # written on the back of the Phidget self.phidget_heading = 589946 # Setup analog output y dim, to change the y dimension of the stimulus self.aout_ydim = VoltageOutput() self.aout_ydim.setDeviceSerialNumber(self.phidget_vision) self.aout_ydim.setChannel(self.aout_channel_ydimension) self.aout_ydim.openWaitForAttachment(5000) self.aout_ydim.setVoltage(0.0) # Setup analog output X self.aout_x = VoltageOutput() self.aout_x.setDeviceSerialNumber(self.phidget_vision) self.aout_x.setChannel(self.aout_channel_x) self.aout_x.openWaitForAttachment(5000) self.aout_x.setVoltage(0.0) # Setup analog output YAW gain self.aout_yaw_gain = VoltageOutput() self.aout_yaw_gain.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw_gain.setChannel(self.aout_channel_yaw_gain) self.aout_yaw_gain.openWaitForAttachment(5000) self.aout_yaw_gain.setVoltage(0.0) # Setup analog output Y self.aout_y = VoltageOutput() self.aout_y.setDeviceSerialNumber(self.phidget_vision) self.aout_y.setChannel(self.aout_channel_y) self.aout_y.openWaitForAttachment(5000) self.aout_y.setVoltage(9.0) # Set up Phidget channels in device 2 to save the heading self.aout_heading_channel = 1 # Setup analog output motor self.aout_heading = VoltageOutput() self.aout_heading.setDeviceSerialNumber(self.phidget_heading) self.aout_heading.setChannel(self.aout_heading_channel) self.aout_heading.openWaitForAttachment(5000) self.aout_heading.setVoltage(0.0) self.print = True # Set up socket info self.HOST = '127.0.0.1' # The (receiving) host IP address (sock_host) self.PORT = 65432 # The (receiving) host port (sock_port) # Set up Arduino connection self.COM = 'COM4' # serial port self.baudrate = 115200 # 9600 self.serialTimeout = 0.001 # blocking timeout for readline() self.done = False self.gain_yaw = 1 self.heading_with_gain = 0 self.bar_jump = True self.bar_jump_size = 0 #initialize the bar on self.bar = True self.bar_moving = True #define times when bar will be turned off self.turn_off_times = np.linspace(900, 3525, 26) #self.turn_off_times = np.linspace(30,300,7) #uncomment for testing #initialize heading with respect to panels to be starting position self.bar_position = np.deg2rad(360 - self.param['offset']) #set up logger to save hd5f file self.logger_fictrac = H5Logger( filename=self.param['logfile_name'], auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #specify a variable for the first message being read self.first_time_in_loop = True def run(self): # UDP # Open the connection (ctrl-c / ctrl-break to quit) with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock,\ serial.Serial(self.COM, self.baudrate, timeout=self.serialTimeout) as ser: sock.bind((self.HOST, self.PORT)) # takes one argument, give it as a tuple sock.setblocking(False) # make it non-blocking # Keep receiving data until FicTrac closes data = "" timeout_in_seconds = 1 while not self.done: # Check to see whether there is data waiting ready = select.select([sock], [], [], timeout_in_seconds) # Only try to receive data if there is data waiting if ready[0]: # Receive one data frame new_data = sock.recv(1024) # Uh oh? if not new_data: break # Decode received data data += new_data.decode('UTF-8') #get time time_now = time.time() self.time_elapsed = time_now - self.time_start # Find the first frame of data endline = data.find("\n") line = data[:endline] # copy first frame data = data[endline + 1:] # delete first frame # Tokenise toks = line.split(", ") # Check that we have sensible tokens if ((len(toks) < 24) | (toks[0] != "FT")): print('Bad read') continue # Extract FicTrac variables # (see https://github.com/rjdmoore/fictrac/blob/master/doc/data_header.txt for descriptions) self.frame = int(toks[1]) self.posx = float(toks[15]) self.posy = float(toks[16]) self.heading = float(toks[17]) self.intx = float(toks[20]) self.inty = float(toks[21]) self.timestamp = float(toks[22]) # calculate delta heading by comparing it to the previous value #if self.first_time_in_loop: # self.prev_heading = float(toks[17]) # self.first_time_in_loop = False #else: # self.prev_heading = self.heading #self.deltaheading = self.heading - self.prev_heading #I had to comment the above lines because they weren't working well. self.deltaheading = float(toks[8]) #Set Phidget voltages using FicTrac data #Set the voltages that don't depend on the time of the experiment # Set analog output voltage X wrapped_intx = (self.intx % (2 * np.pi)) output_voltage_x = wrapped_intx * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_x.setVoltage(output_voltage_x) # Set analog output voltage Y wrapped_inty = self.inty % (2 * np.pi) output_voltage_y = wrapped_inty * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_y.setVoltage(output_voltage_y) #At the right intervals, stop the stimulus and turn it off if ((math.floor(self.time_elapsed) in self.turn_off_times) and (self.bar == True) and (self.bar_moving == True)): self.bar = False self.bar_moving = False self.bar_jump = True #resetting bar jump #At the right intervals, make the stimulus jump 90 deg from its previous position and turn it on if ((math.floor(self.time_elapsed - 15) in self.turn_off_times) and (self.bar == False) and (self.bar_moving == False) and (self.bar_jump == True)): self.bar_moving = True self.bar = True #self.bar_jump_size = random.choice([math.radians(-90),math.radians(90)]) self.bar_jump_size = 0 self.bar_jump = False else: self.bar_jump_size = 0 if self.bar_moving == True: self.heading_with_gain = ( self.heading_with_gain + self.deltaheading * self.gain_yaw + self.bar_jump_size) % (2 * np.pi) output_voltage_yaw_gain = (self.heading_with_gain) * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_yaw_gain.setVoltage(10 - output_voltage_yaw_gain) #store heading data output_voltage_heading = self.heading self.aout_heading.setVoltage(output_voltage_heading) if self.bar == False: y_dim_voltage = 5.0 else: y_dim_voltage = 9.0 self.aout_ydim.setVoltage(y_dim_voltage) # Save fictrac data in HDF5 file self.write_logfile_fictrac() # Display status message if self.print: print(f'time elapsed: {self.time_elapsed: 1.3f}', end='') print( f' bar pos: {np.rad2deg(self.heading_with_gain):3.0f}' ) print(f' ydim volt: {y_dim_voltage:3.0f}') print( f' delta heading: {np.rad2deg(self.deltaheading):3.0f}' ) if self.time_elapsed > self.experiment_time: self.done = True break print('Trial finished - quitting!') #define function to log data to hdf5 file def write_logfile_fictrac(self): log_data = { 'time': self.time_elapsed, 'frame': self.frame, 'posx': self.posx, 'posy': self.posy, 'intx': self.intx, 'inty': self.inty, 'heading': self.heading, 'deltaheading': self.deltaheading, 'bar_position': self.heading_with_gain, } self.logger_fictrac.add(log_data)
def __init__(self, param=DefaultParam): self.param = param self.experiment = self.param['experiment'] self.experiment_time = self.param['experiment_time'] self.time_start = time.time() # Set up Phidget channels self.aout_channel_ydimension = 0 #I'm setting up a channel such that I can change the y dimension of the panels sending a signal through here self.aout_channel_x = 1 self.aout_channel_yaw_gain = 2 self.aout_channel_y = 3 self.aout_max_volt = 10.0 self.aout_min_volt = 0.0 # Set up Phidget serial numbers for using two devices self.phidget_vision = 525577 # written on the back of the Phidget self.phidget_wind = 589946 # for sending the position of the motor to NI-DAQ # Setup analog output YAW self.aout_ydim = VoltageOutput() self.aout_ydim.setDeviceSerialNumber(self.phidget_vision) self.aout_ydim.setChannel(self.aout_channel_ydimension) self.aout_ydim.openWaitForAttachment(5000) self.aout_ydim.setVoltage(0.0) # Setup analog output X self.aout_x = VoltageOutput() self.aout_x.setDeviceSerialNumber(self.phidget_vision) self.aout_x.setChannel(self.aout_channel_x) self.aout_x.openWaitForAttachment(5000) self.aout_x.setVoltage(0.0) # Setup analog output YAW gain self.aout_yaw_gain = VoltageOutput() self.aout_yaw_gain.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw_gain.setChannel(self.aout_channel_yaw_gain) self.aout_yaw_gain.openWaitForAttachment(5000) self.aout_yaw_gain.setVoltage(0.0) # Setup analog output Y self.aout_y = VoltageOutput() self.aout_y.setDeviceSerialNumber(self.phidget_vision) self.aout_y.setChannel(self.aout_channel_y) self.aout_y.openWaitForAttachment(5000) self.aout_y.setVoltage(9.0) # Set up Phidget channels in device 2 for wind self.aout_channel_motor = 0 self.aout_channel_wind_valve = 2 # Setup analog output motor self.aout_motor = VoltageOutput() self.aout_motor.setDeviceSerialNumber(self.phidget_wind) self.aout_motor.setChannel(self.aout_channel_motor) self.aout_motor.openWaitForAttachment(5000) self.aout_motor.setVoltage(0.0) # Setup analog output wind valve self.aout_wind_valve = VoltageOutput() self.aout_wind_valve.setDeviceSerialNumber(self.phidget_wind) self.aout_wind_valve.setChannel(self.aout_channel_wind_valve) self.aout_wind_valve.openWaitForAttachment(5000) self.aout_wind_valve.setVoltage(0.0) self.print = True # Set up socket info self.HOST = '127.0.0.1' # The (receiving) host IP address (sock_host) self.PORT = 65432 # The (receiving) host port (sock_port) # Set up Arduino connection self.COM = 'COM4' # serial port self.baudrate = 115200 # 9600 self.serialTimeout = 0.001 # blocking timeout for readline() self.done = False self.gain_yaw = 1 self.heading_with_gain = 0 self.bar_jump = True self.bar_jump_size = 0 self.wind_jump = True self.wind_jump_size = 0 #initialize the bar on and the wind off self.bar = False self.wind = True #initialize heading with respect to panels to be starting position self.motor_command = 0 self.bar_position = np.deg2rad(360 - self.param['offset']) #set up logger to save hd5f file self.logger_fictrac = H5Logger( filename=self.param['logfile_name'], auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #set up logger to save hd5f file self.logger_arduino = H5Logger( filename=(self.param['logfile_name']).replace( '.hdf5', '_arduino.hdf5'), auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #specify a variable for the first message being read self.first_time_in_loop = True
def __init__(self, master, colorArray): frame1 = Frame(master, borderwidth=2, relief=SUNKEN) frame2 = Frame(master, borderwidth=2, relief=SUNKEN) frame3 = Frame(master, borderwidth=2, relief=SUNKEN) frame4 = Frame(master, borderwidth=2, relief=SUNKEN) frame5 = Frame(master, borderwidth=2, relief=SUNKEN) frame6 = Frame(master, borderwidth=2, relief=SUNKEN) frame7 = Frame(master, borderwidth=2, relief=SUNKEN) camera_frame_1 = Frame(master, borderwidth=2, relief=SUNKEN, bg='LightSkyBlue2') camera_frame_2 = Frame(master, borderwidth=2, relief=SUNKEN, bg='light goldenrod yellow') frame1.grid(row=1, column=0) frame2.grid(row=1, column=1) frame3.grid(row=1, column=2) frame4.grid(row=1, column=3) frame5.grid(row=1, column=4) frame6.grid(row=1, column=5) frame7.grid(row=1, column=6) camera_frame_1.grid(row=3, column=0, columnspan=7, sticky=NSEW) camera_frame_2.grid(row=4, column=0, columnspan=7, sticky=NSEW) self.out1 = AxisFrame(frame1, "BASE CIRC", "VESSEL RIGHT", "VESSEL LEFT", HUB1, 5, colorArray[0], 3.3, 0.55) self.out2 = AxisFrame(frame2, "BASE AUX", "CW/IN", "CCW/OUT", HUB2, 0, colorArray[1], 2.2, 0.11) self.out3 = AxisFrame(frame3, "VARD ROT", "CW", "CCW", HUB1, 3, colorArray[2], 2.2, 0.15) self.out4 = AxisFrame(frame4, "VARD VERT", "UP", "DOWN", HUB1, 4, colorArray[3], 7.8, 0.54) self.out5 = AxisFrame(frame5, "DA MAST", "UP", "DOWN", HUB1, 0, colorArray[4], 8, 0.86) self.out6 = AxisFrame(frame6, "DA PAN", "CW", "CCW", HUB1, 2, colorArray[5], 3.0, 0.30) self.out7 = AxisFrame(frame7, "DA TILT", "UP", "DOWN", HUB1, 1, colorArray[6], 3.6, 0.57) # RJ Camera Control: Code Tool Camera self.invert_tilt_1 = BooleanVar() self.invert_pan_1 = BooleanVar() self.btn_power_1 = Button(camera_frame_1, text="PWR", font="Courier, 12", command=self.toggle_power_1) self.btn_near_1 = Button(camera_frame_1, text="NEAR", font="Courier, 12", width=7) self.btn_far_1 = Button(camera_frame_1, text="FAR", font="Courier, 12", width=7) self.btn_wide_1 = Button(camera_frame_1, text="WIDE", font="Courier, 12", width=7) self.btn_tele_1 = Button(camera_frame_1, text="TELE", font="Courier, 12", width=7) self.btn_ms_1 = Button(camera_frame_1, text="MS", font="Courier, 12", width=7) self.left_light_scale_1 = Scale(camera_frame_1, orient=VERTICAL, from_=0, to=0.45, resolution=0.01, command=self.update_left_intensity_1, bg='LightSkyBlue2', highlightthickness=0) self.right_light_scale_1 = Scale(camera_frame_1, orient=VERTICAL, from_=0, to=0.45, resolution=0.01, command=self.update_right_intensity_1, bg='LightSkyBlue2', highlightthickness=0) self.label_lights_1 = Label(camera_frame_1, text=" Light Intensity", bg='LightSkyBlue2') self.label_camera_type_1 = Label(camera_frame_1, text="TOOL CAMERA", font=("TkDefaultFont", 14), bg='LightSkyBlue2') self.btn_tilt_up_1 = Button(camera_frame_1, text="TILT UP", font="Courier, 12", width=10) self.btn_tilt_down_1 = Button(camera_frame_1, text="TILT DOWN", font="Courier, 12", width=10) self.btn_pan_right_1 = Button(camera_frame_1, text="PAN RIGHT", font="Courier, 12", width=10) self.btn_pan_left_1 = Button(camera_frame_1, text="PAN LEFT", font="Courier, 12", width=10) self.tilt_speed_1 = Scale(camera_frame_1, orient=HORIZONTAL, from_=0.01, to=.5, resolution=0.01, bg='LightSkyBlue2', highlightthickness=0) self.pan_speed_1 = Scale(camera_frame_1, orient=HORIZONTAL, from_=0.01, to=.5, resolution=0.01, bg='LightSkyBlue2', highlightthickness=0) self.ckbx_invert_tilt_1 = Checkbutton(camera_frame_1, text="Invert Tilt", variable=self.invert_tilt_1, bg='LightSkyBlue2') self.ckbx_invert_pan_1 = Checkbutton(camera_frame_1, text="Invert Pan", variable=self.invert_pan_1, bg='LightSkyBlue2') self.activeColor_1 = 'SpringGreen4' self.tilt_speed_1.set(0.15) self.pan_speed_1.set(0.15) # RJ Camera Control: Overview Camera self.invert_tilt_2 = BooleanVar() self.invert_pan_2 = BooleanVar() self.btn_power_2 = Button(camera_frame_2, text="PWR", font="Courier, 12", command=self.toggle_power_2) self.btn_near_2 = Button(camera_frame_2, text="NEAR", font="Courier, 12", width=7) self.btn_far_2 = Button(camera_frame_2, text="FAR", font="Courier, 12", width=7) self.btn_wide_2 = Button(camera_frame_2, text="WIDE", font="Courier, 12", width=7) self.btn_tele_2 = Button(camera_frame_2, text="TELE", font="Courier, 12", width=7) self.btn_ms_2 = Button(camera_frame_2, text="MS", font="Courier, 12", width=7) self.left_light_scale_2 = Scale(camera_frame_2, orient=VERTICAL, from_=0, to=0.45, resolution=0.01, command=self.update_left_intensity_2, bg='light goldenrod yellow', highlightthickness=0) self.right_light_scale_2 = Scale(camera_frame_2, orient=VERTICAL, from_=0, to=0.45, resolution=0.01, command=self.update_right_intensity_2, bg='light goldenrod yellow', highlightthickness=0) self.label_lights_2 = Label(camera_frame_2, text=" Light Intensity", bg='light goldenrod yellow') self.label_camera_type_2 = Label(camera_frame_2, text="OVERVIEW CAMERA", font=("TkDefaultFont", 14), bg='light goldenrod yellow') self.btn_tilt_up_2 = Button(camera_frame_2, text="TILT UP", font="Courier, 12", width=10) self.btn_tilt_down_2 = Button(camera_frame_2, text="TILT DOWN", font="Courier, 12", width=10) self.btn_pan_right_2 = Button(camera_frame_2, text="PAN RIGHT", font="Courier, 12", width=10) self.btn_pan_left_2 = Button(camera_frame_2, text="PAN LEFT", font="Courier, 12", width=10) self.tilt_speed_2 = Scale(camera_frame_2, orient=HORIZONTAL, from_=0.01, to=.5, resolution=0.01, bg='light goldenrod yellow', highlightthickness=0) self.pan_speed_2 = Scale(camera_frame_2, orient=HORIZONTAL, from_=0.01, to=.5, resolution=0.01, bg='light goldenrod yellow', highlightthickness=0) self.ckbx_invert_tilt_2 = Checkbutton(camera_frame_2, text="Invert Tilt", variable=self.invert_tilt_2, bg='light goldenrod yellow') self.ckbx_invert_pan_2 = Checkbutton(camera_frame_2, text="Invert Pan", variable=self.invert_pan_2, bg='light goldenrod yellow') self.activeColor_2 = 'SpringGreen4' self.tilt_speed_2.set(0.15) self.pan_speed_2.set(0.15) # Grid the Tool Camera Controls self.btn_power_1.grid(row=0, column=0, padx=60) self.btn_ms_1.grid(row=1, column=0, padx=5, pady=5) self.btn_near_1.grid(row=0, column=2, padx=20, pady=10) self.btn_far_1.grid(row=1, column=2, padx=20, pady=10) self.btn_tele_1.grid(row=0, column=3, padx=20, pady=10) self.btn_wide_1.grid(row=1, column=3, padx=20, pady=10) self.label_camera_type_1.grid(row=2, column=0, columnspan=4) self.left_light_scale_1.grid(row=0, column=4, rowspan=3, padx=20, pady=5) self.right_light_scale_1.grid(row=0, column=5, rowspan=3, padx=45, pady=5) self.label_lights_1.grid(row=3, column=4, columnspan=2, padx=45, sticky=N) self.btn_tilt_up_1.grid(row=0, column=6, padx=20, pady=5) self.btn_tilt_down_1.grid(row=1, column=6, padx=20, pady=5) self.btn_pan_right_1.grid(row=0, column=8, padx=20, pady=5, rowspan=2) self.btn_pan_left_1.grid(row=0, column=7, padx=20, pady=5, rowspan=2) self.tilt_speed_1.grid(row=2, column=6) self.pan_speed_1.grid(row=2, column=7, columnspan=2) self.ckbx_invert_tilt_1.grid(row=3, column=6) self.ckbx_invert_pan_1.grid(row=3, column=7, columnspan=2) # Grid the Overview Camera Controls self.btn_power_2.grid(row=0, column=0, padx=60) self.btn_ms_2.grid(row=1, column=0, padx=5, pady=5) self.btn_near_2.grid(row=0, column=2, padx=20, pady=10) self.btn_far_2.grid(row=1, column=2, padx=20, pady=10) self.btn_tele_2.grid(row=0, column=3, padx=20, pady=10) self.btn_wide_2.grid(row=1, column=3, padx=20, pady=10) self.label_camera_type_2.grid(row=2, column=0, columnspan=4) self.left_light_scale_2.grid(row=0, column=4, rowspan=3, padx=20, pady=5) self.right_light_scale_2.grid(row=0, column=5, rowspan=3, padx=45, pady=5) self.label_lights_2.grid(row=3, column=4, columnspan=2, padx=45, sticky=N) self.btn_tilt_up_2.grid(row=0, column=6, padx=20, pady=5) self.btn_tilt_down_2.grid(row=1, column=6, padx=20, pady=5) self.btn_pan_right_2.grid(row=0, column=8, padx=20, pady=5, rowspan=2) self.btn_pan_left_2.grid(row=0, column=7, padx=20, pady=5, rowspan=2) self.tilt_speed_2.grid(row=2, column=6) self.pan_speed_2.grid(row=2, column=7, columnspan=2) self.ckbx_invert_tilt_2.grid(row=3, column=6) self.ckbx_invert_pan_2.grid(row=3, column=7, columnspan=2) # Connect to Phidget Devices for Tool Camera self.power_1 = DigitalOutput() self.power_1.setDeviceSerialNumber(HUB2) self.power_1.setIsHubPortDevice(False) self.power_1.setHubPort(1) self.power_1.setChannel(0) try: self.power_1.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (CAM POWER): " + e.details) self.manual_select_1 = DigitalOutput() self.manual_select_1.setDeviceSerialNumber(HUB2) self.manual_select_1.setIsHubPortDevice(False) self.manual_select_1.setHubPort(1) self.manual_select_1.setChannel(1) try: self.manual_select_1.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (Manual Select): " + e.details) self.near_1 = DigitalOutput() self.near_1.setDeviceSerialNumber(HUB2) self.near_1.setIsHubPortDevice(False) self.near_1.setHubPort(1) self.near_1.setChannel(2) try: self.near_1.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (NEAR): " + e.details) self.far_1 = DigitalOutput() self.far_1.setDeviceSerialNumber(HUB2) self.far_1.setIsHubPortDevice(False) self.far_1.setHubPort(1) self.far_1.setChannel(3) try: self.far_1.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (FAR): " + e.details) self.wide_1 = DigitalOutput() self.wide_1.setDeviceSerialNumber(HUB2) self.wide_1.setIsHubPortDevice(False) self.wide_1.setHubPort(1) self.wide_1.setChannel(4) try: self.wide_1.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (WIDE): " + e.details) self.tele_1 = DigitalOutput() self.tele_1.setDeviceSerialNumber(HUB2) self.tele_1.setIsHubPortDevice(False) self.tele_1.setHubPort(1) self.tele_1.setChannel(5) try: self.tele_1.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (TELE): " + e.details) self.left_light_1 = VoltageOutput() self.left_light_1.setDeviceSerialNumber(HUB2) self.left_light_1.setIsHubPortDevice(False) self.left_light_1.setHubPort(2) self.left_light_1.setChannel(0) try: self.left_light_1.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (LEFT LIGHT): " + e.details) self.right_light_1 = VoltageOutput() self.right_light_1.setDeviceSerialNumber(HUB2) self.right_light_1.setIsHubPortDevice(False) self.right_light_1.setHubPort(3) self.right_light_1.setChannel(0) try: self.right_light_1.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (RIGHT LIGHT): " + e.details) self.pan_1 = VoltageOutput() self.pan_1.setDeviceSerialNumber(HUB2) self.pan_1.setIsHubPortDevice(False) self.pan_1.setHubPort(5) self.pan_1.setChannel(0) try: self.pan_1.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (PAN): " + e.details) self.tilt_1 = VoltageOutput() self.tilt_1.setDeviceSerialNumber(HUB2) self.tilt_1.setIsHubPortDevice(False) self.tilt_1.setHubPort(4) self.tilt_1.setChannel(0) try: self.tilt_1.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (TILT): " + e.details) self.btn_near_1.bind('<ButtonPress-1>', lambda event: self.focus_1("+")) self.btn_near_1.bind('<ButtonRelease-1>', lambda event: self.focus_1("0")) self.btn_far_1.bind('<ButtonPress-1>', lambda event: self.focus_1("-")) self.btn_far_1.bind('<ButtonRelease-1>', lambda event: self.focus_1("0")) self.btn_wide_1.bind('<ButtonPress-1>', lambda event: self.zoom_1("-")) self.btn_wide_1.bind('<ButtonRelease-1>', lambda event: self.zoom_1("0")) self.btn_tele_1.bind('<ButtonPress-1>', lambda event: self.zoom_1("+")) self.btn_tele_1.bind('<ButtonRelease-1>', lambda event: self.zoom_1("0")) self.btn_ms_1.bind('<ButtonPress-1>', lambda event: self.focus_type_1("ON")) self.btn_ms_1.bind('<ButtonRelease-1>', lambda event: self.focus_type_1("OFF")) self.btn_tilt_up_1.bind('<ButtonPress-1>', lambda event: self.tilt_move_1("-")) self.btn_tilt_up_1.bind('<ButtonRelease-1>', lambda event: self.tilt_move_1("0")) self.btn_tilt_down_1.bind('<ButtonPress-1>', lambda event: self.tilt_move_1("+")) self.btn_tilt_down_1.bind('<ButtonRelease-1>', lambda event: self.tilt_move_1("0")) self.btn_pan_right_1.bind('<ButtonPress-1>', lambda event: self.pan_move_1("R")) self.btn_pan_right_1.bind('<ButtonRelease-1>', lambda event: self.pan_move_1("0")) self.btn_pan_left_1.bind('<ButtonPress-1>', lambda event: self.pan_move_1("L")) self.btn_pan_left_1.bind('<ButtonRelease-1>', lambda event: self.pan_move_1("0")) # Connect to Phidget Devices for Overview Camera self.power_2 = DigitalOutput() self.power_2.setDeviceSerialNumber(HUB2) self.power_2.setIsHubPortDevice(False) self.power_2.setHubPort(1) self.power_2.setChannel(0) try: self.power_2.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (CAM POWER): " + e.details) self.manual_select_2 = DigitalOutput() self.manual_select_2.setDeviceSerialNumber(HUB2) self.manual_select_2.setIsHubPortDevice(False) self.manual_select_2.setHubPort(1) self.manual_select_2.setChannel(1) try: self.manual_select_2.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (Manual Select): " + e.details) self.near_2 = DigitalOutput() self.near_2.setDeviceSerialNumber(HUB2) self.near_2.setIsHubPortDevice(False) self.near_2.setHubPort(1) self.near_2.setChannel(2) try: self.near_2.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (NEAR): " + e.details) self.far_2 = DigitalOutput() self.far_2.setDeviceSerialNumber(HUB2) self.far_2.setIsHubPortDevice(False) self.far_2.setHubPort(1) self.far_2.setChannel(3) try: self.far_2.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (FAR): " + e.details) self.wide_2 = DigitalOutput() self.wide_2.setDeviceSerialNumber(HUB2) self.wide_2.setIsHubPortDevice(False) self.wide_2.setHubPort(1) self.wide_2.setChannel(4) try: self.wide_2.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (WIDE): " + e.details) self.tele_2 = DigitalOutput() self.tele_2.setDeviceSerialNumber(HUB2) self.tele_2.setIsHubPortDevice(False) self.tele_2.setHubPort(1) self.tele_2.setChannel(5) try: self.tele_2.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (TELE): " + e.details) self.left_light_2 = VoltageOutput() self.left_light_2.setDeviceSerialNumber(HUB2) self.left_light_2.setIsHubPortDevice(False) self.left_light_2.setHubPort(2) self.left_light_2.setChannel(0) try: self.left_light_2.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (LEFT LIGHT): " + e.details) self.right_light_2 = VoltageOutput() self.right_light_2.setDeviceSerialNumber(HUB2) self.right_light_2.setIsHubPortDevice(False) self.right_light_2.setHubPort(3) self.right_light_2.setChannel(0) try: self.right_light_2.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (RIGHT LIGHT): " + e.details) self.pan_2 = VoltageOutput() self.pan_2.setDeviceSerialNumber(HUB2) self.pan_2.setIsHubPortDevice(False) self.pan_2.setHubPort(5) self.pan_2.setChannel(0) try: self.pan_2.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (PAN): " + e.details) self.tilt_2 = VoltageOutput() self.tilt_2.setDeviceSerialNumber(HUB2) self.tilt_2.setIsHubPortDevice(False) self.tilt_2.setHubPort(4) self.tilt_2.setChannel(0) try: self.tilt_2.openWaitForAttachment(1000) except PhidgetException as e: print("Failed to open (TILT): " + e.details)
#!/usr/bin/env python3 from Phidget22.Phidget import * from Phidget22.Devices.VoltageOutput import * import sys import time experiment_time = float(sys.argv[1]) + 2.0 # adding two extra seconds phidget_wind = 589946 # for sending the position of the motor to NI-DAQ aout_channel_wind_valve = 2 aout_wind_valve = VoltageOutput() aout_wind_valve.setDeviceSerialNumber(phidget_wind) aout_wind_valve.setChannel(aout_channel_wind_valve) aout_wind_valve.openWaitForAttachment(5000) aout_wind_valve.setVoltage(0.0) time_start = time.time() print(f'Turning MFC on for {experiment_time} seconds') while True: time_elapsed = time.time() - time_start aout_wind_valve.setVoltage(5.0) if time_elapsed > experiment_time: aout_wind_valve.setVoltage(0.0) print('Turning MFC off') break
# The following is from the 'init' part of analogout.py (https://github.com/jennyl617/fly_experiments/blob/master/fictrac_2d/analogout.py) # *********** Set up aout params *********** rate_to_volt_const = 50, aout_max_volt = 10.0, aout_min_volt = 0.0, aout_max_volt_vel = 10.0, aout_min_volt_vel = 0.0, lowpass_cutoff = 0.5, # *********** Set up analog output channels *********** # Setup analog output 'runSpeed' - inst. running speed in rads/frame aout_runSpeed = VoltageOutput() aout_runSpeed.setChannel(0) aout_runSpeed.openWaitForAttachment(5000) aout_runSpeed.setVoltage(0.0) aout_runSpeed.setDeviceSerialNumber(525438) # Setup analog output 'animalheading360' -- this will be fly heading in degrees (0-3.6V) as in open loop trials aout_animalheading360 = VoltageOutput() aout_animalheading360.setChannel(1) aout_animalheading360.openWaitForAttachment(5000) aout_animalheading360.setVoltage(0.0) aout_animalheading360.setDeviceSerialNumber(525438) # xpos command to controller aout_xposcmd = VoltageOutput() aout_xposcmd.setChannel(2)
def get_device_channel(serial_number, channel): try: """ * Allocate a new Phidget Channel object """ ch = VoltageOutput() """ * Set matching parameters to specify which channel to open """ #You may remove this line and hard-code the addressing parameters to fit your application ch.setDeviceSerialNumber(serial_number) ch.setIsHubPortDevice(False) ch.setChannel(channel) """ * Add event handlers before calling open so that no events are missed. """ print("\n--------------------------------------") print("\nSetting OnAttachHandler...") ch.setOnAttachHandler(onAttachHandler) print("Setting OnDetachHandler...") ch.setOnDetachHandler(onDetachHandler) print("Setting OnErrorHandler...") ch.setOnErrorHandler(onErrorHandler) """ * Open the channel with a timeout """ print("\nOpening and Waiting for Attachment...") try: ch.openWaitForAttachment(5000) except PhidgetException as e: PrintOpenErrorMessage(e, ch) raise EndProgramSignal("Program Terminated: Open Failed") # ch.setVoltage(voltage) ''' * Perform clean up and exit ''' return ch except: pass
def __init__(self, param=DefaultParam): self.param = param self.experiment = self.param['experiment'] self.experiment_time = self.param['experiment_time'] self.time_start = time.time() # Set up Phidget channels self.aout_channel_yaw = 0 self.aout_channel_x = 1 self.aout_channel_yaw_gain = 2 self.aout_channel_y = 3 self.aout_max_volt = 10.0 self.aout_min_volt = 0.0 # Set up Phidget serial numbers for using two devices self.phidget_vision = 525577 # written on the back of the Phidget self.phidget_wind = 589946 # for sending the position of the motor to NI-DAQ # Setup analog output YAW self.aout_yaw = VoltageOutput() self.aout_yaw.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw.setChannel(self.aout_channel_yaw) self.aout_yaw.openWaitForAttachment(5000) self.aout_yaw.setVoltage(0.0) # Setup analog output X self.aout_x = VoltageOutput() self.aout_x.setDeviceSerialNumber(self.phidget_vision) self.aout_x.setChannel(self.aout_channel_x) self.aout_x.openWaitForAttachment(5000) self.aout_x.setVoltage(0.0) # Setup analog output YAW gain self.aout_yaw_gain = VoltageOutput() self.aout_yaw_gain.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw_gain.setChannel(self.aout_channel_yaw_gain) self.aout_yaw_gain.openWaitForAttachment(5000) self.aout_yaw_gain.setVoltage(0.0) # Setup analog output Y self.aout_y = VoltageOutput() self.aout_y.setDeviceSerialNumber(self.phidget_vision) self.aout_y.setChannel(self.aout_channel_y) self.aout_y.openWaitForAttachment(5000) self.aout_y.setVoltage(0.0) self.print = True # Set up socket info self.HOST = '127.0.0.1' # The (receiving) host IP address (sock_host) #self.HOST = '10.119.97.141' self.PORT = 65432 # The (receiving) host port (sock_port) self.done = False # Set initial bar position self.bar_position = np.deg2rad( 360 - self.param['offset']) # right to the fly is +90 deg #set up logger to save hd5f file self.logger = H5Logger( filename=self.param['logfile_name'], auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #specify a variable for the first message being read self.first_time_in_loop = True
class SocketClientGainChange(object): DefaultParam = { 'experiment': 1, 'experiment_time': 30, 'logfile_name': 'Z:/Wilson Lab/Mel/FlyOnTheBall/data', 'logfile_auto_incr': True, 'logfile_auto_incr_format': '{0:06d}', 'logfile_dt': 0.01, } def __init__(self, param=DefaultParam): self.param = param self.experiment = self.param['experiment'] self.experiment_time = self.param['experiment_time'] self.time_start = time.time() self.phidget_vision = 525577 # written on the back of the Phidget # Set up Phidget channels self.aout_channel_yaw = 0 self.aout_channel_x = 1 self.aout_channel_yaw_gain = 2 self.aout_channel_y = 3 self.aout_max_volt = 10.0 self.aout_min_volt = 0.0 # Setup analog output YAW self.aout_yaw = VoltageOutput() self.aout_yaw.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw.setChannel(self.aout_channel_yaw) self.aout_yaw.openWaitForAttachment(5000) self.aout_yaw.setVoltage(0.0) # Setup analog output X self.aout_x = VoltageOutput() self.aout_x.setDeviceSerialNumber(self.phidget_vision) self.aout_x.setChannel(self.aout_channel_x) self.aout_x.openWaitForAttachment(5000) self.aout_x.setVoltage(0.0) # Setup analog output YAW gain self.aout_yaw_gain = VoltageOutput() self.aout_yaw_gain.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw_gain.setChannel(self.aout_channel_yaw_gain) self.aout_yaw_gain.openWaitForAttachment(5000) self.aout_yaw_gain.setVoltage(0.0) # Setup analog output Y self.aout_y = VoltageOutput() self.aout_y.setDeviceSerialNumber(self.phidget_vision) self.aout_y.setChannel(self.aout_channel_y) self.aout_y.openWaitForAttachment(5000) self.aout_y.setVoltage(0.0) self.print = True # Set up socket info self.HOST = '127.0.0.1' # The (receiving) host IP address (sock_host) self.PORT = 65432 # The (receiving) host port (sock_port) self.done = False self.gain_yaw = 1 self.gain_change = True self.heading_with_gain = 0 #set up logger to save hd5f file self.logger = H5Logger( filename=self.param['logfile_name'], auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) def run(self): # UDP # Open the connection (ctrl-c / ctrl-break to quit) with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: sock.bind((self.HOST, self.PORT)) sock.setblocking(0) # Keep receiving data until FicTrac closes data = "" timeout_in_seconds = 1 while not self.done: # Check to see whether there is data waiting ready = select.select([sock], [], [], timeout_in_seconds) # Only try to receive data if there is data waiting if ready[0]: # Receive one data frame new_data = sock.recv(1024) # Uh oh? if not new_data: break # Decode received data data += new_data.decode('UTF-8') #get time time_now = time.time() self.time_elapsed = time_now - self.time_start # Find the first frame of data endline = data.find("\n") line = data[:endline] # copy first frame data = data[endline + 1:] # delete first frame # Tokenise toks = line.split(", ") # Check that we have sensible tokens if ((len(toks) < 24) | (toks[0] != "FT")): print('Bad read') continue # Extract FicTrac variables # (see https://github.com/rjdmoore/fictrac/blob/master/doc/data_header.txt for descriptions) self.frame = int(toks[1]) self.posx = float(toks[15]) self.posy = float(toks[16]) self.heading = float(toks[17]) self.deltaheading = float(toks[8]) self.intx = float(toks[20]) self.inty = float(toks[21]) self.timestamp = float(toks[22]) #Set Phidget voltages using FicTrac data # Set analog output voltage yaw output_voltage_yaw = (self.heading) * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_yaw.setVoltage(output_voltage_yaw) # Set analog output voltage X wrapped_intx = (self.intx % (2 * np.pi)) output_voltage_x = wrapped_intx * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_x.setVoltage(output_voltage_x) # Set analog output voltage YAW_gain #set yaw gain depending on how much time has elapsed if ((self.time_elapsed > 200) and (self.gain_change == True)): self.gain_yaw = -1 self.gain_change = False elif self.time_elapsed > 1000: self.gain_yaw = 1 self.heading_with_gain = ( self.heading_with_gain + self.deltaheading * self.gain_yaw) % (2 * np.pi) output_voltage_yaw_gain = (self.heading_with_gain) * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_yaw_gain.setVoltage(10 - output_voltage_yaw_gain) # Set analog output voltage Y wrapped_inty = self.inty % (2 * np.pi) output_voltage_y = wrapped_inty * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_y.setVoltage(output_voltage_y) # Save data in log file self.write_logfile() # Display status message if self.print: print('frame: {0}'.format(self.frame)) print('time elapsed: {0:1.3f}'.format( self.time_elapsed)) print('gain yaw: {0}'.format(self.gain_yaw)) print('gain change: {0}'.format(self.gain_change)) print('yaw: {0:1.3f}'.format(self.heading * 360 / (2 * np.pi))) print( 'volt: {0:1.3f}'.format(output_voltage_yaw_gain)) print('int x: {0:1.3f}'.format(wrapped_intx)) print('volt: {0:1.3f}'.format(output_voltage_x)) print('int y: {0:1.3f}'.format(wrapped_inty)) print('volt: {0:1.3f}'.format(output_voltage_y)) print() if self.time_elapsed > self.experiment_time: self.done = True break # END OF EXPERIMENT print('Trial finished - quitting!') #define function to log data to hdf5 file def write_logfile(self): log_data = { 'time': self.time_elapsed, 'frame': self.frame, 'posx': self.posx, 'posy': self.posy, 'intx': self.intx, 'inty': self.inty, 'heading': self.heading, 'heading_with_gain': self.heading_with_gain, 'deltaheading': self.deltaheading, 'gain_yaw': self.gain_yaw } self.logger.add(log_data)
def __init__(self, param=DefaultParam): self.param = param self.experiment = self.param['experiment'] self.experiment_time = self.param['experiment_time'] self.time_start = time.time() # Set up Phidget channels self.aout_channel_ydimension = 0 self.aout_channel_x = 1 self.aout_channel_yaw_gain = 2 self.aout_channel_y = 3 self.aout_max_volt = 10.0 self.aout_min_volt = 0.0 # Set up Phidget serial numbers for using two devices self.phidget_vision = 525577 # written on the back of the Phidget self.phidget_heading = 589946 # Setup analog output y dim, to change the y dimension of the stimulus self.aout_ydim = VoltageOutput() self.aout_ydim.setDeviceSerialNumber(self.phidget_vision) self.aout_ydim.setChannel(self.aout_channel_ydimension) self.aout_ydim.openWaitForAttachment(5000) self.aout_ydim.setVoltage(0.0) # Setup analog output X self.aout_x = VoltageOutput() self.aout_x.setDeviceSerialNumber(self.phidget_vision) self.aout_x.setChannel(self.aout_channel_x) self.aout_x.openWaitForAttachment(5000) self.aout_x.setVoltage(0.0) # Setup analog output YAW gain self.aout_yaw_gain = VoltageOutput() self.aout_yaw_gain.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw_gain.setChannel(self.aout_channel_yaw_gain) self.aout_yaw_gain.openWaitForAttachment(5000) self.aout_yaw_gain.setVoltage(0.0) # Setup analog output Y self.aout_y = VoltageOutput() self.aout_y.setDeviceSerialNumber(self.phidget_vision) self.aout_y.setChannel(self.aout_channel_y) self.aout_y.openWaitForAttachment(5000) self.aout_y.setVoltage(9.0) # Set up Phidget channels in device 2 to save the heading self.aout_heading_channel = 1 # Setup analog output motor self.aout_heading = VoltageOutput() self.aout_heading.setDeviceSerialNumber(self.phidget_heading) self.aout_heading.setChannel(self.aout_heading_channel) self.aout_heading.openWaitForAttachment(5000) self.aout_heading.setVoltage(0.0) self.print = True # Set up socket info self.HOST = '127.0.0.1' # The (receiving) host IP address (sock_host) self.PORT = 65432 # The (receiving) host port (sock_port) # Set up Arduino connection self.COM = 'COM4' # serial port self.baudrate = 115200 # 9600 self.serialTimeout = 0.001 # blocking timeout for readline() self.done = False self.gain_yaw = 1 self.heading_with_gain = 0 self.bar_jump = True self.bar_jump_size = 0 #initialize the bar on self.bar = True self.bar_moving = True #define times when bar will be turned off self.turn_off_times = np.linspace(900, 3525, 26) #self.turn_off_times = np.linspace(30,300,7) #uncomment for testing #initialize heading with respect to panels to be starting position self.bar_position = np.deg2rad(360 - self.param['offset']) #set up logger to save hd5f file self.logger_fictrac = H5Logger( filename=self.param['logfile_name'], auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #specify a variable for the first message being read self.first_time_in_loop = True
class SocketClientWindBarJump(object): DefaultParam = { 'experiment': 1, 'experiment_time': 30, 'logfile_name': 'Z:/Wilson Lab/Mel/FlyOnTheBall/data', 'logfile_auto_incr': True, 'logfile_auto_incr_format': '{0:06d}', 'logfile_dt': 0.01, 'offset': 0 } def __init__(self, param=DefaultParam): self.param = param self.experiment = self.param['experiment'] self.experiment_time = self.param['experiment_time'] self.time_start = time.time() # Set up Phidget channels self.aout_channel_ydimension = 0 #I'm setting up a channel such that I can change the y dimension of the panels sending a signal through here self.aout_channel_x = 1 self.aout_channel_yaw_gain = 2 self.aout_channel_y = 3 self.aout_max_volt = 10.0 self.aout_min_volt = 0.0 # Set up Phidget serial numbers for using two devices self.phidget_vision = 525577 # written on the back of the Phidget self.phidget_wind = 589946 # for sending the position of the motor to NI-DAQ # Setup analog output YAW self.aout_ydim = VoltageOutput() self.aout_ydim.setDeviceSerialNumber(self.phidget_vision) self.aout_ydim.setChannel(self.aout_channel_ydimension) self.aout_ydim.openWaitForAttachment(5000) self.aout_ydim.setVoltage(0.0) # Setup analog output X self.aout_x = VoltageOutput() self.aout_x.setDeviceSerialNumber(self.phidget_vision) self.aout_x.setChannel(self.aout_channel_x) self.aout_x.openWaitForAttachment(5000) self.aout_x.setVoltage(0.0) # Setup analog output YAW gain self.aout_yaw_gain = VoltageOutput() self.aout_yaw_gain.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw_gain.setChannel(self.aout_channel_yaw_gain) self.aout_yaw_gain.openWaitForAttachment(5000) self.aout_yaw_gain.setVoltage(0.0) # Setup analog output Y self.aout_y = VoltageOutput() self.aout_y.setDeviceSerialNumber(self.phidget_vision) self.aout_y.setChannel(self.aout_channel_y) self.aout_y.openWaitForAttachment(5000) self.aout_y.setVoltage(9.0) # Set up Phidget channels in device 2 for wind self.aout_channel_motor = 0 self.aout_channel_wind_valve = 2 # Setup analog output motor self.aout_motor = VoltageOutput() self.aout_motor.setDeviceSerialNumber(self.phidget_wind) self.aout_motor.setChannel(self.aout_channel_motor) self.aout_motor.openWaitForAttachment(5000) self.aout_motor.setVoltage(0.0) # Setup analog output wind valve self.aout_wind_valve = VoltageOutput() self.aout_wind_valve.setDeviceSerialNumber(self.phidget_wind) self.aout_wind_valve.setChannel(self.aout_channel_wind_valve) self.aout_wind_valve.openWaitForAttachment(5000) self.aout_wind_valve.setVoltage(0.0) self.print = True # Set up socket info self.HOST = '127.0.0.1' # The (receiving) host IP address (sock_host) self.PORT = 65432 # The (receiving) host port (sock_port) # Set up Arduino connection self.COM = 'COM4' # serial port self.baudrate = 115200 # 9600 self.serialTimeout = 0.001 # blocking timeout for readline() self.done = False self.gain_yaw = 1 self.heading_with_gain = 0 self.bar_jump = True self.bar_jump_size = 0 self.wind_jump = True self.wind_jump_size = 0 #initialize the bar on and the wind off self.bar = False self.wind = True #initialize heading with respect to panels to be starting position self.motor_command = 0 self.bar_position = np.deg2rad(360 - self.param['offset']) #set up logger to save hd5f file self.logger_fictrac = H5Logger( filename=self.param['logfile_name'], auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #set up logger to save hd5f file self.logger_arduino = H5Logger( filename=(self.param['logfile_name']).replace( '.hdf5', '_arduino.hdf5'), auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #specify a variable for the first message being read self.first_time_in_loop = True def run(self): # UDP # Open the connection (ctrl-c / ctrl-break to quit) with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock,\ serial.Serial(self.COM, self.baudrate, timeout=self.serialTimeout) as ser: sock.bind((self.HOST, self.PORT)) # takes one argument, give it as a tuple sock.setblocking(False) # make it non-blocking # Keep receiving data until FicTrac closes data = "" timeout_in_seconds = 1 while not self.done: motor_pos = np.nan self.motor_pos_rad = np.nan # default value before receiving the data # listening to Arduino msg = ser.readline() # read from serial until there's a \n self.time_arduino = time.time() - self.time_start # (s) if msg: # received a non-empty message try: arduino_line = msg.decode( 'utf-8')[:-2] # decode and remove \r and \n #motor_info = arduino_line.split(", ") #log_arduino = str("{:.7f}".format(time_now)) + "," + motor_info[0] + "\n" # first element is the current motor position (0-360 deg) #f_arduino.writelines(log_arduino) motor_pos = int( arduino_line) # current motor position (0-360 deg) self.motor_pos_rad = np.deg2rad(motor_pos) # Set analog output voltage of Phidget so that it could be recorded using NI-DAQ output_voltage_motor = self.motor_pos_rad * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_motor.setVoltage(output_voltage_motor) # write to HDF5 file self.write_logfile_arduino() except: print("message from Arduino is not a number:", msg) # Check to see whether there is data waiting ready = select.select([sock], [], [], timeout_in_seconds) # Only try to receive data if there is data waiting if ready[0]: # Receive one data frame new_data = sock.recv(1024) # Uh oh? if not new_data: break # Decode received data data += new_data.decode('UTF-8') #get time time_now = time.time() self.time_elapsed = time_now - self.time_start # Find the first frame of data endline = data.find("\n") line = data[:endline] # copy first frame data = data[endline + 1:] # delete first frame # Tokenise toks = line.split(", ") # Check that we have sensible tokens if ((len(toks) < 24) | (toks[0] != "FT")): print('Bad read') continue # Extract FicTrac variables # (see https://github.com/rjdmoore/fictrac/blob/master/doc/data_header.txt for descriptions) self.frame = int(toks[1]) self.posx = float(toks[15]) self.posy = float(toks[16]) self.heading = float(toks[17]) self.intx = float(toks[20]) self.inty = float(toks[21]) self.timestamp = float(toks[22]) # calculate delta heading by comparing it to the previous value #if self.first_time_in_loop: # self.prev_heading = float(toks[17]) # self.first_time_in_loop = False #else: # self.prev_heading = self.heading #self.deltaheading = self.heading - self.prev_heading #I had to comment the above lines because they weren't working well. self.deltaheading = float(toks[8]) #Set Phidget voltages using FicTrac data #Set the voltages that don't depend on the time of the experiment # Set analog output voltage X wrapped_intx = (self.intx % (2 * np.pi)) output_voltage_x = wrapped_intx * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_x.setVoltage(output_voltage_x) # Set analog output voltage Y wrapped_inty = self.inty % (2 * np.pi) output_voltage_y = wrapped_inty * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_y.setVoltage(output_voltage_y) # Specify the time conditions to set the other voltages # Specify the bar jumps if ((math.floor(self.time_elapsed) == 1860) and (self.bar_jump == True)): self.bar_jump_size = math.radians(-120) self.bar_jump = False else: self.bar_jump_size = 0 self.heading_with_gain = ( self.heading_with_gain + self.deltaheading * self.gain_yaw + self.bar_jump_size) % (2 * np.pi) output_voltage_yaw_gain = (self.heading_with_gain) * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_yaw_gain.setVoltage(10 - output_voltage_yaw_gain) # Specify the wind jumps if ((math.floor(self.time_elapsed) == 1380 or math.floor(self.time_elapsed) == 2340) and (self.wind_jump == True)): self.wind_jump_size = math.radians(120) self.wind_jump = False else: self.wind_jump_size = 0 #reset self.jump 1 sec before the wind jump has to happen if ((math.floor(self.time_elapsed) == 2339) and (self.wind_jump == False)): self.wind_jump = True # send the heading signal to Arduino self.motor_command = (self.motor_command + self.deltaheading + self.wind_jump_size) % (2 * np.pi) #animal_heading_360 = int(self.heading * (360 / (2 * np.pi))) # convert from rad to deg arduino_str = "H " + str( np.rad2deg(self.motor_command) ) + "\n" # "H is a command used in the Arduino code to indicate heading #I had to remove the 360- from the above line to make the gain = 1, and I'm not sure why, since in the other codes it works the other way arduino_byte = arduino_str.encode( ) # convert unicode string to byte string ser.write(arduino_byte) # send to serial port # Specify the changes in bar intensity #turn off the bar if ((math.floor(self.time_elapsed) == 1020 or math.floor(self.time_elapsed) == 1500 or math.floor(self.time_elapsed) == 1980 or math.floor(self.time_elapsed) == 2460 or math.floor(self.time_elapsed) == 2700) and (self.bar == True)): self.bar = False #turn on the bar if ((math.floor(self.time_elapsed) == 600 or math.floor(self.time_elapsed) == 1140 or math.floor(self.time_elapsed) == 1620 or math.floor(self.time_elapsed) == 2100 or math.floor(self.time_elapsed) == 2580) and (self.bar == False)): self.bar = True if self.bar == False: y_dim_voltage = 5.0 else: y_dim_voltage = 9.0 self.aout_ydim.setVoltage(y_dim_voltage) # Specify the changes in wind inensity #turn on the wind if ((math.floor(self.time_elapsed) == 900 or math.floor(self.time_elapsed) == 1260 or math.floor(self.time_elapsed) == 1740 or math.floor(self.time_elapsed) == 2220) and (self.wind == False)): self.wind = True #turn off the wind if ((math.floor(self.time_elapsed) == 600 or math.floor(self.time_elapsed) == 1140 or math.floor(self.time_elapsed) == 1620 or math.floor(self.time_elapsed) == 2100 or math.floor(self.time_elapsed) == 2580) and (self.wind == True)): self.wind = False if self.wind == False: wind_valve = 0.0 else: wind_valve = 5.0 self.aout_wind_valve.setVoltage(wind_valve) # Save fictrac data in HDF5 file self.write_logfile_fictrac() # Display status message if self.print: print(f'time elapsed: {self.time_elapsed: 1.3f}', end='') print( f' motor command: {np.rad2deg(self.motor_command):3.0f}', end='') print(f' motor pos: {motor_pos:3.0f}', end='') print( f' bar pos: {np.rad2deg(self.bar_position):3.0f}') print(f' ydim volt: {y_dim_voltage:3.0f}') print( f' delta heading: {np.rad2deg(self.deltaheading):3.0f}' ) if self.time_elapsed > self.experiment_time: self.aout_wind_valve.setVoltage(5.0) self.done = True break # go back to 0 deg at the end of the trial arduino_str = "H " + str( 0 ) + "\n" # "H is a command used in the Arduino code to indicate heading arduino_byte = arduino_str.encode( ) # convert unicode string to byte string ser.write(arduino_byte) # send to serial port print('Trial finished - quitting!') #define function to log data to hdf5 file def write_logfile_fictrac(self): log_data = { 'time': self.time_elapsed, 'frame': self.frame, 'posx': self.posx, 'posy': self.posy, 'intx': self.intx, 'inty': self.inty, 'heading': self.heading, 'deltaheading': self.deltaheading, 'motor': self.motor_pos_rad, 'motor_command': self.motor_command, 'bar_position': self.bar_position, } self.logger_fictrac.add(log_data) def write_logfile_arduino(self): log_data = {'time': self.time_arduino, 'motor': self.motor_pos_rad} self.logger_arduino.add(log_data)
right_light.openWaitForAttachment(5000) right_light.setAcceleration(20) #Setup pan and tilt motors tilt = DCMotor() tilt.setDeviceSerialNumber(465371) tilt.openWaitForAttachment(1000) tilt.setAcceleration(ACCEL) pan = DCMotor() pan.setDeviceSerialNumber(469502) pan.openWaitForAttachment(1000) pan.setAcceleration(ACCEL) #Setup Pnematics pressure_ctrl = VoltageOutput() pressure_ctrl.setDeviceSerialNumber(540047) pressure_ctrl.setIsHubPortDevice(False) pressure_ctrl.setHubPort(3) pressure_ctrl.setChannel(0) pressure_ctrl.openWaitForAttachment(5000) pressure_reading = VoltageRatioInput() pressure_reading.setDeviceSerialNumber(540047) pressure_reading.setIsHubPortDevice(False) pressure_reading.setHubPort(0) pressure_reading.setChannel(0) pressure_reading.openWaitForAttachment(5000) solenoid = DigitalOutput() solenoid.setDeviceSerialNumber(540047)
def __init__(self, master, colorArray): frame1 = Frame(master, borderwidth=2, relief=SUNKEN) frame2 = Frame(master, borderwidth=2, relief=SUNKEN) frame3 = Frame(master, borderwidth=2, relief=SUNKEN) frame4 = Frame(master, borderwidth=2, relief=SUNKEN) frame5 = Frame(master, borderwidth=2, relief=SUNKEN) frame6 = Frame(master, borderwidth=2, relief=SUNKEN) frame7 = Frame(master, borderwidth=2, relief=SUNKEN) camera_frame = Frame(master, borderwidth=2, relief=SUNKEN) frame1.grid(row=1, column=0) frame2.grid(row=1, column=1) frame3.grid(row=1, column=2) frame4.grid(row=1, column=3) frame5.grid(row=1, column=4) frame6.grid(row=1, column=5) frame7.grid(row=1, column=6) camera_frame.grid(row=3, column=0, columnspan=7, sticky=W) self.out1 = AxisFrame(frame1, "BASE CIRC", "VESSEL RIGHT", "VESSEL LEFT", HUB1, 5, colorArray[0], 3.3, 0.55) self.out2 = AxisFrame(frame2, "BASE AUX", "CW/IN", "CCW/OUT", HUB2, 0, colorArray[1], 2.2, 0.11) self.out3 = AxisFrame(frame3, "VARD ROT", "CW", "CCW", HUB1, 3, colorArray[2], 2.2, 0.15) self.out4 = AxisFrame(frame4, "VARD VERT", "UP", "DOWN", HUB1, 4, colorArray[3], 7.8, 0.54) self.out5 = AxisFrame(frame5, "DA MAST", "UP", "DOWN", HUB1, 0, colorArray[4], 8, 0.86) self.out6 = AxisFrame(frame6, "DA PAN", "CW", "CCW", HUB1, 2, colorArray[5], 3.0, 0.30) self.out7 = AxisFrame(frame7, "DA TILT", "UP", "DOWN", HUB1, 1, colorArray[6], 3.6, 0.57) #RJ Camera Control Code self.invert_tilt = BooleanVar() self.invert_pan = BooleanVar() self.btn_power = Button(camera_frame, text="PWR", font="Courier, 12", command=self.toggle_power) self.btn_near = Button(camera_frame, text="NEAR", font="Courier, 12", width=7) self.btn_far = Button(camera_frame, text="FAR", font="Courier, 12", width=7) self.btn_wide = Button(camera_frame, text="WIDE", font="Courier, 12", width=7) self.btn_tele = Button(camera_frame, text="TELE", font="Courier, 12", width=7) self.btn_ms = Button(camera_frame, text="MS", font="Courier, 12", width=7) self.left_light_scale = Scale(camera_frame, orient=VERTICAL, from_=0, to=0.45, resolution=0.01, command=self.update_left_intensity) self.right_light_scale = Scale(camera_frame, orient=VERTICAL, from_=0, to=0.45, resolution=0.01, command=self.update_right_intensity) self.label_lights = Label(camera_frame, text=" Light Intensity") self.btn_tilt_up = Button(camera_frame, text="TILT UP", font="Courier, 12", width=10) self.btn_tilt_down = Button(camera_frame, text="TILT DOWN", font="Courier, 12", width=10) self.btn_pan_right = Button(camera_frame, text="PAN RIGHT", font="Courier, 12", width=10) self.btn_pan_left = Button(camera_frame, text="PAN LEFT", font="Courier, 12", width=10) self.tilt_speed = Scale(camera_frame, orient=HORIZONTAL, from_=0.01, to=.5, resolution=0.01) self.pan_speed = Scale(camera_frame, orient=HORIZONTAL, from_=0.01, to=.5, resolution=0.01) self.ckbx_invert_tilt = Checkbutton(camera_frame, text="Invert Tilt", variable=self.invert_tilt) self.ckbx_invert_pan = Checkbutton(camera_frame, text="Invert Pan", variable=self.invert_pan) self.activeColor = 'SpringGreen4' self.tilt_speed.set(0.15) self.pan_speed.set(0.15) self.btn_power.grid(row=0, column=0, padx=60) self.btn_ms.grid(row=1, column=0, padx=5, pady=5) self.btn_near.grid(row=0, column=2, padx=20, pady=10) self.btn_far.grid(row=1, column=2, padx=20, pady=10) self.btn_tele.grid(row=0, column=3, padx=20, pady=10) self.btn_wide.grid(row=1, column=3, padx=20, pady=10) self.left_light_scale.grid(row=0, column=4, rowspan=3, padx=20, pady=5) self.right_light_scale.grid(row=0, column=5, rowspan=3, padx=45, pady=5) self.label_lights.grid(row=3, column=4, columnspan=2, padx=45, sticky=N) self.btn_tilt_up.grid(row=0, column=6, padx=20, pady=5) self.btn_tilt_down.grid(row=1, column=6, padx=20, pady=5) self.btn_pan_right.grid(row=0, column=8, padx=20, pady=5, rowspan=2) self.btn_pan_left.grid(row=0, column=7, padx=20, pady=5, rowspan=2) self.tilt_speed.grid(row=2, column=6) self.pan_speed.grid(row=2, column=7, columnspan=2) self.ckbx_invert_tilt.grid(row=3, column=6) self.ckbx_invert_pan.grid(row=3, column=7, columnspan=2) #Connect to Phidget Devices self.power = DigitalOutput() self.power.setDeviceSerialNumber(HUB2) self.power.setIsHubPortDevice(False) self.power.setHubPort(1) self.power.setChannel(0) self.power.openWaitForAttachment(5000) self.manual_select = DigitalOutput() self.manual_select.setDeviceSerialNumber(HUB2) self.manual_select.setIsHubPortDevice(False) self.manual_select.setHubPort(1) self.manual_select.setChannel(1) self.manual_select.openWaitForAttachment(5000) self.near = DigitalOutput() self.near.setDeviceSerialNumber(HUB2) self.near.setIsHubPortDevice(False) self.near.setHubPort(1) self.near.setChannel(2) self.near.openWaitForAttachment(5000) self.far = DigitalOutput() self.far.setDeviceSerialNumber(HUB2) self.far.setIsHubPortDevice(False) self.far.setHubPort(1) self.far.setChannel(3) self.far.openWaitForAttachment(5000) self.wide = DigitalOutput() self.wide.setDeviceSerialNumber(HUB2) self.wide.setIsHubPortDevice(False) self.wide.setHubPort(1) self.wide.setChannel(4) self.wide.openWaitForAttachment(5000) self.tele = DigitalOutput() self.tele.setDeviceSerialNumber(HUB2) self.tele.setIsHubPortDevice(False) self.tele.setHubPort(1) self.tele.setChannel(5) self.tele.openWaitForAttachment(5000) self.left_light = VoltageOutput() self.left_light.setDeviceSerialNumber(HUB2) self.left_light.setIsHubPortDevice(False) self.left_light.setHubPort(2) self.left_light.setChannel(0) self.left_light.openWaitForAttachment(5000) self.right_light = VoltageOutput() self.right_light.setDeviceSerialNumber(HUB2) self.right_light.setIsHubPortDevice(False) self.right_light.setHubPort(3) self.right_light.setChannel(0) self.right_light.openWaitForAttachment(5000) self.pan = VoltageOutput() self.pan.setDeviceSerialNumber(HUB2) self.pan.setIsHubPortDevice(False) self.pan.setHubPort(5) self.pan.setChannel(0) self.pan.openWaitForAttachment(5000) self.tilt = VoltageOutput() self.tilt.setDeviceSerialNumber(HUB2) self.tilt.setIsHubPortDevice(False) self.tilt.setHubPort(4) self.tilt.setChannel(0) self.tilt.openWaitForAttachment(5000) self.btn_near.bind('<ButtonPress-1>', lambda event: self.focus("+")) self.btn_near.bind('<ButtonRelease-1>', lambda event: self.focus("0")) self.btn_far.bind('<ButtonPress-1>', lambda event: self.focus("-")) self.btn_far.bind('<ButtonRelease-1>', lambda event: self.focus("0")) self.btn_wide.bind('<ButtonPress-1>', lambda event: self.zoom("-")) self.btn_wide.bind('<ButtonRelease-1>', lambda event: self.zoom("0")) self.btn_tele.bind('<ButtonPress-1>', lambda event: self.zoom("+")) self.btn_tele.bind('<ButtonRelease-1>', lambda event: self.zoom("0")) self.btn_ms.bind('<ButtonPress-1>', lambda event: self.focus_type("ON")) self.btn_ms.bind('<ButtonRelease-1>', lambda event: self.focus_type("OFF")) self.btn_tilt_up.bind('<ButtonPress-1>', lambda event: self.tilt_move("-")) self.btn_tilt_up.bind('<ButtonRelease-1>', lambda event: self.tilt_move("0")) self.btn_tilt_down.bind('<ButtonPress-1>', lambda event: self.tilt_move("+")) self.btn_tilt_down.bind('<ButtonRelease-1>', lambda event: self.tilt_move("0")) self.btn_pan_right.bind('<ButtonPress-1>', lambda event: self.pan_move("R")) self.btn_pan_right.bind('<ButtonRelease-1>', lambda event: self.pan_move("0")) self.btn_pan_left.bind('<ButtonPress-1>', lambda event: self.pan_move("L")) self.btn_pan_left.bind('<ButtonRelease-1>', lambda event: self.pan_move("0"))
class SocketClient(object): DefaultParam = { 'experiment': 1, 'stim_speed': 30, 'turn_type': 'clockwise', 'experiment_time': 30, 'logfile_name': 'Z:/Wilson Lab/Mel/FlyOnTheBall/data', 'logfile_auto_incr': True, 'logfile_auto_incr_format': '{0:06d}', 'logfile_dt': 0.01, } def __init__(self, param=DefaultParam): self.param = param self.experiment = self.param['experiment'] self.stim_speed = self.param['stim_speed'] self.turn_type = self.param['turn_type'] self.experiment_time = self.param['experiment_time'] self.time_start = time.time( ) # get the current time and use it as a ref for elapsed time self.current_wind_dir = 0 # Set up Phidget serial numbers for using two devices self.phidget_vision = 525577 # written on the back of the Phidget self.phidget_wind = 589946 # for sending the position of the motor to NI-DAQ # Set up Phidget channels in device 1 for vision (0-index) self.aout_channel_yaw = 0 self.aout_channel_x = 1 self.aout_channel_yaw_gain = 2 self.aout_channel_y = 3 self.aout_max_volt = 10.0 self.aout_min_volt = 0.0 # Setup analog output YAW self.aout_yaw = VoltageOutput() self.aout_yaw.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw.setChannel(self.aout_channel_yaw) self.aout_yaw.openWaitForAttachment(5000) self.aout_yaw.setVoltage(0.0) # Setup analog output X self.aout_x = VoltageOutput() self.aout_x.setDeviceSerialNumber(self.phidget_vision) self.aout_x.setChannel(self.aout_channel_x) self.aout_x.openWaitForAttachment(5000) self.aout_x.setVoltage(0.0) # Setup analog output YAW gain self.aout_yaw_gain = VoltageOutput() self.aout_yaw_gain.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw_gain.setChannel(self.aout_channel_yaw_gain) self.aout_yaw_gain.openWaitForAttachment(5000) self.aout_yaw_gain.setVoltage(0.0) # Setup analog output Y self.aout_y = VoltageOutput() self.aout_y.setDeviceSerialNumber(self.phidget_vision) self.aout_y.setChannel(self.aout_channel_y) self.aout_y.openWaitForAttachment(5000) self.aout_y.setVoltage(0.0) # Set up Phidget channels in device 2 for wind (0-index) self.aout_channel_motor = 0 self.aout_channel_wind_valve = 2 # Setup analog output motor self.aout_motor = VoltageOutput() self.aout_motor.setDeviceSerialNumber(self.phidget_wind) self.aout_motor.setChannel(self.aout_channel_motor) self.aout_motor.openWaitForAttachment(5000) self.aout_motor.setVoltage(0.0) # Setup analog output wind valve self.aout_wind_valve = VoltageOutput() self.aout_wind_valve.setDeviceSerialNumber(self.phidget_wind) self.aout_wind_valve.setChannel(self.aout_channel_wind_valve) self.aout_wind_valve.openWaitForAttachment(5000) self.aout_wind_valve.setVoltage(0.0) self.print = True # Set up socket info for connecting with the FicTrac self.HOST = '127.0.0.1' # The (receiving) host IP address (sock_host) self.PORT = 65432 # The (receiving) host port (sock_port) # Set up Arduino connection self.COM = 'COM4' # serial port self.baudrate = 115200 # 9600 self.serialTimeout = 0.001 # blocking timeout for readline() # flag for indicating when the trial is done self.done = False #set up logger to save hd5f file self.logger_fictrac = H5Logger( filename=self.param['logfile_name'], auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #set up logger to save hd5f file self.logger_arduino = H5Logger( filename=(self.param['logfile_name']).replace( '.hdf5', '_arduino.hdf5'), auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) def run(self, gain_x=1): # connect to socket via UDP, not TCP! # connect to Arduino via serial with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock,\ serial.Serial(self.COM, self.baudrate, timeout=self.serialTimeout) as ser: sock.bind((self.HOST, self.PORT)) # takes one argument, give it as a tuple sock.setblocking(False) # make it non-blocking # Keep receiving data from socket until FicTrac closes data = "" timeout_in_seconds = 1 self.time_end = time.time() #initialize turn time while not self.done: # main loop self.aout_wind_valve.setVoltage( 5.0) # keep the wind on for the duration of the trial motor_pos = np.nan self.motor_pos_rad = np.nan # default value before receiving the data # listening to Arduino msg = ser.readline() # read from serial until there's a \n self.time_arduino = time.time() - self.time_start # (s) if msg: # received a non-empty message try: arduino_line = msg.decode( 'utf-8')[:-2] # decode and remove \r and \n motor_pos = int( arduino_line) # current motor position (0-360 deg) self.motor_pos_rad = np.deg2rad(motor_pos) # Set analog output voltage of Phidget output_voltage_motor = self.motor_pos_rad * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_motor.setVoltage(output_voltage_motor) # write to HDF5 file self.write_logfile_arduino() except: print("message from Arduino is not a number:", msg) # ask the OS whether the socket is readable # give 3 lists of sockets for reading, writing, and checking for errors; we only care about the first one # https://docs.python.org/3/howto/sockets.html#socket-programming-howto ready = select.select( [sock], [], [], timeout_in_seconds ) # returns the subset of sockets that are actually readable # Only try to receive data if there is data waiting if ready[0]: # Receive one data frame new_data = sock.recv( 1024 ) # buffer size, should be a relatively small power of 2 if not new_data: break # Decode received data data += new_data.decode('UTF-8') self.time_elapsed = time.time() - self.time_start # (s) # Find the first frame of data endline = data.find("\n") line = data[:endline] # copy first frame data = data[endline + 1:] # delete first frame # Tokenise toks = line.split(", ") # Check that we have sensible tokens if ((len(toks) < 24) | (toks[0] != "FT")): print('Bad read') continue # Extract FicTrac variables # (see https://github.com/rjdmoore/fictrac/blob/master/doc/data_header.txt for descriptions) self.frame = int(toks[1]) # frame counter self.posx = float(toks[15]) # integrated x position (rad) self.posy = float(toks[16]) # integrated y position (rad) self.heading = float( toks[17] ) # integrated heading direction of the animal in lab coords (rad) self.intx = float( toks[20] ) # integrated x position (rad) of the sphere in lab coord neglecting heading self.inty = float( toks[21] ) # integrated y position (rad) of the sphere in lab coord neglecting heading self.timestamp = float( toks[22]) # frame capture time (ms) since epoch ## Set Phidget voltages using FicTrac data # Set analog output voltage X wrapped_intx = (self.intx % (2 * np.pi)) output_voltage_x = wrapped_intx * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_x.setVoltage(output_voltage_x) # Set analog output voltage YAW output_voltage_yaw = (self.heading) * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_yaw.setVoltage(output_voltage_yaw) self.aout_yaw_gain.setVoltage(output_voltage_yaw) # Set analog output voltage Y wrapped_inty = self.inty % (2 * np.pi) output_voltage_y = wrapped_inty * ( self.aout_max_volt - self.aout_min_volt) / (2 * np.pi) self.aout_y.setVoltage(output_voltage_y) # Save fictrac data in HDF5 file self.write_logfile_fictrac() # open-loop wind self.time_step = (time.time() - self.time_end) if self.turn_type == 'clockwise': self.current_wind_dir = ( self.current_wind_dir + (self.time_step * self.stim_speed)) % 360 elif self.turn_type == 'counterclockwise': self.current_wind_dir = ( self.current_wind_dir - (self.time_step * self.stim_speed)) % 360 self.time_end = time.time() # send the wind direction to Arduino arduino_str = "H " + str( self.current_wind_dir ) + "\n" # "H is a command used in the Arduino code to indicate heading arduino_byte = arduino_str.encode( ) # convert unicode string to byte string ser.write(arduino_byte) # send to serial port # Set analog output voltage of Phidget (note different from closed-loop, due to the infrequent nature of communication) output_voltage_motor = (self.current_wind_dir / 360) * 10 # convert from deg to V self.aout_motor.setVoltage(output_voltage_motor) # Display status message if self.print: print(f'time elapsed: {self.time_elapsed: 1.3f} s', end='') print(f'\t wind dir: {self.current_wind_dir:3.0f} deg') #print(f'\t time step: {self.time_step:3.6f} s') if self.time_elapsed > self.experiment_time: self.done = True break # go back to 0 deg at the end of the trial arduino_str = "H " + str( 0 ) + "\n" # "H is a command used in the Arduino code to indicate heading arduino_byte = arduino_str.encode( ) # convert unicode string to byte string ser.write(arduino_byte) # send to serial port self.aout_wind_valve.setVoltage( 0.0) # turn the wind off at the end of the trial print('Trial finished - quitting!') #define function to log data to hdf5 file def write_logfile_fictrac(self): log_data = { 'time': self.time_elapsed, 'frame': self.frame, 'posx': self.posx, 'posy': self.posy, 'intx': self.intx, 'inty': self.inty, 'heading': self.heading, 'motor': self.motor_pos_rad } self.logger_fictrac.add(log_data) def write_logfile_arduino(self): log_data = {'time': self.time_arduino, 'motor': self.motor_pos_rad} self.logger_arduino.add(log_data)
def __init__(self, master, initial_name, top_name, color, sol, reg_pwr, reg_set, reg_get, PSI): self.frame = Frame(master, borderwidth=2, relief=SUNKEN, bg=color) self.frame.pack() self.master = master self.frame_name = StringVar() self.frame_name.set(initial_name) self.state = 0 self.fontType = "Comic Sans" self.activeColor = 'SpringGreen4' self.frameColor = color self.pressure = IntVar() self.lock_flag = IntVar() self.pressure.set("") self.power = Button(self.frame, text="PWR", activebackground=self.activeColor, command=lambda: self.toggle_pwr()) self.set_label = Button(self.frame, text="SET LABEL", font=(self.fontType, 7), command=lambda: self.get_label_input()) self.observed_pressure = Entry(self.frame, width=5, state="readonly", textvariable=self.pressure) if self.frame_name.get() == "Hydro": self.set_pressure_scale = Scale(self.frame, orient=HORIZONTAL, from_=0, to=92, resolution=0.5, bg=color, label="Set Pressure (PSI)", highlightthickness=0, command=self.set_pressure) else: self.set_pressure_scale = Scale(self.frame, orient=HORIZONTAL, from_=0, to=50, resolution=0.5, bg=color, label="Set Pressure (PSI)", highlightthickness=0, command=self.set_pressure) self.custom_label = Label(self.frame, textvariable=self.frame_name, font=(self.fontType, 14), bg=color) self.label = Label(self.frame, text=initial_name, bg=color) self.lock = Checkbutton(self.frame, text="LOCK", bg=color, variable=self.lock_flag, command=self.lock) self.frame_name.set(top_name) # Init the pressure scale to the default value. self.set_pressure_scale.set(PSI) # Lock hydo at startup if initial_name == "Hydro": self.lock.select() self.set_pressure_scale.config(state="disabled") self.power.config(state="disable") self.frame.rowconfigure(0, minsize=30) self.custom_label.grid(row=0, column=0, columnspan=2, sticky=S) self.set_label.grid(column=0, row=1, columnspan=2) self.frame.rowconfigure(2, minsize=50) self.power.grid(column=0, row=2) self.observed_pressure.grid(column=1, row=2) self.set_pressure_scale.grid(column=0, row=3, columnspan=2, padx=20) self.frame.rowconfigure(4, minsize=5) self.label.grid(column=0, row=5) self.lock.grid(column=1, row=5) # Connect to Phidget Solid State Relay for solinoid control if self.frame_name.get() == "Hydro": self.solenoid_switch = DigitalOutput() self.solenoid_switch.setDeviceSerialNumber(sol[0]) self.solenoid_switch.setIsHubPortDevice(False) self.solenoid_switch.setHubPort(sol[1]) self.solenoid_switch.setChannel(sol[2]) self.solenoid_switch.openWaitForAttachment(5000) #Connect to Phidget Solid State Relay for regulator power control self.reg_switch = DigitalOutput() self.reg_switch.setDeviceSerialNumber(reg_pwr[0]) self.reg_switch.setIsHubPortDevice(False) self.reg_switch.setHubPort(reg_pwr[1]) self.reg_switch.setChannel(reg_pwr[2]) self.reg_switch.openWaitForAttachment(5000) #Connect to Phidget Voltage Ouptut for pressure control self.pressure_ctrl = VoltageOutput() self.pressure_ctrl.setDeviceSerialNumber(reg_set[0]) self.pressure_ctrl.setIsHubPortDevice(False) self.pressure_ctrl.setHubPort(reg_set[1]) self.pressure_ctrl.setChannel(reg_set[2]) self.pressure_ctrl.openWaitForAttachment(5000) #Connect to Phidget Analog Input for pressure reading self.pressure_reading = VoltageRatioInput() self.pressure_reading.setDeviceSerialNumber(reg_get[0]) #One of the VINT Hubs on the SBC is used and needs special configuration if reg_get[0] == SBCH: self.pressure_reading.setIsHubPortDevice(True) self.pressure_reading.setHubPort(0) self.pressure_reading.setChannel(reg_get[1]) self.pressure_reading.openWaitForAttachment(5000)
def __init__(self, param=DefaultParam): self.param = param self.experiment = self.param['experiment'] self.stim_speed = self.param['stim_speed'] self.turn_type = self.param['turn_type'] self.experiment_time = self.param['experiment_time'] self.time_start = time.time( ) # get the current time and use it as a ref for elapsed time self.current_wind_dir = 0 # Set up Phidget serial numbers for using two devices self.phidget_vision = 525577 # written on the back of the Phidget self.phidget_wind = 589946 # for sending the position of the motor to NI-DAQ # Set up Phidget channels in device 1 for vision (0-index) self.aout_channel_yaw = 0 self.aout_channel_x = 1 self.aout_channel_yaw_gain = 2 self.aout_channel_y = 3 self.aout_max_volt = 10.0 self.aout_min_volt = 0.0 # Setup analog output YAW self.aout_yaw = VoltageOutput() self.aout_yaw.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw.setChannel(self.aout_channel_yaw) self.aout_yaw.openWaitForAttachment(5000) self.aout_yaw.setVoltage(0.0) # Setup analog output X self.aout_x = VoltageOutput() self.aout_x.setDeviceSerialNumber(self.phidget_vision) self.aout_x.setChannel(self.aout_channel_x) self.aout_x.openWaitForAttachment(5000) self.aout_x.setVoltage(0.0) # Setup analog output YAW gain self.aout_yaw_gain = VoltageOutput() self.aout_yaw_gain.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw_gain.setChannel(self.aout_channel_yaw_gain) self.aout_yaw_gain.openWaitForAttachment(5000) self.aout_yaw_gain.setVoltage(0.0) # Setup analog output Y self.aout_y = VoltageOutput() self.aout_y.setDeviceSerialNumber(self.phidget_vision) self.aout_y.setChannel(self.aout_channel_y) self.aout_y.openWaitForAttachment(5000) self.aout_y.setVoltage(0.0) # Set up Phidget channels in device 2 for wind (0-index) self.aout_channel_motor = 0 self.aout_channel_wind_valve = 2 # Setup analog output motor self.aout_motor = VoltageOutput() self.aout_motor.setDeviceSerialNumber(self.phidget_wind) self.aout_motor.setChannel(self.aout_channel_motor) self.aout_motor.openWaitForAttachment(5000) self.aout_motor.setVoltage(0.0) # Setup analog output wind valve self.aout_wind_valve = VoltageOutput() self.aout_wind_valve.setDeviceSerialNumber(self.phidget_wind) self.aout_wind_valve.setChannel(self.aout_channel_wind_valve) self.aout_wind_valve.openWaitForAttachment(5000) self.aout_wind_valve.setVoltage(0.0) self.print = True # Set up socket info for connecting with the FicTrac self.HOST = '127.0.0.1' # The (receiving) host IP address (sock_host) self.PORT = 65432 # The (receiving) host port (sock_port) # Set up Arduino connection self.COM = 'COM4' # serial port self.baudrate = 115200 # 9600 self.serialTimeout = 0.001 # blocking timeout for readline() # flag for indicating when the trial is done self.done = False #set up logger to save hd5f file self.logger_fictrac = H5Logger( filename=self.param['logfile_name'], auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #set up logger to save hd5f file self.logger_arduino = H5Logger( filename=(self.param['logfile_name']).replace( '.hdf5', '_arduino.hdf5'), auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param)
def __init__(self, param=DefaultParam): self.param = param self.experiment = self.param['experiment'] self.stim_speed = self.param['stim_speed'] self.turn_type = self.param['turn_type'] self.bar_offset = self.param[ 'bar_offset'] # bar relative to wind [deg] self.experiment_time = self.param['experiment_time'] self.time_start = time.time( ) # get the current time and use it as a ref for elapsed time self.stim_dir = 0 self.offset_adjust = 15 # use this offset to make bars perfectly aligned to wind, hard coded (deg) self.fly_heading = 0 # for calculating heading of the fly (rad) self.first_time_in_loop = True self.print = True # for printing the current values on the console # specify the time epochs in the experiment self.time_baseline = 10 # [s] baseline period self.epoch_dur = 200 # [s] duration of an individual epoch self.epoch_num = 6 # total number of epochs # set voltage range for Phidget self.aout_max_volt = 10.0 self.aout_min_volt = 0.0 # set up two Phidgets self.phidget_vision = 525577 # for writing Fictrac x, y, and panels (yaw_gain) self.phidget_wind = 589946 # for sending the position of the motor to NI-DAQ, actual animal yaw # Set up Phidget channels in device 1 for vision (0-index) self.aout_channel_ydimension = 0 self.aout_channel_x = 1 self.aout_channel_y = 3 self.aout_channel_yaw_gain = 2 # Setup analog output X self.aout_x = VoltageOutput() self.aout_x.setDeviceSerialNumber(self.phidget_vision) self.aout_x.setChannel(self.aout_channel_x) self.aout_x.openWaitForAttachment(5000) self.aout_x.setVoltage(0.0) # Setup analog output Y self.aout_y = VoltageOutput() self.aout_y.setDeviceSerialNumber(self.phidget_vision) self.aout_y.setChannel(self.aout_channel_y) self.aout_y.openWaitForAttachment(5000) self.aout_y.setVoltage(0.0) # Setup analog output YAW (use this channel to turn panels on and off) self.aout_ydim = VoltageOutput() self.aout_ydim.setDeviceSerialNumber(self.phidget_vision) self.aout_ydim.setChannel(self.aout_channel_ydimension) self.aout_ydim.openWaitForAttachment(5000) self.aout_ydim.setVoltage(0.0) # Setup analog output YAW gain (use this channel to control panel bar position) self.aout_yaw_gain = VoltageOutput() self.aout_yaw_gain.setDeviceSerialNumber(self.phidget_vision) self.aout_yaw_gain.setChannel(self.aout_channel_yaw_gain) self.aout_yaw_gain.openWaitForAttachment(5000) self.aout_yaw_gain.setVoltage(0.0) # Set up Phidget channels in device 2 for wind (0-index) self.aout_channel_motor = 0 self.aout_channel_yaw = 1 # for recording the actual yaw of the fly self.aout_channel_wind_valve = 2 # Setup analog output motor self.aout_motor = VoltageOutput() self.aout_motor.setDeviceSerialNumber(self.phidget_wind) self.aout_motor.setChannel(self.aout_channel_motor) self.aout_motor.openWaitForAttachment(5000) self.aout_motor.setVoltage(0.0) # Setup analog output for yaw self.aout_yaw = VoltageOutput() self.aout_yaw.setDeviceSerialNumber(self.phidget_wind) self.aout_yaw.setChannel(self.aout_channel_yaw) self.aout_yaw.openWaitForAttachment(5000) self.aout_yaw.setVoltage(0.0) # Setup analog output wind valve self.aout_wind_valve = VoltageOutput() self.aout_wind_valve.setDeviceSerialNumber(self.phidget_wind) self.aout_wind_valve.setChannel(self.aout_channel_wind_valve) self.aout_wind_valve.openWaitForAttachment(5000) self.aout_wind_valve.setVoltage(0.0) # Set up socket info for connecting with the FicTrac self.HOST = '127.0.0.1' # The (receiving) host IP address (sock_host) self.PORT = 65432 # The (receiving) host port (sock_port) # Set up Arduino connection self.COM = 'COM4' # serial port self.baudrate = 115200 # 9600 self.serialTimeout = 0.001 # blocking timeout for readline() # flag for indicating when the trial is done self.done = False #set up logger to save hd5f file self.logger_fictrac = H5Logger( filename=self.param['logfile_name'], auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param) #set up logger to save hd5f file self.logger_arduino = H5Logger( filename=(self.param['logfile_name']).replace( '.hdf5', '_arduino.hdf5'), auto_incr=self.param['logfile_auto_incr'], auto_incr_format=self.param['logfile_auto_incr_format'], param_attr=self.param)
ch2.setDeviceSerialNumber(118651) ch2.setChannel(0) ch2.setOnAttachHandler(onAttachHandler) ch2.setOnTemperatureChangeHandler(onTemperatureChangeHandler) ch2.openWaitForAttachment(5000) temp9 = ch2.getTemperature() * 9 / 5 + 32 temp8 = temp9 #time.sleep(10) ch2.close() print("i got the temperature, its ", temp9) return temp8 voltageOutput0 = VoltageOutput() def setheatersignal(heatersignal): global voltageOutput0 voltageOutput0.openWaitForAttachment(5000) voltout = heatersignal / 100 * 5.0 if voltout >= 0 and voltout <= 5.0: voltageOutput0.setVoltage(voltout) print("first") time.sleep(10) #voltageOutput0.close() def endheatersignal(): voltageOutput0 = VoltageOutput()