Ajout pywiiuse, version transmise par mail par Gary Bishop.
authorpin <pin@fe552daf-6dbe-4428-90eb-1537e0879342>
Fri, 2 Apr 2010 13:24:44 +0000 (13:24 +0000)
committerpin <pin@fe552daf-6dbe-4428-90eb-1537e0879342>
Fri, 2 Apr 2010 13:24:44 +0000 (13:24 +0000)
git-svn-id: https://svn.cri.ensmp.fr/svn/minwii/trunk@121 fe552daf-6dbe-4428-90eb-1537e0879342

src/pywiiuse/PyWiiUse.py [new file with mode: 0755]
src/pywiiuse/example.py [new file with mode: 0755]
src/pywiiuse/setup.py [new file with mode: 0755]
src/pywiiuse/wiiuse.dll [new file with mode: 0755]

diff --git a/src/pywiiuse/PyWiiUse.py b/src/pywiiuse/PyWiiUse.py
new file mode 100755 (executable)
index 0000000..55a1c98
--- /dev/null
@@ -0,0 +1,361 @@
+'''Python interface to the wiiuse library for the wii remote
+
+Just a simple wrapper, no attempt to make the api pythonic. I tried to hide ctypes where
+necessary.
+
+This software is free for any use. If you or your lawyer are stupid enough to believe I have any
+liability for it, then don't use it; otherwise, be my guest.
+
+Gary Bishop, January 2008
+hacked for new API and data June 2009
+'''
+
+import os
+import ctypes
+from ctypes import c_char_p, c_int, c_byte, c_uint, c_uint16, c_float, c_short, c_void_p, c_char
+from ctypes import CFUNCTYPE, Structure, POINTER, Union, byref, cdll
+import sys
+
+# duplicate the wiiuse data structures
+
+class _Structure(Structure):
+    def __repr__(self):
+        '''Print the fields'''
+        res = []
+        for field in self._fields_:
+            res.append('%s=%s' % (field[0], repr(getattr(self, field[0]))))
+        return self.__class__.__name__ + '(' + ','.join(res) + ')'
+
+class vec2b(_Structure):
+    _fields_ = [('x', c_byte),
+                ('y', c_byte),
+                ]
+
+class vec3b(_Structure):
+    _fields_ = [('x', c_byte),
+                ('y', c_byte),
+                ('z', c_byte),
+                ]
+
+class vec3f(_Structure):
+    _fields_ = [('x', c_float),
+                ('y', c_float),
+                ('z', c_float),
+                ]
+
+class orient(_Structure):
+    _fields_ = [('roll', c_float),
+                ('pitch', c_float),
+                ('yaw', c_float),
+                ('a_roll', c_float),
+                ('a_pitch', c_float),
+                ]
+
+    def __repr__(self):
+        return 'orient(roll=%f pitch=%f yaw=%f a_roll=%f a_pitch=%f)' % (
+            self.roll, self.pitch, self.yaw, self.a_roll, self.a_pitch)
+
+class accel(_Structure):
+    _fields_ = [('cal_zero', vec3b),
+                ('cal_g', vec3b),
+                ('st_roll', c_float),
+                ('st_pitch', c_float),
+                ('st_alpha', c_float),
+                ]
+
+class ir_dot(_Structure):
+    _fields_ = [('visible', c_byte),
+                ('x', c_uint),
+                ('y', c_uint),
+                ('rx', c_short),
+                ('ry', c_short),
+                ('order', c_byte),
+                ('size', c_byte),
+                ]
+
+class ir(_Structure):
+    _fields_ = [('dot', ir_dot*4),
+                ('num_dots', c_byte),
+                ('aspect', c_int),
+                ('pos', c_int),
+                ('vres', c_uint*2),
+                ('offset', c_int*2),
+                ('state', c_int),
+                ('ax', c_int),
+                ('ay', c_int),
+                ('x', c_int),
+                ('y', c_int),
+                ('distance', c_float),
+                ('z', c_float),
+                ]
+
+class joystick(_Structure):
+    _fields_ = [('max', vec2b),
+                ('min', vec2b),
+                ('center', vec2b),
+                ('ang', c_float),
+                ('mag', c_float),
+                ]
+
+class nunchuk(_Structure):
+    _fields_ = [('accel_calib', accel),
+                ('js', joystick),
+                ('flags', POINTER(c_int)),
+                ('btns', c_byte),
+                ('btns_held', c_byte),
+                ('btns_released', c_byte),
+                ('orient_threshold', c_float),
+                ('accel_threshold', c_int),
+                ('accel', vec3b),
+                ('orient', orient),
+                ('gforce', vec3f),
+                ]
+
+class classic_ctrl(_Structure):
+    _fields_ = [('btns', c_short),
+                ('btns_held', c_short),
+                ('btns_released', c_short),
+                ('r_shoulder', c_float),
+                ('l_shoulder', c_float),
+                ('ljs', joystick),
+                ('rjs', joystick),
+                ]
+
+class guitar_hero_3(_Structure):
+    _fields_ = [('btns', c_short),
+                ('btns_held', c_short),
+                ('btns_released', c_short),
+                ('whammy_bar', c_float),
+                ('js', joystick),
+                ]
+
+class expansion_union(Union):
+    _fields_ = [('nunchuk', nunchuk),
+                ('classic', classic_ctrl),
+                ('gh3', guitar_hero_3),
+                ]
+
+class expansion(_Structure):
+    _fields_ = [('type', c_int),
+                ('u', expansion_union),
+                ]
+
+class wiimote_state(_Structure):
+    _fields_ = [('exp_ljs_ang', c_float),
+                ('exp_rjs_ang', c_float),
+                ('exp_ljs_mag', c_float),
+                ('exp_rjs_mag', c_float),
+                ('exp_btns', c_uint16),
+                ('exp_orient', orient),
+                ('exp_accel', vec3b),
+                ('exp_r_shoulder', c_float),
+                ('exp_l_shoulder', c_float),
+                ('ir_ax', c_int),
+                ('ir_ay', c_int),
+                ('ir_distance', c_float),
+                ('orient', orient),
+                ('btns', c_uint16),
+                ('accel', vec3b),
+                ]
+
+if os.name == 'nt':
+    JunkSkip = [('dev_handle', c_void_p),
+                ('hid_overlap', c_void_p*5), # skipping over this data structure
+                ('stack', c_int),
+                ('timeout', c_int),
+                ('normal_timeout', c_byte),
+                ('exp_timeout', c_byte),
+                ]
+else:
+    JunkSkip = [('bdaddr', c_void_p),
+                ('bdaddr_str', c_char*18),
+                ('out_sock', c_int),
+                ('in_sock', c_int),
+                ]
+
+EVENT = 1
+STATUS = 2
+CONNECT = 3
+DISCONNECT = 4
+UNEXPECTED_DISCONNECT = 5
+READ_DATA = 6
+NUNCHUK_INSERTED = 7
+NUNCHUK_REMOVED = 8
+CLASSIC_CTRL_INSERTED = 9
+CLASSIC_CTRL_REMOVED = 10
+GUITAR_HERO_3_CTRL_INSERTED = 11
+GUITAR_HERO_3_CTRL_REMOVED = 12
+
+class wiimote(_Structure):
+    _fields_ = [('unid', c_int),
+                ] + JunkSkip + [
+                ('state', c_int),
+                ('leds', c_byte),
+                ('battery_level', c_float),
+                ('flags', c_int),
+                ('handshake_state', c_byte),
+                ('read_req', c_void_p),
+                ('accel_calib', accel),
+                ('exp', expansion),
+                ('accel', vec3b),
+                ('orient', orient),
+                ('gforce', vec3f),
+                ('ir', ir),
+                ('btns', c_uint16),
+                ('btns_held', c_uint16),
+                ('btns_released', c_uint16),
+                ('orient_threshold', c_float),
+                ('accel_threshold', c_int),
+                ('lstate', wiimote_state),
+                ('event', c_int),
+                ('event_buf', c_byte*32),
+                ]
+
+wiimote_p = POINTER(wiimote)
+wiimote_pp = POINTER(wiimote_p)
+
+# make function prototypes a bit easier to declare
+def cfunc(name, dll, result, *args):
+    '''build and apply a ctypes prototype complete with parameter flags
+    e.g.
+cvMinMaxLoc = cfunc('cvMinMaxLoc', _cxDLL, None,
+                    ('image', POINTER(IplImage), 1),
+                    ('min_val', POINTER(double), 2),
+                    ('max_val', POINTER(double), 2),
+                    ('min_loc', POINTER(CvPoint), 2),
+                    ('max_loc', POINTER(CvPoint), 2),
+                    ('mask', POINTER(IplImage), 1, None))
+means locate cvMinMaxLoc in dll _cxDLL, it returns nothing.
+The first argument is an input image. The next 4 arguments are output, and the last argument is
+input with an optional value. A typical call might look like:
+
+min_val,max_val,min_loc,max_loc = cvMinMaxLoc(img)
+    '''
+    atypes = []
+    aflags = []
+    for arg in args:
+        atypes.append(arg[1])
+        aflags.append((arg[2], arg[0]) + arg[3:])
+    return CFUNCTYPE(result, *atypes)((name, dll), tuple(aflags))
+
+# get the shared library
+if os.name == 'nt':
+    dll = cdll.LoadLibrary('wiiuse.dll')
+else:
+    dll = cdll.LoadLibrary('libwiiuse.so')
+
+# access the functions
+init = cfunc('wiiuse_init', dll, wiimote_pp,
+             ('wiimotes', c_int, 1))
+# find = cfunc('wiiuse_find', dll, c_int,
+#              ('wm', wiimote_pp, 1),
+#              ('max_wiimotes', c_int, 1),
+#              ('timeout', c_int, 1))
+# connect = cfunc('wiiuse_connect', dll, c_int,
+#                 ('wm', wiimote_pp, 1),
+#                 ('wiimotes', c_int, 1))
+# poll = cfunc('wiiuse_poll', dll, c_int,
+#              ('wm', wiimote_pp, 1),
+#              ('wiimotes', c_int, 1))
+find = dll.wiiuse_find
+connect = dll.wiiuse_connect
+poll = dll.wiiuse_poll
+set_leds = dll.wiiuse_set_leds
+motion_sensing = dll.wiiuse_motion_sensing
+set_accel_threshold = dll.wiiuse_set_accel_threshold
+set_orient_threshold = dll.wiiuse_set_orient_threshold
+set_orient_threshold.argtypes = [wiimote_p, c_float]
+set_timeout = dll.wiiuse_set_timeout
+
+def is_pressed(dev, button):
+    return dev.btns & button
+
+def is_held(dev, button):
+    return dev.btns_held & button
+
+def is_released(dev, button):
+    return dev.btns_released & button
+
+def is_just_pressed(dev, button):
+    return is_pressed(dev, button) and not is_held(dev, button)
+
+def using_acc(wm):
+    return wm.state & 0x10
+
+def using_exp(wm):
+    return wm.state & 0x20
+
+def using_ir(wm):
+    return wm.state & 0x40
+
+LED_NONE = 0
+LED_1 = 0x10
+LED_2 = 0x20
+LED_3 = 0x40
+LED_4 = 0x80
+
+LED = [LED_1, LED_2, LED_3, LED_4]
+
+EXP_NONE = 0
+EXP_NUNCHUK = 1
+EXP_CLASSIC = 2
+
+SMOOTHING = 0x01
+CONTINUOUS = 0x02
+ORIENT_THRESH = 0x04
+INIT_FLAGS = SMOOTHING | ORIENT_THRESH
+
+IR_ABOVE = 0
+IR_BELOW = 1
+
+ASPECT_4_3 = 0
+ASPECT_16_9 = 1
+
+button = { '2':0x0001,
+           '1':0x0002,
+           'B':0x0004,
+           'A':0x0008,
+           '-':0x0010,
+           'Home':0x0080,
+           'Left':0x0100,
+           'Right':0x0200,
+           'Down':0x0400,
+           'Up':0x0800,
+           '+':0x1000,
+           }
+
+nunchuk_button = { 'Z':0x01,
+                   'C':0x02,
+                   }
+
+
+if __name__ == '__main__':
+    def handle_event(wm):
+        print 'EVENT', wm.unid, wm.btns
+        print wm.gforce.x, wm.gforce.y, wm.gforce.z
+        
+    nmotes = 1
+    wiimotes = init(nmotes)
+    print 'press 1&2'
+    found = find(wiimotes, nmotes, 2)
+    if not found:
+        print 'no wiimotes found'
+        sys.exit(1)
+    
+    connected = connect(wiimotes, nmotes)
+    if connected:
+        print 'connected to %d wiimotes (of %d found)' % (connected, found)
+    else:
+        print 'failed to connect to any wiimote.'
+        sys.exit(1)
+
+    set_leds(wiimotes[0], 0x50)
+    motion_sensing(wiimotes[0], 1)
+
+    while True:
+        if poll(wiimotes, nmotes):
+            for i in range(nmotes):
+                m = wiimotes[i][0]
+                if wiimotes[i][0].event == EVENT:
+                    handle_event(wiimotes[i][0])
diff --git a/src/pywiiuse/example.py b/src/pywiiuse/example.py
new file mode 100755 (executable)
index 0000000..27721b4
--- /dev/null
@@ -0,0 +1,114 @@
+#! /usr/bin/python
+
+'''Try to implement the example in python'''
+
+import PyWiiUse as wiiuse
+
+import sys
+import time
+import os
+
+nmotes = 2
+
+def handle_event(wm):
+    print '--- EVENT [wiimote id %i] ---' % wm.unid, wm.btns, wm.btns_held, wm.btns_released
+    if wm.btns:
+        for name,b in wiiuse.button.items():
+            if wiiuse.is_pressed(wm, b):
+                print name,'pressed'
+
+        if wiiuse.is_just_pressed(wm, wiiuse.button['-']):
+            wiiuse.motion_sensing(wmp, 0)
+        if wiiuse.is_just_pressed(wm, wiiuse.button['+']):
+            wiiuse.motion_sensing(wmp, 1)
+        if wiiuse.is_just_pressed(wm, wiiuse.button['B']):
+            wiiuse.toggle_rumble(wmp)
+        if wiiuse.is_just_pressed(wm, wiiuse.button['Up']):
+            wiiuse.set_ir(wmp, 1)
+        if wiiuse.is_just_pressed(wm, wiiuse.button['Down']):
+            wiiuse.set_ir(wmp, 0)
+    
+    if wiiuse.using_acc(wm):
+        print 'roll  = %f' % wm.orient.roll
+        print 'pitch = %f' % wm.orient.pitch
+        print 'yaw   = %f' % wm.orient.yaw
+
+    if wiiuse.using_ir(wm):
+        for i in range(4):
+            if wm.ir.dot[i].visible:
+                print 'IR source %i: (%u, %u)' % (i, wm.ir.dot[i].x, wm.ir.dot[i].y)
+        print 'IR cursor: (%u, %u)' % (wm.ir.x, wm.ir.y)
+        print 'IR z distance: %f' % wm.ir.z
+
+    if wm.exp.type == wiiuse.EXP_NUNCHUK:
+        nc = wm.exp.u.nunchuk
+        
+        for name,b in wiiuse.nunchuk_button.items():
+            if wiiuse.is_pressed(nc, b):
+                print 'Nunchuk: %s is pressed' % name
+
+        print 'nunchuk roll  = %f' % nc.orient.roll
+        print 'nunchuk pitch = %f' % nc.orient.pitch
+        print 'nunchuk yaw   = %f' % nc.orient.yaw
+        print 'nunchuk joystick angle:     %f' % nc.js.ang
+        print 'nunchuk joystick magnitude: %f' % nc.js.mag
+
+
+def handle_ctrl_status(wmp, attachment, speaker, ir, led, battery_level):
+    wm = wmp[0]
+    print '--- Controller Status [wiimote id %i] ---' % wm.unid
+    print 'attachment', attachment
+    print 'speaker', speaker
+    print 'ir', ir
+    print 'leds', led[0], led[1], led[2], led[3]
+    print 'battery', battery_level
+
+def handle_disconnect(wmp):
+    print 'disconnect'
+
+if os.name != 'nt': print 'Press 1&2'
+
+wiimotes = wiiuse.init(nmotes)
+
+found = wiiuse.find(wiimotes, nmotes, 5)
+if not found:
+    print 'not found'
+    sys.exit(1)
+
+connected = wiiuse.connect(wiimotes, nmotes)
+if connected:
+    print 'Connected to %i wiimotes (of %i found).' % (connected, found)
+else:
+    print 'failed to connect to any wiimote.'
+    sys.exit(1)
+
+for i in range(nmotes):
+    wiiuse.set_leds(wiimotes[i], wiiuse.LED[i])
+    #wiiuse.rumble(wiimotes[i], 1)
+
+# for i in range(nmotes):
+#     wiiuse.rumble(wiimotes[i], 0)
+
+#wiiuse.status(wiimotes[0])
+
+wiiuse.motion_sensing(wiimotes[0], 1)
+
+fp = file('mydata.txt', 'w')
+t0 = time.time()
+try:
+    while True:
+        if wiiuse.poll(wiimotes, nmotes):
+            for i in range(nmotes):
+                m = wiimotes[i][0]
+                if wiimotes[i][0].event == wiiuse.EVENT:
+                    #handle_event(wiimotes[i][0])
+                    wm = wiimotes[i][0]
+                    t = time.time() - t0
+                    print >>fp, i, t, wm.gforce.x, wm.gforce.y, wm.gforce.z
+except KeyboardInterrupt:
+    for i in range(nmotes):
+        wiiuse.set_leds(wiimotes[i], 0)
+        #wiiuse.disconnect(wiimotes[i])
+
+fp.close()
+print 'done'
diff --git a/src/pywiiuse/setup.py b/src/pywiiuse/setup.py
new file mode 100755 (executable)
index 0000000..d96beb6
--- /dev/null
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+
+from distutils.core import setup
+import os
+
+setup(name='PyWiiUse',
+      version='2.00',
+      description='Python wrapper for the wiiuse interface to the Wiimote',
+      author='Gary Bishop',
+      author_email='gb@cs.unc.edu',
+      url='http://www.cs.unc.edu/~gb/',
+      py_modules=['PyWiiUse' ],
+      )
+
diff --git a/src/pywiiuse/wiiuse.dll b/src/pywiiuse/wiiuse.dll
new file mode 100755 (executable)
index 0000000..a7e228c
Binary files /dev/null and b/src/pywiiuse/wiiuse.dll differ