Package VisionEgg :: Package PyroApps :: Module MouseTargetServer
[frames] | no frames]

Source Code for Module VisionEgg.PyroApps.MouseTargetServer

  1  #!/usr/bin/env python 
  2  # 
  3  # The Vision Egg: MouseTargetServer 
  4  # 
  5  # Copyright (C) 2001-2003 Andrew Straw. 
  6  # Author: Andrew Straw <astraw@users.sourceforge.net> 
  7  # URL: <http://www.visionegg.org/> 
  8  # 
  9  # Distributed under the terms of the GNU Lesser General Public License 
 10  # (LGPL). See LICENSE.TXT that came with this file. 
 11  # 
 12  # $Id$ 
 13   
 14  """Handle mouse-controlled small targets (server-side)""" 
 15   
 16  import VisionEgg, string 
 17  import VisionEgg.ParameterTypes as ve_types 
 18   
 19  __version__ = VisionEgg.release_name 
 20  __cvs__ = string.split('$Revision$')[1] 
 21  __date__ = string.join(string.split('$Date$')[1:3], ' ') 
 22  __author__ = 'Andrew Straw <astraw@users.sourceforge.net>' 
 23   
 24  import sys, os, math 
 25  import VisionEgg.Core 
 26  import VisionEgg.FlowControl 
 27  import VisionEgg.MoreStimuli 
 28  import VisionEgg.PyroHelpers 
 29  import Pyro.core 
 30  import pygame, pygame.locals 
 31   
 32  from VisionEgg.PyroApps.MouseTargetGUI import MouseTargetMetaParameters 
 33   
 34  # Variables to store the mouse position 
 35  mouse_position = (320.0, 240.0) 
 36  last_mouse_position = (0.0,0.0) 
 37   
 38  # target size global variables 
 39  target_w = 50.0 
 40  target_h = 10.0 
 41   
 42  # key state global variables 
 43  up = 0 
 44  down = 0 
 45  left = 0 
 46  right = 0 
 47   
48 -def keydown(event):
49 global up, down, left, right 50 if event.key == pygame.locals.K_UP: 51 up = 1 52 elif event.key == pygame.locals.K_DOWN: 53 down = 1 54 elif event.key == pygame.locals.K_RIGHT: 55 right = 1 56 elif event.key == pygame.locals.K_LEFT: 57 left = 1
58
59 -def keyup(event):
60 global up, down, left, right 61 if event.key == pygame.locals.K_UP: 62 up = 0 63 elif event.key == pygame.locals.K_DOWN: 64 down = 0 65 elif event.key == pygame.locals.K_RIGHT: 66 right = 0 67 elif event.key == pygame.locals.K_LEFT: 68 left = 0
69 70 handle_event_callbacks = [(pygame.locals.KEYDOWN, keydown), 71 (pygame.locals.KEYUP, keyup)] 72
73 -class MouseTargetExperimentMetaController( Pyro.core.ObjBase ):
74 - def __init__(self,screen,presentation,stimuli):
75 global screen_global 76 screen_global = screen 77 # get stimulus 78 assert( stimuli[0][0] == '2d_overlay') 79 target = stimuli[0][1] 80 81 Pyro.core.ObjBase.__init__(self) 82 self.meta_params = MouseTargetMetaParameters() 83 if not isinstance(screen,VisionEgg.Core.Screen): 84 raise ValueError("Expecting instance of VisionEgg.Core.Screen") 85 if not isinstance(presentation,VisionEgg.FlowControl.Presentation): 86 raise ValueError("Expecting instance of VisionEgg.FlowControl.Presentation") 87 if not isinstance(target,VisionEgg.MoreStimuli.Target2D): 88 raise ValueError("Expecting instance of VisionEgg.MoreStimuli.Target2D") 89 90 self.screen = screen 91 self.p = presentation 92 self.stim = target 93 94 self.p.add_controller(target,'position', TargetPositionController()) 95 self.p.add_controller(target,'size', VisionEgg.FlowControl.FunctionController(during_go_func=get_target_size, 96 between_go_func=get_target_size) ) 97 self.p.add_controller(target,'orientation', TargetOrientationController() ) 98 self.mouse_position_controller = MousePositionController() 99 self.p.add_controller(None,None,self.mouse_position_controller) 100 self.orig_event_handlers = self.p.parameters.handle_event_callbacks 101 self.p.parameters.handle_event_callbacks = handle_event_callbacks 102 103 self.update() # set stimulus parameters to initial defaults
104
105 - def __del__(self):
106 self.p.parameters.handle_event_callbacks = self.orig_event_handlers 107 self.p.remove_controller(None,None,self.mouse_position_controller) 108 self.p.remove_controller(self.stim,'position') 109 self.p.remove_controller(self.stim,'size') 110 self.p.remove_controller(self.stim,'orientation')
111
112 - def get_parameters(self):
113 return self.meta_params
114
115 - def set_parameters(self, new_parameters):
116 if isinstance(new_parameters, MouseTargetMetaParameters): 117 self.meta_params = new_parameters 118 else: 119 raise ValueError("Argument to set_parameters must be instance of MouseTargetMetaParameters") 120 self.update()
121
122 - def update(self):
123 stim_params = self.stim.parameters # shorthand 124 meta_params = self.meta_params # shorthand 125 126 # colors 127 stim_params.color = meta_params.color 128 self.screen.parameters.bgcolor = meta_params.bgcolor
129
130 - def go(self):
131 pass
132 #self.p.parameters.enter_go_loop = 1 133
134 - def quit_server(self):
135 self.p.parameters.quit = 1
136
137 -def get_meta_controller_class():
138 return MouseTargetExperimentMetaController
139
140 -def make_stimuli():
141 stimulus = VisionEgg.MoreStimuli.Target2D(anchor='center') 142 return [('2d_overlay',stimulus)]
143
144 -def get_meta_controller_stimkey():
145 return "mouse_target_server"
146 147 ######################## 148 # Define controllers # 149 ######################## 150
151 -class MousePositionController( VisionEgg.FlowControl.Controller ):
152 - def __init__(self):
153 global mouse_position 154 VisionEgg.FlowControl.Controller.__init__(self, 155 return_type=ve_types.get_type(None), 156 eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME) 157 self.between_go_eval = self.during_go_eval
158
159 - def during_go_eval(self,t=None):
160 # Convert pygame mouse position to OpenGL position 161 global mouse_position, last_mouse_position, screen_global 162 just_current_pos = mouse_position 163 (x,y) = pygame.mouse.get_pos() 164 y = screen_global.size[1]-y 165 mouse_position = (x,y) 166 if just_current_pos != mouse_position: 167 last_mouse_position = just_current_pos 168 return None
169
170 -class TargetPositionController( VisionEgg.FlowControl.Controller ):
171 - def __init__(self):
172 global mouse_position 173 VisionEgg.FlowControl.Controller.__init__(self, 174 return_type=ve_types.Sequence2(ve_types.Real), 175 eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME) 176 self.between_go_eval = self.during_go_eval
177
178 - def during_go_eval(self,t=None):
179 global mouse_position 180 return mouse_position
181
182 -def cross_product(b,c):
183 """Cross product between vectors, represented as tuples of length 3.""" 184 det_i = b[1]*c[2] - b[2]*c[1] 185 det_j = b[0]*c[2] - b[2]*c[0] 186 det_k = b[0]*c[1] - b[1]*c[0] 187 return (det_i,-det_j,det_k)
188
189 -def mag(b):
190 """Magnitude of a vector.""" 191 return b[0]**2.0 + b[1]**2.0 + b[2]**2.0
192
193 -class TargetOrientationController( VisionEgg.FlowControl.Controller ):
194 - def __init__(self):
195 VisionEgg.FlowControl.Controller.__init__(self, 196 return_type=ve_types.Real, 197 eval_frequency=VisionEgg.FlowControl.Controller.EVERY_FRAME) 198 self.c = (0.0,0.0,1.0) 199 self.last_orientation = 0.0 200 self.between_go_eval = self.during_go_eval
201
202 - def during_go_eval(self):
203 global mouse_position, last_mouse_position 204 205 b = (float(last_mouse_position[0]-mouse_position[0]), 206 float(last_mouse_position[1]-mouse_position[1]), 207 0.0) 208 209 if mag(b) > 1.0: # Must mouse 1 pixel before changing orientation (supposed to reject noise) 210 # find cross product b x c. assume b and c are 3-vecs, b has 211 # 3rd component 0. 212 orientation_vector = cross_product(b,self.c) 213 self.last_orientation = math.atan2(orientation_vector[1],orientation_vector[0])/math.pi*180.0 214 return self.last_orientation
215
216 -def get_target_size(t=None):
217 global target_w, target_h 218 global up, down, left, right 219 220 amount = 0.02 221 222 if up: 223 target_w = target_w+(amount*target_w) 224 elif down: 225 target_w = target_w-(amount*target_w) 226 elif right: 227 target_h = target_h+(amount*target_h) 228 elif left: 229 target_h = target_h-(amount*target_h) 230 target_w = max(target_w,0.0) 231 target_h = max(target_h,0.0) 232 233 return (target_w, target_h)
234 235 # Don't do anything unless this script is being run 236 if __name__ == '__main__': 237 238 pyro_server = VisionEgg.PyroHelpers.PyroServer() 239 240 screen = VisionEgg.Core.Screen.create_default() 241 242 # get Vision Egg stimulus ready to go 243 stimuli = make_stimuli() 244 stimulus = stimuli[0][1] 245 viewport = VisionEgg.Core.Viewport(screen=screen,stimuli=[stimulus]) 246 p = VisionEgg.FlowControl.Presentation(viewports=[viewport]) 247 248 # now hand over control of grating and mask to FlatGratingExperimentMetaController 249 meta_controller = MouseTargetExperimentMetaController(screen,p,stimuli) 250 pyro_server.connect(meta_controller,get_meta_controller_stimkey()) 251 252 # get listener controller and register it 253 p.add_controller(None,None, pyro_server.create_listener_controller()) 254 255 # enter endless loop 256 p.run_forever() 257