#1




Flock of Birds question (again)
If I collect with the Birds through Vizard, I get a different number of data points each time I run the program. Even if I standardize the collection rate at "(1.0/30)" because I want it to collect at 30 Hz. So I should be getting 1800 data points all of the time. The problem is that sometimes I get 1700, sometimes 1800, often times a completely random value like 1793, etc.
def onkeydown(key): if key == ' ': viz.starttimer(0,(1.0/30),viz.FOREVER) viz.starttimer(4,(1.0/30),viz.FOREVER) viz.starttimer(3,60,1) Is this a problem with the code or a processing speed problem? I'm using an old computer (and it happens to be the only one I can use) so if it's a problem with the processing speed of the computer then it could be a problem. Also the way the Birds are hooked up are that all 6 of them can be "plugged into" the other computer (the one with MotionMonitor) but on the computer with Vizard only Bird 1 can be plugged and subsequent birds are read through that. That being said, could that be contributing to a slow processing speedthe fact that everything has to be channelled through 1 Bird? I hope it's something in the code that I'm missing because that would save me a lot of hassle. So If I'm trying to standardize my data collection and collect at 30 Hz for 60 seconds and get 1800 data points everytime (or at the very least some consistent amount of data points close to 1800) is there something in the code that I'm missing? Sorry to be longwinded. Thanks for the help in advance. 
#2




If you need exactly 1800 samples, then setup a counter that will stop the timer after the specified number of samples have been recorded. Here is some sample code that should show you how it works:
Code:
import viz viz.go() MAX_SAMPLES = 1800 SAMPLE_RATE = 1.0 / 30.0 samples = 0 def onTimer(num): global samples if num == 1: #TODO: Process sample #Increment samples samples += 1 if samples < MAX_SAMPLES: viz.starttimer(1,SAMPLE_RATE) else: print 'Finished collecting samples' viz.callback(viz.TIMER_EVENT,onTimer) def onKeyDown(key): global samples if key == ' ': #Clear samples and start timer samples = 0 viz.starttimer(1,SAMPLE_RATE) viz.callback(viz.KEYDOWN_EVENT,onKeyDown) 
#3




But I also need it to be flexible in the sense that if I collect for one minute so then I get 1800 samples at a rate of 30 Hz, but if I only collect for 30 seconds then I need 900 samples still at a rate of 30 Hz. Likewise if I only collect for 42 seconds at 30 Hz I need 1260 data points. Does this allow for that? Or will it continue to collect until all 1800 samples are obtained?

#4




Set the MAX_SAMPLES variable to however many samples you need, it's up to you. If you want to collect for only 45 seconds then set it to the following:
Code:
MAX_SAMPLES = 45 * 30 
#5




I got that, but what if I need MAX SAMPLES to be variable...i.e. to be able to be changed depending on how long the participant takes to complete a task. I.e. to make a general code because I won't be able to know how long each trial will last. Trial 1 might last 30s, or 31s, or 27s, or 37s, etc. And there is no way to plan ahead. Or does it have to be fixed beforehand?

#6




You can change the value of MAX_SAMPLES anytime you want. If you want to set it in your callback then you can do the following:
Code:
def onKeyDown(key): global samples, MAX_SAMPLES if key == ' ': #Clear samples and start timer samples = 0 MAX_SAMPLES = 45 * 30 viz.starttimer(1,SAMPLE_RATE) viz.callback(viz.KEYDOWN_EVENT,onKeyDown) 
#7




So with this code would I have to alter the code between each trial? Like if I'm running 10 trials each of which lasts as long as it takes the participant to perform the desired goalaction, would I have to change the max samples in between each trial? Or is there a way to make it such that it collects at a constant collection rate for however long it takes the participant?
Also I don't understand the notation: MAX_SAMPLES = 45 * 30 What's the * do? Does that mean that it will collect for 45 seconds at a rate of 30Hz? (That's what I gathered from an earlier response of yours). But the issue I will run into with that is that I'm not working with fixed time on any trial and I have no way of knowing exactly how long it will take. (E.g. if people are running from A to B to C to D etc. everyone will take a different amount of time depending on their respective abilities. There's no way to know exactly how long it will take a person to do that beforehand.) This code seems to be predicated on knowing how long the trial will last prior to the onset. Whereas I need to be able to be flexible enough such that whenever the person is done (accomplishes the goal) the collection stops (and that could range anywhere from 5 seconds to 20 minutes). So maybe is there a way to do: MAX_SAMPLES = N * 30 (where N is however many seconds it takes on that particular trial)? 
#8




I'm confused, I thought the whole point was that you wanted to collect a preset amount of samples? If the duration of the trial is not known at runtime, then the number of samples to collect cannot be known either.
To answer your other question, the '*' is simply the multiplication operator. 
#9




Ok, you're right. Originally I wanted to collect a fixed amount of data points. But then I switched which program I was working on and the new one needs to be flexible depending on how long the trial lasts. Given that....I'm worried that if i'm unable to specify MAX_SAMPLES value then I will get disparate values across the board (i.e. two different independent trials which both happen to be for the same duration may yield different amount of data points (e.g. 2000 vs 1849)). Which is what leads me to think it might be a processing speed issue. Unless, if I'm able to specify the SAMPLE_RATE and that would hold true for all trials then if everything goes smoothly it should collect properly. (i.e. if i can get the Birds to collect at 30 Hz consistently then I don't have any other problem.) My problem was that when I set (what I thought was) the collection rate to 1.0/30: viz.starttimer(0,(1.0/30),viz.FOREVER)
viz.starttimer(4,(1.0/30),viz.FOREVER) I thought that that would tell Vizard to record data at a rate of 30 Hz. If that's not how I'm supposed to tell the Birds what rate to collect at then that's what I need to know. Namely, all I need is for the Birds to collect at a fixed rate for every trial (and the right (i.e. consistent) amount of total data points should emerge from that every timewithout a need to specify MAX_SAMPLES). 
#10




So if I define the sample rate but not max samples then it should sample at that rate regardless right? And then data collection would stop whenever the trial ended? So everytime a trial lasted 60 seconds I should get 1800 data points (without having to define max samples). And everytime a trial lasted 30 seconds I should get 900 data points (without having to define max samples)....etc etc etc.????

#11




Computers are not %100 perfect when it comes to timing, however you should be able to achieve a reliable sample rate of 30Hz. I did some tests here and I got the same number of samples every time. I don't know why you would get such varying values. Is your simulation running at 60Hz? Do you have a simple script that reproduces your results?

#12




How do I check/make sure it is running at 60Hz?
Reproduces what results? 
#13




Press the F4 key while your script is running and it will display the framerate in the upper left corner of the window.
I was referring to the results of your script that vary between 1700 to 1800 samples recorded. 
#14




When I press F4 the number keeps rapidly changing. It looks like it's fluctuating between 4555. I don't know what that means but that's what I got. Is it supposed to be stationary? If so, is there a way to fix that value?

#15




Here's the code of what I have:
import viz import math import whrandom import string viz.go(viz.PROMPT) # Get subject number from prompt box promptMesg = viz.get(viz.INITMESG) if promptMesg == "": Subnum = 999 Trial = 100 else: text = string.split(promptMesg) Subnum = int(text[0]) Trial = int(text[1]) print "Subnum =", Subnum print "Trial =", Trial PORT_FOB = 1 NUM_FOB = 6 NUM_DOTS = 900 RADIUS = .5 DATA = 2 AMPLITUDE = .05 X1 = 0 X2 = 64 MAX_SAMPLES = 60.0 * 30.0 SAMPLE_RATE = 1.0 / 30.0 samples = 0 viz.startlayer(viz.POINTS) viz.vertexcolor(1,1,1) viz.pointsize(4) for i in range(0, NUM_DOTS): x = whrandom.random()  0.5 y = whrandom.random()  0.5 z = whrandom.random()  0.5 length = math.sqrt(x*x + y*y + z*z) x = x / length * RADIUS y = y / length * RADIUS z = z / length * RADIUS viz.vertex(x, y, z) sphere = viz.endlayer() sphere.translate(0,1.8,.2) flock1 = viz.add('flockofbirds.dls') #flock2 = viz.add('flockofbirds.dls') #flock3 = viz.add('flockofbirds.dls') #flock4 = viz.add('flockofbirds.dls') flock1.command(6) #flock2.command(6) #flock3.command(6) #flock4.command(6) tracking_data = open('openloopsine_complex/headdata_'+ str(Subnum) + " " + str(Trial) + '.txt', 'a') #tracking_data2 = open('openloopsine_complex/hipdata_'+ str(Subnum) + " " + str(Trial) + '.txt', 'a') #tracking_data3 = open('openloopsine_complex/kneedata_'+ str(Subnum) + " " + str(Trial) + '.txt', 'a') #tracking_data4 = open('openloopsine_complex/ankledata_'+ str(Subnum) + " " + str(Trial) + '.txt', 'a') def mytimer(num): if num == 0: global AMPLITUDE, TOTALCYCLES, X1, X2, samples data1 = flock1.get() HEADLAT = data1[0] HEADVERT = data1[1] HEADAP = data1[2] HEADYAW = data1[3] HEADPITCH = data1[4] HEADROLL = data1[5] head_data = str(Subnum) + '\t' + str(Trial) + '\t' + str(HEADAP) + '\t' +str(HEADLAT) + '\t' +str(HEADVERT) + '\t' +str(HEADYAW) + '\t' +str(HEADPITCH) + '\t' +str(HEADROLL) +'\n' tracking_data.write(head_data) if num == 4: xmove = AMPLITUDE*math.sin(2*(math.pi/180)*X1) + AMPLITUDE*math.sin(2.5*(math.pi/180)*X1) + AMPLITUDE*math.sin(3.5*(math.pi/180)*X1) + AMPLITUDE*math.sin(1.75*(math.pi/180)*X1) + AMPLITUDE*math.sin(2*(math.pi/180)*X1) + AMPLITUDE*math.sin(2.5*(math.pi/180)*X1) + AMPLITUDE*math.sin(3*(math.pi/180)*X1) + AMPLITUDE*math.sin(2.5*(math.pi/180)*X1)+ AMPLITUDE*math.sin(2*(math.pi/180)*X1) + AMPLITUDE*math.sin(1.75*(math.pi/180)*X1) X1 = X1 + 1 # print xmove sphere.translate(0,1.8,.2+.3*xmove, viz.ABSOLUTE) if num == 3: viz.quit() if num == 1: #TODO: Process sample #Increment samples samples += 1 if samples < MAX_SAMPLES: viz.starttimer(1,SAMPLE_RATE) else: print 'Finished collecting samples' viz.callback(viz.TIMER_EVENT,mytimer) def onkeydown(key): if key == ' ': viz.starttimer(0,(1.0/30.0), viz.FOREVER) #Clear samples and start timer samples = 0 MAX_SAMPLES = 60 * 30 viz.starttimer(1,SAMPLE_RATE) viz.starttimer(4,(1.0/30.0),viz.FOREVER) viz.callback(viz.KEYDOWN_EVENT,onkeydown) In this instance I need it to collect for 60 seconds at a rate of 30 HZ recording from the birds once I press ' ' at which point everything should start. The field of points should only run for 60 seconds and I need to collect at 30Hz for a total of 1800 points. I ran this once so far and I got 1167 points of data. Additionally, I also need to be able to not have to specify the amount of time that I'm collecting for or the total number of samples I need but rather JUST the sample rate or collection rate. That way I will consistently collect at 30Hz but the amount of data points will vary given the length of the trial (but in each instance will be a multiple of 30 Hz). What am I missing/doing wrong/why isn't this working? 
#16




I cannot run your code because it is not inside the [code][/code] tags. Python code depends on indentation, and posting code without the proper tag loses the indentation.
Either way, I've included a sample script that will manually maintain a proper sample rate. Here is the code: Code:
import viz from time import clock viz.go() class SampleRate(viz.EventClass): def __init__(self,rate,func): viz.EventClass.__init__(self) self.rate = rate self.func = func self.lastSampleTime = 0.0 self.callback(viz.TIMER_EVENT,self.onTimer) def onTimer(self,num): now = clock() while (now  self.lastSampleTime) >= self.rate: self.func() self.lastSampleTime += self.rate def start(self): self.killtimer(0) self.lastSampleTime = clock() self.starttimer(0,0,viz.FOREVER) def stop(self): self.killtimer(0) def DoSample(): #Collect sample here pass #Call function 'DoSample' at rate of '1/30.0' sampler = SampleRate(1/30.0,DoSample) #Start the sampler sampler.start() 
#17




Also, your framerate should usually be 60. What is your framerate when you run the following basic script?
Code:
import viz viz.go() 
#18




Hopefully you can run it now:
Code:
import viz import math import whrandom import string viz.go(viz.PROMPT) # Get subject number from prompt box promptMesg = viz.get(viz.INITMESG) if promptMesg == "": Subnum = 999 Trial = 100 else: text = string.split(promptMesg) Subnum = int(text[0]) Trial = int(text[1]) print "Subnum =", Subnum print "Trial =", Trial PORT_FOB = 1 NUM_FOB = 6 NUM_DOTS = 900 RADIUS = .5 DATA = 2 AMPLITUDE = .05 X1 = 0 X2 = 64 MAX_SAMPLES = 60.0 * 30.0 SAMPLE_RATE = 1.0 / 30.0 samples = 0 viz.startlayer(viz.POINTS) viz.vertexcolor(1,1,1) viz.pointsize(4) for i in range(0, NUM_DOTS): x = whrandom.random()  0.5 y = whrandom.random()  0.5 z = whrandom.random()  0.5 length = math.sqrt(x*x + y*y + z*z) x = x / length * RADIUS y = y / length * RADIUS z = z / length * RADIUS viz.vertex(x, y, z) sphere = viz.endlayer() sphere.translate(0,1.8,.2) flock1 = viz.add('flockofbirds.dls') #flock2 = viz.add('flockofbirds.dls') #flock3 = viz.add('flockofbirds.dls') #flock4 = viz.add('flockofbirds.dls') flock1.command(6) #flock2.command(6) #flock3.command(6) #flock4.command(6) tracking_data = open('openloopsine_complex/headdata_'+ str(Subnum) + " " + str(Trial) + '.txt', 'a') #tracking_data2 = open('openloopsine_complex/hipdata_'+ str(Subnum) + " " + str(Trial) + '.txt', 'a') #tracking_data3 = open('openloopsine_complex/kneedata_'+ str(Subnum) + " " + str(Trial) + '.txt', 'a') #tracking_data4 = open('openloopsine_complex/ankledata_'+ str(Subnum) + " " + str(Trial) + '.txt', 'a') def mytimer(num): if num == 0: global AMPLITUDE, TOTALCYCLES, X1, X2, samples data1 = flock1.get() HEADLAT = data1[0] HEADVERT = data1[1] HEADAP = data1[2] HEADYAW = data1[3] HEADPITCH = data1[4] HEADROLL = data1[5] head_data = str(Subnum) + '\t' + str(Trial) + '\t' + str(HEADAP) + '\t' +str(HEADLAT) + '\t' +str(HEADVERT) + '\t' +str(HEADYAW) + '\t' +str(HEADPITCH) + '\t' +str(HEADROLL) +'\n' tracking_data.write(head_data) if num == 4: xmove = AMPLITUDE*math.sin(2*(math.pi/180)*X1) + AMPLITUDE*math.sin(2.5*(math.pi/180)*X1) + AMPLITUDE*math.sin(3.5*(math.pi/180)*X1) + AMPLITUDE*math.sin(1.75*(math.pi/180)*X1) + AMPLITUDE*math.sin(2*(math.pi/180)*X1) + AMPLITUDE*math.sin(2.5*(math.pi/180)*X1) + AMPLITUDE*math.sin(3*(math.pi/180)*X1) + AMPLITUDE*math.sin(2.5*(math.pi/180)*X1)+ AMPLITUDE*math.sin(2*(math.pi/180)*X1) + AMPLITUDE*math.sin(1.75*(math.pi/180)*X1) X1 = X1 + 1 # print xmove sphere.translate(0,1.8,.2+.3*xmove, viz.ABSOLUTE) if num == 3: viz.quit() if num == 1: #TODO: Process sample #Increment samples samples += 1 if samples < MAX_SAMPLES: viz.starttimer(1,SAMPLE_RATE) else: print 'Finished collecting samples' viz.callback(viz.TIMER_EVENT,mytimer) def onkeydown(key): if key == ' ': viz.starttimer(0,(1.0/30.0), viz.FOREVER) #Clear samples and start timer samples = 0 MAX_SAMPLES = 60 * 30 viz.starttimer(1,SAMPLE_RATE) viz.starttimer(4,(1.0/30.0),viz.FOREVER) viz.callback(viz.KEYDOWN_EVENT,onkeydown) 
#19




When I run that simple script my fram rate is essentially 60 (it constantly changes between 59 and 60).

#20




So now the question is why am I not getting consistent data collection results?

#21




I'm not sure, it might be a framerate issue. Did the sample script I posted above give you better results?

#22




The sample script didn't really do anything. Maybe I'm not implementing it correctly, but I can't seem to get consistent results. When I'm running a script other than just that simple script the frame rate fluctuates around 49. Anyway, is there a way that I'm supposed to put your sample script within the code I have to make it work? Because what I did didn't do anything.

#23




Did you place your code for collecting samples in the DoSample function? That function will be called at the specified rate.

#24




This is what I did:
Code:
class SampleRate(viz.EventClass): def __init__(self,rate,func): viz.EventClass.__init__(self) self.rate = rate self.func = func self.lastSampleTime = 0.0 self.callback(viz.TIMER_EVENT,self.onTimer) def onTimer(self,num): now = clock() while (now  self.lastSampleTime) >= self.rate: self.func() self.lastSampleTime += self.rate def start(self): self.killtimer(0) self.lastSampleTime = clock() self.starttimer(0,0,viz.FOREVER) def stop(self): self.killtimer(0) def DoSample(): #Collect sample here flock1 = viz.add('flockofbirds.dls') flock1.command(6) tracking_data = open('openloopsine_complex/headdata_'+ str(Subnum) + " " + str(Trial) + '.txt', 'a') def mytimer(num): if num == 0: global AMPLITUDE, TOTALCYCLES, X1, X2, samples data1 = flock1.get() HEADLAT = data1[0] HEADVERT = data1[1] HEADAP = data1[2] HEADYAW = data1[3] HEADPITCH = data1[4] HEADROLL = data1[5] head_data = str(Subnum) + '\t' + str(Trial) + '\t' + str(HEADAP) + '\t' +str(HEADLAT) + '\t' +str(HEADVERT) + '\t' +str(HEADYAW) + '\t' +str(HEADPITCH) + '\t' +str(HEADROLL) +'\n' tracking_data.write(head_data) if num == 4: xmove = AMPLITUDE*math.sin(2*(math.pi/180)*X1) + AMPLITUDE*math.sin(2.5*(math.pi/180)*X1) + AMPLITUDE*math.sin(3.5*(math.pi/180)*X1) + AMPLITUDE*math.sin(1.75*(math.pi/180)*X1) + AMPLITUDE*math.sin(2*(math.pi/180)*X1) + AMPLITUDE*math.sin(2.5*(math.pi/180)*X1) + AMPLITUDE*math.sin(3*(math.pi/180)*X1) + AMPLITUDE*math.sin(2.5*(math.pi/180)*X1)+ AMPLITUDE*math.sin(2*(math.pi/180)*X1) + AMPLITUDE*math.sin(1.75*(math.pi/180)*X1) X1 = X1 + 1 sphere.translate(0,1.8,.2+.3*xmove, viz.ABSOLUTE) if num == 3: viz.quit() pass #Call function 'DoSample' at rate of '1/30.0' sampler = SampleRate(1/30.0,DoSample) #Start the sampler sampler.start() viz.callback(viz.TIMER_EVENT,mytimer) def onkeydown(key): if key == ' ': viz.starttimer(0,(1.0/30.0), viz.FOREVER) viz.starttimer(4,(1.0/30.0),viz.FOREVER) viz.starttimer(3,60,1) viz.callback(viz.KEYDOWN_EVENT,onkeydown) I think my problem is that I don't know how to embed "mytimer" within "dosample." Because even when I try different indentations it doesn't start at all. And it keeps giving me this error message: Traceback (most recent call last): File "<string>", line 12, in ? File "openloopsine(complex)_adjusted timer3.py", line 111, in ? viz.callback(viz.TIMER_EVENT,mytimer) NameError: name 'mytimer' is not defined So I'm assuming that it's not registering it as it's own identity/function but I'm a bit confused as to how that would work. Would I have to change "dosample" to a class? And if so, would the rest stay the same? 
#25




You only need to place your timer code inside the DoSample function. Everything else should be outside the function. So it should looke something like this:
Code:
def DoSample(): global AMPLITUDE, TOTALCYCLES, X1, X2, samples data1 = flock1.get() HEADLAT = data1[0] HEADVERT = data1[1] HEADAP = data1[2] HEADYAW = data1[3] HEADPITCH = data1[4] HEADROLL = data1[5] head_data = str(Subnum) + '\t' + str(Trial) + '\t' + str(HEADAP) + '\t' +str(HEADLAT) + '\t' +str(HEADVERT) + '\t' +str(HEADYAW) + '\t' +str(HEADPITCH) + '\t' +str(HEADROLL) +'\n' tracking_data.write(head_data) 
Thread Tools  
Display Modes  Rate This Thread 


Similar Threads  
Thread  Thread Starter  Forum  Replies  Last Post 
Flock of Birds recognized, but no data sent  sjroorda  Vizard  9  03012016 08:48 PM 
Using vrpn_server with Flock of birds  sylvain  Precision Position Tracker (PPT)  3  11302007 09:45 AM 
Flock of Birds  Elittdogg  Vizard  9  10022007 01:53 PM 
Flock of birds extended range problem  theuberk  Vizard  4  07302007 09:31 AM 
Adding more than one Flock of Birds  asimbh  Vizard  3  12152006 01:48 AM 