from managerConn import ManagerConnection import time, sys from pywii import Wii, _ClassWiimote import pywii import cmath # types of messages sent to the manager MOVE = 0 TRANSLATE = 1 ROTATE = 2 RESIZE = 3 CHANGE_Z = 4 FULLSCREEN = 5 # wiimote Buttons BUTTON_A = 0 BUTTON_B = 1 BUTTON_1 = 2 BUTTON_2 = 3 BUTTON_PLUS = 4 BUTTON_MINUS = 5 BUTTON_HOME = 6 BUTTON_UP = 7 BUTTON_DOWN = 8 BUTTON_LEFT = 9 BUTTON_RIGHT = 10 # constants for gaussaian smoothing HISTORY_LENGTH = 150 STD_DEVIATION = 15.0 #Rotating constants NO_ROTATE = 0 LEFT_ROTATE = 1 RIGHT_ROTATE = -1 class Position: def __init__(self, x, y): self.x = x self.y = y class Wiimote: def __init__(self, manager): self.__buttons = {} for i in range (0, 11): self.__buttons[i] = False self.history = [] self.gauss = [] for i in range (-HISTORY_LENGTH + 1, 1): self.gauss.append(abs(1/(cmath.sqrt(2*cmath.pi*pow(STD_DEVIATION,2)))*cmath.exp(-(pow(i,2)/(2*pow(STD_DEVIATION,2)))))) gaussSum = 0 for i in self.gauss: gaussSum += i for i in range(0,HISTORY_LENGTH): self.gauss[i] = self.gauss[i] / gaussSum self.pointerPosition = None self.wii = Wii() self.wiimote = self.wii.QuickConnect()[0] self.wiimote.SetMotionSensingMode(self.wiimote.ON) self.wiimote.SetLEDs(_ClassWiimote.LED_1) self.wiimote.IR.SetMode(self.wiimote.IR.ON) self.wiimote.IR.SetAspectRatio(self.wiimote.IR.ASPECT_16_9) self.initialOrientation = [0,0] self.displaySize = [660.0, 370.0] self.outPointerCount = 0 # Potrzebne przy obrotach na akcelerometrze # self.rotateInit = 80 # self.rotateDone = 40 # self.rotating = NO_ROTATE self.buttonMap = {} self.buttonMap[BUTTON_A] = self.wiimote.Buttons.BUTTON_A self.buttonMap[BUTTON_B] = self.wiimote.Buttons.BUTTON_B self.buttonMap[BUTTON_1] = self.wiimote.Buttons.BUTTON_ONE self.buttonMap[BUTTON_2] = self.wiimote.Buttons.BUTTON_TWO self.buttonMap[BUTTON_PLUS] = self.wiimote.Buttons.BUTTON_PLUS self.buttonMap[BUTTON_MINUS] = self.wiimote.Buttons.BUTTON_MINUS self.buttonMap[BUTTON_HOME] = self.wiimote.Buttons.BUTTON_HOME self.buttonMap[BUTTON_UP] = self.wiimote.Buttons.BUTTON_UP self.buttonMap[BUTTON_DOWN] = self.wiimote.Buttons.BUTTON_DOWN self.buttonMap[BUTTON_LEFT] = self.wiimote.Buttons.BUTTON_LEFT self.buttonMap[BUTTON_RIGHT] = self.wiimote.Buttons.BUTTON_RIGHT self.buttonHandler = {} self.__registerButtonHandler(BUTTON_A, self.onButtonA) self.__registerButtonHandler(BUTTON_B, self.onButtonB) self.__registerButtonHandler(BUTTON_LEFT, self.onButtonLeft) self.__registerButtonHandler(BUTTON_RIGHT, self.onButtonRight) self.__registerButtonHandler(BUTTON_UP, self.onButtonUp) self.__registerButtonHandler(BUTTON_DOWN, self.onButtonDown) self.__registerButtonHandler(BUTTON_HOME, self.onButtonHome) self.manager = manager handlerMap = { self.wiimote.EVENT_EVENT: self.handleEvent } try: self.wii.PollMapped(handlerMap, self.wii.POLL_FOREVER) except: self.manager.quit() sys.exit(0) def __registerButtonHandler(self, buttonCode, buttonHandler): self.buttonHandler[buttonCode] = buttonHandler def __calculateGaussAverage(self): sumx = 0 sumy = 0 sumweight = 0 for i in range(0,len(self.history)): sumx += self.history[i].x * self.gauss[i] sumy += self.history[i].y * self.gauss[i] sumweight += self.gauss[i] if len(self.history) < HISTORY_LENGTH: self.pointerPosition = Position(sumx/sumweight, sumy/sumweight) else: self.pointerPosition = Position(sumx, sumy) def __updatePointerPosition(self, point): if point.x == 0 and point.y == 1: if self.outPointerCount == HISTORY_LENGTH / 3: self.history = [] self.pointerPosition = Position(-1,-1) else: self.outPointerCount += 1 else: self.history.append(point) self.pointerPosition = None self.outPointerCount = 0 if len(self.history) == (HISTORY_LENGTH + 1): self.history.pop(0) self.__calculateGaussAverage() def handleEvent(self, wm): for i in self.buttonHandler: self.__checkSingleButton(wm, i) #obroty na akcelerometrze # if wm.Buttons.isPressed(wm.Buttons.BUTTON_A): # pitch, roll, _ = wm.Accelerometer.GetOrientation() # if self.rotating == NO_ROTATE: # if self.initialOrientation[1] - roll > self.rotateInit: # self.rotating = LEFT_ROTATE # self.sendMsg(ROTATE,self.rotating) # elif roll - self.initialOrientation[1]> self.rotateInit: # self.rotating = RIGHT_ROTATE # self.sendMsg(ROTATE,self.rotating) # elif self.rotating == LEFT_ROTATE and self.initialOrientation[1] - roll < self.rotateDone: # self.rotating = NO_ROTATE # self.sendMsg(ROTATE,self.rotating) # elif self.rotating == RIGHT_ROTATE and roll - self.initialOrientation[1] < self.rotateDone: # self.rotating = NO_ROTATE # self.sendMsg(ROTATE,self.rotating) if wm.isUsingIR() and wm.IR.GetNumDots >= 2: mx, my = wm.IR.GetCursorPosition() x = float(mx/self.displaySize[0]) y = 1-float(my/self.displaySize[1]) self.__updatePointerPosition(Position(x,y)) if not self.pointerPosition == None: self.sendMsg(MOVE,self.pointerPosition.x, self.pointerPosition.y) def __checkSingleButton(self, wm, buttonCode): if wm.Buttons.isJustPressed(self.buttonMap[buttonCode]): self.__buttons[buttonCode] = True self.buttonHandler[buttonCode](wm, True) if self.__buttons[buttonCode] and not wm.Buttons.isPressed(self.buttonMap[buttonCode]): self.__buttons[buttonCode] = False self.buttonHandler[buttonCode](wm, False) def onButtonA(self, wm, isDown): if isDown: self.sendMsg(TRANSLATE, 1) self.initialOrientation[0], self.initialOrientation[1], _ = wm.Accelerometer.GetOrientation() else: self.sendMsg(TRANSLATE, 0) def onButtonB(self, wm, isDown): if isDown: self.sendMsg(RESIZE, 1) else: self.sendMsg(RESIZE, 0) def onButtonLeft(self, wm, isDown): if isDown: self.sendMsg(ROTATE, LEFT_ROTATE) def onButtonRight(self, wm, isDown): if isDown: self.sendMsg(ROTATE, RIGHT_ROTATE) def onButtonUp(self, wm, isDown): if isDown: self.sendMsg(CHANGE_Z, 1) def onButtonDown(self, wm, isDown): if isDown: self.sendMsg(CHANGE_Z, -1) def onButtonHome(self, wm, isDown): if isDown: self.sendMsg(FULLSCREEN) def sendMsg(self, *data): msg = "" for m in data: msg+=str(m)+" " self.manager.sendMessage("wii", "wiimote", msg) # you can optionally pass in a port number of the manager on command line port = 20005 if len(sys.argv) < 2: print "Usage: python " + sys.argv[0] + " sageIP" sys.exit(0) elif len(sys.argv) > 2: port = int(sys.argv[2]) # start everything off Wiimote( ManagerConnection(sys.argv[1], port) )