WorldViz User Forum  

Go Back   WorldViz User Forum > Vizard

Reply
 
Thread Tools Rate Thread Display Modes
  #1  
Old 03-09-2009, 12:29 PM
mberkes mberkes is offline
Member
 
Join Date: Mar 2009
Posts: 8
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!
Reply With Quote
  #2  
Old 03-09-2009, 02:05 PM
Jeff Jeff is offline
WorldViz Team Member
 
Join Date: Aug 2008
Posts: 2,471
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()
Reply With Quote
  #3  
Old 03-10-2009, 10:03 AM
mberkes mberkes is offline
Member
 
Join Date: Mar 2009
Posts: 8
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.
Reply With Quote
  #4  
Old 03-13-2009, 11:37 AM
mberkes mberkes is offline
Member
 
Join Date: Mar 2009
Posts: 8
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?
Reply With Quote
  #5  
Old 03-13-2009, 12:43 PM
Jeff Jeff is offline
WorldViz Team Member
 
Join Date: Aug 2008
Posts: 2,471
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)
Reply With Quote
  #6  
Old 03-17-2009, 01:48 PM
mberkes mberkes is offline
Member
 
Join Date: Mar 2009
Posts: 8
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()
Again, this isn't the complete code, but where I would think the issue lies.
Reply With Quote
  #7  
Old 03-17-2009, 02:16 PM
Jeff Jeff is offline
WorldViz Team Member
 
Join Date: Aug 2008
Posts: 2,471
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
Reply With Quote
  #8  
Old 03-19-2009, 10:11 AM
mberkes mberkes is offline
Member
 
Join Date: Mar 2009
Posts: 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)
It just goes back to prep, and I would think that it should just repeat what happened before, but no such luck. Still can't disable the mouseclick where I need to or write data, but looking into that. There's also a lot of incomplete code in there, or unnecessary code I need to get rid of (like the arrow over objects)
Reply With Quote
  #9  
Old 03-19-2009, 02:35 PM
Jeff Jeff is offline
WorldViz Team Member
 
Join Date: Aug 2008
Posts: 2,471
each time prep is called another vizact object is created.
Code:
def prep():
	viz.MainScene.visible(viz.OFF)
	vizact.onkeydown(' ', sceneOn,1)
The first time in prep when spacebar is pressed sceneOn gets called 1 time, if you click your mouse again and then the space bar, there are two vizact objects calling sceneOn twice, and so on. That's why more than one object is moving.

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.
Reply With Quote
  #10  
Old 03-26-2009, 10:44 AM
mberkes mberkes is offline
Member
 
Join Date: Mar 2009
Posts: 8
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
Reply With Quote
  #11  
Old 03-26-2009, 12:18 PM
Jeff Jeff is offline
WorldViz Team Member
 
Join Date: Aug 2008
Posts: 2,471
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
Reply With Quote
  #12  
Old 05-21-2009, 10:29 AM
mberkes mberkes is offline
Member
 
Join Date: Mar 2009
Posts: 8
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?')
If I could get some help here telling me what's unnecessary, what's good and that I should keep expanding on, that would be amazing. In particular, my problems include:

- 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.
Reply With Quote
  #13  
Old 05-22-2009, 03:30 PM
Gladsomebeast Gladsomebeast is offline
Member
 
Join Date: Mar 2005
Location: Isla Vizta, CA
Posts: 397
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)
Also i added a viz.pick call to get the geometry the mouse clicked on. It pases the result to a new recordTrialResponse function. I'ed make this function check if it was the correct object and write the results to a file.

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
Reply With Quote
  #14  
Old 05-27-2009, 12:44 PM
mberkes mberkes is offline
Member
 
Join Date: Mar 2009
Posts: 8
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)
SceneOn(3) calls a rotated version of the scene now. A quick question though:
I have the following code for when an object moves:
Code:
print 'object ' + str(rand_obj) + ' moved to position ' + str(rand_position)
How can I make it to show the object name instead of number? Right now it says 'object x moved to position y', but I'd like it to say the actual object name instead.
Reply With Quote
  #15  
Old 05-27-2009, 12:54 PM
Gladsomebeast Gladsomebeast is offline
Member
 
Join Date: Mar 2005
Location: Isla Vizta, CA
Posts: 397
<node3d>.getFilename
__________________
Paul Elliott
WorldViz LLC
Reply With Quote
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump

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


All times are GMT -7. The time now is 02:20 AM.


Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2024, vBulletin Solutions, Inc.
Copyright 2002-2023 WorldViz LLC