#1
|
|||
|
|||
motion tracker changes Vizard timing
Hello!
I am having very weird timing problems when running my script with the Polhemus motion tracker as opposed to without. It only happens when I uncomment the section of the code that writes an output file with the position data of the tracker markers. It does not matter if Polhemus is running in parallel, as long as the Vizard script is not using the data. Has anyone ever had anything similar and knows how to solve this problem? Thanks in advance! J |
#2
|
|||
|
|||
Can you explain further what you mean by timing problems? It would probably help if you post example code that shows the issue.
|
#3
|
|||
|
|||
Dear Jeff,
I will try to post some code later this evening, the script is so large by now, it really is difficult to tell what is causing it. So I will need to try and create a simpler version. In principle, I think it could be related to frequency or sampling. I've had a colleague who has told me that she had sounds in her script (like me) and they did not play at exactly the same time from one execution to the next. Another one had a countdown timer clock that was sometimes skipping the display of seconds. And another who had a beep sound that played three times at the end of a trial. There was supposed to be a 1s gap between each beep but sometimes the gaps were audibly uneven and the timer on screen was a bit slow. While for them this was not crucial, the timing of the sounds in my experiment is! All of us were/are using the Polhemus motion tracker. I will follow this up later with a less complex code version that hopefully still illustrates the problem! |
#4
|
|||
|
|||
Dear Jeff,
I have some code below, which is also writing an output file. It only requires a sound .wav file as a cue, otherwise it should run on the spot and illustrate the issue. When running it, you can see on the screen display that the sampling will freeze and skip seconds. Mostly it seems as if it balances itself out, meaning that if one second froze for too long, then another second at another time will be skipped. Another thing I am thinking is (because my other colleagues also had similar problem when using sound) that maybe the sampling is faster than the sound and this interaction somehow causes some problems. But running the code with all the sound related things commented still has the problem... Code:
import time import viztask import numpy as np import random import vizact import itertools viz.go() ########################### ## GENERAL SETUP ########################### viz.MainView.setPosition(0,1.8,0) viz.MainView.setEuler(0,0,0) viz.mouse.setVisible(viz.OFF) #Stops the mouse appearing on the screen. viz.mouse.setOverride(viz.ON) #Stops Vizard navigation using the mouse. #Set background colour viz.clearcolor(viz.BLACK) #Set background colour to black ID = input('Participant ID: ') #This is the unique ID number to identify the participant. suffix = input('Suffix: ') #This is the suffix to the participant's ID number, used for not overwriting data files. #Create a data ID and data header for the participant: dataID = str(ID) + '_' + str(suffix) #Adds a suffix to the session number so that files can't be overwritten. #Create a first line to write to data files: firstLine = 'Study Data \n' ####~~~~~~~Make Windows for Textures~~~~~~~#### #make box for clock timeBox = viz.addText('', viz.SCREEN) timeBox.setPosition(0.5,0.5) timeBox.setScale([0.4, 0.4, 0.4]) timeBox.alignment(viz.ALIGN_CENTER_CENTER) timeBox.color([1,1,1]) ########################### ## OUTPUT FILE ########################### ####~~~~~~~OUTPUT~~~~~~~#### Data = open(str(dataID) + '_Data3.txt','w') DataHeaders = 'ID\tPic\tTimeNow\tPicstate\tBeepstate\n' Data.write(firstLine) Data.close() ####~~~~~~~Create fuction for saving data~~~~~~~#### def saveData(): global picstateString, beepstateString, timeNow Data = open(str(dataID) + '_Data3.txt','a', 1) # 'a' means append the file rather than overwrite vars = "%s\t%s\t%s\t%s\t%s\n" %( ID, hno, timeNow, picstateString, beepstateString) Data.write(vars) ########################### ## STIMULI ########################### ### Cue sound cue = viz.addAudio('cues\dong.wav') cueDuration = cue.getDuration() picList = np.arange(1, 59, 1) # this is in the real experiment an actual list of jpegs ### Timings ### beeptimes = [] otimes2 = [] ctimes2 = [] otimes_short2 = [] otimes_long2 = [] ctimes_short2 = [] ctimes_long2 = [] def uniform_min_range(a, b, n, min_dist): while True: atimes = np.random.uniform(a, b, size=n) np.sort(atimes) if np.all(np.diff(atimes) >= min_dist): return atimes def timings(): global condition, beeptimes, otimes, ctimes, otimes2, ctimes2, otimes_short2, otimes_long2, ctimes_short2, ctimes_long2, ctimes2String, otimes2String, beeptimesString beeptimes = uniform_min_range(0, 20, 5, 1.0) print 'beep times: ', beeptimes beeptimesString = 'BeepTimes: '+','.join(map(str,beeptimes)) + '\n' num_to_select = 4 otimes = random.sample(beeptimes, num_to_select) ctimes = list(set(beeptimes) - set(otimes)) otimes1 = [oo + 0.8 for oo in otimes] otimes2 = np.sort(otimes1) print 'otimes short', otimes2 ctimes2 = [ctimes[0] + 0.8] print 'ctimes short', ctimes2 otimes2String = 'S1 Times: ' + ',' .join(map(str,otimes2)) +'\n' ctimes2String = 'S2 Times: ' + ','.join(map(str,ctimes2)) +'\n' ### Picture state hno = 30 def setup_pics(): # at 0 nothing happens; at 1 (or -1) something happens (a beep, a pic) --> this sets it up global tt, picstate, beepstate, picstateString, beepstateString, beeptimesString, otimes2String, ctimes2String global beeptimes, otimes, ctimes, otimes_short2, otimes_long2, ctimes_short2, ctimes_long2 timings() Data = open(str(dataID) + '_Data3.txt','a',1) Data.write(beeptimesString) Data.write(otimes2String) Data.write(ctimes2String) Data.write(DataHeaders) tt =[] dt = 0.04 #seconds for increment tt.append(0) #first elem in tt is 0 picstate = [] picstate.append(0) #first elem in picstate is 0 beepstate = [] beepstate.append(0) n=0 done = 0 while not done: #keep adding elements to the picstate list n=n+1 #elem by elem picstate.append(0) beepstate.append(0) tt.append(tt[n-1]+dt) #keep adding time elements to time list, by adding dt = 0.04 s to the one b4 for oo in otimes2: # for each elem in the otimes if (oo - tt[n]<0.5 and oo-tt[n]>0): #if the element in the otimes minus the current element in tt is lower than 0.5 and bigger than 0 (basically between 0 and 0,5) than choose action 1 picstate[n] = 1 for pp in ctimes2: #if the element in the closing times minus the current element in tt is lower than 0.5 and bigger than 0 (basically between 0 and 0,5) than choose action 2 if (pp - tt[n]<0.5 and pp-tt[n]>0): picstate[n] = -1 for bs in beeptimes: if (bs - tt[n]<0.5 and bs-tt[n]>0): beepstate[n] = 1 if tt[n] > 25: # if the current element in tt is bigger than 20 then stop the loop to add to the list, it's over done = 1 print 'tt', tt print 'picstate', picstate print 'beepstate', beepstate def choose_pic(): global picstate, beepstate, picstateString, beepstateString, timeNow global hno global tt, start, ntt ntt = viz.tick()-start # get time NOW since start of trial (can be made to be since start of experiment) nn = np.searchsorted(tt,ntt,side='left') thispic = picstate[nn] thisbeep = beepstate[nn] if thisbeep == 1 and thisbeep-1 == 0: def cueplay(): cue.play() #yield viztask.waitTime(cueDuration) #cue.stop() cueplay() picstateString = str(picstate[nn]) beepstateString = str(beepstate[nn]) timeNow = str(round(ntt,2)) # string of time Now ntt (rounded) to print in output file ### DEFAULT - random walk if thispic==0: prob = [0.05, 0.95] # Probability to move up or down rr = np.random.random(1) if hno<27: hno = hno+2 elif hno>35: hno = hno-2 else: if rr < prob[0] and hno>27: hno = hno-1 elif rr > prob[1] and hno<35: hno = hno+1 ### STATE1 elif thispic==1: ## state for triggering action 1 if hno<54: hno = hno+5 ### STATE2 elif thispic==-1: ## state for triggering action 1 if hno>4: hno = hno-5 ##save stuff saveData() ## DISPLAY time_left = round(20-ntt,0) timeBox.message('Time: '+str(int(round(ntt)))+' - '+'PictureNo: '+ str(picstate[nn])+ ' - '+ 'Beep: '+str(beepstate[nn])+' - ' + str(nn)) ########################### ## TRIAL ########################### def mainTrial(): global start, nn nn = 1 setup_pics() start = viz.tick() vizact.ontimer2(0.035,500,choose_pic) yield viztask.waitTime(25) viztask.schedule(mainTrial()) Any help or ideas are very welcome and I would be very grateful for them! |
#5
|
|||
|
|||
For now, I think I have found the problem! It explains why I had the issue with the motion tracker on or off. The cause was not the tracker itself but the way the function which was writing the output was implemented. It was messing up the sampling, slowing it down, since the output file had to be opened, data saved and written each time.
Now that I am only saving data at each timepoint and writing it only once at the very end, the issue seems to be gone. |
Tags |
motion tracking, polhemus, timing |
Thread Tools | |
Display Modes | Rate This Thread |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Motion Builder + Vizard Objects | ForeverBound | Vizard | 1 | 04-01-2015 03:49 AM |
Unusual tracker sensor setup with Vizard | Zhi | Vizard | 2 | 06-12-2012 09:52 AM |
Vizard tech tip: Using the Python Imaging Library (PIL) | Jeff | Vizard | 0 | 03-23-2009 11:13 AM |
problem in using xsens motion trackers in Vizard | bharatbhushan | Vizard | 3 | 01-26-2009 05:51 PM |
Can Vizard interact with the Arrington eye tracker? | Deltcho | Vizard | 1 | 09-18-2007 02:38 PM |