1 # -*- coding: utf-8 -*-
3 wiimote -> mouse interface
9 from threading
import Thread
10 from Queue
import Queue
, Empty
13 # events to use. Is there a way to get ones known to be unused?
16 wiiuse
= None # import within the thread, why do I have to do this?
18 class wiimote_thread(Thread
):
19 '''Manage the wiiuse interface'''
20 def __init__(self
, nmotes
=1, timeout
=5):
21 Thread
.__init
__(self
, name
='wiimote')
23 self
.startup
= Queue()
25 self
.timeout
= timeout
29 self
.startup
.get(True) # wait for the thread to get started and acquire the motes
32 '''This runs in a separate thread'''
34 import PyWiiUse
as wiiuse
# import here to avoid thread problems on windows
35 self
.wiimotes
= wiiuse
.init(self
.nmotes
)
36 found
= wiiuse
.find(self
.wiimotes
, self
.nmotes
, self
.timeout
)
37 self
.actual_nmotes
= wiiuse
.connect(self
.wiimotes
, self
.nmotes
)
39 self
.previousPositions
= {}
41 for i
in range(self
.nmotes
):
42 wiiuse
.set_leds(self
.wiimotes
[i
], wiiuse
.LED
[i
])
43 self
.previousPositions
[self
.wiimotes
[i
][0].unid
] = (0, 0)
45 self
.go
= self
.actual_nmotes
!= 0
47 self
.startup
.put(self
.go
)
50 if self
._paused
: continue
52 if wiiuse
.poll(self
.wiimotes
, self
.nmotes
) :
53 for i
in range(self
.nmotes
):
55 if m
[0].event
== wiiuse
.EVENT
:
61 # wiiuse.poll(self.wiimotes, self.nmotes)
65 # allow executing functions in this thread
68 func
, args
= self
.queue
.get_nowait()
71 print 'do:', func
.__name
__, args
80 def do(self
, func
, *args
):
81 '''Run the function in the thread handling the wiimote'''
82 self
.queue
.put((func
, args
))
84 def event_cb(self
, wmp
):
85 '''Called when the library has some data for the user.'''
88 # for name,b in wiiuse.button.items():
89 # if wiiuse.is_just_pressed(wm, b):
90 # pygame.event.post(pygame.event.Event(WIIMOTE_BUTTON_PRESS, button=name,
94 # if wm.btns_released:
95 # for name,b in wiiuse.button.items():
96 # if wiiuse.is_released(wm, b):
97 # pygame.event.post(pygame.event.Event(WIIMOTE_BUTTON_RELEASE, button=name,
102 # pygame.event.post(pygame.event.Event(WIIMOTE_ACCEL,
103 # orient=(wm.orient.roll, wm.orient.pitch,
105 # accel=(wm.gforce.x, wm.gforce.y, wm.gforce.z),
109 #dots = [ (wm.ir.dot[i].visible, wm.ir.dot[i].x, wm.ir.dot[i].y) for i in range(4) ]
110 #pygame.event.post(pygame.event.Event(WIIMOTE_IR,
112 # cursor=(wm.ir.x, wm.ir.y, wm.ir.z),
116 dots
= [ (wm
.ir
.dot
[i
].visible
, wm
.ir
.dot
[i
].x
, wm
.ir
.dot
[i
].y
) for i
in range(4) ]
117 cursor
=(wm
.ir
.x
, wm
.ir
.y
, wm
.ir
.z
)
119 previousPos
= self
.previousPositions
[wm
.unid
]
120 rel
= (pos
[0] - previousPos
[0], pos
[1] - previousPos
[1])
121 self
.previousPositions
[wm
.unid
] = pos
123 evt
= pygame
.event
.Event(pygame
.MOUSEMOTION
,
128 cursor
=(wm
.ir
.x
, wm
.ir
.y
, wm
.ir
.z
),
131 pygame
.event
.post(evt
)
134 # if wm.exp.type == wiiuse.EXP_NUNCHUK:
135 # nc = wm.exp.u.nunchuk
137 # for name,b in wiiuse.nunchuk_button.items():
138 # if wiiuse.is_just_pressed(nc, b):
139 # pygame.event.post(pygame.event.Event(NUNCHUK_BUTTON_PRESS, button=name,
142 # elif wiiuse.is_released(nc, b):
143 # pygame.event.post(pygame.event.Event(NUNCHUK_BUTTON_RELEASE, button=name,
147 # pygame.event.post(pygame.event.Event(NUNCHUK_ACCEL,
148 # orient=(nc.orient.roll, nc.orient.pitch,
150 # accel=(nc.gforce.x, nc.gforce.y, nc.gforce.z),
153 # pygame.event.post(pygame.event.Event(NUNCHUK_JOY,
159 def control_cb(self
, wmp
, attachment
, speaker
, ir
, led
, battery
):
160 '''Could check the battery level and such here'''
161 pygame
.event
.post(pygame
.event
.Event(WIIMOTE_STATUS
,
162 attachment
=attachment
,
165 led
=[led
[i
] for i
in range(4)],
169 def disconnect_cb(self
, wmp
):
170 '''What should we do here?'''
171 pygame
.event
.post(pygame
.event
.Event(WIIMOTE_DISCONNECT
,
176 for i
in range(self
.nmotes
):
177 wiiuse
.set_leds(self
.wiimotes
[i
], 0)
178 wiiuse
.disconnect(self
.wiimotes
[i
])
183 def init(nmotes
, timeout
):
184 '''Initialize the module.'''
188 WT
= wiimote_thread(nmotes
, timeout
)
191 '''How many Wiimotes were found?'''
192 return WT
.actual_nmotes
195 '''Gracefully shutdown the connection and turn off the wiimote leds'''
199 class wiimote(object):
200 '''Object representing a Wiimote'''
201 def __init__(self
, n
):
202 self
.wm
= WT
.wiimotes
[n
]
204 def enable_leds(self
, m
):
205 '''Control leds. The lower 4 bits map to the 4 leds'''
206 WT
.do(wiiuse
.set_leds
, self
.wm
, sum([wiiuse
.LED
[i
] for i
in range(4) if m
& (1<<i
)]))
208 def enable_rumble(self
, on
):
210 WT
.do(wiiuse
.rumble
, self
.wm
, on
)
212 def enable_accels(self
, on
):
213 '''Control reporting of accelerometer data.'''
214 WT
.do(wiiuse
.motion_sensing
, self
.wm
, on
)
216 def enable_ir(self
, on
, vres
=None, position
=None, aspect
=None):
217 '''Control reporting IR data.'''
218 WT
.do(wiiuse
.set_ir
, self
.wm
, on
)
220 WT
.do(wiiuse
.set_ir_vres
, self
.wm
, *vres
)
221 if position
is not None:
222 WT
.do(wiiuse
.set_ir_position
, self
.wm
, position
)
223 if aspect
is not None:
224 WT
.do(wiiuse
.set_aspect_ratio
, self
.wm
, aspect
)
226 def set_flags(self
, smoothing
=None, continuous
=None, threshold
=None):
227 '''Set flags SMOOTHING, CONTINUOUS, ORIENT_THRESH'''
229 if smoothing
is not None:
231 enable |
= wiiuse
.SMOOTHING
233 disable |
= wiiuse
.SMOOTHING
234 if continuous
is not None:
236 enable |
= wiiuse
.CONTINUOUS
238 disable |
= wiiuse
.CONTINUOUS
239 if threshold
is not None:
241 enable |
= wiiuse
.ORIENT_THRESH
243 disable |
= wiiuse
.ORIENT_THRESH
244 print enable
, disable
245 WT
.do(wiiuse
.set_flags
, self
.wm
, enable
, disable
)
247 def set_orient_thresh(self
, thresh
):
248 '''Set orientation threshold'''
249 WT
.do(wiiuse
.set_orient_threshold
, self
.wm
, thresh
)
252 '''Trigger a status callback.'''
253 WT
.do(wiiuse
.status
, self
.wm
)
255 def disconnect(self
):
256 '''Disconnect this Wiimote'''
257 WT
.do(wiiuse
.disconnect(self
.wm
))
260 '''Get the object for the nth Wiimote'''