#1
|
|||
|
|||
Need help with a project
So I'm VERY new to programming and WorldViz, and only have the basics down. I am, unfortunately, on a tight schedule though and need to create a simple project before April.
The project simply requires a table, 5 objects, and 9 locations. The 5 objects are randomly placed at one of the 9 locations each, and then after 3 seconds of viewing, the scene clears for 10 seconds. The scene should then reappear, with one random object moved to a location close to it's original. The viewer makes a judgement based on which object moved, and then the next 'trial' starts. I can do the timing functions (I think) and have the 3dmax models for the objects, but am unsure of how to set up the random assignments as well as 'clearing' the scene, and how to record the response. Any help with those functions is appreciated, thank you! |
#2
|
|||
|
|||
This will turn the scene's visibility on and off based on a timer and reset the objects randomly in one of nine specified positions when the scene comes back
check out the Vizard docs to learn how to write to files so you can record user responses. Code:
import viz viz.go() viz.MainView.move(0,0,-10) #keep nine positions in an array pos = [[-4,0,0],[-3,0,0],[-2,0,0],[-1,0,0],[0,0,0],[1,0,0],[2,0,0],[3,0,0],[4,0,0]] box = viz.add('box.wrl') ball = viz.add('ball.wrl') whiteball = viz.add('white_ball.wrl') import random def sceneOn(): #set objects to 3 different random positions rand_numbers = [0,1,2,3,4,5,6,7,8] random.shuffle(rand_numbers) box.setPosition(pos[rand_numbers[0]]) ball.setPosition(pos[rand_numbers[1]]) whiteball.setPosition(pos[rand_numbers[2]]) viz.MainScene.visible(viz.ON) vizact.ontimer2(2,0,sceneOff) def sceneOff(): viz.MainScene.visible(viz.OFF) vizact.ontimer2(2,0,sceneOn) sceneOn() |
#3
|
|||
|
|||
Hey thanks! This provides a good start. I've added in another function which brings up the object array and let's the viewer make a choice as to which object switched positions before starting again with sceneOn, but how do you make it to only move one object randomly? As it is, all the objects move when the scene turns on again.
|
#4
|
|||
|
|||
Still can't figure out how to just move one object from the initial randomised scene to the returned scene. Actually, can't figure out a lot of things haha. I have a mouseclick selecting an object and should (hopefully) record the data of which object was clicked (which should also match with the object that moved, though can't figure that out, obviously), but I can't disable the mouseclicking before I need it. Any help?
|
#5
|
|||
|
|||
To move one of the objects to a new place, you need to randomly select one of your objects and then randomly select one of the available positions to move it to.
Code:
import viz viz.go() viz.MainView.move(0,0,-10) #keep nine positions in an array pos = [[-4,0,0],[-3,0,0],[-2,0,0],[-1,0,0],[0,0,0],[1,0,0],[2,0,0],[3,0,0],[4,0,0]] #add objects to an array box = viz.add('box.wrl') ball = viz.add('ball.wrl') whiteball = viz.add('white_ball.wrl') objects = [box,ball,whiteball] import random rand_positions = [] def sceneOn(num): global rand_positions positions = [0,1,2,3,4,5,6,7,8] if num == 1: #set objects to 3 different random positions rand_positions = random.sample(positions,3) objects[0].setPosition(pos[rand_positions[0]]) objects[1].setPosition(pos[rand_positions[1]]) objects[2].setPosition(pos[rand_positions[2]]) vizact.ontimer2(2,0,sceneOff) elif num == 2: #choose one object to move randomly and leave others in there places #first get available positions diff_list = [item for item in positions if not item in rand_positions] rand_position = random.sample(diff_list,1)[0] #choose one of the objects rand_obj = random.randint(0,2) #set the randomly chosen object to the new random position objects[rand_obj].setPosition(pos[rand_position]) print 'object ' + str(rand_obj) + ' moved to position ' + str(rand_position) viz.MainScene.visible(viz.ON) def sceneOff(): viz.MainScene.visible(viz.OFF) vizact.ontimer2(2,0,sceneOn,2) sceneOn(1) |
#6
|
|||
|
|||
Thanks, that works great. I have an issue though where it runs through once perfectly, but then on any time after that, more than one object moves. I'll post the code, and would you be able to see where the issue lies? I added in a function ('prep') that keeps the screen blank and waits for a space press before going to 'sceneOn', and a mouseclick goes to 'prep'. Thanks
Code:
import random objects = [bottle, candle, clamp, lock, wood] def prep(): viz.MainScene.visible(viz.OFF) vizact.onkeydown(' ', sceneOn,1) rand_positions = [] def sceneOn(num): global rand_positions positions = [0,1,2,3,4,5,6,7,8] if num == 1: #set objects to 5 different random positions rand_positions = random.sample(positions,5) objects[0].setPosition(pos[rand_positions[0]]) objects[1].setPosition(pos[rand_positions[1]]) objects[2].setPosition(pos[rand_positions[2]]) objects[3].setPosition(pos[rand_positions[3]]) objects[4].setPosition(pos[rand_positions[4]]) vizact.ontimer2(3,0,sceneOff) elif num == 2: #choose one object to move randomly and leave others in their places #first get available positions diff_list = [item for item in positions if not item in rand_positions] rand_position = random.sample(diff_list,1)[0] #choose one of the objects rand_obj = random.randint(0,4) #set the randomly chosen object to the new random position objects[rand_obj].setPosition(pos[rand_position]) print 'object ' + str(rand_obj) + ' moved to position ' + str(rand_position) viz.MainScene.visible(viz.ON) def sceneOff(): viz.MainScene.visible(viz.OFF) vizact.ontimer2(10,0,sceneOn,2) prep() |
#7
|
|||
|
|||
That code just goes through one trial. To see why following trials are not working I'd have to see the code you added for that
|
#8
|
|||
|
|||
I have this code for the mouseclick:
Code:
def mouseclick(button): if button == viz.MOUSEBUTTON_LEFT: object = viz.pick() if object.valid(): data = 'Selected' + items position = object.get(viz.POSITION) position[1] += 1.2 arrow.translate(position) arrow.visible(viz.ON) #record response response_data.write(data) #flush internal buffer response_data.flush() viz.callback(viz.MOUSEDOWN_EVENT,mouseclick) #go to blank scene vizact.whilemousedown(viz.MOUSEBUTTON_LEFT,prep) #disable mouse navigation viz.mouse(viz.OFF) |
#9
|
|||
|
|||
each time prep is called another vizact object is created.
Code:
def prep(): viz.MainScene.visible(viz.OFF) vizact.onkeydown(' ', sceneOn,1) Probably the best thing to do is to re-arrange your code using viztask. Waiting for mouseclicks, keypresses, and timers can all be done within the task function. Check out the documentation on viztask and let me know if you have any questions. |
#10
|
|||
|
|||
Didn't have time to work on this recently, but just a quick question about viztask. Do I need to rewrite the previous functions into a task, or just include them into my task with yield statements? Can I write the whole project under one task? Thanks
|
#11
|
|||
|
|||
You just need one task function for this and can call sceneOn from there. You could take out vizact.ontimer from sceneOn and use viztask.waittime instead in the task function
|
#12
|
|||
|
|||
So after a two month absense from working on this, I'm back at it, and realised I don't know what I'm doing! My code seems to be a mess with extraneous, or at least poorly written, code and the experiment doesn't work how I'd like. Here's my code:
Code:
import viz import viztask import random viz.go() viz.MainView.move(0,1.4,-13) #add pathway to bring objects from viz.res.addPath('C:\Users\Matyi\Desktop\2009 Experiments') #field of view at 45 degrees viz.fov(45) #keep nine positions in an array pos = [[-2.667, 0.0, -1.524],[1.51892, 0.0, -2.53492],[-0.82042, 0.0, 2.89052],[2.286, 0.0, -0.04572],[-1.17856, 0.0, -1.30302],[1.8415, 0.0, 2.06248],[-0.94996, 0.0, -2.85242],[-3.15722, 0.0, 0.82042],[-0.20828, 0.0, 0.84328]] #add table, keep it in position, scale table = viz.add('bluetable.wrl') table.setPosition(0,0,0) table.setScale(.5,.5,.5) table.disable(viz.PICKING) #add objects and scale bottle = viz.add('bottle.wrl') bottle.setScale(.5,.5,.5) bottle.center(0,0,0) candle = viz.add('candle.wrl') candle.setScale(.5,.5,.5) candle.center(0,0,0) clamp = viz.add('clamp.wrl') clamp.setScale(.5,.5,.5) clamp.center(0,.5,0) clamp.rotate(0,150,90) lock = viz.add('lock.wrl') lock.setScale(.5,.5,.5) lock.center(0,0,.0) wood = viz.add('wood.wrl') wood.setScale(.5,.5,.5) wood.center(0,0,0) #make a list with the objects in it objects = [bottle, candle, clamp, lock, wood] #disable mouse navigation viz.mouse(viz.OFF) def prep(): viz.MainScene.visible(viz.OFF) #vizact.onkeydown(' ', sceneOn,1) rand_positions = [] def sceneOn(num): global rand_positions positions = [0,1,2,3,4,5,6,7,8] if num == 1: #set objects to 5 different random positions rand_positions = random.sample(positions,5) objects[0].setPosition(pos[rand_positions[0]]) objects[1].setPosition(pos[rand_positions[1]]) objects[2].setPosition(pos[rand_positions[2]]) objects[3].setPosition(pos[rand_positions[3]]) objects[4].setPosition(pos[rand_positions[4]]) #vizact.ontimer2(3,0,sceneOff) elif num == 2: #choose one object to move randomly and leave others in their places #first get available positions diff_list = [item for item in positions if not item in rand_positions] rand_position = random.sample(diff_list,1)[0] #choose one of the objects rand_obj = random.randint(0,4) #set the randomly chosen object to the new random position objects[rand_obj].setPosition(pos[rand_position]) print 'object ' + str(rand_obj) + ' moved to position ' + str(rand_position) viz.MainScene.visible(viz.ON) def sceneOff(): viz.MainScene.visible(viz.OFF) #vizact.ontimer2(10,0,sceneOn,2) #define the file to save subject responses response_data = open('exp_data','a') #use this; viztask is better def experiment(): while True: viz.MainScene.visible(viz.OFF) yield viztask.waitKeyDown(' ') yield sceneOn(1) viztask.waitTime(3) yield sceneOff() viztask.waitTime(10) yield sceneOn(2) d = viz.Data() yield viztask.waitMouseDown(viz.MOUSEBUTTON_LEFT, d) print str(objects), 'was selected at', d.time viztask.schedule( experiment() ) #viz.callback(viz.MOUSEDOWN_EVENT,mouseclick) #go to blank scene #vizact.whilemousedown(viz.MOUSEBUTTON_LEFT,prep) #input subject number at start subject = viz.input('What is the participant number?') - subject number can be blank and it still accepts this, I need that to change - data file doesn't exist; do I create a spreadsheet and it stores there, or automatically makes one with the correct code? - pressing space now just moves an object with no timing at all or scene change - clicking anywhere at all makes the scene blank and gives me lines saying [vizard object yada yada yada moved positions] with nothing relevant, or the object name Thanks for your help, my complete lack of understanding with vizard is getting somewhat discouraging. |
#13
|
|||
|
|||
Don't give up hope yet. Clearly you have some work ahead of you, but listing what your missing is a start.
First, lets fix your stimulus presentation. Your syntax in the experiment task is incorrect. Place "yield" statments in front of 'viztask.wait' functions. Do not put a yield in front of plain functions like 'sceneOn.' Code:
def experiment(): while True: viz.MainScene.visible(viz.OFF) yield viztask.waitKeyDown(' ') sceneOn(1) yield viztask.waitTime(3) sceneOff() viztask.waitTime(10) sceneOn(2) d = viz.Data() yield viztask.waitMouseDown(viz.MOUSEBUTTON_LEFT, d) pickedObject = viz.pick() recordTrialResponse(pickedObject, d.time) Vizard's installation directory has an example directory called file_io that has filewriting examples. If you put a tab between each of your data points and a new line between reach response the data file should import into Matlab or Excel nicely.
__________________
Paul Elliott WorldViz LLC |
#14
|
|||
|
|||
Hey thanks for the help. Haven't quite got the data writing down yet, but my code now looks like this:
Code:
def Experiment(): while True: viz.MainScene.visible(viz.OFF) for n in range(4): for i in range(5): yield viztask.waitKeyDown(' ') sceneOn(1) yield viztask.waitTime(3) viz.MainScene.visible(viz.OFF) yield viztask.waitTime(3) sceneOn(2) yield viztask.waitMouseDown(viz.MOUSEBUTTON_LEFT, d) viz.MainScene.visible(viz.OFF) for j in range(5): yield viztask.waitKeyDown(' ') sceneOn(1) group.rotate(0,1,0,0, viz.ABS_GLOBAL) yield viztask.waitTime(3) viz.MainScene.visible(viz.OFF) yield viztask.waitTime(3) sceneOn(3) yield viztask.waitMouseDown(viz.MOUSEBUTTON_LEFT, d) viz.MainScene.visible(viz.OFF) I have the following code for when an object moves: Code:
print 'object ' + str(rand_obj) + ' moved to position ' + str(rand_position) |
#15
|
|||
|
|||
<node3d>.getFilename
__________________
Paul Elliott WorldViz LLC |
|
|
Similar Threads | ||||
Thread | Thread Starter | Forum | Replies | Last Post |
Sharing Files on SourceForge | farshizzo | Vizard | 1 | 09-03-2012 12:18 PM |
Project .avi or .mpeg file | pattie | Vizard | 2 | 02-06-2007 09:09 AM |