class Experiment_Session: def __init__(self): # Set the basic params of windows self.root = Tkinter.Tk() self.root.title("Haptic Experiment") w = self.root.winfo_screenwidth() h = self.root.winfo_screenheight() self.width = w self.height = h self.root.geometry("%dx%d" % (w, h)) self.root.minsize(300, 240) self.user_num = -1 self.user_name = "" self.user_gender = "" self.user_age = 0 self.haptic_feel_lookup = { 1: 'empty', 2: 'low', 3: 'high', 4: 'medium', 5: 'click', 6: 'drop', 7: 'None' } self.cmd = Produce_Read_Order_List.Produce_Read_Order_List( ) # Initiate list of command self.User_feel_FP = "" # record the user's actual choice of haptic feeling self.global_times_counter = 0 # record the user's repeated times self.current_time = 0 self.correct_times = 0 self.correct_RL_times = 0 self.RL_total = 0 self.start = 0 # Start timestamp for haptic sensing self.end = 0 # End timestamp for haptic sensing self.deltatime = 0 # The time duration for haptic sensing self.startTrialNum = 0 # Start number specified for program crash self.outputfile = None # Output file for trial recording self.outputfile_timeStamp = None # Output file for timestamp self.currentTrial = None # Current trial information self.play_electronic_element = None # Define the instance of electronic element sound play self.SpacePressTime = 0 # Times of press [Space] self.EnterPressTime = 0 # Times of press [Enter] self.PressSpaceTwice = False # Space pressed for more than twice without [Enter] self.user_choice = -1 # User choice of last i'th electronic element self.ask_last_num = -1 # the last i'th elements hear of under the Recongnition load self.write_info = "" # Information written to output file self.show_info = "" # Information showed on the panel self.pin_height = "" # Information of the pin height self.last_num = [] # list for last ask number contains [2(27), 1(27)] self.space_sound_start = "" # Timestamp of Space and music start time self.force_profile_start = "" # Timestamp of Force profile start self.sound_stop = "" # Timestamp of sound stop self.space_curTrial_stop = "" # Timestamp of current trial stop # Switch between show debug and not show self.show_debug = False self.TrialInfo = Tkinter.StringVar(value='') # Trial information self.Answer = Tkinter.StringVar(value='') # User answer self.Question_text = Tkinter.StringVar(value='') # Text of Question self.Position_Info = Tkinter.StringVar( value='') # Position Information about the Spring self.Debug_Info = Tkinter.StringVar( value='') # Debug Information about the Spring # Bind the Space Key press to continue self.root.bind( "<KeyPress>", self.SpaceContinue) # Bind the [Space] press and its function self.root.focus_set() self.root.bind('<Return>', self.EnterPress) # Bind the [Enter] Key press self.varNum = Tkinter.StringVar(value='') self.varName = Tkinter.StringVar(value='') self.varGender = Tkinter.StringVar(value='') self.varAge = Tkinter.StringVar(value='') # Top level Panel for user information enter, show at program boot, hide when information entered and confirmed top_entry_y = h / 80 top_col_1 = w / 15 top_col_2 = top_col_1 + w / 12 + w / 18 top_col_3 = top_col_2 + w / 12 + w / 18 top_col_4 = top_col_3 + w / 12 + w / 18 top_col_5 = top_col_4 + w / 12 + w / 15 top_col_6 = top_col_5 + w / 12 + w / 12 self.labelNum = Tkinter.Label(self.root, text='User Num:') self.labelNum.place(x=top_col_1, y=top_entry_y, width=w / 12, height=h / 20) self.labelNum.config(font=("Courier", 15, "bold")) self.entryNum = Tkinter.Entry(self.root, textvariable=self.varNum) self.entryNum.place(x=top_col_1 + w / 12, y=top_entry_y, width=w / 18, height=h / 20) self.LabelName = Tkinter.Label(self.root, text='Name:') self.LabelName.place(x=top_col_2, y=top_entry_y, width=w / 12, height=h / 20) self.LabelName.config(font=("Courier", 15, "bold")) self.entryName = Tkinter.Entry(self.root, textvariable=self.varName) self.entryName.place(x=top_col_2 + w / 12, y=top_entry_y, width=w / 20, height=h / 20) self.LabelGender = Tkinter.Label(self.root, text='Gender:') self.LabelGender.place(x=top_col_3, y=top_entry_y, width=w / 12, height=h / 20) self.LabelGender.config(font=("Courier", 15, "bold")) self.entryGender = Tkinter.Entry(self.root, width=80, textvariable=self.varGender) self.entryGender.place(x=top_col_3 + w / 12, y=top_entry_y, width=w / 20, height=h / 20) self.LabelAge = Tkinter.Label(self.root, text='Age:') self.LabelAge.place(x=top_col_4, y=top_entry_y, width=w / 12, height=h / 20) self.LabelAge.config(font=("Courier", 15, "bold")) self.entryAge = Tkinter.Entry(self.root, width=80, textvariable=self.varAge) self.entryAge.place(x=top_col_4 + w / 12, y=top_entry_y, width=w / 20, height=h / 20) self.LabelStartFromTrial = Tkinter.Label(self.root, text='Start Num:') self.LabelStartFromTrial.place(x=top_col_5, y=top_entry_y, width=w / 12, height=h / 20) self.LabelStartFromTrial.config(font=("Courier", 15, "bold")) self.entryStartFromTrial = Tkinter.Entry( self.root, width=80, textvariable=self.startTrialNum) self.entryStartFromTrial.place(x=top_col_5 + w / 12, y=top_entry_y, width=w / 20, height=h / 20) self.buttonOk = Tkinter.Button(self.root, text='Confirm', command=self.login) self.buttonOk.place(x=top_col_6, y=top_entry_y, width=w / 20, height=h / 20) self.buttonOk.config(font=("Courier", 12, "bold")) self.buttonCancel = Tkinter.Button(self.root, text='Cancel', command=self.cancel) self.buttonCancel.place(x=top_col_6 + w / 18, y=top_entry_y, width=w / 20, height=h / 20) self.buttonCancel.config(font=("Courier", 12, "bold")) self.buttonRetry = Tkinter.Button(self.root, text='Retry', command=self.retry) self.buttonRetry.place(x=top_col_6 + 2 * w / 18, y=top_entry_y, width=w / 20, height=h / 20) self.buttonRetry.config(font=("Courier", 12, "bold")) self.Info_Header = Label(self.root, text="Trial\tRecongition Load\tComponent", anchor=W) self.Info_Header.config(font=("Courier", 12, "bold")) self.Info = Label(self.root, textvariable=self.TrialInfo, anchor=W) self.Info.config(font=("Courier", 12, "bold")) img_dx = w / 5 img_dy = h / 5 # Set up and place the images at the second level img_1 = Image.open('img/F01.jpg') img_1 = img_1.resize((img_dx, img_dy), Image.ANTIALIAS) img_1 = ImageTk.PhotoImage(img_1) img_2 = Image.open('img/F02.jpg') img_2 = img_2.resize((img_dx, img_dy), Image.ANTIALIAS) img_2 = ImageTk.PhotoImage(img_2) img_3 = Image.open('img/F03.jpg') img_3 = img_3.resize((img_dx, img_dy), Image.ANTIALIAS) img_3 = ImageTk.PhotoImage(img_3) img_4 = Image.open('img/F04.jpg') img_4 = img_4.resize((img_dx, img_dy), Image.ANTIALIAS) img_4 = ImageTk.PhotoImage(img_4) img_5 = Image.open('img/F05.jpg') img_5 = img_5.resize((img_dx, img_dy), Image.ANTIALIAS) img_5 = ImageTk.PhotoImage(img_5) img_6 = Image.open('img/F06.jpg') img_6 = img_6.resize((img_dx, img_dy), Image.ANTIALIAS) img_6 = ImageTk.PhotoImage(img_6) col_x_1 = 2 * w / 20 col_x_2 = 4 * w / 20 + img_dx col_x_3 = 6 * w / 20 + 2 * img_dx label_level_1_y = top_entry_y + 2 * h / 20 label_level_2_y = top_entry_y + 4 * h / 20 + img_dy img_level_1_y = top_entry_y + 3 * h / 20 img_level_2_y = top_entry_y + 5 * h / 20 + img_dy self.FP1 = Label(self.root, text="1. empty", fg='blue') self.FP1.place(x=col_x_1, y=label_level_1_y) self.FP1.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_1).place(x=col_x_1, y=img_level_1_y) self.FP2 = Label(self.root, text="2. low", fg='blue') self.FP2.place(x=col_x_2, y=label_level_1_y) self.FP2.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_2).place(x=col_x_2, y=img_level_1_y) self.FP3 = Label(self.root, text="3. high", fg='blue') self.FP3.place(x=col_x_3, y=label_level_1_y) self.FP3.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_3).place(x=col_x_3, y=img_level_1_y) self.FP4 = Label(self.root, text="4. medium", fg='blue') self.FP4.place(x=col_x_1, y=label_level_2_y) self.FP4.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_4).place(x=col_x_1, y=img_level_2_y) self.FP5 = Label(self.root, text="5. click", fg='blue') self.FP5.place(x=col_x_2, y=label_level_2_y) self.FP5.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_5).place(x=col_x_2, y=img_level_2_y) self.FP6 = Label(self.root, text="6. drop", fg='blue') self.FP6.place(x=col_x_3, y=label_level_2_y) self.FP6.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_6).place(x=col_x_3, y=img_level_2_y) # User haptic feel part and Quize part self.Question = Label(self.root, textvariable=self.Question_text) # Show the current position information on right side self.CurrPosition = Label(self.root, text="Position Info", textvariable=self.Position_Info) self.CurrPosition.place(x=12 * self.width / 16, y=7 * self.height / 8) self.CurrPosition.config(font=("Courier", 15, "bold"), fg="red") # Show the Force Profile on left side self.CurrDebug = Label(self.root, text="Debug Info", textvariable=self.Debug_Info) if self.show_debug: self.CurrDebug.place(x=2 * self.width / 16, y=3 * self.height / 4) self.CurrDebug.config(font=("Courier", 20, "bold"), fg="red") self.User_Answer = Tkinter.Label(self.root, text='Answer: ', fg="blue") self.User_Answer.place(x=w / 2 - w / 8, y=7 * h / 8) self.User_Answer.config(font=("Courier", 20, "bold")) self.entry_Answer = Tkinter.Entry(self.root, width=80, textvariable=self.Answer) self.entry_Answer.place(x=w / 2 - w / 25, y=7 * h / 8, width=w / 12, height=h / 25) self.read_first_100 = [] f_first = open("First_100.txt", 'r') self.word_pron = [] for i in f_first: self.word_pron.append(i) self.root.mainloop() def login(self): if self.entryNum.get() == "": tkMessageBox.showinfo(title='Warning', message='Please complete number') return self.user_num = int(self.entryNum.get()) if 0 < self.user_num < 13: self.user_name = self.entryName.get() self.user_age = self.entryAge.get() self.user_gender = self.entryGender.get() if self.user_name == "": tkMessageBox.showinfo(title='Warning', message='Please complete name') return if self.user_age == "": tkMessageBox.showinfo(title='Warning', message='Please complete age') return if self.user_gender == "": tkMessageBox.showinfo(title='Warning', message='Please complete gender') return if self.entryStartFromTrial.get() != "": self.startTrialNum = int(self.entryStartFromTrial.get()) # check the existence of program crash if self.startTrialNum != 0: existFilename = "User_Records/Participant" + str( self.user_num) + "/order_list.txt" self.cmd.read_command( existFilename ) # Read commands => commands in existence file self.correct_RL_times, self.RL_total = Recover_from_Record( "User_Records/Participant" + str(self.user_num) + "/user_record.txt") else: dir = os.getcwd() + "/User_Records/Participant" + str( self.user_num) if not os.path.exists(dir): os.makedirs(dir) # make dirs self.cmd.start_up(int( self.user_num)) # Produce commands by user number self.cmd.read_command() # Read commands => commands # write the head information to the first line in the file self.outputfile = open( "User_Records/Participant" + str(self.user_num) + "/user_record.txt", "w") self.outputfile_timeStamp = open( "User_Records/Participant" + str(self.user_num) + "/user_timeStamp.txt", "w") self.outputfile_timeStamp.write( "space_sound_start,force_profile_start,sound_stop,space_curTrial_stop\n" ) self.outputfile.write( "User_num,User_name,User_age,User_gender,Trials,Pin_height,Recognition_Load,Force_Profile,Component_Num,Duration_Time,User_Choice,Haptic_Choice_Correctness, ask_last_num,Recognition_Load_Correctness,space_sound_start,force_profile_start,sound_stop,space_curTrial_stop\n" ) self.outputfile_timeStamp.close() self.outputfile.close() # Re-open the output file again for later record useage self.outputfile = open( "User_Records/Participant" + str(self.user_num) + "/user_record.txt", "a") self.outputfile_timeStamp = open( "User_Records/Participant" + str(self.user_num) + "/user_timeStamp.txt", "a") else: tkMessageBox.showinfo('Error', message='Please enter an valid number[0-12]') return # Hide the label and entry from the panel self.labelNum.place_forget() self.entryNum.place_forget() self.LabelName.place_forget() self.entryName.place_forget() self.LabelGender.place_forget() self.entryGender.place_forget() self.LabelAge.place_forget() self.entryAge.place_forget() self.LabelStartFromTrial.place_forget() self.entryStartFromTrial.place_forget() self.buttonOk.place_forget() self.buttonCancel.place_forget() # Show the trial information after confirmation self.Info_Header.place(x=30 * self.width / 80, y=self.height / 80, width=17 * self.width / 64, height=self.height / 25) self.Info_Header.config(bg="red", fg="white") self.Info_Header.config(font=("Courier", 15, "bold")) self.Info.place(x=30 * self.width / 80, y=self.height / 80 + self.height / 22, width=17 * self.width / 64, height=self.height / 25) self.Info.config(font=("Courier", 15, "bold")) self.Info.config(bg="blue", fg="white") def cancel(self): self.varNum.set('') self.varAge.set('') self.varGender.set('') self.varName.set('') # Start and End a haptic trial by [Space] keypress def SpaceContinue(self, event): if event.keysym == "space": # Press [Enter] for 1,3,5,7,9 if self.EnterPressTime == 0: tkMessageBox.showinfo( 'Warning', message='Press [Enter] to start a trial before proceed') return # Press Space more than twice without press [Enter] if self.PressSpaceTwice is True: tkMessageBox.showinfo( 'Warning', message='Answer the question before proceed') return print "Space Entered" if self.SpacePressTime % 2 == 0: self.Question_text.set("Sound START") self.Question.place(x=7 * self.width / 16, y=3 * self.height / 4) self.Question.config(fg="red", font=("Courier", 23, "bold")) # Start to play sounds in recognition load if self.currentTrial[1] == '1': self.play_electronic_element = play_electronic_element() self.play_electronic_element.start() self.space_sound_start = datetime.datetime.now().strftime( '%Y-%m-%d %H:%M:%S.%f').split()[1] else: self.space_sound_start = "-1" else: # Stop the movement of Haptic Spring self.spring.terminate() self.deltatime = int(round(time.time() * 1000)) - self.start self.Question_text.set("Haptic Test END, Select a Haptic Feel") self.space_curTrial_stop = datetime.datetime.now().strftime( '%Y-%m-%d %H:%M:%S.%f').split()[1] self.PressSpaceTwice = True self.SpacePressTime += 1 # [Enter] Press for 1. Show a Trial Information 2. Show a electronic elements def EnterPress(self, event): # Incomplete Personal Information if self.EnterPressTime == 0: if self.user_num == -1 or self.user_name == "" or self.user_gender == "" or self.user_age == "": tkMessageBox.showinfo( 'Warning', message='Complete Personal Info before proceed') return # the first time press [Enter]: show a Trial Information if self.EnterPressTime == 0: start_num = self.startTrialNum if start_num == 0: self.currentTrial = self.cmd.read_command_by_line() while start_num != 0: self.currentTrial = self.cmd.read_command_by_line() start_num -= 1 print self.currentTrial # Current/Total times self.write_info += str( self.user_num) + "," + self.user_name + "," + str( self.user_age) + "," + self.user_gender + "," if self.startTrialNum == 0: self.current_time = self.global_times_counter + 1 else: self.current_time = self.global_times_counter + self.startTrialNum self.show_info += " " + str(self.current_time) + "\t " self.write_info += str(self.current_time) + "," for i in range(len(self.currentTrial)): if i == 0: self.pin_height = self.currentTrial[i] self.write_info += str( self.cmd.condition_lookup_table.index( self.pin_height)) + "," if i == 1: if self.currentTrial[i] == '1': self.show_info += " True\t\t" self.write_info += "1," else: self.show_info += " False\t\t" self.write_info += "0," if i == 2: self.write_info += str( self.cmd.Force_Profile.index( self.currentTrial[i])) + "," self.Debug_Info.set("FP: " + self.currentTrial[i]) if i == 3: self.show_info += self.cmd.Electronic_Element_Component_lookup[ self.currentTrial[i]] self.write_info += self.currentTrial[i] + "," self.TrialInfo.set(self.show_info) self.global_times_counter += 1 self.show_info = "" self.spring_start() elif self.EnterPressTime % 2 == 1: # Incomplete Haptic Test Start--End if self.PressSpaceTwice is False: tkMessageBox.showinfo( 'Warning', message='Finish Haptic Test before proceed Press [Space]') return if len(self.entry_Answer.get()) == 0: tkMessageBox.showinfo( 'Warning', message='Enter your haptic feel before proceed') return else: if self.entry_Answer.get().strip().isdigit() and 0 < int( self.entry_Answer.get().strip()) < 8: self.User_feel_FP = self.haptic_feel_lookup[int( self.entry_Answer.get())] result = tkMessageBox.askyesno( title='Notice', message='Your Haptic Choice: ' + self.User_feel_FP + '\nCan you confirm ?') if result is True: pass else: return else: tkMessageBox.showinfo( title='Warning', message='Your Choice MUST BE Integer in [1-7]') return self.Answer.set("") # Show the recognition load question if self.currentTrial[1] == '1': self.ask_last_num = int(self.currentTrial[-1]) self.Question_text.set("Select the Last " + str(self.ask_last_num) + " Chinese word\n") print "word_Pronounce: " + self.word_pron[ self.play_electronic_element.last_i_th( self.ask_last_num)].decode("gbk") else: self.ask_last_num = -1 self.Question_text.set( "No Question just Press [Enter] to Proceed") # Write the current user trial data information to output file # and choice and show a trial Information elif self.EnterPressTime % 2 == 0: # Recognition Load question answer if self.currentTrial[1] == '1': if len(self.entry_Answer.get()) == 0: tkMessageBox.showinfo( 'Warning', message= 'Enter the correctness of recognition Load before proceed' ) return else: if self.entry_Answer.get().strip().isdigit(): self.user_choice = int(self.entry_Answer.get()) else: tkMessageBox.showinfo( title='Notice', message='Your Choice MUST BE Integer in [1-9]') return result = tkMessageBox.askyesno( 'Notice', message='Your Recognition Load Correctness: ' + str(self.user_choice) + '\nCan you confirm ?') if result is True: pass else: return else: self.user_choice = -1 self.Question_text.set("") self.Answer.set("") self.write_info += str(self.deltatime) + "," if self.User_feel_FP != 'None': self.write_info += str( self.cmd.Force_Profile.index(self.User_feel_FP)) + "," if self.User_feel_FP == self.currentTrial[2]: self.write_info += str(1) + "," self.correct_times += 1 else: self.write_info += str(0) + "," else: self.write_info += str(7) + ',' print "Actual FP: " + self.currentTrial[ 2] + "----User FP: " + self.User_feel_FP print "***" + str(self.correct_times) + "/" + str( self.global_times_counter) self.write_info += str(self.ask_last_num) + "," if self.currentTrial[1] == '1': self.write_info += str(self.user_choice) + "\n" if self.user_choice == 1: self.correct_RL_times += 1 self.RL_total += 1 else: self.write_info += str(-1) + "," self.write_info += str(self.user_choice) + "\n" timeStamp = self.space_sound_start + "," + self.force_profile_start + "," + self.sound_stop + "," + self.space_curTrial_stop + "\n" self.outputfile_timeStamp.write(timeStamp) self.outputfile.write(self.write_info) self.outputfile_timeStamp.flush() self.outputfile.flush() self.write_info = "" # When the trial times reach the end if self.current_time == len(self.cmd.Commands): tkMessageBox.showinfo('Notice', message='Haptic Test End, Thank you!!') return # Begin the next trial self.currentTrial = self.cmd.read_command_by_line() print self.currentTrial # Current/Total times self.write_info += str( self.user_num) + "," + self.user_name + "," + str( self.user_age) + "," + self.user_gender + "," if self.startTrialNum == 0: self.current_time = self.global_times_counter + 1 else: self.current_time = self.global_times_counter + self.startTrialNum self.show_info += str(self.current_time) + "\t\t" self.write_info += str(self.current_time) + "," for i in range(len(self.currentTrial)): if i == 0: self.pin_height = self.currentTrial[i] self.write_info += str( self.cmd.condition_lookup_table.index( self.pin_height)) + "," if i == 1: if self.currentTrial[i] == '1': self.show_info += "True\t\t" self.write_info += "1," else: self.show_info += "False\t\t" self.write_info += "0," if i == 2: # self.show_info += self.currentTrial[i] + "\t\t" self.Debug_Info.set("FP: " + self.currentTrial[i]) self.write_info += str( self.cmd.Force_Profile.index( self.currentTrial[i])) + "," if i == 3: self.show_info += self.cmd.Electronic_Element_Component_lookup[ self.currentTrial[i]] self.write_info += self.currentTrial[i] + "," self.PressSpaceTwice = False self.TrialInfo.set(self.show_info) if self.RL_total != 0: precision = float(self.correct_RL_times) / self.RL_total self.Position_Info.set( str(self.correct_RL_times) + "/" + str(self.RL_total) + "=" + str(round(precision * 100)) + "%") self.global_times_counter += 1 self.show_info = "" self.spring_start() self.EnterPressTime += 1 def retry(self): # Recognition Load question answer if self.currentTrial[1] == '1': if len(self.entry_Answer.get()) == 0: tkMessageBox.showinfo( 'Warning', message='Select the Electronic Element before retry') return else: if self.entry_Answer.get().strip().isdigit() and 0 < int( self.entry_Answer.get().strip()) < 10: self.user_choice = int(self.entry_Answer.get()) else: tkMessageBox.showinfo( title='Notice', message='Your Choice MUST BE Integer in [1-9]') return result = tkMessageBox.askyesno( 'Notice', message='Your Recognition Load Choice: ' + str(self.user_choice) + '\nCan you confirm ?') if result is True: pass else: return else: self.user_choice = -1 self.Question_text.set("") self.Answer.set("") self.write_info += str(self.deltatime) + "," if self.User_feel_FP != 'None': self.write_info += str( self.cmd.Force_Profile.index(self.User_feel_FP)) + "," if self.User_feel_FP == self.currentTrial[2]: self.write_info += str(1) + "," self.correct_times += 1 print str(self.correct_times) + "/" + str( self.global_times_counter) else: self.write_info += str(0) + "," else: self.write_info += str(7) + ',' self.write_info += str(self.ask_last_num) + "," if self.currentTrial[1] == '1': self.write_info += str( self.play_electronic_element.last_i_th( self.ask_last_num)) + "," self.write_info += str(self.user_choice) + "\n" else: self.write_info += str(-1) + "," self.write_info += str(self.user_choice) + "\n" timeStamp = self.space_sound_start + "," + self.force_profile_start + "," + self.sound_stop + "," + self.space_curTrial_stop + "\n" self.outputfile_timeStamp.write(timeStamp) self.outputfile.write(self.write_info) self.outputfile_timeStamp.flush() self.outputfile.flush() self.write_info = "" # Begin the next trial print self.currentTrial self.global_times_counter -= 1 # Current/Total times self.write_info += str( self.user_num) + "," + self.user_name + "," + str( self.user_age) + "," + self.user_gender + "," if self.startTrialNum == 0: self.current_time = self.global_times_counter + 1 else: self.current_time = self.global_times_counter + self.startTrialNum self.show_info += str(self.current_time) + "\t\t" self.write_info += str(self.current_time) + "," for i in range(len(self.currentTrial)): if i == 0: self.pin_height = self.currentTrial[i] self.write_info += str( self.cmd.condition_lookup_table.index( self.pin_height)) + "," if i == 1: if self.currentTrial[i] == '1': self.show_info += "True\t\t" self.write_info += "1," else: self.show_info += "False\t\t" self.write_info += "0," if i == 2: self.Debug_Info.set("FP: " + self.currentTrial[i]) self.write_info += str( self.cmd.Force_Profile.index(self.currentTrial[i])) + "," if i == 3: self.show_info += self.cmd.Electronic_Element_Component_lookup[ self.currentTrial[i]] self.write_info += self.currentTrial[i] + "," self.PressSpaceTwice = False self.TrialInfo.set(self.show_info) self.Position_Info.set( str(self.correct_RL_times) + "/" + str(self.RL_total) + "=" + str(self.correct_RL_times / self.RL_total * 1.0)) self.show_info = "" self.global_times_counter += 1 self.EnterPressTime += 1 self.spring_start() def spring_start(self): self.spring = Spring(self.time_counter, self.sound_stopper) Pin_height = int(self.currentTrial[3]) if 1 <= Pin_height and Pin_height <= 3: self.spring.set_profile(self.currentTrial[2], 'long') elif 4 <= Pin_height and Pin_height <= 6: self.spring.set_profile(self.currentTrial[2], 'middle') elif 7 <= Pin_height and Pin_height <= 9: self.spring.set_profile(self.currentTrial[2], 'short') self.spring.start() def time_counter(self): if self.SpacePressTime % 2 != 1: tkMessageBox.showinfo( 'Warning', message='Press [Space] before Force Profile Sense') return self.start = int(round(time.time() * 1000)) self.Question_text.set("Haptic Test START") self.force_profile_start = datetime.datetime.now().strftime( '%Y-%m-%d %H:%M:%S.%f').split()[1] self.Question.place(x=6 * self.width / 16, y=3 * self.height / 4) self.Question.config(font=("Courier", 23, "bold")) self.Question.config(fg="green") def sound_stopper(self): # Stop play the sound of electronic element self.Question_text.set("Sound END") self.Question.place(x=7 * self.width / 16, y=3 * self.height / 4) self.Question.config(fg="red", font=("Courier", 23, "bold")) if self.currentTrial[1] == '1': self.play_electronic_element.terminate() self.sound_stop = datetime.datetime.now().strftime( '%Y-%m-%d %H:%M:%S.%f').split()[1] else: self.sound_stop = "-1"
class Experiment_Session: def __init__(self): # Set the basic params of windows self.root = Tkinter.Tk() self.root.title("Haptic Experiment") w = 1920 #self.root.winfo_screenwidth() h = 1080 #self.root.winfo_screenheight() self.width = w self.height = h self.root.geometry("%dx%d" % (w, h)) self.root.minsize(300, 240) self.user_num = -1 self.user_name = "" self.user_gender = "" self.user_age = 0 self.haptic_feel_lookup = { 1: 'empty', 2: 'low', 3: 'high', 4: 'medium', 5: 'increasing', 6: 'decreasing', 7: 'click', 8: 'drop', 9: 'None', } self.cmd = Produce_Read_Order_List.Produce_Read_Order_List( ) # Initiate list of command self.User_feel_FP = "" # record the user's actual choice of haptic feeling self.global_times_counter = 0 # record the user's repeated times self.correct_times = 0 self.correct_RL_times = 0 self.RL_total = 0 self.start = 0 # Start timestamp for haptic sensing self.end = 0 # End timestamp for haptic sensing self.deltatime = 0 # The time duration for haptic sensing self.startTrialNum = 0 # Start number specified for program crash self.outputfile = None # Output file for trial recording self.currentTrial = None # Current trial information self.play_electronic_element = None # Define the instance of electronic element sound play self.SpacePressTime = 0 # Times of press [Space] self.EnterPressTime = 0 # Times of press [Enter] self.PressSpaceTwice = False # Space pressed for more than twice without [Enter] self.user_choice = -1 # User choice of last i'th electronic element self.ask_last_num = -1 # the last i'th elements hear of under the Recongnition load self.trackLength = 0 # track the length of the sound playlist self.write_info = "" # Information written to output file self.show_info = "" # Information showed on the panel self.pin_height = "" # Information of the pin height # Switch between show debug and not show self.show_debug = False self.TrialInfo = Tkinter.StringVar(value='') # Trial information self.Answer = Tkinter.StringVar(value='') # User answer self.Question_text = Tkinter.StringVar(value='') # Text of Question self.Question_choice_row_1 = Tkinter.StringVar( value='') # First row of choice of question self.Question_choice_row_2 = Tkinter.StringVar( value='') # Second row of choice of question self.Question_choice_row_3 = Tkinter.StringVar( value='') # Third row of choice of question self.Position_Info = Tkinter.StringVar( value='') # Position Information about the Spring self.Debug_Info = Tkinter.StringVar( value='') # Debug Information about the Spring # Bind the Space Key press to continue self.root.bind( "<KeyPress>", self.SpaceContinue) # Bind the [Space] press and its function self.root.focus_set() self.root.bind('<Return>', self.EnterPress) # Bind the [Enter] Key press self.spring = Spring() self.varNum = Tkinter.StringVar(value='') self.varName = Tkinter.StringVar(value='') self.varGender = Tkinter.StringVar(value='') self.varAge = Tkinter.StringVar(value='') # Top level Panel for user information enter, show at program boot, hide when information entered and confirmed top_entry_y = h / 80 top_col_1 = w / 15 top_col_2 = top_col_1 + w / 12 + w / 18 top_col_3 = top_col_2 + w / 12 + w / 18 top_col_4 = top_col_3 + w / 12 + w / 18 top_col_5 = top_col_4 + w / 12 + w / 15 top_col_6 = top_col_5 + w / 12 + w / 12 self.labelNum = Tkinter.Label(self.root, text='User Num:') self.labelNum.place(x=top_col_1, y=top_entry_y, width=w / 12, height=h / 20) self.labelNum.config(font=("Courier", 15, "bold")) self.entryNum = Tkinter.Entry(self.root, textvariable=self.varNum) self.entryNum.place(x=top_col_1 + w / 12, y=top_entry_y, width=w / 18, height=h / 20) self.LabelName = Tkinter.Label(self.root, text='Name:') self.LabelName.place(x=top_col_2, y=top_entry_y, width=w / 12, height=h / 20) self.LabelName.config(font=("Courier", 15, "bold")) self.entryName = Tkinter.Entry(self.root, textvariable=self.varName) self.entryName.place(x=top_col_2 + w / 12, y=top_entry_y, width=w / 20, height=h / 20) self.LabelGender = Tkinter.Label(self.root, text='Gender:') self.LabelGender.place(x=top_col_3, y=top_entry_y, width=w / 12, height=h / 20) self.LabelGender.config(font=("Courier", 15, "bold")) self.entryGender = Tkinter.Entry(self.root, width=80, textvariable=self.varGender) self.entryGender.place(x=top_col_3 + w / 12, y=top_entry_y, width=w / 20, height=h / 20) self.LabelAge = Tkinter.Label(self.root, text='Age:') self.LabelAge.place(x=top_col_4, y=top_entry_y, width=w / 12, height=h / 20) self.LabelAge.config(font=("Courier", 15, "bold")) self.entryAge = Tkinter.Entry(self.root, width=80, textvariable=self.varAge) self.entryAge.place(x=top_col_4 + w / 12, y=top_entry_y, width=w / 20, height=h / 20) self.LabelStartFromTrial = Tkinter.Label(self.root, text='Start Num:') self.LabelStartFromTrial.place(x=top_col_5, y=top_entry_y, width=w / 12, height=h / 20) self.LabelStartFromTrial.config(font=("Courier", 15, "bold")) self.entryStartFromTrial = Tkinter.Entry( self.root, width=80, textvariable=self.startTrialNum) self.entryStartFromTrial.place(x=top_col_5 + w / 12, y=top_entry_y, width=w / 20, height=h / 20) self.buttonOk = Tkinter.Button(self.root, text='Confirm', command=self.login) self.buttonOk.place(x=top_col_6, y=top_entry_y, width=w / 20, height=h / 20) self.buttonOk.config(font=("Courier", 12, "bold")) self.buttonCancel = Tkinter.Button(self.root, text='Cancel', command=self.cancel) self.buttonCancel.place(x=top_col_6 + w / 18, y=top_entry_y, width=w / 20, height=h / 20) self.buttonCancel.config(font=("Courier", 12, "bold")) self.buttonRetry = Tkinter.Button(self.root, text='Retry', command=self.retry) self.buttonRetry.place(x=top_col_6 + 2 * w / 18, y=top_entry_y, width=w / 20, height=h / 20) self.buttonRetry.config(font=("Courier", 12, "bold")) self.Info_Header = Label( self.root, text="Trial\tRecongition Load\tHandness\tComponent", anchor=W) self.Info_Header.config(font=("Courier", 12, "bold")) self.Info = Label(self.root, textvariable=self.TrialInfo, anchor=W) self.Info.config(font=("Courier", 12, "bold")) # Set up and place the images at the second level img_1 = Image.open('img/F01.jpg') img_1 = img_1.resize((w / 6, h / 6), Image.ANTIALIAS) img_1 = ImageTk.PhotoImage(img_1) img_2 = Image.open('img/F02.jpg') img_2 = img_2.resize((w / 6, h / 6), Image.ANTIALIAS) img_2 = ImageTk.PhotoImage(img_2) img_3 = Image.open('img/F03.jpg') img_3 = img_3.resize((w / 6, h / 6), Image.ANTIALIAS) img_3 = ImageTk.PhotoImage(img_3) img_4 = Image.open('img/F04.jpg') img_4 = img_4.resize((w / 6, h / 6), Image.ANTIALIAS) img_4 = ImageTk.PhotoImage(img_4) img_5 = Image.open('img/F05.jpg') img_5 = img_5.resize((w / 6, h / 6), Image.ANTIALIAS) img_5 = ImageTk.PhotoImage(img_5) img_6 = Image.open('img/F06.jpg') img_6 = img_6.resize((w / 6, h / 6), Image.ANTIALIAS) img_6 = ImageTk.PhotoImage(img_6) img_7 = Image.open('img/F07.jpg') img_7 = img_7.resize((w / 6, h / 6), Image.ANTIALIAS) img_7 = ImageTk.PhotoImage(img_7) img_8 = Image.open('img/F08.jpg') img_8 = img_8.resize((w / 6, h / 6), Image.ANTIALIAS) img_8 = ImageTk.PhotoImage(img_8) col_x_1 = w / 15 col_x_2 = 2 * w / 15 + w / 6 col_x_3 = 3 * w / 15 + 2 * w / 6 col_x_4 = 4 * w / 15 + 3 * w / 6 label_level_1_y = top_entry_y + 2 * h / 20 label_level_2_y = top_entry_y + 4 * h / 20 + h / 6 img_level_1_y = top_entry_y + 3 * h / 20 img_level_2_y = top_entry_y + 5 * h / 20 + h / 6 self.FP1 = Label(self.root, text="1. empty", fg='blue') self.FP1.place(x=col_x_1, y=label_level_1_y) self.FP1.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_1).place(x=col_x_1, y=img_level_1_y) self.FP2 = Label(self.root, text="2. low", fg='blue') self.FP2.place(x=col_x_2, y=label_level_1_y) self.FP2.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_2).place(x=col_x_2, y=img_level_1_y) self.FP3 = Label(self.root, text="3. high", fg='blue') self.FP3.place(x=col_x_3, y=label_level_1_y) self.FP3.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_3).place(x=col_x_3, y=img_level_1_y) self.FP4 = Label(self.root, text="4. medium", fg='blue') self.FP4.place(x=col_x_4, y=label_level_1_y) self.FP4.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_4).place(x=col_x_4, y=img_level_1_y) self.FP5 = Label(self.root, text="5. increasing", fg='blue') self.FP5.place(x=col_x_1, y=label_level_2_y) self.FP5.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_5).place(x=col_x_1, y=img_level_2_y) self.FP6 = Label(self.root, text="6. decreasing", fg='blue') self.FP6.place(x=col_x_2, y=label_level_2_y) self.FP6.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_6).place(x=col_x_2, y=img_level_2_y) self.FP7 = Label(self.root, text="7. click", fg='blue') self.FP7.place(x=col_x_3, y=label_level_2_y) self.FP7.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_7).place(x=col_x_3, y=img_level_2_y) self.FP8 = Label(self.root, text="8. drop", fg='blue') self.FP8.place(x=col_x_4, y=label_level_2_y) self.FP8.config(font=("Courier", 15, "bold")) Label(self.root, text="abc", image=img_8).place(x=col_x_4, y=img_level_2_y) # User haptic feel part and Quize part self.Question = Label(self.root, textvariable=self.Question_text) # Show the current position information on right side self.CurrPosition = Label(self.root, text="Position Info", textvariable=self.Position_Info) self.CurrPosition.place(x=12 * self.width / 16, y=7 * self.height / 8) self.CurrPosition.config(font=("Courier", 15, "bold"), fg="red") # Show the Force Profile on left side self.CurrDebug = Label(self.root, text="Debug Info", textvariable=self.Debug_Info) if self.show_debug: self.CurrDebug.place(x=2 * self.width / 16, y=3 * self.height / 4) self.CurrDebug.config(font=("Courier", 20, "bold"), fg="red") self.Choice_row_1 = Label(self.root, textvariable=self.Question_choice_row_1) self.Choice_row_2 = Label(self.root, textvariable=self.Question_choice_row_2) self.Choice_row_3 = Label(self.root, textvariable=self.Question_choice_row_3) self.User_Answer = Tkinter.Label(self.root, text='Answer: ', fg="blue") self.User_Answer.place(x=w / 2 - w / 8, y=7 * h / 8) self.User_Answer.config(font=("Courier", 20, "bold")) self.entry_Answer = Tkinter.Entry(self.root, width=80, textvariable=self.Answer) self.entry_Answer.place(x=w / 2 - w / 25, y=7 * h / 8, width=w / 12, height=h / 25) self.root.mainloop() def login(self): if self.entryNum.get() == "": tkMessageBox.showinfo(title='Warning', message='Please complete number') return self.user_num = int(self.entryNum.get()) if 0 < self.user_num < 13: self.user_name = self.entryName.get() self.user_age = self.entryAge.get() self.user_gender = self.entryGender.get() if self.user_name == "": tkMessageBox.showinfo(title='Warning', message='Please complete name') return if self.user_age == "": tkMessageBox.showinfo(title='Warning', message='Please complete age') return if self.user_gender == "": tkMessageBox.showinfo(title='Warning', message='Please complete gender') return if self.entryStartFromTrial.get() != "": self.startTrialNum = int(self.entryStartFromTrial.get()) # check the existence of program crash if self.startTrialNum != 0: existFilename = "Order_List/User_" + str( self.user_num) + "_order_list.txt" self.cmd.read_command( existFilename ) # Read commands => commands in existence file else: self.cmd.start_up(int( self.user_num)) # Produce commands by user number self.cmd.read_command() # Read commands => commands # write the head information to the first line in the file self.outputfile = open( "Records/User_" + str(self.user_num) + "_record.txt", "w") self.outputfile.write( "User_num,User_name,User_age,User_gender,Trials,Pin_height,Recognition_Load,Handness,Force_Profile,Component_Num,Duration_Time,User_Choice,Haptic_Choice_Correctness, ask_last_num,actual_electronic_element,user_RL_Choice,Recognition_Load_Correctness\n" ) self.outputfile.close() # Re-open the output file again for later record useage self.outputfile = open( "Records/User_" + str(self.user_num) + "_record.txt", "a") else: tkMessageBox.showinfo('Error', message='Please enter an valid number[0-12]') return # Hide the label and entry from the panel self.labelNum.place_forget() self.entryNum.place_forget() self.LabelName.place_forget() self.entryName.place_forget() self.LabelGender.place_forget() self.entryGender.place_forget() self.LabelAge.place_forget() self.entryAge.place_forget() self.LabelStartFromTrial.place_forget() self.entryStartFromTrial.place_forget() self.buttonOk.place_forget() self.buttonCancel.place_forget() # Show the trial information after confirmation self.Info_Header.place(x=20 * self.width / 80, y=self.height / 80, width=34 * self.width / 64, height=self.height / 25) self.Info_Header.config(bg="red", fg="white") self.Info_Header.config(font=("Courier", 15, "bold")) self.Info.place(x=20 * self.width / 80, y=self.height / 80 + self.height / 22, width=34 * self.width / 64, height=self.height / 25) self.Info.config(font=("Courier", 15, "bold")) self.Info.config(bg="blue", fg="white") def cancel(self): self.varNum.set('') self.varAge.set('') self.varGender.set('') self.varName.set('') # Start and End a haptic trial by [Space] keypress def SpaceContinue(self, event): if event.keysym == "Right": # Stop play the sound of electronic element if self.currentTrial[1] == '1': self.play_electronic_element.terminate() self.trackLength = len(self.play_electronic_element.traceList) if event.keysym == "space": # Press [Enter] for 1,3,5,7,9 if self.EnterPressTime == 0: tkMessageBox.showinfo( 'Warning', message='Press [Enter] to start a trial before proceed') return # Press Space more than twice without press [Enter] if self.PressSpaceTwice is True: tkMessageBox.showinfo( 'Warning', message='Answer the question before proceed') return print "Space Entered" if self.SpacePressTime % 2 == 0: self.start = int(round(time.time() * 1000)) self.Question_text.set("Haptic Test START") self.Question.place(x=6 * self.width / 16, y=3 * self.height / 4) self.Question.config(font=("Courier", 23, "bold")) self.Question.config(fg="green") # Start to play the electronic element if self.currentTrial[1] == '1': self.play_electronic_element = play_electronic_element() self.play_electronic_element.start() else: # Stop the movement of Haptic Spring self.spring.terminate() self.deltatime = int(round(time.time() * 1000)) - self.start self.Question_text.set("Haptic Test END") self.Question.place(x=7 * self.width / 16, y=3 * self.height / 4) self.Question.config(fg="red", font=("Courier", 23, "bold")) self.Question.after(500, lambda: self.Question_text.set("")) self.Question.after( 500, lambda: self.Question_text.set("Select a Haptic Feel")) self.Question.place(x=5 * self.width / 16, y=3 * self.height / 4) self.Question.config(font=("Courier", 23, "bold"), fg="blue") self.PressSpaceTwice = True self.SpacePressTime += 1 # [Enter] Press for 1. Show a Trial Information 2. Show a electronic elements def EnterPress(self, event): # Incomplete Personal Information if self.EnterPressTime == 0: if self.user_num == -1 or self.user_name == "" or self.user_gender == "" or self.user_age == "": tkMessageBox.showinfo( 'Warning', message='Complete Personal Info before proceed') return # the first time press [Enter]: show a Trial Information if self.EnterPressTime == 0: start_num = self.startTrialNum if start_num == 0: self.currentTrial = self.cmd.read_command_by_line() while start_num != 0: self.currentTrial = self.cmd.read_command_by_line() start_num -= 1 print self.currentTrial # Current/Total times self.write_info += str( self.user_num) + "," + self.user_name + "," + str( self.user_age) + "," + self.user_gender + "," if self.startTrialNum == 0: current_time = self.global_times_counter + 1 else: current_time = self.global_times_counter + self.startTrialNum self.show_info += " " + str(current_time) + "\t " self.write_info += str(current_time) + "," for i in range(len(self.currentTrial)): if i == 0: self.pin_height = self.currentTrial[i] self.write_info += str( self.cmd.condition_lookup_table.index( self.pin_height)) + "," if i == 1: if self.currentTrial[i] == '1': self.show_info += " True\t\t" self.write_info += "1," else: self.show_info += " False\t\t" self.write_info += "0," if i == 2: if self.currentTrial[i] == '1': self.show_info += "Dominant\t " self.write_info += "1," else: self.show_info += "Non-Dominant\t " self.write_info += "0," if i == 3: self.write_info += str( self.cmd.Force_Profile.index( self.currentTrial[i])) + "," self.Debug_Info.set("FP: " + self.currentTrial[i]) if i == 4: self.show_info += self.cmd.Electronic_Element_Component_lookup[ self.currentTrial[i]] self.write_info += self.currentTrial[i] + "," self.TrialInfo.set(self.show_info) self.global_times_counter += 1 self.show_info = "" # Create thread for handling haptic Spring #self.spring = Spring(self.Position_Info.set) self.spring = Spring() Pin_height = int(self.currentTrial[4]) if 1 <= Pin_height and Pin_height <= 3: self.spring.set_profile(self.currentTrial[3], 'long') elif 4 <= Pin_height and Pin_height <= 6: self.spring.set_profile(self.currentTrial[3], 'middle') elif 7 <= Pin_height and Pin_height <= 9: self.spring.set_profile(self.currentTrial[3], 'short') self.spring.start() elif self.EnterPressTime % 2 == 1: # Incomplete Haptic Test Start--End if self.PressSpaceTwice is False: tkMessageBox.showinfo( 'Warning', message='Finish Haptic Test before proceed Press [Space]') return if len(self.entry_Answer.get()) == 0: tkMessageBox.showinfo( 'Warning', message='Enter your haptic feel before proceed') return else: if self.entry_Answer.get().strip().isdigit() and 0 < int( self.entry_Answer.get().strip()) < 10: self.User_feel_FP = self.haptic_feel_lookup[int( self.entry_Answer.get())] result = tkMessageBox.askyesno( title='Notice', message='Your Haptic Choice: ' + self.User_feel_FP + '\nCan you confirm ?') if result is True: pass else: return else: tkMessageBox.showinfo( title='Warning', message='Your Choice MUST BE Integer in [1-9]') return self.Answer.set("") # Show the recognition load question if self.currentTrial[1] == '1': self.ask_last_num = random.randrange( 1, 4) # random number for quiz of last element if self.ask_last_num > self.trackLength: self.ask_last_num = self.trackLength self.Question_text.set("Select the Last " + str(self.ask_last_num) + " Electronic Element\n") self.Question_choice_row_1.set("1. 光敏电阻\t2. 发光二极管\t3. 电阻") self.Question_choice_row_2.set("4. 场效应管\t5. 三极管\t6. 电容") self.Question_choice_row_3.set("7. 芯片\t\t8. 电位器\t9. 跳线") base_question_x = 19 * self.width / 64 base_question_y = 11 * self.height / 16 base_question_y_row_1 = base_question_y + 30 base_question_y_row_2 = base_question_y_row_1 + 30 base_question_y_row_3 = base_question_y_row_2 + 30 self.Question.place(x=base_question_x, y=base_question_y, anchor=W) self.Choice_row_1.place(x=base_question_x, y=base_question_y_row_1, anchor=W) self.Choice_row_2.place(x=base_question_x, y=base_question_y_row_2, anchor=W) self.Choice_row_3.place(x=base_question_x, y=base_question_y_row_3, anchor=W) self.Question.config(font=("Courier", 20, "bold"), fg="red") self.Choice_row_1.config(font=("Courier", 20, "bold"), fg="black") self.Choice_row_2.config(font=("Courier", 20, "bold"), fg="black") self.Choice_row_3.config(font=("Courier", 20, "bold"), fg="black") else: self.ask_last_num = -1 self.Question_text.set( "No Question just Press [Enter] to Proceed") # Write the current user trial data information to output file # and choice and show a trial Information elif self.EnterPressTime % 2 == 0: # Recognition Load question answer if self.currentTrial[1] == '1': if len(self.entry_Answer.get()) == 0: tkMessageBox.showinfo( 'Warning', message='Select the Electronic Element before proceed') return else: if self.entry_Answer.get().strip().isdigit() and 0 < int( self.entry_Answer.get().strip()) < 10: self.user_choice = int(self.entry_Answer.get()) else: tkMessageBox.showinfo( title='Notice', message='Your Choice MUST BE Integer in [1-9]') return result = tkMessageBox.askyesno( 'Notice', message='Your Recognition Load Choice: ' + str(self.user_choice) + '\nCan you confirm ?') if result is True: pass else: return else: self.user_choice = -1 self.Question_text.set("") self.Question_choice_row_1.set("") self.Question_choice_row_2.set("") self.Question_choice_row_3.set("") self.Answer.set("") self.write_info += str(self.deltatime) + "," if self.User_feel_FP != 'None': self.write_info += str( self.cmd.Force_Profile.index(self.User_feel_FP)) + "," if self.User_feel_FP == self.currentTrial[3]: self.write_info += str(1) + "," self.correct_times += 1 else: self.write_info += str(0) + "," else: self.write_info += str(8) + ',' print "Actual FP: " + self.currentTrial[ 3] + " User FP: " + self.User_feel_FP print "***" + str(self.correct_times) + "/" + str( self.global_times_counter) self.write_info += str(self.ask_last_num) + "," if self.currentTrial[1] == '1': self.write_info += str( self.play_electronic_element.last_i_th( self.ask_last_num)) + "," self.write_info += str(self.user_choice) + "," if int(self.user_choice) == int( self.play_electronic_element.last_i_th( self.ask_last_num)): self.write_info += str(1) + "\n" self.correct_RL_times += 1 else: self.write_info += str(0) + "\n" self.RL_total += 1 else: self.write_info += str(-1) + "," self.write_info += str(self.user_choice) + "," self.write_info += str(-1) + "\n" self.outputfile.write(self.write_info) self.outputfile.flush() self.write_info = "" # When the trial times reach the end if self.global_times_counter == len(self.cmd.Commands): tkMessageBox.showinfo('Notice', message='Haptic Test End, Thank you!!') return # Begin the next trial self.currentTrial = self.cmd.read_command_by_line() print self.currentTrial # Current/Total times self.write_info += str( self.user_num) + "," + self.user_name + "," + str( self.user_age) + "," + self.user_gender + "," if self.startTrialNum == 0: current_time = self.global_times_counter + 1 else: current_time = self.global_times_counter + self.startTrialNum self.show_info += str(current_time) + "\t\t" self.write_info += str(current_time) + "," for i in range(len(self.currentTrial)): if i == 0: self.pin_height = self.currentTrial[i] self.write_info += str( self.cmd.condition_lookup_table.index( self.pin_height)) + "," if i == 1: if self.currentTrial[i] == '1': self.show_info += "True\t\t" self.write_info += "1," else: self.show_info += "False\t\t" self.write_info += "0," if i == 2: if self.currentTrial[i] == '1': self.show_info += "Dominant\t " self.write_info += "1," else: self.show_info += "Non-Dominant\t " self.write_info += "0," if i == 3: # self.show_info += self.currentTrial[i] + "\t\t" self.Debug_Info.set("FP: " + self.currentTrial[i]) self.write_info += str( self.cmd.Force_Profile.index( self.currentTrial[i])) + "," if i == 4: self.show_info += self.cmd.Electronic_Element_Component_lookup[ self.currentTrial[i]] self.write_info += self.currentTrial[i] + "," self.PressSpaceTwice = False self.TrialInfo.set(self.show_info) self.Position_Info.set( str(self.correct_RL_times) + "/" + str(self.RL_total)) self.global_times_counter += 1 self.show_info = "" # Create thread for handling haptic Spring #self.spring = Spring(self.Position_Info.set) self.spring = Spring() Pin_height = int(self.currentTrial[4]) if 1 <= Pin_height and Pin_height <= 3: self.spring.set_profile(self.currentTrial[3], 'long') elif 4 <= Pin_height and Pin_height <= 6: self.spring.set_profile(self.currentTrial[3], 'middle') elif 7 <= Pin_height and Pin_height <= 9: self.spring.set_profile(self.currentTrial[3], 'short') self.spring.start() self.EnterPressTime += 1 def retry(self): # Recognition Load question answer if self.currentTrial[1] == '1': if len(self.entry_Answer.get()) == 0: tkMessageBox.showinfo( 'Warning', message='Select the Electronic Element before retry') return else: if self.entry_Answer.get().strip().isdigit() and 0 < int( self.entry_Answer.get().strip()) < 10: self.user_choice = int(self.entry_Answer.get()) else: tkMessageBox.showinfo( title='Notice', message='Your Choice MUST BE Integer in [1-9]') return result = tkMessageBox.askyesno( 'Notice', message='Your Recognition Load Choice: ' + str(self.user_choice) + '\nCan you confirm ?') if result is True: pass else: return else: self.user_choice = -1 self.Question_text.set("") self.Question_choice_row_1.set("") self.Question_choice_row_2.set("") self.Question_choice_row_3.set("") self.Answer.set("") self.write_info += str(self.deltatime) + "," if self.User_feel_FP != 'None': self.write_info += str( self.cmd.Force_Profile.index(self.User_feel_FP)) + "," if self.User_feel_FP == self.currentTrial[3]: self.write_info += str(1) + "," self.correct_times += 1 print str(self.correct_times) + "/" + str( self.global_times_counter) else: self.write_info += str(0) + "," else: self.write_info += str(8) + ',' self.write_info += str(self.ask_last_num) + "," if self.currentTrial[1] == '1': self.write_info += str( self.play_electronic_element.last_i_th( self.ask_last_num)) + "," self.write_info += str(self.user_choice) + "," if int(self.user_choice) == int( self.play_electronic_element.last_i_th(self.ask_last_num)): self.write_info += str(1) + "\n" else: self.write_info += str(0) + "\n" else: self.write_info += str(-1) + "," self.write_info += str(self.user_choice) + "," self.write_info += str(-1) + "\n" self.outputfile.write(self.write_info) self.outputfile.flush() self.write_info = "" # Begin the next trial print self.currentTrial self.global_times_counter -= 1 # Current/Total times self.write_info += str( self.user_num) + "," + self.user_name + "," + str( self.user_age) + "," + self.user_gender + "," if self.startTrialNum == 0: current_time = self.global_times_counter + 1 else: current_time = self.global_times_counter + self.startTrialNum self.show_info += str(current_time) + "\t\t" self.write_info += str(current_time) + "," for i in range(len(self.currentTrial)): if i == 0: self.pin_height = self.currentTrial[i] self.write_info += str( self.cmd.condition_lookup_table.index( self.pin_height)) + "," if i == 1: if self.currentTrial[i] == '1': self.show_info += "True\t\t" self.write_info += "1," else: self.show_info += "False\t\t" self.write_info += "0," if i == 2: if self.currentTrial[i] == '1': self.show_info += "Dominant\t " self.write_info += "1," else: self.show_info += "Non-Dominant\t " self.write_info += "0," if i == 3: self.Debug_Info.set("FP: " + self.currentTrial[i]) self.write_info += str( self.cmd.Force_Profile.index(self.currentTrial[i])) + "," if i == 4: self.show_info += self.cmd.Electronic_Element_Component_lookup[ self.currentTrial[i]] self.write_info += self.currentTrial[i] + "," self.PressSpaceTwice = False self.TrialInfo.set(self.show_info) self.Position_Info.set( str(self.correct_RL_times) + "/" + str(self.RL_total)) self.show_info = "" self.global_times_counter += 1 self.EnterPressTime += 1 # Create thread for handling haptic Spring #self.spring = Spring(self.Position_Info.set) self.spring = Spring() Pin_height = int(self.currentTrial[4]) if 1 <= Pin_height and Pin_height <= 3: self.spring.set_profile(self.currentTrial[3], 'long') elif 4 <= Pin_height and Pin_height <= 6: self.spring.set_profile(self.currentTrial[3], 'middle') elif 7 <= Pin_height and Pin_height <= 9: self.spring.set_profile(self.currentTrial[3], 'short') self.spring.start()