-
Notifications
You must be signed in to change notification settings - Fork 0
/
Oculus_inbuilt_Vizard.py
353 lines (257 loc) · 9.58 KB
/
Oculus_inbuilt_Vizard.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
'''
April 2016
Aneesh Rangnekar, Anna Starynska, Arun K., Mahshad M., Sanketh Moudgalya, Rakshit Kothari
Gabriel Diaz
Carlson Center for Imaging Science
Rochester Institute of Technology
'''
import viz
viz.res.addPath('resources')
sys.path.append('utils')
import oculus
from configobj import ConfigObj
from configobj import flatten_errors
from validate import Validator
import vizconnect
import platform
import os.path
import vizact
import vizshape
class Configuration():
def __init__(self, expCfgName = ""):
"""
Opens and interprets both the system config (as defined by the <platform>.cfg file) and the experiment config
(as defined by the file in expCfgName). Both configurations MUST conform the specs given in sysCfgSpec.ini and
expCfgSpec.ini respectively. It also initializes the system as specified in the sysCfg.
"""
self.__createSysCfg()
for pathName in self.sysCfg['set_path']:
viz.res.addPath(pathName)
self.vizconnect = vizconnect.go( 'vizConnect/' + self.sysCfg['vizconfigFileName'])
self.__postVizConnectSetup()
def __postVizConnectSetup(self):
'''
This is where one can run any system-specific code that vizconnect can't handle
'''
dispDict = vizconnect.getRawDisplayDict()
self.clientWindow = dispDict['exp_display']
self.riftWindow = dispDict['rift_display']
if( self.sysCfg['use_wiimote']):
# Create wiimote holder
self.wiimote = 0
self.__connectWiiMote()
if self.sysCfg['use_phasespace']:
from mocapInterface import phasespaceInterface
self.mocap = phasespaceInterface(self.sysCfg);
self.linkObjectsUsingMocap()
self.use_phasespace = True
else:
self.use_phasespace = False
if self.sysCfg['use_hmd'] and self.sysCfg['hmd']['type'] == 'DK2':
#self.__setupOculusMon()
self.hmd = oculus.Rift()
self.setupExperimenterDisplay()
self.placeEyeNodes()
viz.setOption("viz.glfinish", 1)
viz.setOption("viz.dwm_composition", 0)
def __createSysCfg(self):
"""
Set up the system config section (sysCfg)
"""
# Get machine name
#sysCfgName = platform.node()+".cfg"
sysCfgName = "sysConfig"+".cfg"
if not(os.path.isfile(sysCfgName)):
sysCfgName = "defaultSys.cfg"
print "Loading system config file: " + sysCfgName
# Parse system config file
sysCfg = ConfigObj(sysCfgName, configspec='sysCfgSpec.ini', raise_errors = True)
validator = Validator()
sysCfgOK = sysCfg.validate(validator)
if sysCfgOK == True:
print "System config file parsed correctly"
else:
print 'System config file validation failed!'
res = sysCfg.validate(validator, preserve_errors=True)
for entry in flatten_errors(sysCfg, res):
# each entry is a tuple
section_list, key, error = entry
if key is not None:
section_list.append(key)
else:
section_list.append('[missing section]')
section_string = ', '.join(section_list)
if error == False:
error = 'Missing value or section.'
print section_string, ' = ', error
sys.exit(1)
self.sysCfg = sysCfg
def setupExperimenterDisplay(self):
viz.window.setFullscreenMonitor(self.sysCfg['experimenterDisplay'])
viz.window.setFullscreen(1)
def __connectWiiMote(self):
wii = viz.add('wiimote.dle')#Add wiimote extension
# Replace old wiimote
if( self.wiimote ):
print 'Wiimote removed.'
self.wiimote.remove()
self.wiimote = wii.addWiimote()# Connect to first available wiimote
vizact.onexit(self.wiimote.remove) # Make sure it is disconnected on quit
self.wiimote.led = wii.LED_1 | wii.LED_4 #Turn on leds to show connection
def linkObjectsUsingMocap(self):
self.headTracker = vizconnect.getRawTracker('head_tracker')
self.mocap.start_thread()
trackerDict = vizconnect.getTrackerDict()
if( 'rift_tracker' in trackerDict.keys() ):
self.UpdateViewAct = vizact.onupdate(viz.PRIORITY_LINKS, self.updateHeadTracker)
else:
print '*** Experiment:linkObjectsUsingMocap: Rift not enabled as a tracker'
return
def updateHeadTracker(self):
"""
A specailized per-frame function
That updates an empty viznode with:
- position info from mocap
- orientation from rift
"""
riftOriTracker = vizconnect.getTracker('rift_tracker').getNode3d()
ori_xyz = riftOriTracker.getEuler()
self.headTracker.setEuler( ori_xyz )
headRigidTracker = self.mocap.get_rigidTracker('hmd')
self.headTracker.setPosition( headRigidTracker.get_position() )
def resetHeadOrientation(self):
vizconnect.getTracker('rift_tracker').resetHeading()
def placeEyeNodes(self):
'''
For convenience, this places nodes at the cyclopean eye, left eye, and right eye.
When linkjing things to the eyes, link them to the cyclopean, left, or right eye nodes
e.g. viz.link(config.cycEyeNode,vizshape.addSphere(radius=0.05))
'''
IOD = self.hmd.getIPD()
print("IOD")
print(IOD)
self.cycEyeNode = vizshape.addSphere(0.015, color = viz.GREEN)
self.cycEyeNode.setParent(self.headTracker)
self.cycEyeNode.disable(viz.RENDERING)
self.leftEyeNode = vizshape.addSphere(0.005, color = viz.BLUE)
self.leftEyeNode.disable(viz.RENDERING)
self.leftEyeNode.setParent(self.headTracker)
self.leftEyeNode.setPosition(-IOD/2, 0, 0.0,viz.ABS_PARENT)
self.rightEyeNode = vizshape.addSphere(0.005, color = viz.RED)
self.rightEyeNode.disable(viz.RENDERING)
self.rightEyeNode.setParent(self.headTracker)
self.rightEyeNode.setPosition(IOD/2, 0, 0.0,viz.ABS_PARENT)
################################################################################
################################################################################
## Here is where the magic happens
def printEyePositions():
'''
Print eye positions in global coordinates
'''
print 'Left eye: ' + str(config.leftEyeNode.getPosition(viz.ABS_GLOBAL))
print 'Right eye: ' + str(config.rightEyeNode.getPosition(viz.ABS_GLOBAL))
print 'Cyclopean eye: ' + str(config.cycEyeNode.getPosition(viz.ABS_GLOBAL))
config = Configuration()
vizact.onkeydown('o', config.resetHeadOrientation)
if( config.sysCfg['use_phasespace'] ):
vizact.onkeydown('s', config.mocap.saveRigid,'hmd')
vizact.onkeydown('r', config.mocap.resetRigid,'hmd')
print 'Using Phasespace'
else:
viz.MainView.setPosition([0,1.6,0])
print 'Using Vizard world view'
viz.go
###############################################################################
################################################################################
################start playing around from here ################################
pl_left = False
pl_right = False
global cam1
global cam2
cam1 = False
cam2 = False
def changeCamID():
global cam1
global cam2
tempVar1 = cam1
tempvar2 = cam2
cam1 = tempvar2
cam2 = tempVar1
def showImageToBothEyes():
global cam1
global cam2
video = viz.add('VideoCamera.dle')
outP = video.getWebcamNames(available = False)
print(outP)
cam1 = video.addWebcam(id=0, size=(640,480))
cam2 = video.addWebcam(id=1, size=(640,480))
s = 3000
focalLen = 0.00081566 * s
planeHeight = 0.00126 * s
planeWidth = 0.0022 * s
camcenter_dX = (640-606.3966)*1.75*(10^-6) * s
camcenter_dY = (360-310.6875)*1.75*(10^-6) * s
pl_left = vizshape.addPlane(
size = [planeWidth,planeHeight],
axis = vizshape.AXIS_Z,
cullFace = False
)
pl_right = vizshape.addPlane(
size = [planeWidth,planeHeight],
axis = vizshape.AXIS_Z,
cullFace = False
)
pl_left.texture(cam1)
pl_right.texture(cam2)
pl_left.setParent(config.leftEyeNode)
pl_left.setPosition([0,0,focalLen],viz.ABS_PARENT)
pl_right.setParent(config.rightEyeNode)
pl_right.setPosition([0,0,focalLen],viz.ABS_PARENT)
## Add code to update orientation with changes in head orientation
headEuler_YPR = config.headTracker.getEuler()
pl_left.setEuler([180+headEuler_YPR[0],0+headEuler_YPR[1],-90+headEuler_YPR[2]])
pl_right.setEuler([180+headEuler_YPR[0],0+headEuler_YPR[1],-90+headEuler_YPR[2]])
pl_left.renderToEye(viz.LEFT_EYE)
pl_right.renderToEye(viz.RIGHT_EYE)
# Press 'w' to change camera order
vizact.onkeydown('w', changeCamID)
def showBoxOnEyes(tableIn):
tableTracker = config.mocap.get_rigidTracker('table')#gets the table location and orientation from Phasespace
loc_table = tableTracker.get_position() #this stores the location in a list for modifying
tableIn.setPosition(loc_table[0], loc_table[1]/2.0, loc_table[2])
ori_table = tableTracker.get_euler()
tableIn.setEuler(ori_table)
#table = vizshape.addBox([0.460,0.66,0.60],splitFaces=False)
#vizact.onupdate(viz.PRIORITY_LINKS,showBoxOnEyes,table)
#piazza = viz.addChild('piazza.osgb')
showImageToBothEyes()
# Code not needed
'''
#def showDuckToBothEyes():
# ## Here is an example of how to place something in front of the left eye, and to make it visible to ONLY the left eye
# binocularRivalDuck = viz.addChild('duck.cfg')
# binocularRivalDuck.setScale([0.25]*3)
# binocularRivalDuck.setParent(config.leftEyeNode)
# binocularRivalDuck.setPosition([0,-.3,2],viz.ABS_PARENT)
# binocularRivalDuck.setEuler([180,0,0])
# ## do not write renderToEye(viz.RIGHT_EYE) function if you want to render to both eyes. If both eyes have to show,
# ## keep it as it is
def showImageToOneEye():
s = 10000
focalLen = 0.00081566 * s
planeWidth = 0.00126 * s
planeHeight = 0.0022 * s
camcenter_dX = (640-606.3966)*1.75*(10^-6) * s
camcenter_dY = (360-310.6875)*1.75*(10^-6) * s
br = vizshape.addPlane(
size = [planeHeight,planeWidth],
axis = vizshape.AXIS_Z,
cullFace = False
)
pic = viz.addTexture('imcalib30_corr.jpg')
br.texture(pic)
br.setParent(config.rightEyeNode)
br.setPosition([0,0,focalLen],viz.ABS_PARENT)
br.setEuler([180,0,0])
br.renderToEye(viz.RIGHT_EYE)
'''