View Single Post
  #2  
Old 12-16-2013, 05:25 AM
chris2307 chris2307 is offline
Member
 
Join Date: Nov 2013
Posts: 36
As promised, the class code for followAvatarTask:

Code:
import viz
import vizshape
import vizact
import vizmat 
import sys
import os

sys.path.append(os.getcwd() + '/functions')#Standard imports above here!

from sensor import Sensor
from messages import Messages
import routeList

class FollowAvatar:
	
	#
	# Training phase constructor. Takes in the current main screen as a parameter which is
	# needed to set up a messages object, in order to display messages to the screen from
	# here. No other set up parameters are taken here because this is called once at the
	# start of the program. setUpExperiment() should be used to initialise a new experiment.
	# Constructor takes care of the default settings which will never change throughtout the
	# various training phases to be completed in the experiment.
	#
	def __init__(self, screenToUse = False):
		
		self.message = Messages(screenToUse)
		
		self.avatar = viz.addAvatar('vcc_male.cfg', pos = [0,0,0])
		self.avatar.state(1)
		self.avatar.disable(viz.DYNAMICS)
		self.avatar.setScale(1,1,1)
		self.avatar.visible(False)
	
		self.shadowTex = viz.addTexture('shadow.png')
		self.shadow = vizshape.addQuad(parent = self.avatar, axis = vizshape.AXIS_Y)
		self.shadow.texture(self.shadowTex)
		self.shadow.zoffset()
	
		self.head = self.avatar.getBone('Bip01 Head')
	
		viz.playSound('footsteps.wav',viz.SOUND_PRELOAD)
		viz.playSound('../sounds/ARETHERE.wav',viz.SOUND_PRELOAD)
		self.avatarSpeak = vizact.speak('../sounds/ARETHERE.wav')

		self.avatar.visible(False)
		
	#
	# Used to setup a new training phase. Takes in the route used for this phase and the failure 
	# coordinates. Failure coordinates are used to detect when a user strays from tha path during 
	# the training phase. The route is used to set up a list of sensors which will be used to detect
	# AND control the avatar movement along the route. Avatar and user position are also initialised here
	#
	def setUpExperiment(self, route, failureCoords):
		
		self.distanceFromAvatar = 0
		self.avatarWalking = True
		self.speakingFlag = True
		self.experimentEnded = False
		self.firstRun = False
		
		self.failureCoordinates = [ Sensor(coord, size=2) for coord in failureCoords ]	
		
		self.avatarStartLocation = [ route[0][0], route[0][1], route[0][2]+5 ]
		self.avatarLookAtLocation = route[1]
		self.goalLocation = route[-1]
		self.startLocation = route[0]
		
		self.sensors = [ Sensor(loc) for loc in route ]
		del self.sensors[0] # We only needed the first coordinate to set the above positions
		
		print "About reset the Avatar Euler"
		self.avatar.setPosition(self.avatarStartLocation)
		self.avatar.lookAt([0,0,0])

		viz.collision(viz.OFF)
		viz.MainView.setPosition(self.startLocation)	
		viz.MainView.reset(viz.HEAD_ORI | viz.BODY_ORI)
		viz.collision(viz.ON)

		self.actions = [
		vizact.method.playsound('footsteps.wav',viz.LOOP),
		vizact.walkTo(self.sensors[0].getPosition(), 1, turnSpeed = 25.0),
		vizact.method.playsound('footsteps.wav',viz.STOP),
		vizact.turn(self.sensors[0].getPosition()),
		]
		self.avatar.visible(True)
		
		return 0

	#
	# The main run function for an experiment instance. Calls the main internal functions used to
	# control the experiment. 
	#
	def runExperiment(self):
		
		if(self.firstRun == False):
			self._runFirst()
			
		self._updatePositionInformation()
		self._checkDistanceFromAvatar()
		self._checkSensors()
		self._checkForStray()
		
	#
	# This function is run once at the start of an experiment. It kick starts the avatar's actions.
	#
	def _runFirst(self):
		self.avatar.runAction(vizact.sequence(self.actions))
		self.firstRun = True
			
	#
	# Updates positional data which is used throughout this class. Also calculated the distance
	# between the user and the avatar.
	#
	def _updatePositionInformation(self):
		self.avatarPos = self.head.getPosition(viz.ABS_GLOBAL)
		self.position = viz.MainView.getPosition()
		self.distanceFromAvatar = vizmat.Distance(self.avatarPos,self.position)
	
	#
	# Checks to see if we are further than 15 metres away from the avatar. If so then the avatar
	# is halted in order to wait for the user to catch up. If not then the avatar continues on
	#
	def _checkDistanceFromAvatar(self):
		if(self.distanceFromAvatar > 15):
			self.avatar.state(1)
			self.avatarWalking = False
			self.avatar.endAction(pool=0)
		elif(self.distanceFromAvatar < 15 and self.avatarWalking == False):
			self.avatar.state(2)
			self.avatarWalking = True
			self.avatar.runAction(vizact.sequence(self.actions))
			
	#
	# Checks the sensors for avatar and player collision. Uses these collisions to determine
	# when the avatar should turn and continue to the next route location as well as sensing
	# when the player has arrived at the final destination of the route which triggers the
	# end of the training phase. 
	#
	def _checkSensors(self):
		if(len(self.sensors) > 1 ):
			if(self.sensors[0].onEnter(self.avatarPos)):				
				try:
					self.nextLocation = self.sensors[1].getPosition()				
				except IndexError:
					print "Index Error"
					
				self.actions = [
				vizact.method.playsound('footsteps.wav',viz.LOOP),
				vizact.walkTo(self.nextLocation, 1, turnSpeed = 200.0),
				vizact.method.playsound('footsteps.wav',viz.STOP),
				vizact.turn(self.goalLocation),
				]
				self.avatar.runAction(vizact.sequence(self.actions))
				del self.sensors[0]
				
		elif(len(self.sensors) == 1 and self.sensors[0].onEnter(self.avatarPos)):
			self.avatar.state(1)
			
			if(self.sensors[0].onEnter(self.position)):
				self.firstRun = False
				self.avatar.visible(False)
				self.experimentEnded = True
			
	def _checkForStray(self):
		pass
		
	def returnAvatarEuler(self):
		return self.avatar.getEuler()
		
	def setAvatarEuler(self):
		self.avatar.lookAt([0,0,0,])
Reply With Quote