def main(): print("Waiting for boot signal") print(s.read()) print("Writing sway command") s.write("".join(map(chr, [0x55, 0x0, 0x3, 0, 2, 72]))) # equivalent to .join['U', '\x00', '\x03', '\x00', '\x02', 'H'] # between every elements in the list, put "" # that will convert it as one string ''Ux00x03x00x02H'' print(s.read()) # print("Reading motor encoders") # s.write("".join(map(chr, [0x55, 0x1, 0x12]))) # print(["0x%.02x " % ord(x) for x in s.read(12)]) server = OSCServer( ("192.168.123.75", 10000) ) server.timeout = 0 # funny python's way to add a method to an instance of a class import types server.handle_timeout = types.MethodType(handle_timeout, server) server.addMsgHandler( "/rotate", rotate_callback ) server.addMsgHandler( "/bf", bf_callback ) try: while 1: server.handle_request() except KeyboardInterrupt: pass server.close()
def main(): print("Waiting for boot signal") print(s.read()) print("Writing sway command") s.write("".join(map(chr, [0x55, 0x0, 0x3, 0, 2, 72]))) print(s.read()) # print("Reading motor encoders") # s.write("".join(map(chr, [0x55, 0x1, 0x12]))) # print(["0x%.02x " % ord(x) for x in s.read(12)]) server = OSCServer( ("192.168.123.75", 10000) ) server.timeout = 0 # funny python's way to add a method to an instance of a class import types server.handle_timeout = types.MethodType(handle_timeout, server) server.addMsgHandler( "/rotate", rotate_callback ) server.addMsgHandler( "/bf", bf_callback ) try: while 1: server.handle_request() except KeyboardInterrupt: pass server.close()
class OSCServerClass: def __init__(self, id, ip, port): self.robot = id self.bridge = MeccaBridge() self.server = OSCServer((ip, port)) self.server.timeout = 0 self.active = True self.server.handle_timeout = types.MethodType(handle_timeout, self.server) self.server.addMsgHandler("/" + self.robot + "/pinMove" , self.pinMoveHandler ) self.server.addMsgHandler("/" + self.robot + "/pinLight" , self.pinLightHandler ) self.server.addMsgHandler("/" + self.robot + "/init" , self.initHandler ) self.server.addMsgHandler("/" + self.robot + "/headLight", self.headLightHandler) self.gotMessage = False ####################################################################### def run(self): print("serving on {}".format(self.server.server_address)) self.server.running = True while self.server.running: while True: self.server.handle_request() if not self.gotMessage: break self.gotMessage = False self.bridge.sendMessages() time.sleep(0.01); ###################################################################### def pinMoveHandler(self, path, tags, args, source): #print(path + "\n") #print ', '.join(map(str, args)) self.bridge.sendServoPosition(args[0], args[1], args[2], args[3]) self.gotMessage = True ###################################################################### def pinLightHandler(self, path, tags, args, source): self.bridge.sendPinLight(args[0], args[1], args[2]) self.gotMessage = True ###################################################################### def initHandler(self, path, tags, args, source): self.bridge.sendInit(args[0], args[1]) self.gotMessage = True ###################################################################### def headLightHandler(self, path, targs, args, source): self.bridge.sendHeadLight(args[0], args[1], args[2], args[3]) self.gotMessage = True
class OSCPlotter(object): """Set up OSC server and other handlers.""" def __init__(self, port, scope): host="localhost" logger.info( "Initializing server at %s:%d"%(host,port)) try: self.m_oscserver = OSCServer( (host, port) ) except: logger.fatal("System:Unable to create OSC handler at %s:%d"%(host,port),exc_info=True) sys.exit(1) self.m_oscserver.timeout = 0 self.m_oscserver.print_tracebacks = True self.m_scope = scope self.m_fnum = 0 # add a method to an instance of the class self.m_oscserver.handle_timeout = types.MethodType(handle_timeout,self.m_oscserver) # this registers a 'default' handler (for unmatched messages), # an /'error' handler, an '/info' handler. # And, if the client supports it, a '/subscribe' & # '/unsubscribe' handler self.m_oscserver.addDefaultHandlers() self.m_oscserver.addMsgHandler("default", self.default_handler) self.m_oscserver.addMsgHandler("/pf/frame", self.pf_frame) # self.m_oscserver.addMsgHandler("/pf/update", self.pf_update) self.m_oscserver.addMsgHandler("/conductor/attr", self.cond_attr) def handle(self): self.m_oscserver.handle_request() def cond_attr(self, path, tags, args, source): attr=args[0] uid=args[1] value=args[2] logger.info("%d.%s=%f"%(uid,attr,value)) if attr=="kinetic": self.m_scope.append(uid,self.m_fnum,value) def pf_update(self, path, tags, args, source): t=args[1] uid=args[2] x=args[3] logger.debug("uid=%d,t=%f, x=%f"%(uid,t,x)) # self.m_scope.append(uid,t,x) def pf_frame(self, path, tags, args, source): self.m_fnum=args[0] if self.m_fnum%5==0: self.m_scope.update(self.m_fnum) def default_handler(self, path, tags, args, source): # logger.debug("got message for "+path+" with tags "+tags) return None
class Manta(object): def __init__(self, receive_port=31416, send_port=31417, send_address='127.0.0.1'): self.osc_client = OSCClient() self.osc_server = OSCServer(('127.0.0.1', receive_port)) self.osc_client.connect(('127.0.0.1', send_port)) # set the osc server to time out after 1ms self.osc_server.timeout = 0.001 self.event_queue = [] self.osc_server.addMsgHandler('/manta/continuous/pad', self._pad_value_callback) self.osc_server.addMsgHandler('/manta/continuous/slider', self._slider_value_callback) self.osc_server.addMsgHandler('/manta/continuous/button', self._button_value_callback) self.osc_server.addMsgHandler('/manta/velocity/pad', self._pad_velocity_callback) self.osc_server.addMsgHandler('/manta/velocity/button', self._button_velocity_callback) def process(self): self.osc_server.handle_request() ret_list = self.event_queue self.event_queue = [] return ret_list def _pad_value_callback(self, path, tags, args, source): self.event_queue.append(PadValueEvent(args[0], args[1])) def _slider_value_callback(self, path, tags, args, source): touched = False if args[1] == 0xffff else True scaled_value = args[1] / 4096.0 self.event_queue.append(SliderValueEvent(args[0], touched, scaled_value)) def _button_value_callback(self, path, tags, args, source): pass def _pad_velocity_callback(self, path, tags, args, source): self.event_queue.append(PadVelocityEvent(args[0], args[1])) def _button_velocity_callback(self, path, tags, args, source): self.event_queue.append(ButtonVelocityEvent(args[0], args[1])) def _send_osc(self, path, *args): msg = OSCMessage(path) msg.append(args) self.osc_client.send(msg) def set_led_enable(self, led_type, enabled): self._send_osc('/manta/ledcontrol', led_type, 1 if enabled else 0) def set_led_pad(self, led_state, pad_index): self._send_osc('/manta/led/pad', led_state, pad_index)
class OscServerThread(Thread): def __init__(self, host, stopEvent): Thread.__init__(self) self.server = OSCServer(host) self.stopEvent = stopEvent def setCallBacks(self, callBacks): for callBack in callBacks: self.server.addMsgHandler(callBack[0], callBack[1]) def run(self): while not self.stopEvent.is_set(): self.server.handle_request() self.server.close()
class OSC(threading.Thread): def __init__(self): global run threading.Thread.__init__(self) self.daemon = True self.server = OSCServer(("localhost", 15000)) self.server.timeout = 0 def handle_timeout(self): self.time_out = True self.server.handle_timeout = types.MethodType(handle_timeout, self.server) def user_callback(path, tags, args, source): global RGB global BRIGHTNESS #print "here" RGB[0] = args[0] RGB[1] = args[1] RGB[2] = args[2] BRIGHTNESS = args[3] def quit_callback(path, tags, args, source): global run run = False self.server.addMsgHandler("/colors", user_callback) self.server.addMsgHandler("/quit", quit_callback) def each_frame(self): self.server.timed_out = False while not self.server.timed_out: self.server.handle_request() def run(self): global run while run: sleep(1) self.each_frame()
def app(): global dxlIO, server, client ports = pypot.dynamixel.get_available_ports() if not ports: raise IOError('No port available.') dxlIO = pypot.dynamixel.DxlIO(ports[0]) availableIDs = dxlIO.scan() server = OSCServer(('0.0.0.0', 8000)) for motorID in availableIDs: server.addMsgHandler('/motor/' + str(motorID), motorHandler) # Register OSC handlers for each found ID client = OSCClient() client.connect(('localhost', 8001)) print 'Ready. Found ID(s) ' + str(availableIDs) while True: server.handle_request() sleep(0.01)
class ServerLighthouse(object): def __init__(self, address='192.168.1.145', recvPort=recvPort): self.address = address self.recvPort = recvPort # Setup a reciever for OSC. self.server = OSCServer((self.address, self.recvPort)) self.server.timeout = 0 self.server.handleTimeout = types.MethodType(self.handleTimeout, self.server) # Startup light self.intitializeLight() def handleTimeout(self): self.timedOut = True def eachFrame(self): # clear timed_out flag self.server.timed_out = False # handle all pending requests then return while not self.server.timed_out: self.server.handle_request() def handleEvent(self, address, functionToCall): def internalFunction(path, tags, args, source): arg = int(args[0]) functionToCall(arg) def internalFunctionZ(path, tags, args, source): pass self.server.addMsgHandler(address, internalFunction) self.server.addMsgHandler('%s/z' % address, internalFunctionZ)
def main(robotIP, PORT = 9559): myBroker = ALBroker("myBroker", #needed for subscribers and to construct naoqi modules "0.0.0.0", 0, robotIP, PORT) meanx = 0.21835 meany = 0.035625 global ReactToTouch, go_to_center, global_time global server, client client = OSCClient() client.connect(("192.168.0.5",1234)) global motionProxy, jointNames motionProxy = ALProxy("ALMotion", robotIP, PORT) postureProxy = ALProxy("ALRobotPosture", robotIP, PORT) motionProxy.setStiffnesses("Body",0) motionProxy.setStiffnesses(jointNames,1) #motionProxy.openHand("LHand") #motionProxy.closeHand("LHand") maxSpeedFraction = 0.3 for i in range(1): motionProxy.angleInterpolationWithSpeed(jointNames, p[i], maxSpeedFraction) time.sleep(1.0) minx = -999 maxx = 999 miny = -999 maxy = 999 # Copy from inverse kinematics effector = "LArm" space = motion.FRAME_ROBOT axisMask = almath.AXIS_MASK_VEL # just control position isAbsolute = False # Since we are in relative, the current position is zero currentPos = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0] center = currentPos # Define the changes relative to the current position dx = 0.03 # translation axis X (meters) dy = -0.04 # translation axis Y (meters) dz = 0.03 # translation axis Z (meters) dwx = 0.00 # rotation axis X (radians) dwy = 0.00 # rotation axis Y (radians) dwz = 0.00 # rotation axis Z (radians) targetPos = [dx, dy, dz, dwx, dwy, dwz] # Go to the target and back again path = [targetPos] times = [1.5] # seconds motionProxy.positionInterpolation(effector, space, path, axisMask, times, isAbsolute) dz=0.00 currentPos = motionProxy.getPosition(effector, space, True) offx = 0.034 offy = 0.02 xy=[1345+103-(currentPos[0]+offx)*400/(0.07), (currentPos[1]+offy)*400/(0.07)+11-87-45] #print xy input('Press 1 to begin: ') k=2.5 L=0.5 n=10 speed = 0.15 #Initialize listener ReactToTouch = ReactToTouch("ReactToTouch") center = motionProxy.getPosition(effector, space, True) print "center: " + str(center[0]) + ", " + str(center[1]) try: while 1:#for i in range(n): if go_to_center: if random.random()<0.95: k=max(0.9,k-0.15) speed = 0.4 go_to_center = False #print 'going to center!' # Get current Position & define target position if random.random()<0.8: currentPos = motionProxy.getPosition(effector, space, True) maxx = min(maxx,abs(currentPos[0]-meanx)) maxy = min(maxy,abs(currentPos[1]-meany)) #targetPos = currentPos targetPos[0] = center[0] targetPos[1] = center[1] targetPos[2] = center[2] #print 'new target' #print targetPos # Move to position, being able to interrupt motionProxy.setPosition(effector, space, targetPos, speed, axisMask) #Try it twice, because it doesn't seem to get there '''currentPos = motionProxy.getPosition(effector, space, True) motionProxy.positionInterpolation(effector, space, [currentPos], axisMask, [0.51], isAbsolute) targetPos = [currentPos[0]-center[0], currentPos[1]-center[1], currentPos[2]-center[2], 0.0, 0.0, 0.0] path = [targetPos] print targetPos motionProxy.positionInterpolation(effector, space, path, axisMask, [0.51], isAbsolute) print "sleeping 2 seconds"''' global_time = time.time() else: speed = 0.18 # False learning if random.random()<0.15: k=max(0.85,k-0.15) # Generate next target x,y x = k*random.random()*L-L/2 + center[0] y = k*random.random()*L-L/2 + center[1] # Get current Position & define target position #currentPos = motionProxy.getPosition(effector, space, True) #targetPos = currentPos targetPos[0] = x#min(max(x,meanx-maxx),meanx+maxx) targetPos[1] = y#min(max(y,meany-maxy),meany+maxy) targetPos[2] = center[2] #print 'new target' #print targetPos # Move to position, being able to interrupt motionProxy.setPosition(effector, space, targetPos, speed, axisMask) now = time.time() go_to_center = False while time.time()-now < times[0] and not go_to_center: #time.sleep(0.1) currentPos = motionProxy.getPosition(effector, space, True) offx = 0.034 offy = 0.04 xy=[1345+97-(currentPos[0]+offx)*400/(0.07), (currentPos[1]+offy)*400/(0.07)+107-87-45] #print xy sendOSC('/xy',xy) time.sleep(0.01) print 'out of the loop' """else: #currentPos = motionProxy.getPosition(effector, space, True) #center[0] -= targetPos[0] #center[1] -= targetPos[1] """ print 'Done!' server = OSCServer( ("" , 2222) ) server.addMsgHandler("/move", move) while 1: server.handle_request() except KeyboardInterrupt: print "closing all OSC connections... and exit" motionProxy.rest() myBroker.shutdown() server.close() motionProxy.rest()
class Matrix(object): server = None driver = None led = None modes = [] running = False color = None wheel = None pong = None scope = None mode = 0; joysticks = [] pong_running = False scope_running = False def __init__(self): self.server = OSCServer( ("192.168.2.122", 5005) ) self.server.timeout = 0 self.driver = DriverAdaMatrix(rows=32, chain=2) self.driver.SetPWMBits(6) self.led = LEDMatrix(self.driver, 64, 32, serpentine=False) self.modes = [self.mode_presets, self.color_presets, self.color_gradient, self.white_gradient, self.direct_control, self.arcade, self.mindfuck] self.color = colors.Salmon self.wheel = ColorWheel() self.running = True self.joysticks = [0] * 5 self.pong = Pong(self.led) self.scope = Scope(self.led, self.wheel) self.scheme = [] # funny python's way to add a method to an instance of a class # import types # self.server.handle_timeout = types.MethodType(lambda: self.handle_timeout(self), self.server) self.server.addMsgHandler("/mode", self.mode_callback) self.server.addMsgHandler("/coin", self.coin_callback) self.server.addMsgHandler("/js", self.joystick_callback) self.server.addMsgHandler("/pot", self.pot_callback) self.server.addMsgHandler("/fad", self.fader_callback) self.server.addMsgHandler("/beam", self.beam_callback) self.server.addMsgHandler("/scheme", self.scheme_callback) self.server.addMsgHandler("/sleep", self.sleep_callback) # this method of reporting timeouts only works by convention # that before calling handle_request() field .timed_out is # set to False def handle_timeout(self): self.timed_out = True # TODO: update this to take all the joysticks and send them off selectively def joystick_callback(self, path, tags, args, source): if self.pong_running: self.pong.update_sticks(args[0], args[4]) elif self.scope_running: self.scope.update_sticks(args) def pot_callback(self, path, tags, args, source): if self.scope_running: self.scope.update_pots(args) def fader_callback(self, path, tags, args, source): if self.scope_running: self.scope.update_faders(args) def beam_callback(self, path, tags, args, source): if self.scope_running: self.scope.update_beam(args[0]) def mode_callback(self, path, tags, args, source): self.scope_running = True self.led.all_off() if (self.mode == 5 and int(args[0]) != 5): self.pong_running = False self.mode =int(args[0]) self.modes[self.mode]() self.led.update() sleep(1) def coin_callback(self, path, tags, args, source): self.led.all_off() self.led.update() count = 0 while count < 5: self.led.drawText("Thank You!!", 4, 10, size=1, color=colors.Lavender) self.led.update() sleep(1) self.led.all_off() self.led.update() sleep(0.5) count += 1 self.modes[self.mode]() self.led.update() def scheme_callback(self, path, tags, args, source): self.scheme = [] for i in xrange(0, len(args), 3): self.scheme.append(args[i:i+3]) self.wheel.setScheme(self.scheme) def sleep_callback(self, path, tags, args, source): print("sleep plz") self.scope_running = False self.pong_running = False self.led.all_off() self.led.update() # user script that's called by the game engine every frame def each_frame(self): # clear timed_out flag self.server.timed_out = False # handle all pending requests then return while not self.server.timed_out: self.server.handle_request() if self.pong_running: self.led.all_off() self.pong.step() self.led.update() sleep(0.05) elif self.scope_running: self.led.all_off() self.scope.step() self.led.update() sleep(0.05) def mode_presets(self): self.led.drawText("Mode", 6, 5, size=1, color=self.color) self.led.drawText("Presets", 6, 15, size=1, color=self.color) def color_presets(self): self.led.drawText("Color", 6, 5, size=1, color=self.color) self.led.drawText("Presets", 6, 15, size=1, color=self.color) def color_gradient(self): self.led.drawText("Color", 6, 5, size=1, color=self.color) self.led.drawText("Gradients", 6, 15, size=1, color=self.color) def white_gradient(self): self.led.drawText("White", 6, 5, size=1, color=self.color) self.led.drawText("Gradients", 6, 15, size=1, color=self.color) def direct_control(self): self.led.drawText("Direct", 6, 5, size=1, color=self.color) self.led.drawText("Control", 6, 15, size=1, color=self.color) def arcade(self): # self.led.drawText("Arcade", 6, 5, size=1, color=self.color) # self.led.drawText("Mode!!!", 6, 15, size=1, color=self.color) anim = ScrollText(self.led, "Arcade Mode!!!!!", 64, 13, size=1, color=self.color) anim.run(fps=30, untilComplete=True, max_cycles=1) self.pong.reset() self.scope_running = False self.pong_running = True def mindfuck(self): self.led.drawText("Y U NO", 6, 5, size=1, color=self.color) self.led.drawText("LISTEN?!", 6, 15, size=1, color=self.color) self.scope_running = False def run(self): while self.running: sleep(1) self.each_frame()
class Main: roll = 0.0 pitch = 0.0 yawrate = 0 thrust = 10001 def __init__(self): self.server = OSCServer (("0.0.0.0", 8000)) self.server.addMsgHandler("/1/rollpitch", self.roll_pitch_callback) self.server.addMsgHandler("/1/yawthrust", self.yaw_thrust_callback) self.server.addMsgHandler("/1/stop", self.stop_callback) self.server.addMsgHandler("/1/hovermode", self.hovermode_callback) self.crazyflie = Crazyflie() cflib.crtp.init_drivers() available_radios = cflib.crtp.scan_interfaces() print available_radios #For now assume we want the 1st radio radio = available_radios[0][0] #Connect to the flie self.crazyflie.open_link(radio) self.crazyflie.connectSetupFinished.add_callback(self.connectSetupFinished) self.crazyflie.connectionFailed.add_callback(self.connectionLost) self.crazyflie.connectionLost.add_callback(self.connectionLost) def connectSetupFinished(self, linkURI): Thread(target=self.send_setpoint_loop).start() Thread(target=self.osc_loop).start() self.crazyflie.param.set_value("stabilizer.debug", "0") self.crazyflie.param.add_update_callback("stabilizer.debug", self.paramUpdateCallback) self.crazyflie.param.add_update_allback("stabilizer.mode", self.paramUpdateCallback) def paramUpdateCallback(self, name, value): print "%s has value %d" % (name, value) def accel_log_callback(self, data): logging.info("Accelerometer: x+%.2f, y=%.2f, z=%.2f" % (data["acc.x"], data["acc.y"], data["acc.z"])) def osc_loop(self): while True: self.server.handle_request() def roll_pitch_callback(self, path, tags, args, source): #print ("path", path) #print ("args", args) #print ("source", source) print "ROLL", args[0] #self.roll=(args[0]*180)-90 self.roll=(args[0]*90)-45 print "PITCH", args[1] #self.pitch=(180*args[1])-90 self.pitch=(args[1]*90)-45 def yaw_thrust_callback(self, path, tags, args, source): #print ("path", path) #print ("args", args) #print ("source", source) print "YAW", (180*args[1])-90 print "THRUST", (49999*args[0])+10001 self.thrust = (49999*args[0]) + 10001 self.yawrate = (args[1]*90)-45 def stop_callback(self, path, tags, args, source): self.crazyflie.param.set_value("stabilizer.debug", "1") self.thrust = 0 self.send_setpoint() self.crazyflie.close_link() exit() def hovermode_callback(self, path, tags, args, source): if args[0]: logging.info("Entering hover mode.") self.crazyflie.param.set_value("stabilizer.mode", "1") else: logging.info("Exiting hover mode.") self.crazyflie.param.set_value("stabilizer.mode", "0") def send_setpoint_loop(self): while True: self.send_setpoint() time.sleep(0.1) def send_setpoint(self): self.crazyflie.commander.send_setpoint(self.roll, self.pitch, self.yawrate, self.thrust) def connectionLost(self, linkURI): print "CONNECTION LOST!" exit()
print args print source print mDirection print '-----------' if mDirection == 'forward' and msgVal == 1: moveRover.forward(config.getint('motor_params', 'DEFAULT_SPEED')) elif mDirection == 'backward' and msgVal == 1: moveRover.backward(config.getint('motor_params', 'DEFAULT_SPEED')) elif mDirection == 'right' and msgVal == 1: moveRover.right(config.getint('motor_params', 'DEFAULT_SPEED')) elif mDirection == 'left' and msgVal == 1: moveRover.left(config.getint('motor_params', 'DEFAULT_SPEED')) else: moveRover.stop() directions = ['forward', 'backward', 'right', 'left'] #Message Handlers and Callback functions for direction in directions: oscSrv.addMsgHandler("/move/" + direction, move) print "\n listening on port: %s" % config.get('osc_srv', 'PORT') try: while True: oscSrv.handle_request() except KeyboardInterrupt: print "Quit" oscSrv.close()
class MuseIO(): def __init__(self, port=DEFAULT_MUSEIO_PORT, signal=None, ip=DEFAULT_MUSEIO_IP): self.signal = signal self.port = port self.udp_ip = ip if not has_oscserver: raise Exception('ERROR: OSC not found') self.server = OSCServer((self.udp_ip, self.port)) self.server.timeout = 0 self.current_sample_id = 0 # funny python's way to add a method to an instance of a class self.server.handle_timeout = types.MethodType(handle_timeout, self.server) # add message handlers if 'eeg' in self.signal: self.server.addMsgHandler('/muse/eeg', self.callback_eeg_raw) if 'concentration' in self.signal: self.server.addMsgHandler('/muse/elements/beta_relative/', self.callback_concentration) def callback_eeg_raw(self, path, tags, args, source): if 'eeg' in self.signal: self.signal['eeg'].lock.acquire() self.signal['eeg'].id = self.current_sample_id self.signal['eeg'].add_data(args, add_time=False) self.signal['eeg'].add_time(time.time()) self.signal['eeg'].add_datetime(datetime.now()) self.signal['eeg'].lock.release() def callback_concentration(self, path, tags, args, source): if 'concentration' in self.signal: self.signal['concentration'].lock.acquire() self.signal['concentration'].id = self.current_sample_id self.signal['concentration'].add_data(args, add_time=False) self.signal['concentration'].add_time(time.time()) self.signal['concentration'].add_datetime(datetime.now()) self.signal['concentration'].lock.release() def handle_request(self): self.server.timed_out = False # handle all pending requests then return while not self.server.timed_out: self.server.handle_request() def start(self, freq=DEFAULT_FREQ): update_timing = 1.0 / float(freq) while True: try: time.sleep(update_timing) self.handle_request() except KeyboardInterrupt: print('KeyboardInterrupt on line {}'.format( sys.exc_info()[-1].tb_lineno)) sys.exit(2) except Exception as e: print('Error on line {}'.format(sys.exc_info()[-1].tb_lineno)) print(str(e)) sys.exit(2)
class OSCHandler(object): """Set up OSC server and other handlers.""" def __init__(self, field): self.m_field = field self.m_server = OSCServer( (OSCHOST, OSCPORT) ) self.m_server.timeout = OSCTIMEOUT self.m_run = True self.m_xmin = 0 self.m_ymin = 0 self.m_xmax = 0 self.m_ymax = 0 self.eventfunc = { 'ping': self.event_tracking_ping, 'ack': self.event_tracking_ack, 'start': self.event_tracking_start, 'entry': self.event_tracking_entry, 'exit': self.event_tracking_exit, 'frame': self.event_tracking_frame, 'stop': self.event_tracking_stop, 'minx': self.event_tracking_set, 'miny': self.event_tracking_set, 'maxx': self.event_tracking_set, 'maxy': self.event_tracking_set, 'npeople': self.event_tracking_set, 'groupdist': self.event_tracking_set, 'ungroupdist': self.event_tracking_set, 'fps': self.event_tracking_set, 'update': self.event_tracking_update, 'leg': self.event_tracking_leg, 'body': self.event_tracking_body, } # add a method to an instance of the class self.m_server.handle_timeout = types.MethodType(handle_timeout, self.m_server) for i in self.eventfunc: self.m_server.addMsgHandler(OSCPATH[i], self.eventfunc[i]) # this registers a 'default' handler (for unmatched messages), # an /'error' handler, an '/info' handler. # And, if the client supports it, a '/subscribe' & # '/unsubscribe' handler self.m_server.addDefaultHandlers() self.m_server.addMsgHandler("default", self.default_handler) # TODO: Handle errors from OSCServer #self.m_server.addErrorHandlers() #self.m_server.addMsgHandler("error", self.default_handler) self.honey_im_home() def honey_im_home(self): """Broadcast a hello message to the network.""" # TODO: Broadcast hello message return True def each_frame(self): # clear timed_out flag self.m_server.timed_out = False # handle all pending requests then return while not self.m_server.timed_out: self.m_server.handle_request() def user_callback(self, path, tags, args, source): # which user will be determined by path: # we just throw away all slashes and join together what's left user = ''.join(path.split("/")) # tags will contain 'fff' # args is a OSCMessage with data # source is where the message came from (in case you need to reply) if dbug.LEV & dbug.MSGS: print ("Now do something with", user,args[2],args[0],1-args[1]) def quit_callback(self, path, tags, args, source): # don't do this at home (or it'll quit blender) self.m_run = False # Event handlers def default_handler(self, path, tags, args, source): if dbug.LEV & dbug.MORE: print "OSC:default_handler:No handler registered for ", path return None def event_tracking_ping(self, path, tags, args, source): if dbug.LEV & dbug.MSGS: print "OSC:event_ping:code",args[0] return None def event_tracking_ack(self, path, tags, args, source): if dbug.LEV & dbug.MSGS: print "OSC:event_ack:code",args[0] return None def event_tracking_start(self, path, tags, args, source): """Tracking system is starting. Sent before first /pf/update message for that target args: [ aparently no params now] samp - sample number t - time of sample (elapsed time in seconds since beginning of run) target - UID of target channel - channel number assigned """ #samp = args[0] if dbug.LEV & dbug.MSGS: print "OSC:event_start" def event_tracking_set(self, path, tags, args, source): """Tracking subsystem is setting params. Send value of various parameters. args: minx, miny, maxx, maxy - bounds of PF in units npeople - number of people currently present """ if dbug.LEV & dbug.MSGS: print "OSC:event_set:",path,args,source if path == OSCPATH['minx']: self.m_xmin = int(100*args[0]) if dbug.LEV & dbug.MSGS: print "OSC:event_set:set_scaling(",\ (self.m_xmin,self.m_ymin),",",(self.m_xmax,self.m_ymax),")" # we might not have everything yet, but we udate with what we have self.m_field.set_scaling(pmin_field=(self.m_xmin,self.m_field.m_ymin_field)) elif path == OSCPATH['miny']: self.m_ymin = int(100*args[0]) if dbug.LEV & dbug.MSGS: print "OSC:event_set:set_scaling(",\ (self.m_xmin,self.m_ymin),",",(self.m_xmax,self.m_ymax),")" # we might not have everything yet, but we udate with what we have self.m_field.set_scaling(pmin_field=(self.m_field.m_xmin_field,self.m_ymin)) elif path == OSCPATH['maxx']: self.m_xmax = int(100*args[0]) if dbug.LEV & dbug.MSGS: print "OSC:event_set:set_scaling(",\ (self.m_xmin,self.m_ymin),",",(self.m_xmax,self.m_ymax),")" # we might not have everything yet, but we udate with what we have self.m_field.set_scaling(pmax_field=(self.m_xmax,self.m_field.m_ymax_field)) elif path == OSCPATH['maxy']: self.m_ymax = int(100*args[0]) if dbug.LEV & dbug.MSGS: print "OSC:event_set:set_scaling(",\ (self.m_xmin,self.m_ymin),",",(self.m_xmax,self.m_ymax),")" # we might not have everything yet, but we udate with what we have self.m_field.set_scaling(pmax_field=(self.m_field.m_xmax_field,self.m_ymax)) elif path == OSCPATH['npeople']: self.m_field.check_people_count(args[0]) return elif path == OSCPATH['groupdist']: self.m_field.update(groupdist=args[0]) return elif path == OSCPATH['ungroupdist']: self.m_field.update(ungroupdist=args[0]) return elif path == OSCPATH['fps']: self.m_field.update(oscfps=args[0]) return #if self.m_xmin and self.m_ymin and self.m_xmax and self.m_ymax: #print "set_scaling(",(self.m_xmin,self.m_ymin),",",(self.m_xmax,self.m_ymax),")" #self.m_field.set_scaling((self.m_xmin,self.m_ymin),(self.m_xmax,self.m_ymax)) #self.m_field.updateScreen() def event_tracking_entry(self, path, tags, args, source): """Event when person enters field. Sent before first /pf/update message for that target args: samp - sample number t - time of sample (elapsed time in seconds since beginning of run) target - UID of target channel - channel number assigned """ #print "OSC:event_entry:",path,args,source #print "args:",args,args[0],args[1],args[2] samp = args[0] time = args[1] id = args[2] if dbug.LEV & dbug.MSGS: print "OSC:event_entry:cell:",id self.m_field.create_cell(id) def event_tracking_exit(self, path, tags, args, source): """Event when person exits field. args: samp - sample number t - time of sample (elapsed time in seconds since beginning of run) target - UID of target """ #print "OSC:event_exit:",path,args,source samp = args[0] time = args[1] id = args[2] if dbug.LEV & dbug.MSGS: print "OSC:event_exit:cell:",id #print "BEFORE: cells:",self.m_field.m_cell_dict #print "BEFORE: conx:",self.m_field.m_connector_dict self.m_field.del_cell(id) #print "AFTER: cells:",self.m_field.m_cell_dict #print "AFTER: conx:",self.m_field.m_connector_dict def event_tracking_body(self, path, tags, args, source): """Information about people's movement within field. Update position of target. args: samp - sample number target - UID of target x,y - position of person within field in m ex,ey - standard error of measurement (SEM) of position, in meters spd, heading - estimate of speed of person in m/s, heading in degrees espd, eheading - SEM of spd, heading facing - direction person is facing in degees efacing - SEM of facing direction diam - estimated mean diameter of legs sigmadiam - estimated sigma (sqrt(variance)) of diameter sep - estimated mean separation of legs sigmasep - estimated sigma (sqrt(variance)) of sep leftness - measure of how likely leg 0 is the left leg visibility - number of frames since a fix was found for either leg """ for index, item in enumerate(args): if item == 'nan': args[index] = 0 samp = args[0] id = args[1] x = int(100*args[2]) # comes in meters, convert to cm y = int(100*args[3]) ex = int(100*args[4]) ey = int(100*args[5]) spd = int(100*args[6]) heading = args[7] espd = int(100*args[8]) eheading = args[9] facing = args[10] efacing = args[11] diam = int(100*args[12]) sigmadiam = int(100*args[13]) sep = int(100*args[14]) sigmasep = int(100*args[15]) leftness = args[16] vis = args[17] if id not in self.m_field.m_cell_dict: if dbug.LEV & dbug.MSGS: print "OSC:event_body:no id",id,"in registered id list" if samp%FREQ_REG_REPORT == 0: if dbug.LEV & dbug.MSGS: print " OSC:event_body:id:",id,"pos:",(x,y) self.m_field.update_body(id, x, y, ex, ey, spd, espd, facing, efacing, diam, sigmadiam, sep, sigmasep, leftness, vis) def event_tracking_leg(self, path, tags, args, source): """Information about individual leg movement within field. Update position of leg. args: samp - sample number id - UID of target leg - leg number (0..nlegs-1) nlegs - number of legs target is modeled with x,y - position within field in m ex,ey - standard error of measurement (SEM) of position, in meters spd, heading - estimate of speed of leg in m/s, heading in degrees espd, eheading - SEM of spd, heading visibility - number of frames since a positive fix """ for index, item in enumerate(args): if item == 'nan': args[index] = 0 samp = args[0] id = args[1] leg = args[2] nlegs = args[3] x = int(100*args[4]) # comes in meters, convert to cm y = int(100*args[5]) ex = int(100*args[6]) ey = int(100*args[7]) spd = int(100*args[8]) heading = args[9] espd = int(100*args[10]) eheading = args[11] vis = args[12] if id not in self.m_field.m_cell_dict: if dbug.LEV & dbug.MSGS: print "OSC:event_leg:no id",id,"in registered id list" if samp%FREQ_REG_REPORT == 0: if dbug.LEV & dbug.MSGS: print " OSC:event_leg:id:",id,"leg:",leg,"pos:",(x,y) self.m_field.update_leg(id, leg, nlegs, x, y, ex, ey, spd, espd, heading, eheading, vis) def event_tracking_update(self, path, tags, args, source): """Information about people's movement within field. Update position of target. args: samp - sample number t - time of sample (elapsed time in seconds since beginning of run) target - UID of target x,y - position within field in units - increasing in value towards right and down vx,vy - estimate of velocity in m/s major,minor - major/minor axis size in m groupid - id number of group groupsize - number of people in group channel - channel number assigned """ for index, item in enumerate(args): if item == 'nan': args[index] = 0 samp = args[0] time = args[1] id = args[2] if id not in self.m_field.m_cell_dict: if dbug.LEV & dbug.MSGS: print "OSC:event_update:no id",id,"in registered id list" x = int(100*args[3]) # comes in meters, convert to cm y = int(100*args[4]) vx = int(100*args[5]) vy = int(100*args[6]) major = int(100*args[7]/2) minor = int(100*args[8]/2) gid = args[9] gsize = args[10] channel = args[11] #print "OSC:event_update:",path,args,source if samp%FREQ_REG_REPORT == 0: #print "OSC:event_update:",path,args,source if dbug.LEV & dbug.MSGS: print " OSC:event_update:id:",id,"pos:",(x,y),"axis:",major #print "field.update_cell(",id,",",(x,y),",",major,")" self.m_field.update_cell(id,(x,y),major) #print "OSC:event_update: Done" def event_tracking_frame(self, path, tags, args, source): """New frame event. args: samp - sample number """ #print "OSC:event_frame:",path,args,source samp = args[0] if samp%FREQ_REG_REPORT == 0: #print "OSC:event_update:",path,args,source if dbug.LEV & dbug.MSGS: print " OSC:event_frame::",samp return None def event_tracking_stop(self, path, tags, args, source): """Tracking has stopped.""" if dbug.LEV & dbug.MSGS: print "OSC:event_stop:",path,args,source return None
class Osc(object): def __init__(self, listen_port=7331, timeout=4, timeout_fade_duration=4): # create an OSC server and bind it to listen on port 7331 self.server = OSCServer(("", listen_port)) self.server.timeout = 0 self.server.handle_timeout = types.MethodType( lambda x: self.handle_timeout(), self.server) # Create handlers for "/rgb" and "/hsv". This causes a packet to "/rgb" to call self.set_rgb() # and a packet to "/hsv" to call self.set_hsv(), with the arguments path, tags, args, source self.server.addMsgHandler("/rgbw", lambda p, t, a, s: self.set_rgbw(p, t, a, s)) self.server.addMsgHandler("/rgb", lambda p, t, a, s: self.set_rgb(p, t, a, s)) self.server.addMsgHandler("/r", lambda p, t, a, s: self.set_r(p, t, a, s)) self.server.addMsgHandler("/g", lambda p, t, a, s: self.set_g(p, t, a, s)) self.server.addMsgHandler("/b", lambda p, t, a, s: self.set_b(p, t, a, s)) self.server.addMsgHandler("/w", lambda p, t, a, s: self.set_w(p, t, a, s)) self.server.addMsgHandler("/hsv", lambda p, t, a, s: self.set_hsv(p, t, a, s)) self.server.addMsgHandler("/h", lambda p, t, a, s: self.set_h(p, t, a, s)) self.server.addMsgHandler("/s", lambda p, t, a, s: self.set_s(p, t, a, s)) self.server.addMsgHandler("/v", lambda p, t, a, s: self.set_v(p, t, a, s)) # Initialize variables self.color = Color(0.0, 0.0, 0.0, 0.0) self.opacity = 0.0 self.timeout = timeout self.timeout_fade_duration = timeout_fade_duration # Setup our animation queue self.anim_queue = AnimationQueue() # The last time we got a message on our socket self.last_msg_time = time.time() # Close the socket on exit def cleanup(self): self.server.close() def got_a_packet(self): self.opacity = 1.0 self.last_msg_time = time.time() self.anim_queue.clear() # Set the current color in either RGB or HSV colorspace def set_rgbw(self, path, tags, args, source): self.color.setRGBW(*args) self.got_a_packet() def set_rgb(self, path, tags, args, source): self.color.setRGB(*args) self.got_a_packet() def set_r(self, path, tags, args, source): print path, tags, args, source self.color.setR(args[0]) self.got_a_packet() def set_g(self, path, tags, args, source): self.color.setG(args[0]) self.got_a_packet() def set_b(self, path, tags, args, source): self.color.setB(args[0]) self.got_a_packet() def set_w(self, path, tags, args, source): self.color.setB(args[0]) self.got_a_packet() def set_hsv(self, path, tags, args, source): self.color.setHSV(*args) self.got_a_packet() def set_h(self, path, tags, args, source): self.color.setH(args[0]) self.got_a_packet() def set_s(self, path, tags, args, source): self.color.setS(args[0]) self.got_a_packet() def set_v(self, path, tags, args, source): self.color.setV(args[0]) self.got_a_packet() # This gets called when we have no more packets waiting to be processed def handle_timeout(self): self.timed_out = True # This function retrieves the next color from the Audio object def next(self, color_in): # process any messages we might have waiting for us. We do this by calling handle_request() until # handle_timeout() gets called, at which point we stop: self.timed_out = False while not self.timed_out: self.server.handle_request() # If we've not received a message for `timeout` seconds, slowly ease back to 1.0 power if self.last_msg_time + self.timeout < time.time( ) and self.opacity != 0.0: # Ease slowly from the current value of self.opacity to 0.0 self.anim_queue.push( ease(self.opacity, 0.0, self.timeout_fade_duration, sin_ease)) # This ensures that once the animation is done, we stay at 0.0, and also that we # don't keep on animating over and over again (e.g. the if statement directly above # doesn't keep on activating over and over again) self.opacity = 0.0 # If we're easing back to 0.0 after a client disconnect, then this animation does something. # If we're receiving packets like normal, this animation does nothing, it just returns self.opacity animated_opacity = self.anim_queue.animate(default_value=self.opacity) # Mix between color_in and our stored self.color return color_in * (1.0 - animated_opacity) + animated_opacity * self.color
class LiveRawAPI(object): """ This is close to live's API objects as possible Of course, they are designed to be manipulated from a patcher, not real code, so a bit more wrapping is in order. To keep everything minimal, this is done in a subclass. """ _incoming = None _handled = True _received = False debug = False def __init__(self, there_host="localhost", there_port=7400, here_host="localhost", here_port=7401, debug=False, *args, **kwargs): super(LiveRawAPI, self).__init__(*args, **kwargs) self.oscserver = OSCServer((here_host, here_port)) self.oscclient = OSCClient() self.oscclient.connect((there_host, there_port)) self.oscserver.addMsgHandler('/response', self._handle_response) self._incoming = [] def raw_query(self, *args): """Posts a query, waits for a response. Returns it. Note that state is fragile here, so you'd better be sure that there will be a response, or it will hang waiting.""" self.oscclient.send(OSCMessage('/query', args)) return self.handle_request() def raw_call(self, *args): """Posts a call, returns nothing. Note that state is fragile here, so you'd better be sure that there will be no response, or you won't know what returned what.""" self.oscclient.send(OSCMessage('/query', ['path', 'getpath'])) def _handle_response(self, path, tags, args, source): """private callback to handle OSC responses. Sets state.""" if self.debug: print "callback", path, args, source self._incoming.append(args) self._received = True def handle_request(self): """hack to handle asynchronous calls: 1 try to get something returned and tacked onto the class. 2 Return it and reset. This is completely f****d at the momenl I can't make timeouts work in any usable fashion.""" try: self.oscserver.handle_request() while self._received: self._received = False self.oscserver.handle_request() _incoming = self._incoming return _incoming finally: self._incoming = [] self._received = False def close(self): self.oscserver.close() ### more structured access involves navigating places with the path object def goto(self, *args): resp = self.raw_query('path', 'goto', *args) prefix, path = resp[1], resp[2:] #sanity check that we are getting the right message assert prefix=='path' self.path = path def path(self, *args): return self.goto(*args) def getchildren(self): resp = self.raw_query('path', 'getchildren') return resp[1:] def getcount(self): resp = self.raw_query('path', 'getcount') return resp[1:]
class Server(): """Listener to collect results of Keykit server. (Adaption of OSC package example.) """ def __init__(self, server_adr): self.server = OSCServer(server_adr) self.server.socket.settimeout(3) self.run = True self.timed_out = False # funny python's way to add a method to an instance of a class # import types # self.server.handle_timeout = types.MethodType( # self.handle_timeout, self.server) # or self.server.handle_timeout = self.handle_timeout # Handler self.server.addMsgHandler("/quit", self.quit_callback) self.server.addMsgHandler("/keykit/pyconsole/out", self.print_callback) self.server.addMsgHandler("/keykit/pyconsole/err", self.err_callback) self.server.addMsgHandler( "/keykit/pyconsole/start", self.print_callback) self.server.addMsgHandler("/keykit/pyconsole/lsdir", self.dir_callback) def handle_timeout(self, server=None): self.timed_out = True def each_frame(self): # clear timed_out flag self.timed_out = False # handle all pending requests then return while not self.timed_out and self.run: self.server.handle_request() # Line reached after each socket read sleep(.05) def start(self): # print("Wait on client input...") sys.stdout.write("%s" % (MY_PROMPT)) sys.stdout.flush() while self.run: self.each_frame() # Line reached after each socket timeout sleep(1) def stop(self): self.run = False # Invoke shutdown. Socket still wait on timeout... try: import socket self.server.socket.shutdown(socket.SHUT_RDWR) except socket.error: pass self.server.close() # Callbacks def quit_callback(self, path, tags, args, source): self.run = False def print_callback(self, path, tags, args, source, textColor=ColorOut): current_input = readline.get_line_buffer() # Add Tab at every input line out = args[0].replace("\n", "\n\t") # Delete current input, insert output and add input again. # \r : Carriage return, \033[K : Delete everything after the cursor. sys.stdout.write("\r\033[K") sys.stdout.write( "\t%s%s%s\n%s%s" % (textColor, out, ColorReset, MY_PROMPT, current_input)) sys.stdout.flush() def err_callback(self, path, tags, args, source): """ Same as print_callback but mark output as error. """ self.print_callback(path, tags, args, source, ColorWarn) def dir_callback(self, path, tags, args, source): """ Store current working dir for tab completion. This is mainly releated to chdir() and lsdir(). """ lsdir_string_part = args[0] if lsdir_string_part[0] == "^": self.keykit_lsdir_string = lsdir_string_part else: self.keykit_lsdir_string += lsdir_string_part if self.keykit_lsdir_string[-1] == "$": try: lsdir = [] # Convert string into list of files. Second argument flags # directories. # Example string: ^["foldername"=1,"filename"=0]$ re_entries = '".+?"=[01][,\]]' entries = re.finditer(re_entries, self.keykit_lsdir_string) for entry in entries: sname = entry.group()[1:-4] bFolder = entry.group()[-2] == "1" lsdir.append((sname, bFolder)) self.keykit_lsdir = lsdir except: sys.stderr.write("(dir_callback) Unable to fetch folder content.") self.keykit_lsdir = []
class OscReader: def __init__(self, host="127.0.0.1", port=8080, manager=None, threaded=False, autoStart=True): # params self.manager = manager self.host = host self.port = port self.threaded = threaded # attrs self._kill = False self.oscServer = None self.thread = None if autoStart: self.start() def setup(self): if self.oscServer != None: self.destroy() ColorTerminal().output( "Starting OSC server with host {0} and port {1}".format( self.host, self.port)) self.oscServer = OSCServer((self.host, self.port)) self.oscServer.handle_timeout = self.handleTimeout self.oscServer.addMsgHandler('/marker', self.oscMarkerHandler) self.oscServer.addMsgHandler('/rigidbody', self.oscRigidBodyHandler) ColorTerminal().success("Server running") def destroy(self): if self.oscServer == None: return self.oscServer.close() self.oscServer = None def update(self): if self.oscServer == None: return # we'll enforce a limit to the number of osc requests # we'll handle in a single iteration, otherwise we might # get stuck in processing an endless stream of data limit = 10 count = 0 # clear timed_out flag self.oscServer.timed_out = False # handle all pending requests then return while not self.oscServer.timed_out and count < limit: self.oscServer.handle_request() count += 1 def oscMarkerHandler(self, addr, tags, data, client_address): if self.manager: self.manager.processMarkersData([data[0]]) def oscRigidBodyHandler(self, addr, tags, data, client_address): # readers can interface with the mocap data manager directly (most efficient) if self.manager: self.manager.processRigidBodyJson(data[0]) def handleTimeout(self): if self.oscServer != None: self.oscServer.timed_out = True def start(self): if not self.threaded: self.setup() return if self.thread and self.thread.isAlive(): ColorTerminal().warn( "OscReader - Can't start while a thread is already running") return self._kill = False # threaded loop method will call setup self.thread = threading.Thread(target=self.threaded_loop) self.thread.start() def stop(self): if self.threaded: # threaded loop method will call destroy self._kill = True else: self.destroy() def threaded_loop(self): self.setup() while not self._kill: self.update() self.destroy()
sys.stdout.write(RED) print '\n waiting for Phone TouchOSC App...\n' sys.stdout.write(RESET) # Create virtual environment ------------------------------------------------------------------------------------------- # first we create the arrow to show current position of the servo measuringArrow = arrow(pos=(0, -10, 0), axis=(0, 10, 0), shaftwidth=0.4, headwidth=0.6) # and now the labels angleLabel = label(text='angle: 90', pos=(0, 5, 0), height=15, box=false) angle0 = label(text='0', pos=(-10, -10, 0), height=15, box=false) angle45 = label(text='45', pos=(-7.5, -2.5, 0), height=15, box=false) angle90 = label(text='90', pos=(0, 1, 0), height=15, box=false) angle135 = label(text='135', pos=(7.5, -2.5, 0), height=15, box=false) angle180 = label(text='180', pos=(10, -10, 0), height=15, box=false) # Main ----------------------------------------------------------------------------------------------------------------- while True: Conrol = get_Conrol() # get path control string from Phone touchOSC server = OSCServer( (serverAdr, serverPort)) # define OSC server on computer client = OSCClient() # define OSC client on Phone touchOSC client.connect((clientAdr, clientPort)) # connect to client server.addMsgHandler( Conrol, servo_call) # use the control path and process message server.handle_request() # handle request rate(20) # refresh rate required for VPython server.close() # close the server, start over again and again.
class Matrix(object): server = None driver = None led = None modes = [] running = False color = None wheel = None pong = None scope = None mode = 0 joysticks = [] pong_running = False scope_running = False def __init__(self): self.server = OSCServer(("192.168.2.122", 5005)) self.server.timeout = 0 self.driver = DriverAdaMatrix(rows=32, chain=2) self.driver.SetPWMBits(6) self.led = LEDMatrix(self.driver, 64, 32, serpentine=False) self.modes = [ self.mode_presets, self.color_presets, self.color_gradient, self.white_gradient, self.direct_control, self.arcade, self.mindfuck ] self.color = colors.Salmon self.wheel = ColorWheel() self.running = True self.joysticks = [0] * 5 self.pong = Pong(self.led) self.scope = Scope(self.led, self.wheel) self.scheme = [] # funny python's way to add a method to an instance of a class # import types # self.server.handle_timeout = types.MethodType(lambda: self.handle_timeout(self), self.server) self.server.addMsgHandler("/mode", self.mode_callback) self.server.addMsgHandler("/coin", self.coin_callback) self.server.addMsgHandler("/js", self.joystick_callback) self.server.addMsgHandler("/pot", self.pot_callback) self.server.addMsgHandler("/fad", self.fader_callback) self.server.addMsgHandler("/beam", self.beam_callback) self.server.addMsgHandler("/scheme", self.scheme_callback) self.server.addMsgHandler("/sleep", self.sleep_callback) # this method of reporting timeouts only works by convention # that before calling handle_request() field .timed_out is # set to False def handle_timeout(self): self.timed_out = True # TODO: update this to take all the joysticks and send them off selectively def joystick_callback(self, path, tags, args, source): if self.pong_running: self.pong.update_sticks(args[0], args[4]) elif self.scope_running: self.scope.update_sticks(args) def pot_callback(self, path, tags, args, source): if self.scope_running: self.scope.update_pots(args) def fader_callback(self, path, tags, args, source): if self.scope_running: self.scope.update_faders(args) def beam_callback(self, path, tags, args, source): if self.scope_running: self.scope.update_beam(args[0]) def mode_callback(self, path, tags, args, source): self.scope_running = True self.led.all_off() if (self.mode == 5 and int(args[0]) != 5): self.pong_running = False self.mode = int(args[0]) self.modes[self.mode]() self.led.update() sleep(1) def coin_callback(self, path, tags, args, source): self.led.all_off() self.led.update() count = 0 while count < 5: self.led.drawText("Thank You!!", 4, 10, size=1, color=colors.Lavender) self.led.update() sleep(1) self.led.all_off() self.led.update() sleep(0.5) count += 1 self.modes[self.mode]() self.led.update() def scheme_callback(self, path, tags, args, source): self.scheme = [] for i in xrange(0, len(args), 3): self.scheme.append(args[i:i + 3]) self.wheel.setScheme(self.scheme) def sleep_callback(self, path, tags, args, source): print("sleep plz") self.scope_running = False self.pong_running = False self.led.all_off() self.led.update() # user script that's called by the game engine every frame def each_frame(self): # clear timed_out flag self.server.timed_out = False # handle all pending requests then return while not self.server.timed_out: self.server.handle_request() if self.pong_running: self.led.all_off() self.pong.step() self.led.update() sleep(0.05) elif self.scope_running: self.led.all_off() self.scope.step() self.led.update() sleep(0.05) def mode_presets(self): self.led.drawText("Mode", 6, 5, size=1, color=self.color) self.led.drawText("Presets", 6, 15, size=1, color=self.color) def color_presets(self): self.led.drawText("Color", 6, 5, size=1, color=self.color) self.led.drawText("Presets", 6, 15, size=1, color=self.color) def color_gradient(self): self.led.drawText("Color", 6, 5, size=1, color=self.color) self.led.drawText("Gradients", 6, 15, size=1, color=self.color) def white_gradient(self): self.led.drawText("White", 6, 5, size=1, color=self.color) self.led.drawText("Gradients", 6, 15, size=1, color=self.color) def direct_control(self): self.led.drawText("Direct", 6, 5, size=1, color=self.color) self.led.drawText("Control", 6, 15, size=1, color=self.color) def arcade(self): # self.led.drawText("Arcade", 6, 5, size=1, color=self.color) # self.led.drawText("Mode!!!", 6, 15, size=1, color=self.color) anim = ScrollText(self.led, "Arcade Mode!!!!!", 64, 13, size=1, color=self.color) anim.run(fps=30, untilComplete=True, max_cycles=1) self.pong.reset() self.scope_running = False self.pong_running = True def mindfuck(self): self.led.drawText("Y U NO", 6, 5, size=1, color=self.color) self.led.drawText("LISTEN?!", 6, 15, size=1, color=self.color) self.scope_running = False def run(self): while self.running: sleep(1) self.each_frame()
class OSCHandler(object): """Set up OSC server and other handlers.""" def __init__(self, field): self.m_field = field self.m_server = OSCServer( (OSCHOST, OSCPORT) ) self.m_server.timeout = OSCTIMEOUT self.m_run = True self.m_xmin = 0 self.m_ymin = 0 self.m_xmax = 0 self.m_ymax = 0 self.eventfunc = { 'ping': self.event_tracking_ping, 'start': self.event_tracking_start, 'stop': self.event_tracking_stop, 'entry': self.event_tracking_entry, 'exit': self.event_tracking_exit, 'update': self.event_tracking_update, 'frame': self.event_tracking_frame, 'minx': self.event_tracking_set, 'miny': self.event_tracking_set, 'maxx': self.event_tracking_set, 'maxy': self.event_tracking_set, 'npeople': self.event_tracking_set, } # add a method to an instance of the class import types self.m_server.handle_timeout = types.MethodType(handle_timeout, self.m_server) for i in self.eventfunc: self.m_server.addMsgHandler(OSCPATH[i], self.eventfunc[i]) # user script that's called by the game engine every frame def each_frame(self): # clear timed_out flag self.m_server.timed_out = False # handle all pending requests then return while not self.m_server.timed_out: self.m_server.handle_request() def user_callback(self, path, tags, args, source): # which user will be determined by path: # we just throw away all slashes and join together what's left user = ''.join(path.split("/")) # tags will contain 'fff' # args is a OSCMessage with data # source is where the message came from (in case you need to reply) #print ("Now do something with", user,args[2],args[0],1-args[1]) def quit_callback(self, path, tags, args, source): self.m_run = False # Event handlers def event_tracking_ping(self, path, tags, args, source): """Ping from tracking system.""" #print "OSC: ping:",args,source pass def event_tracking_start(self, path, tags, args, source): """Tracking system is starting. Sent before first /pf/update message for that target args: samp - sample number t - time of sample (elapsed time in seconds since beginning of run) target - UID of target channel - channel number assigned """ print "OSC: start:",args def event_tracking_set(self, path, tags, args, source): """Tracking subsystem is setting params. Send value of various parameters. args: minx, miny, maxx, maxy - bounds of PF in units npeople - number of people currently present """ split = path.split("/") param = split.pop() print "OSC: set:",path,param,args,source if param == OSCPATH_SET_DICT['minx']: self.m_field.setparam(xmin=int(100*args[0])) elif param == OSCPATH_SET_DICT['miny']: self.m_field.setparam(ymin=int(100*args[0])) elif param == OSCPATH_SET_DICT['maxx']: self.m_field.setparam(xmax=int(100*args[0])) elif param == OSCPATH_SET_DICT['maxy']: self.m_field.setparam(ymax=int(100*args[0])) elif param == OSCPATH_SET_DICT['npeople']: self.m_field.setparam(npeople=args[0]) else: pass def event_tracking_entry(self, path, tags, args, source): """Event when person enters field. Sent before first /pf/update message for that target args: samp - sample number t - time of sample (elapsed time in seconds since beginning of run) target - UID of target channel - channel number assigned """ print "OSC: entry:",args sample = args[0] time = args[1] id = args[2] self.m_field.create_cell(id) def event_tracking_exit(self, path, tags, args, source): """Event when person exits field. args: samp - sample number t - time of sample (elapsed time in seconds since beginning of run) target - UID of target """ print "OSC: exit:",args sample = args[0] time = args[1] id = args[2] self.m_field.del_cell(id) def event_tracking_update(self, path, tags, args, source): """Information about people's movement within field. Update position of target. args: samp - sample number t - time of sample (elapsed time in seconds since beginning of run) target - UID of target x,y - position within field in units - increasing in value towards right and down vx,vy - estimate of velocity in m/s major,minor - major/minor axis size in m groupid - id number of group groupsize - number of people in group channel - channel number assigned """ #print "OSC: update:",args for index, item in enumerate(args): if item == 'nan': args[index] = 0 samp = args[0] time = args[1] id = args[2] x = int(100*args[3]) # comes in meters, convert to cm y = int(100*args[4]) vx = int(100*args[5]) vy = int(100*args[6]) major = int(100*args[7]/2) minor = int(100*args[8]/2) gid = args[9] gsize = args[10] channel = args[11] # TODO: if gid is not equal to 0 than we have a grouping, we need to # stop mapping the cell(s) that are not getting updated in new frames # alternately, we can just turn all cells invisible each frame and then # make them visible as we get an update #print "field.update_cell(",id,",",(x,y),",",major,")" self.m_field.update_cell(id,x,y,vx,vy,major,minor,gid,gsize) # TODO: What happens to connections when someone joins a group? Oh god. # In our OSC messages, when two cells become a group, a gid is assigned # the groupsize is incremented, and only one of the cells gets updated # Like so: # /pf/update 410 28.8 2 1.1 -1.4 -1.2 -0.2 nan nan 1 2 2 # /pf/update 410 28.8 4 0.9 -1.0 -0.2 -2.4 nan nan 1 2 4 # /pf/update 411 28.8 4 0.9 -1.0 nan nan nan nan 1 2 4 # /pf/update 412 29.0 4 0.9 -1.0 nan nan nan nan 1 2 4 def event_tracking_frame(self, path, tags, args, source): """New frame event. args: samp - sample number """ self.m_field.m_samp = args[0] #print "OSC: frame:",args self.m_field.full_status() def event_tracking_stop(self, path, tags, args, source): """Tracking has stopped.""" print "OSC: stop:",args
class MuseIO(): def __init__(self, port=5001, signal=None): self.signal = signal self.port = port self.udp_ip = '127.0.0.1' if not has_oscserver: raise Exception('ERROR: OSC not found') self.server = OSCServer((self.udp_ip, self.port)) self.server.timeout = 0 # funny python's way to add a method to an instance of a class self.server.handle_timeout = types.MethodType(handle_timeout, self.server) # add message handlers if 'eeg' in self.signal: self.server.addMsgHandler('/muse/eeg', self.callback_eeg_raw) if 'concentration' in self.signal: self.server.addMsgHandler('/muse/elements/experimental/concentration', self.callback_concentration) if 'mellow' in self.signal: self.server.addMsgHandler('/muse/elements/experimental/mellow', self.callback_mellow) self.server.addMsgHandler("default", self.default_handler) def default_handler(self, addr, tags, stuff, source): # nothing to do here. This function is called for all messages that are not supported by the application. #print "SERVER: No handler registered for ", addr return None def callback_eeg_raw(self, path, tags, args, source): # which user will be determined by path: # we just throw away all slashes and join together what's left # tags will contain 'ffff' # args is a OSCMessage with data # source is where the message came from (in case you need to reply) self.signal['eeg'].lock.acquire() self.signal['eeg'].add_data(args) self.signal['eeg'].lock.release() def callback_concentration(self, path, tags, args, source): if 'concentration' in self.signal: self.signal['concentration'].add_time() self.signal['concentration'].add_concentration(args[0]) #self.game.change_velocity(self.signal['concentration'].concentration) def callback_mellow(self, path, tags, args, source): if 'mellow' in self.signal: self.signal['mellow'].add_time() self.signal['mellow'].add_mellow(args[0]) def handle_request(self): # clear timed_out flag self.server.timed_out = False # handle all pending requests then return while not self.server.timed_out: self.server.handle_request() def start(self, freq=220): update_timing = 1.0/float(freq) while True: try: time.sleep(update_timing) self.handle_request() except KeyboardInterrupt: import sys print('KeyboardInterrupt on line {}'.format(sys.exc_info()[-1].tb_lineno)) sys.exit(2) except Exception as e: import sys print('Error on line {}'.format(sys.exc_info()[-1].tb_lineno)) print(str(e)) sys.exit(2)
class KinectReceiver(avg.Publisher): """Class to process OSC messages from the kinect tracking system. Subscribers will receive messages for each joint or kill, containing either [skeleton_id, skeleton_joint] or [skeleton_id, 'kill') """ OSC_kinect_MessageID = avg.Publisher.genMessageID() OSC_kinect_hand_MessageID = avg.Publisher.genMessageID() def __init__(self, ip): """Initialize the server on localhost.""" avg.Publisher.__init__(self) self.__active_skeleton_ids = [] try: self.__server = OSCServer((ip, 27015)) self.__server.print_tracebacks = True # TODO check the ThreadingOSCServer class as possible alternative except OSCError: print "############################################" print "####### could not open OSCServer ###########" print "############################################" return if self.__server is None: print "OSC KINECT RECEIVER: server is not initialized" return print "Kinect receiver: ", self.__server self.__server.handle_timeout = types.MethodType( self.__handle_timeout, self.__server) self.__server.timeout = 0 self.__server.addMsgHandler("/joint", self.__on_osc_joint_message_received) self.__server.addMsgHandler("/hand", self.__on_osc_hand_message_received) self.__server.addMsgHandler("/kill", self.__on_osc_kill_message_received) self.publish(self.OSC_kinect_MessageID) self.publish(self.OSC_kinect_hand_MessageID) def __handle_timeout(self, statusnachricht): """Handle server timeouts.""" self.__server.timed_out = True def onFrame(self): """Stay active.""" self.__server.timed_out = False # handle all pending requests than return while not self.__server.timed_out: self.__server.handle_request() def run(self): """Start running the server.""" while True: self.__server.handle_request() self.__server.close() def __on_osc_joint_message_received(self, addr, tags, data, client_address): """Receives an OSC message, transforms the data and notifies subscribers by sending a message (type: list) containing skeleton_id and skeleton_joint (type: SkeletonJoint) Args: addr: the address (str e.g. /joint) tags: tags (str with i for int32 and f for float, e.g. iiiifff) data: tracking data, containing id, convertMode, jointtype, trackingstate, and if trackingstate != OKTS_NOTTRACKED, x,y and z client_address: client address as (ip, port) tuple """ # check if length could actually be a skeleton joint message if len(data) < 4: return # initialize position values x = 0 y = 0 z = 0 # only if joint is tracked, additional position values are given if data[3] is not OSCJointTrackingState.OKTS_NOTTRACKED and len( data) >= 7: x = data[4] y = data[5] z = data[6] # create the skeleton joint from received data # joint_type = OSCKinectJoint(data[2]) joint_type = data[2] skeleton_joint = SkeletonJoint(x, y, z, joint_type) skeleton_joint.tracking_state = data[3] # add skeletonID to active skeleton list if data[0] not in self.__active_skeleton_ids: self.__active_skeleton_ids.append(data[0]) # message for subscribers consists of skeletonID and joint message = [data[0], skeleton_joint] # send new skeleton_joint to subscriber self.notifySubscribers(self.OSC_kinect_MessageID, [message]) def __on_osc_hand_message_received(self, addr, tags, data, client_address): """ received hand state events from oscserver and if this skeleton already exists it norfies subscribers with message skeleton_id and list["left"/"right", value] """ if len(data) < 3: return if data[1] != "left" and data[1] != "right": return if data[0] in self.__active_skeleton_ids: message = [data[0], (data[1], data[2])] self.notifySubscribers(self.OSC_kinect_hand_MessageID, [message]) def __on_osc_kill_message_received(self, addr, tags, data, client_address): """ receives the kill event from oscserver and reacts by sending out a message (list) ONCE that includes skeleton_id and 'kill' """ # kill will be received constantly, only send message once # when skeletonID is still in active skeleton list if data[0] in self.__active_skeleton_ids: # message for subscribers consists of skeletonID and 'kill' message = [data[0], 'kill'] # send message self.notifySubscribers(self.OSC_kinect_MessageID, [message]) # remove skeletonID from active skeleton list self.__active_skeleton_ids.remove(data[0]) pass
class LiveRawAPI(object): """ This is close to live's API objects as possible Of course, they are designed to be manipulated from a patcher, not real code, so a bit more wrapping is in order. To keep everything minimal, this is done in a subclass. """ _incoming = None _handled = True _received = False debug = False def __init__(self, there_host="localhost", there_port=7400, here_host="localhost", here_port=7401, debug=False, *args, **kwargs): super(LiveRawAPI, self).__init__(*args, **kwargs) self.oscserver = OSCServer((here_host, here_port)) self.oscclient = OSCClient() self.oscclient.connect((there_host, there_port)) self.oscserver.addMsgHandler('/response', self._handle_response) self._incoming = [] def raw_query(self, *args): """Posts a query, waits for a response. Returns it. Note that state is fragile here, so you'd better be sure that there will be a response, or it will hang waiting.""" self.oscclient.send(OSCMessage('/query', args)) return self.handle_request() def raw_call(self, *args): """Posts a call, returns nothing. Note that state is fragile here, so you'd better be sure that there will be no response, or you won't know what returned what.""" self.oscclient.send(OSCMessage('/query', ['path', 'getpath'])) def _handle_response(self, path, tags, args, source): """private callback to handle OSC responses. Sets state.""" if self.debug: print "callback", path, args, source self._incoming.append(args) self._received = True def handle_request(self): """hack to handle asynchronous calls: 1 try to get something returned and tacked onto the class. 2 Return it and reset. This is completely f****d at the momenl I can't make timeouts work in any usable fashion.""" try: self.oscserver.handle_request() while self._received: self._received = False self.oscserver.handle_request() _incoming = self._incoming return _incoming finally: self._incoming = [] self._received = False def close(self): self.oscserver.close() ### more structured access involves navigating places with the path object def goto(self, *args): resp = self.raw_query('path', 'goto', *args) prefix, path = resp[1], resp[2:] #sanity check that we are getting the right message assert prefix == 'path' self.path = path def path(self, *args): return self.goto(*args) def getchildren(self): resp = self.raw_query('path', 'getchildren') return resp[1:] def getcount(self): resp = self.raw_query('path', 'getcount') return resp[1:]
class MuseIO(): def __init__(self, port=5001, signal=None): self.signal = signal self.port = port self.udp_ip = '127.0.0.1' if not has_oscserver: raise Exception('ERROR: OSC not found') self.server = OSCServer((self.udp_ip, self.port)) self.server.timeout = 0 self.current_sample_id = 0 self.init_time = None self.sample_rate = 220.0 # funny python's way to add a method to an instance of a class self.server.handle_timeout = types.MethodType(handle_timeout, self.server) # add message handlers if 'eeg' in self.signal: self.server.addMsgHandler('/muse/eeg', self.callback_eeg_raw) if 'concentration' in self.signal: self.server.addMsgHandler('/muse/elements/experimental/concentration', self.callback_concentration) if 'mellow' in self.signal: self.server.addMsgHandler('/muse/elements/experimental/mellow', self.callback_mellow) self.server.addMsgHandler("default", self.default_handler) def default_handler(self, addr, tags, stuff, source): # nothing to do here. This function is called for all messages that are not supported by the application. #print "SERVER: No handler registered for ", addr return None def callback_eeg_raw(self, path, tags, args, source): # which user will be determined by path: # we just throw away all slashes and join together what's left # tags will contain 'ffff' # args is a OSCMessage with data # source is where the message came from (in case you need to reply) self.signal['eeg'].lock.acquire() self.signal['eeg'].id = self.current_sample_id self.signal['eeg'].add_data(args, add_time=False) self.signal['eeg'].add_time(time.time()) self.signal['eeg'].add_datetime(datetime.now()) self.signal['eeg'].lock.release() def callback_concentration(self, path, tags, args, source): if 'concentration' in self.signal: self.signal['concentration'].lock.acquire() self.signal['concentration'].id = self.current_sample_id self.signal['concentration'].add_data(args, add_time=False) self.signal['concentration'].add_time(time.time()) self.signal['concentration'].add_datetime(datetime.now()) self.signal['concentration'].lock.release() def callback_mellow(self, path, tags, args, source): if 'mellow' in self.signal: self.signal['mellow'].lock.acquire() self.signal['mellow'].id = self.current_sample_id self.signal['mellow'].add_data(args, add_time=False) self.signal['mellow'].add_time(time.time()) self.signal['mellow'].add_datetime(datetime.now()) self.signal['mellow'].lock.release() def handle_request(self): # clear timed_out flag self.server.timed_out = False # handle all pending requests then return while not self.server.timed_out: self.server.handle_request() def start(self, freq=220): update_timing = 1.0/float(freq) while True: try: time.sleep(update_timing) self.handle_request() except KeyboardInterrupt: import sys print('KeyboardInterrupt on line {}'.format(sys.exc_info()[-1].tb_lineno)) sys.exit(2) except Exception as e: import sys print('Error on line {}'.format(sys.exc_info()[-1].tb_lineno)) print(str(e)) sys.exit(2)
#These are all the add-ons that you can name in the TouchOSC layout designer (you can set the values and directories) server.addMsgHandler("redfader",faderR) server.addMsgHandler("greenfader",faderG) server.addMsgHandler("bluefader",faderB) server.addMsgHandler("numfader",faderN) server.addMsgHandler("colorcycle1",ccButton) server.addMsgHandler("cyclestep",ccStepFader) server.addMsgHandler("dotOnOff",dotButton) server.addMsgHandler("dotXY",dotPosition) # main loop while True: # read data server.handle_request() if isCycling: cycleColor() pixels = [ (0,0,0) ] * maxNum for i in range(num): if i == dotIndex: if isDot: pixels[i] = (255,255,255) else: pixels[i] = (r,b,g) else: pixels[i] = (r,b,g) opcClient.put_pixels(pixels) print "r:%i g:%i b:%i num:%i " % (r,g,b,num)
class OSCHandler(object): """Set up OSC server and other handlers.""" def __init__(self, field=None, conductor=None): self.m_conductor = conductor self.cidkeys={} self.lastcid=1 self.m_field = field self.m_run = True self.m_downClients={} self.m_missingHandlers={} self.m_xmin = 0 self.m_ymin = 0 self.m_xmax = 0 self.m_ymax = 0 self.m_health = 0 # Setup OSC server and clients osc_server = [] osc_clients = [] for host in OSC_IPS: if host == IAM: logger.info("setting server for %s to %s: %s",host,OSC_IPS[host],OSC_PORTS[host]) osc_server = [('server', OSC_IPS[host], OSC_PORTS[host])] elif host == 'localhost' or host == 'default': continue else: logger.info("setting client for %s to %s:%s",host,OSC_IPS[host],OSC_PORTS[host]) osc_clients.append((host, OSC_IPS[host], OSC_PORTS[host])) (name, host, port) = osc_server[0] self.m_oscserver = OSCServer( (host, port) ) logger.info( "Initializing server at %s:%s",host, port) self.m_oscserver.timeout = config.osctimeout self.m_oscserver.print_tracebacks = True self.m_osc_clients = {} for i in range(len(osc_clients)): (name, host, port) = osc_clients[i] for j in range(i): (oldname, oldhost, oldport) = osc_clients[j] if host == oldhost and port == oldport: self.m_osc_clients[name] = self.m_osc_clients[oldname] logger.warning( "%s same as %s",name,oldname) break if not name in self.m_osc_clients: try: self.m_osc_clients[name] = OSCClient() except socket.error: logger.error( "Unable to create OSC handler for client %s at %s:%s",name,host,port,exc_info=True) self.m_osc_clients[name].connect( (host, port) ) logger.info( "Connecting to %s at %s:%s",name,host,port) self.send_to(name,"/ping",[0]) # common self.m_oscserver.addMsgHandler("/ping",self.event_ping) self.m_oscserver.addMsgHandler( "/ack",self.event_ack) # from tracker self.m_oscserver.addMsgHandler("/pf/started",self.event_tracking_start) self.m_oscserver.addMsgHandler("/pf/stopped",self.event_tracking_stop) self.m_oscserver.addMsgHandler("/pf/entry",self.event_tracking_entry) self.m_oscserver.addMsgHandler("/pf/exit",self.event_tracking_exit) self.m_oscserver.addMsgHandler("/pf/frame",self.event_tracking_frame) self.m_oscserver.addMsgHandler("/pf/set/minx",self.event_tracking_set) self.m_oscserver.addMsgHandler("/pf/set/miny",self.event_tracking_set) self.m_oscserver.addMsgHandler("/pf/set/maxx",self.event_tracking_set) self.m_oscserver.addMsgHandler("/pf/set/maxy",self.event_tracking_set) self.m_oscserver.addMsgHandler("/pf/set/npeople",self.event_tracking_set) self.m_oscserver.addMsgHandler("/pf/set/groupdist",self.event_tracking_set) self.m_oscserver.addMsgHandler("/pf/set/ungroupdist",self.event_tracking_set) self.m_oscserver.addMsgHandler("/pf/set/fps",self.event_tracking_set) self.m_oscserver.addMsgHandler("/pf/update",self.event_tracking_update) self.m_oscserver.addMsgHandler("/pf/leg",self.event_tracking_leg) self.m_oscserver.addMsgHandler("/pf/body",self.event_tracking_body) self.m_oscserver.addMsgHandler("/pf/group",self.event_tracking_group) self.m_oscserver.addMsgHandler("/pf/geo",self.event_tracking_geo) # to conductor self.m_oscserver.addMsgHandler( "/conductor/dump",self.event_conduct_dump) # global sensitivity for conx attr self.m_oscserver.addMsgHandler( "/ui/condglobal",self.event_ui_condglobal) # global sensitivity for cell attr self.m_oscserver.addMsgHandler( "/ui/cellglobal",self.event_ui_cellglobal) for atype in CELL_ATTR_TYPES + CONX_ATTR_TYPES: for param in ("trigger", "memory", "maxage","qual","qualmin","qualmax"): self.m_oscserver.addMsgHandler("/ui/cond/"+atype+"/"+param,self.event_ui_condparam) # add a method to an instance of the class self.m_oscserver.handle_timeout = types.MethodType(handle_timeout, self.m_oscserver) # this registers a 'default' handler (for unmatched messages), # an /'error' handler, an '/info' handler. # And, if the client supports it, a '/subscribe' & # '/unsubscribe' handler self.m_oscserver.addDefaultHandlers() self.m_oscserver.addMsgHandler("default", self.default_handler) # TODO: Handle errors from OSCServer #self.m_oscserver.addErrorHandlers() #self.m_oscserver.addMsgHandler("error", self.default_handler) self.honey_im_home() def each_frame(self): # clear timed_out flag self.m_oscserver.timed_out = False # handle all pending requests then return while not self.m_oscserver.timed_out: self.m_oscserver.handle_request() def user_callback(self, path, tags, args, source): # which user will be determined by path: # we just throw away all slashes and join together what's left user = ''.join(path.split("/")) # tags will contain 'fff' # args is a OSCMessage with data # source is where the message came from (in case you need to reply) logger.debug("user_callback( "+str(user)+" "+str(tags)+" "+str(args)+" "+str(source)) def quit_callback(self, path, tags, args, source): # don't do this at home (or it'll quit blender) self.m_run = False # # General OUTGOING # def send_to(self, clientkey, path, args): """Send OSC Message to one client.""" try: self.m_osc_clients[clientkey].send(OSCMessage(path,args)) if args: logger.debug( "Send to %s: %s %s" ,clientkey,path,args) except: lastError=self.m_downClients.get(clientkey,0) if time()-lastError >30: logger.warning("send_to: Unable to reach host %s (will suppress this warning for 30 seconds)",clientkey,exc_info=False) self.m_downClients[clientkey]=time() return False return True def send_laser(self, path, args): """Send OSC Message to one client.""" self.send_to('laser', path, args) self.send_to('recorder', path, args) def send_downstream(self, path, args): """Send OSC Message to one client.""" self.send_to('sound', path, args) self.send_to('recorder', path, args) self.send_to('laser', path, args) def send_to_all_clients(self, path, args): """Broadcast to all the clients.""" for clientkey in self.m_osc_clients: self.send_to(clientkey, path, args) # # General INCOMING # def default_handler(self, path, tags, args, source): if not self.m_missingHandlers.get(path,False): logger.warning( "default_handler:No handler registered for "+path) self.m_missingHandlers[path]=True return None def event_ping(self, path, tags, args, source): if len(args)<1: # Possibly ping from touchosc which doesn't include code return ping_code = args[0] source_ip = source[0] logger.debug( "ping from %s:code:%s", source_ip, ping_code) for clientkey, client in self.m_osc_clients.iteritems(): target_ip = client.address()[0] if target_ip == source_ip: self.send_to(clientkey, "/ack", ping_code) def event_ack(self, path, tags, args, source): logger.debug( "event_ack:code "+str(args[0])) return None # # Tracking INCOMING # def event_tracking_start(self, path, tags, args, source): """Tracking system is starting. Sent before first /pf/update message for that target """ logger.info( "event_track_start") def event_tracking_set(self, path, tags, args, source): """Tracking subsystem is setting params. Send value of various parameters. args: minx, miny, maxx, maxy - bounds of PF in units npeople - number of people currently present """ logger.debug( "event_track_set:"+str(path)+" "+str(args)+" "+str(source)) if path =="/pf/set/minx": self.m_xmin = args[0] elif path == "/pf/set/miny": self.m_ymin = args[0] elif path == "/pf/set/maxx": self.m_xmax = args[0] elif path == "/pf/set/maxy": self.m_ymax = args[0] elif path == "/pf/set/npeople": self.m_field.check_people_count(args[0]) elif path == "/pf/set/groupdist": self.m_field.update(groupdist=args[0]) elif path == "/pf/set/ungroupdist": self.m_field.update(ungroupdist=args[0]) elif path == "/pf/set/fps": self.m_field.update(oscfps=args[0]) def event_tracking_entry(self, path, tags, args, source): """Event when person enters field. Sent before first /pf/update message for that target args: frame - frame number t - time of frame (elapsed time in seconds since beginning of run) target - UID of target channel - channel number assigned """ #print "event_track_entry:",path,args,source #print "args:",args,args[0],args[1],args[2] #frame = args[0] #etime = args[1] uid = args[2] logging.getLogger("cells").info("entry of cell "+str(uid)) self.m_field.create_cell(uid) def event_tracking_exit(self, path, tags, args, source): """Event when person exits field. args: frame - frame number t - time of frame (elapsed time in seconds since beginning of run) target - UID of target """ #print "event_track_exit:",path,args,source #frame = args[0] #etime = args[1] uid = args[2] logging.getLogger("cells").info("exit of cell "+str(uid)) #print "BEFORE: cells:",self.m_field.m_cell_dict #print "BEFORE: conx:",self.m_field.m_conx_dict self.m_field.del_cell(uid) #print "AFTER: cells:",self.m_field.m_cell_dict #print "AFTER: conx:",self.m_field.m_conx_dict def event_tracking_body(self, path, tags, args, source): """Information about people's movement within field. Update position of target. args: frame - frame number target - UID of target x,y - position of person within field in m ex,ey - standard error of measurement (SEM) of position, in meters spd, heading - estimate of speed of person in m/s, heading in degrees espd, eheading - SEM of spd, heading facing - direction person is facing in degees efacing - SEM of facing direction diam - estimated mean diameter of legs sigmadiam - estimated sigma (sqrt(variance)) of diameter sep - estimated mean separation of legs sigmasep - estimated sigma (sqrt(variance)) of sep leftness - measure of how likely leg 0 is the left leg visibility - number of frames since a fix was found for either leg """ for index, item in enumerate(args): if item == 'nan': args[index] = None frame = args[0] uid = args[1] x = args[2] # comes in meters y = args[3] ex = args[4] ey = args[5] spd = args[6] #heading = args[7] espd = args[8] #eheading = args[9] facing = args[10] efacing = args[11] diam = args[12] sigmadiam = args[13] sep = args[14] sigmasep = args[15] leftness = args[16] vis = args[17] if uid not in self.m_field.m_cell_dict: logger.info( "event_track_body:no uid "+str(uid)+" in registered cell list") if frame%config.report_frequency['debug'] == 0: logger.debug(" ".join([str(msgpart) for msgpart in [ " event_track_body:id:",uid,"pos:", (x, y), "data:", ex, ey, spd, espd, facing, efacing, diam, sigmadiam, sep, sigmasep, leftness, vis]])) self.m_field.update_body(uid, x, y, ex, ey, spd, espd, facing, efacing, diam, sigmadiam, sep, sigmasep, leftness, vis) def event_tracking_leg(self, path, tags, args, source): """Information about individual leg movement within field. Update position of leg. args: frame - frame number id - UID of target leg - leg number (0..nlegs-1) nlegs - number of legs target is modeled with x,y - position within field in m ex,ey - standard error of measurement (SEM) of position, in meters spd, heading - estimate of speed of leg in m/s, heading in degrees espd, eheading - SEM of spd, heading visibility - number of frames since a positive fix """ for index, item in enumerate(args): if item == 'nan': args[index] = None frame = args[0] uid = args[1] leg = args[2] nlegs = args[3] x = args[4] # comes in meters y = args[5] ex = args[6] ey = args[7] spd = args[8] heading = args[9] espd = args[10] eheading = args[11] vis = args[12] if uid not in self.m_field.m_cell_dict: logger.info( "event_track_leg:no uid "+str(uid)+" in registered cell list") if frame%config.report_frequency['debug'] == 0: logger.debug(" ".join([str(msgpart) for msgpart in [" event_track_leg:id:", uid, "leg:", leg, "pos:", (x,y), "data:", ex, ey, spd, espd, heading, eheading, vis]])) self.m_field.update_leg(uid, leg, nlegs, x, y, ex, ey, spd, espd, heading, eheading, vis) def event_tracking_update(self, path, tags, args, source): """Information about people's movement within field. Update position of target. args: /pf/update frame t target x y vx vy major minor groupid groupsize channel frame - frame number t - time of frame (elapsed time in seconds) target - UID of target, always increments x,y - position within field in meters vx,vy - estimate of velocity in m/s major,minor - major/minor axis size in m groupid - id number of group (0 if not in any group) groupsize - number of people in group (including this person) channel - channel number assigned """ for index, item in enumerate(args): if item == 'nan': args[index] = None frame = args[0] # etime = args[1] uid = args[2] if uid not in self.m_field.m_cell_dict: logger.info( "event_track_update:no uid "+str(uid)+" in registered cell list") x = args[3] # comes in meters y = args[4] vx = args[5] vy = args[6] major = args[7] minor = args[8] gid = args[9] gsize = args[10] #channel = args[11] #print "event_track_update:",path,args,source if frame%config.report_frequency['debug'] == 0: #print "event_track_update:",path,args,source logger.debug(" ".join([str(msgpart) for msgpart in [ " event_track_update:id:",uid,"pos:", (x, y), "data:", \ vx, vy, major, minor, gid, gsize]])) self.m_field.update_cell(uid, x, y, vx, vy, major, minor, gid, gsize, frame=frame) def event_tracking_group(self, path, tags, args, source): """Information about people's movement within field. Update info about group /pf/group frame gid gsize duration centroidX centroidY diameter args: frame - frame number gid - group ID gsize - number of people in group duration - time since first formed in seconds centroidX, centroidY - location of centroid of group diameter - current diameter (mean distance from centroid) """ for index, item in enumerate(args): if item == 'nan': args[index] = None #frame = args[0] gid = args[1] gsize = args[2] # comes in meters duration = args[3] x = args[4] y = args[5] diam = args[6] if gid not in self.m_field.m_group_dict: logger.info( "event_track_group:no gid "+str(gid)+" in group list") # if frame%config.report_frequency['debug'] == 0: logger.debug(" ".join([str(msgpart) for msgpart in [" event_track_group:gid:",gid, "pos:", (x, y), "data:",gsize, duration, diam]])) self.m_field.update_group(gid, gsize, duration, x, y, diam) def event_tracking_geo(self, path, tags, args, source): """Information about people's movement within field. Update info about group /pf/geo frame target fromcenter fromothers fromexit args: frame - frame number uid - UID of target fromcenter -target's distance from geographic center of everyone fromnearest - target's distance from the nearest other person (-1 if nobody else) fromexit - This person's distance from nearest exit from tracked area """ for index, item in enumerate(args): if item == 'nan': args[index] = None frame = args[0] uid = args[1] fromcenter = args[2] # comes in meters fromnearest = args[3] fromexit = args[4] if uid not in self.m_field.m_cell_dict: logger.info("event_track_geo:no uid "+str(uid)+" in registered cell list") if frame%config.report_frequency['debug'] == 0: logger.debug(" ".join([str(x) for x in [" event_track_geo:uid:",uid, "data:", fromcenter, fromnearest, fromexit]])) self.m_field.update_geo(uid, fromcenter, fromnearest, fromexit) def event_tracking_frame(self, path, tags, args, source): """New frame event. args: frame - frame number """ #print "event_track_frame:",path,args,source frame = args[0] self.m_field.update(frame=frame) if frame%config.report_frequency['debug'] == 0: logger.debug( "event_track_frame::"+str(frame)) return None def event_tracking_stop(self, path, tags, args, source): """Tracking has stopped.""" logger.info(" ".join([str(x) for x in ["event_tracking_stop: ",path,args,source]])) return None def update(self, field=None, conductor=None): self.m_field = field self.m_conductor = conductor # # INCOMING to Conductor # def event_conduct_dump(self, path, tags, args, source): source_ip = source[0] logger.debug( "dump req:from"+str(source_ip)) for clientkey, client in self.m_osc_clients.iteritems(): target_ip = client.address()[0] if target_ip == source_ip: #TODO: Decide what we dump and dump it #self.sendto(clientkey, '/ping', ping_code) logger.debug( "dump to "+str(clientkey)) def event_ui_condglobal(self, path, tags, args, source): """Receive condglobal from UI. Sent from UI. args: frame - frame number cg - conx global """ #print "event_track_entry:",path,args,source #print "args:",args,args[0],args[1],args[2] #frame = args[0] cg = args[0] logger.debug("event_ui_condglobal:cg ="+str(cg)) self.m_conductor.update(condglobal=cg) def event_ui_cellglobal(self, path, tags, args, source): """Receive cellglobal from UI. Sent from UI. args: frame - frame number cg - cell global """ #print "event_track_entry:",path,args,source #print "args:",args,args[0],args[1],args[2] #frame = args[0] cg = args[0] logger.debug("event_ui_cellglobal:cg ="+str(cg)) self.m_conductor.update(cellglobal=cg) def event_ui_condparam(self, path, tags, args, source): """Receive condparam from UI. Sent from UI. args: type - type of attr param - conductor param value - value to change to """ #print "event_track_entry:",path,args,source #print "args:",args,args[0],args[1],args[2] #frame = args[0] pathsplit = path.split('/') atype = pathsplit[len(pathsplit)-2] param = pathsplit[len(pathsplit)-1] value = args[0] # if I received the type and attr as args, I'd use these 3 lines #type = args[0] #param = args[1] #value = args[2] logger.debug("event_ui_condparam: type=%s,param=%s,value=%.2f",atype,param,value) if atype in CELL_ATTR_TYPES: self.m_conductor.update_cell_param(atype,param, value) elif atype in CONX_ATTR_TYPES: self.m_conductor.update_conx_param(atype,param, value) # # OUTGOING from Conductor # # Startup def honey_im_home(self): """Broadcast a hello message to the network.""" self.send_to_all_clients('/conductor/start',[]) # Regular Reports def send_regular_reports(self): """Send all the reports that are send every cycle.""" frame = self.m_field.m_frame if frame%config.report_frequency['rollcall'] == 0: self.send_rollcall() if frame%config.report_frequency['attrs'] == 0: self.send_cell_attrs() if frame%config.report_frequency['conxs'] == 0: self.send_conx_attr() if frame%config.report_frequency['gattrs'] == 0: self.send_group_attrs() if frame%config.report_frequency['uisettings'] == 0: self.send_uisettings() if frame%config.report_frequency['health'] == 0: self.send_health() def send_health(self): self.m_field.m_osc.send_to("touchosc","/health/COND",self.m_health) self.m_health=1-self.m_health def send_uisettings(self): #print "Sending ui settings" fd=open("settings.py","w") for key in config.connector_avg_triggers: self.m_field.m_osc.send_to("touchosc","/ui/cond/"+key+"/trigger",config.connector_avg_triggers[key]) print >>fd,"config.connector_avg_triggers['"+key+"']=",config.connector_avg_triggers[key] for key in config.connector_memory_time: self.m_field.m_osc.send_to("touchosc","/ui/cond/"+key+"/memory",config.connector_memory_time[key]) print >>fd,"config.connector_memory_time['"+key+"']=",config.connector_memory_time[key] for key in config.connector_max_age: self.m_field.m_osc.send_to("touchosc","/ui/cond/"+key+"/maxage",config.connector_max_age[key]) print >>fd,"config.connector_max_age['"+key+"']=",config.connector_max_age[key] for key in config.connector_qualifying_triggers: if key.endswith("-min"): k=key[:len(key)-4] a="qualmin" elif key.endswith("-max"): k=key[:len(key)-4] a="qualmax" else: k=key a="qual" # print "Setting ","/ui/cond/"+k+"/"+a+" to ", config.connector_qualifying_triggers[key] self.m_field.m_osc.send_to("touchosc","/ui/cond/"+k+"/"+a,config.connector_qualifying_triggers[key]) print >>fd,"config.connector_qualifying_triggers['"+key+"']=",config.connector_qualifying_triggers[key] # Same for cells for key in config.cell_avg_triggers: self.m_field.m_osc.send_to("touchosc","/ui/cond/"+key+"/trigger",config.cell_avg_triggers[key]) print >>fd,"config.cell_avg_triggers['"+key+"']=",config.cell_avg_triggers[key] for key in config.cell_memory_time: self.m_field.m_osc.send_to("touchosc","/ui/cond/"+key+"/memory",config.cell_memory_time[key]) print >>fd,"config.cell_memory_time['"+key+"']=",config.cell_memory_time[key] for key in config.cell_max_age: self.m_field.m_osc.send_to("touchosc","/ui/cond/"+key+"/maxage",config.cell_max_age[key]) print >>fd,"config.cell_max_age['"+key+"']=",config.cell_max_age[key] for key in config.cell_qualifying_triggers: if key.endswith("-min"): k=key[:len(key)-4] a="qualmin" elif key.endswith("-max"): k=key[:len(key)-4] a="qualmax" else: k=key a="qual" # print "Setting ","/ui/cond/"+k+"/"+a+" to ", config.cell_qualifying_triggers[key] self.m_field.m_osc.send_to("touchosc","/ui/cond/"+k+"/"+a,config.cell_qualifying_triggers[key]) print >>fd,"config.cell_qualifying_triggers['"+key+"']=",config.cell_qualifying_triggers[key] fd.close() def send_rollcall(self): """Sends the currently highlighted cells via OSC. /conductor/rollcall [uid,action,numconx] """ for uid,cell in self.m_field.m_cell_dict.iteritems(): if cell.m_visible: action = "visible" else: action = "hidden" #TODO: Should the connector count only show visble connectors? self.m_field.m_osc.send_downstream("/conductor/rollcall",[uid, action, len(cell.m_conx_dict)]) def send_cell_attrs(self): """Sends the current attributes of visible cells. /conductor/attr ["type",uid,value,time] """ for uid, cell in self.m_field.m_cell_dict.iteritems(): if cell.m_visible: for atype, attr in cell.m_attr_dict.iteritems(): duration = time() - attr.m_createtime self.m_field.m_osc.send_downstream("/conductor/attr", [atype, uid, attr.m_value, attr.m_freshness, duration]) def send_conx_attr(self): """Sends the current descriptions of connectors. /conductor/conx [cid,"type",uid0,uid1,value,time] """ for cid,conx in self.m_field.m_conx_dict.iteritems(): if conx.m_cell0.m_visible and conx.m_cell1.m_visible: for atype, attr in conx.m_attr_dict.iteritems(): duration = time() - attr.m_createtime self.send_conx_downstream(cid, atype, conx.m_cell0.m_id, conx.m_cell1.m_id, attr.m_value, attr.m_freshness,duration) def send_group_attrs(self): """Sends the current attributes of visible groups. /conductor/gattr ["type",gid,value,time] """ for gid,group in self.m_field.m_group_dict.iteritems(): if group.m_visible: for atype,attr in group.m_attr_dict.iteritems(): duration = time() - attr.m_createtime self.m_field.m_osc.send_downstream("/conductor/gattr", [atype, gid, attr.m_value, attr.m_freshness,duration]) def send_event(self,event): """Sends notification of an event """ self.m_field.m_osc.send_downstream("/conductor/event",[event.m_type, event.m_id, event.m_uid0, event.m_uid1, event.m_value]) # On-Call Messages def send_conx_downstream(self, cid, atype, uid0, uid1, value, freshness, duration): key=cid+atype if key not in self.cidkeys: self.cidkeys[key]=self.lastcid self.lastcid=self.lastcid+1 cc=self.cidkeys[key] cid="%d"%cc if atype in HAPPENING_TYPES: logger.debug( "send:"+str( ["happening", atype, cid, uid0, uid1, value, duration])) self.m_field.m_osc.send_downstream("/conductor/conx", ["happening", atype, cid, uid0, uid1, 1.0*value, 1.0*freshness, duration]) elif atype in EVENT_TYPES: self.m_field.m_osc.send_downstream("/conductor/event", [atype, cid, uid0, uid1, 1.0*value]) else: self.m_field.m_osc.send_downstream("/conductor/conx", ["persistent", atype, cid, uid0, uid1, 1.0*value, 1.0*freshness, duration]) def nix_cell_attr(self, uid, atype): """Sends OSC messages to announce the removal of cell attr. /conductor/attr ["type",uid,0.0,time]""" if uid in self.m_field.m_cell_dict: cell = self.m_field.m_cell_dict[uid] if atype in cell.m_attr_dict: attr = cell.m_attr_dict[atype] duration = time() - attr.m_createtime self.m_field.m_osc.send_downstream("/conductor/attr", [atype, uid, attr.m_value,0.0, duration]) def nix_conx_attr(self, cid, atype): """Sends OSC messages to announce the removal of connection attr. /conductor/conx ["type","subtype",cid,uid0,uid1,value,0.0,time]""" if cid in self.m_field.m_conx_dict: conx = self.m_field.m_conx_dict[cid] if atype in conx.m_attr_dict: attr = conx.m_attr_dict[atype] duration = time() - attr.m_createtime self.send_conx_downstream(cid, atype, conx.m_cell0.m_id, conx.m_cell1.m_id, attr.m_value, 0.0,duration) # TODO - FIXME - this is never called; do we need it at all? def nix_conxs(self, cid): """Sends OSC messages to announce the removal of a connection. /conductor/conxbreak [cid,uid0,uid1] """ if cid in self.m_field.m_conx_dict: conx = self.m_field.m_conx_dict[cid] for atype,attr in conx.m_attr_dict.iteritems(): duration = time() - attr.m_createtime self.send_conx_downstream(cid, atype, conx.m_cell0.m_id, conx.m_cell1.m_id, conx.m_value,0.0, duration) self.m_field.m_osc.send_downstream("/conductor/conxbreak", [cid, conx.m_cell0.m_id, conx.m_cell1.m_id])
class StretchIO(object): def __init__(self, send, listen=("0.0.0.0", 12340)): self.server = OSCServer(listen) self.server.timeout = 0.0 self.server.timed_out = False def timeout(self): self.timed_out = True self.server.handle_timeout = types.MethodType(timeout, self.server) self.client = OSCClient() self.client.connect(send) self.__fader_state = [8, 8, 8, 8] self.__fader_cb = None self.__toggle_cb = None for i in range(1, 5): self.led(i, 0.) self.toggle(i, 0.) self.fader(i, self.__fader_state[i - 1]) self.server.addMsgHandler('/1/toggle' + str(i), self.osc_handler) self.server.addMsgHandler('/1/fader' + str(i), self.osc_handler) def step(self): self.server.timed_out = False while not self.server.timed_out: self.server.handle_request() def send(self, m): try: self.client.send(m) except OSCClientError: sys.stdout.write('Send Fail: {0} \r'.format(m)) sys.stdout.flush() def close(self): self.server.close() def set_toggle_handler(self, cb): """ Register the function to be called when we press the toggle. <cb> should be a functio with the signature cb(button_number, button_state) """ self.__toggle_cb = cb def set_fader_handler(self, cb): self.__fader_cb = cb def osc_handler(self, path, tags, args, source): paths = path.split('/') # paths looks like this for 'auto' touchOSC elements ['', '1', 'toggle1'] if len(paths) < 3: return match = re.match('([a-zA-Z]+)(\d+)', paths[2]) if not match: print 'osc path match failed' return if len(args) < 1: print 'handler has no arguments' return parts = match.groups() name = parts[0] num = int(parts[1]) state = args[0] if name == 'fader': self.__fader_state[num - 1] = state if name == 'toggle' and self.__toggle_cb is not None: self.__toggle_cb(num, state) elif name == 'fader' and self.__fader_cb is not None: self.__fader_cb(num, state) def led(self, led_num, value): m = OSCMessage('/1/led{0:d}'.format(led_num)) m.append(value) if value > 1.0: value = 1.0 if value < 0.0: value = 0.0 self.send(m) def toggle(self, toggle_num, value): m = OSCMessage('/1/toggle{0:d}'.format(toggle_num)) m.append(1 if value else 0) self.send(m) def fader(self, fader_num, value): m = OSCMessage('/1/fader{0:d}'.format(fader_num)) m.append(float(value)) self.send(m) def fader_state(self, i): """ <i> is the index from zero (unlike the setters, that index from 1) """ return self.__fader_state[i]
class OSCHandler(object): """Set up OSC server and other handlers.""" def __init__(self, osc_server, osc_clients, field=None): self.m_field = field self.m_run = True try: (name, host, port) = osc_server[0] except: print "System:Unable to create OSC handler with server=", osc_server sys.exit(1) self.m_oscserver = OSCServer((host, port)) print "System:init server: %s:%s" % (host, port) self.m_oscserver.timeout = OSCTIMEOUT self.m_oscserver.print_tracebacks = True self.m_osc_clients = {} for i in range(len(osc_clients)): (name, host, port) = osc_clients[i] for j in range(i): (oldname, oldhost, oldport) = osc_clients[j] if host == oldhost and port == oldport: self.m_osc_clients[name] = self.m_osc_clients[oldname] print "System:init %s:same as %s" % (name, oldname) break if not name in self.m_osc_clients: try: self.m_osc_clients[name] = OSCClient() except: print "System:Unable to create OSC handler with client=", ( name, host, port) self.m_osc_clients[name].connect((host, port)) print "System:init %s: %s:%s" % (name, host, port) self.send_to(name, OSCPATH['ping'], [0]) self.m_xmin = 0 self.m_ymin = 0 self.m_xmax = 0 self.m_ymax = 0 """ self.eventfunc = update({ # common 'ping': self.event_ping, 'ack': self.event_ack, }) """ self.eventfunc.update({ # common 'ping': self.event_ping, 'ack': self.event_ack, # from tracker 'track_start': self.event_tracking_start, 'track_stop': self.event_tracking_stop, 'track_entry': self.event_tracking_entry, 'track_exit': self.event_tracking_exit, 'track_frame': self.event_tracking_frame, 'track_minx': self.event_tracking_set, 'track_miny': self.event_tracking_set, 'track_maxx': self.event_tracking_set, 'track_maxy': self.event_tracking_set, 'track_npeople': self.event_tracking_set, 'track_groupdist': self.event_tracking_set, 'track_ungroupdist': self.event_tracking_set, 'track_fps': self.event_tracking_set, 'track_update': self.event_tracking_update, 'track_leg': self.event_tracking_leg, 'track_body': self.event_tracking_body, 'track_group': self.event_tracking_group, 'track_geo': self.event_tracking_geo, }) # add a method to an instance of the class self.m_oscserver.handle_timeout = types.MethodType( handle_timeout, self.m_oscserver) # How to make this match partial paths? # Esp /ui/cond/type/param match /ui/cond/ for i in self.eventfunc: self.m_oscserver.addMsgHandler(OSCPATH[i], self.eventfunc[i]) # We are enumerating paths # Esp /ui/cond/type/param match /ui/cond/ try: for path in self.eventfunc_enum: self.m_oscserver.addMsgHandler(path, self.eventfunc_enum[path]) except NameError: pass # this registers a 'default' handler (for unmatched messages), # an /'error' handler, an '/info' handler. # And, if the client supports it, a '/subscribe' & # '/unsubscribe' handler self.m_oscserver.addDefaultHandlers() self.m_oscserver.addMsgHandler("default", self.default_handler) # TODO: Handle errors from OSCServer #self.m_oscserver.addErrorHandlers() #self.m_oscserver.addMsgHandler("error", self.default_handler) self.honey_im_home() def each_frame(self): # clear timed_out flag self.m_oscserver.timed_out = False # handle all pending requests then return while not self.m_oscserver.timed_out: self.m_oscserver.handle_request() def user_callback(self, path, tags, args, source): # which user will be determined by path: # we just throw away all slashes and join together what's left user = ''.join(path.split("/")) # tags will contain 'fff' # args is a OSCMessage with data # source is where the message came from (in case you need to reply) if dbug.LEV & dbug.MSGS: print("Now do something with", user, args[2], args[0], 1 - args[1]) def quit_callback(self, path, tags, args, source): # don't do this at home (or it'll quit blender) self.m_run = False # # General OUTGOING # def send_to(self, clientkey, path, args): """Send OSC Message to one client.""" try: self.m_osc_clients[clientkey].send(OSCMessage(path, args)) if (dbug.LEV & dbug.MSGS) and args: print "OSC:Send to %s: %s %s" % (clientkey, path, args) except: if dbug.LEV & dbug.MSGS: print "OSC:Send:Unable to reach host", clientkey return False return True def send_laser(self, path, args): """Send OSC Message to one client.""" self.send_to('laser', path, args) self.send_to('recorder', path, args) def send_downstream(self, path, args): """Send OSC Message to one client.""" self.send_to('visual', path, args) self.send_to('sound', path, args) self.send_to('recorder', path, args) self.send_to('laser', path, args) def send_to_all_clients(self, path, args): """Broadcast to all the clients.""" for clientkey, client in self.m_osc_clients.iteritems(): self.send_to(clientkey, path, args) def honey_im_home(self): """Broadcast a hello message to the network.""" pass # # General INCOMING # def default_handler(self, path, tags, args, source): if dbug.LEV & dbug.MORE: print "OSC:default_handler:No handler registered for ", path return None def event_ping(self, path, tags, args, source): if len(args) < 1: # Possibly ping from touchosc which doesn't include code return ping_code = args[0] source_ip = source[0] if dbug.LEV & dbug.MSGS: print "OSC:ping from %s:code:%s" % (source_ip, ping_code) for clientkey, client in self.m_osc_clients.iteritems(): target_ip = client.address()[0] if target_ip == source_ip: try: self.sendto(clientkey, OSCPATH('ack'), ping_code) except: if dbug.LEV & dbug.MSGS: print "OSC:event_ping:unable to ack to", clientkey def event_ack(self, path, tags, args, source): if dbug.LEV & dbug.MSGS: print "OSC:event_ack:code", args[0] return None # # Tracking INCOMING # def event_tracking_start(self, path, tags, args, source): """Tracking system is starting. Sent before first /pf/update message for that target args: no args """ #frame = args[0] if dbug.LEV & dbug.MSGS: print "OSC:event_track_start" def event_tracking_set(self, path, tags, args, source): """Tracking subsystem is setting params. Send value of various parameters. args: minx, miny, maxx, maxy - bounds of PF in units npeople - number of people currently present """ if dbug.LEV & dbug.MSGS: print "OSC:event_track_set:", path, args, source if path == OSCPATH['track_minx']: self.m_xmin = args[0] if dbug.LEV & dbug.MSGS: print "OSC:event_track_set:set_scaling(",\ (self.m_xmin,self.m_ymin),",",(self.m_xmax,self.m_ymax),")" # we might not have everything yet, but we udate with what we have self.m_field.set_scaling(pmin_field=(self.m_xmin, self.m_field.m_ymin_field)) elif path == OSCPATH['track_miny']: self.m_ymin = args[0] if dbug.LEV & dbug.MSGS: print "OSC:event_track_set:set_scaling(",\ (self.m_xmin,self.m_ymin),",",(self.m_xmax,self.m_ymax),")" # we might not have everything yet, but we udate with what we have self.m_field.set_scaling(pmin_field=(self.m_field.m_xmin_field, self.m_ymin)) elif path == OSCPATH['track_maxx']: self.m_xmax = args[0] if dbug.LEV & dbug.MSGS: print "OSC:event_track_set:set_scaling(",\ (self.m_xmin,self.m_ymin),",",(self.m_xmax,self.m_ymax),")" # we might not have everything yet, but we udate with what we have self.m_field.set_scaling(pmax_field=(self.m_xmax, self.m_field.m_ymax_field)) elif path == OSCPATH['track_maxy']: self.m_ymax = args[0] if dbug.LEV & dbug.MSGS: print "OSC:event_track_set:set_scaling(",\ (self.m_xmin,self.m_ymin),",",(self.m_xmax,self.m_ymax),")" # we might not have everything yet, but we udate with what we have self.m_field.set_scaling(pmax_field=(self.m_field.m_xmax_field, self.m_ymax)) elif path == OSCPATH['track_npeople']: self.m_field.check_people_count(args[0]) return elif path == OSCPATH['track_groupdist']: self.m_field.update(groupdist=args[0]) return elif path == OSCPATH['track_ungroupdist']: self.m_field.update(ungroupdist=args[0]) return elif path == OSCPATH['track_fps']: self.m_field.update(oscfps=args[0]) return #if self.m_xmin and self.m_ymin and self.m_xmax and self.m_ymax: #print "set_scaling(",(self.m_xmin,self.m_ymin),",",(self.m_xmax,self.m_ymax),")" #self.m_field.set_scaling((self.m_xmin,self.m_ymin),(self.m_xmax,self.m_ymax)) #self.m_field.updateScreen() def event_tracking_entry(self, path, tags, args, source): """Event when person enters field. Sent before first /pf/update message for that target args: frame - frame number t - time of frame (elapsed time in seconds since beginning of run) target - UID of target channel - channel number assigned """ #print "OSC:event_track_entry:",path,args,source #print "args:",args,args[0],args[1],args[2] frame = args[0] time = args[1] id = args[2] if dbug.LEV & dbug.MSGS: print "OSC:event_track_entry:cell:", id self.m_field.create_cell(id) def event_tracking_exit(self, path, tags, args, source): """Event when person exits field. args: frame - frame number t - time of frame (elapsed time in seconds since beginning of run) target - UID of target """ #print "OSC:event_track_exit:",path,args,source frame = args[0] time = args[1] id = args[2] if dbug.LEV & dbug.MSGS: print "OSC:event_track_exit:cell:", id #print "BEFORE: cells:",self.m_field.m_cell_dict #print "BEFORE: conx:",self.m_field.m_conx_dict self.m_field.del_cell(id) #print "AFTER: cells:",self.m_field.m_cell_dict #print "AFTER: conx:",self.m_field.m_conx_dict def event_tracking_body(self, path, tags, args, source): """Information about people's movement within field. Update position of target. args: frame - frame number target - UID of target x,y - position of person within field in m ex,ey - standard error of measurement (SEM) of position, in meters spd, heading - estimate of speed of person in m/s, heading in degrees espd, eheading - SEM of spd, heading facing - direction person is facing in degees efacing - SEM of facing direction diam - estimated mean diameter of legs sigmadiam - estimated sigma (sqrt(variance)) of diameter sep - estimated mean separation of legs sigmasep - estimated sigma (sqrt(variance)) of sep leftness - measure of how likely leg 0 is the left leg visibility - number of frames since a fix was found for either leg """ for index, item in enumerate(args): if item == 'nan': args[index] = None frame = args[0] id = args[1] x = args[2] # comes in meters y = args[3] ex = args[4] ey = args[5] spd = args[6] heading = args[7] espd = args[8] eheading = args[9] facing = args[10] efacing = args[11] diam = args[12] sigmadiam = args[13] sep = args[14] sigmasep = args[15] leftness = args[16] vis = args[17] if id not in self.m_field.m_cell_dict: if dbug.LEV & dbug.MSGS: print "OSC:event_track_body:no uid", id, "in registered cell list" if frame % REPORT_FREQ['debug'] == 0: if dbug.LEV & dbug.MSGS: print " OSC:event_track_body:id:",id,"pos:", (x, y), "data:", \ ex, ey, spd, espd, facing, efacing, diam, sigmadiam, \ sep, sigmasep, leftness, vis self.m_field.update_body(id, x, y, ex, ey, spd, espd, facing, efacing, diam, sigmadiam, sep, sigmasep, leftness, vis) def event_tracking_leg(self, path, tags, args, source): """Information about individual leg movement within field. Update position of leg. args: frame - frame number id - UID of target leg - leg number (0..nlegs-1) nlegs - number of legs target is modeled with x,y - position within field in m ex,ey - standard error of measurement (SEM) of position, in meters spd, heading - estimate of speed of leg in m/s, heading in degrees espd, eheading - SEM of spd, heading visibility - number of frames since a positive fix """ for index, item in enumerate(args): if item == 'nan': args[index] = None frame = args[0] id = args[1] leg = args[2] nlegs = args[3] x = args[4] # comes in meters y = args[5] ex = args[6] ey = args[7] spd = args[8] heading = args[9] espd = args[10] eheading = args[11] vis = args[12] if id not in self.m_field.m_cell_dict: if dbug.LEV & dbug.MSGS: print "OSC:event_track_leg:no uid", id, "in registered cell list" if frame % REPORT_FREQ['debug'] == 0: if dbug.LEV & dbug.MSGS: print " OSC:event_track_leg:id:", id, "leg:", leg, "pos:", (x,y), \ "data:", ex, ey, spd, espd, heading, eheading, vis self.m_field.update_leg(id, leg, nlegs, x, y, ex, ey, spd, espd, heading, eheading, vis) def event_tracking_update(self, path, tags, args, source): """Information about people's movement within field. Update position of target. args: /pf/update frame t target x y vx vy major minor groupid groupsize channel frame - frame number t - time of frame (elapsed time in seconds) target - UID of target, always increments x,y - position within field in meters vx,vy - estimate of velocity in m/s major,minor - major/minor axis size in m groupid - id number of group (0 if not in any group) groupsize - number of people in group (including this person) channel - channel number assigned """ for index, item in enumerate(args): if item == 'nan': args[index] = None frame = args[0] time = args[1] id = args[2] if id not in self.m_field.m_cell_dict: if dbug.LEV & dbug.MSGS: print "OSC:event_track_update:no uid", id, "in registered cell list" x = args[3] # comes in meters y = args[4] vx = args[5] vy = args[6] major = args[7] minor = args[8] gid = args[9] gsize = args[10] channel = args[11] #print "OSC:event_track_update:",path,args,source if frame % REPORT_FREQ['debug'] == 0: #print "OSC:event_track_update:",path,args,source if dbug.LEV & dbug.MSGS: print " OSC:event_track_update:id:",id,"pos:", (x, y), "data:", \ vx, vy, major, minor, gid, gsize self.m_field.update_cell(id, x, y, vx, vy, major, minor, gid, gsize, frame=frame) def event_tracking_group(self, path, tags, args, source): """Information about people's movement within field. Update info about group /pf/group frame gid gsize duration centroidX centroidY diameter args: frame - frame number gid - group ID gsize - number of people in group duration - time since first formed in seconds centroidX, centroidY - location of centroid of group diameter - current diameter (mean distance from centroid) """ for index, item in enumerate(args): if item == 'nan': args[index] = None frame = args[0] gid = args[1] gsize = args[2] # comes in meters duration = args[3] x = args[4] y = args[5] diam = args[6] if gid not in self.m_field.m_group_dict: if dbug.LEV & dbug.MSGS: print "OSC:event_track_group:no gid", gid, "in group list" if frame % REPORT_FREQ['debug'] == 0: if dbug.LEV & dbug.MSGS: print " OSC:event_track_group:gid:",gid, "pos:", (x, y), "data:", \ gsize, duration, diam self.m_field.update_group(gid, gsize, duration, x, y, diam) def event_tracking_geo(self, path, tags, args, source): """Information about people's movement within field. Update info about group /pf/geo frame target fromcenter fromothers fromexit args: frame - frame number uid - UID of target fromcenter -target's distance from geographic center of everyone fromnearest - target's distance from the nearest other person (-1 if nobody else) fromexit - This person's distance from nearest exit from tracked area """ for index, item in enumerate(args): if item == 'nan': args[index] = None frame = args[0] uid = args[1] fromcenter = args[2] # comes in meters fromnearest = args[3] fromexit = args[4] if uid not in self.m_field.m_cell_dict: if dbug.LEV & dbug.MSGS: print "OSC:event_track_geo:no uid", uid, "in registered cell list" if frame % REPORT_FREQ['debug'] == 0: if dbug.LEV & dbug.MSGS: print " OSC:event_track_geo:uid:",uid, "data:", \ fromcenter, fromnearest, fromexit self.m_field.update_geo(uid, fromcenter, fromnearest, fromexit) def event_tracking_frame(self, path, tags, args, source): """New frame event. args: frame - frame number """ #print "OSC:event_track_frame:",path,args,source frame = args[0] self.m_field.update(frame=frame) if frame % REPORT_FREQ['debug'] == 0: #print "OSC:event_track_update:",frame if dbug.LEV & dbug.MSGS: print " OSC:event_track_frame::", frame return None def event_tracking_stop(self, path, tags, args, source): """Tracking has stopped.""" if dbug.LEV & dbug.MSGS: print "OSC:event_track_stop:", path, args, source return None
print "Hold it there motor man!" ser.write('0') def motor_callback(path, tags, args, source): state = args[0] print state if path == "/lmcp/motor": if state == '1': motorGo(1) elif state == '2': motorGo(2) else: motorStop() def handle_error(self, request, client_address): pass server.addMsgHandler("/lmcp/motor", motor_callback) server.handle_error = types.MethodType(handle_error, server) server.timed_out = False while not server.timed_out: server.handle_request() server.close()
class OscReader: def __init__(self, host="127.0.0.1", port=8080, manager=None, threaded=False, autoStart=True): # params self.manager = manager self.host = host self.port = port self.threaded = threaded # attrs self._kill = False self.oscServer = None self.thread = None if autoStart: self.start() def setup(self): if self.oscServer != None: self.destroy() ColorTerminal().output("Starting OSC server with host {0} and port {1}".format(self.host, self.port)) self.oscServer = OSCServer((self.host, self.port)) self.oscServer.handle_timeout = self.handleTimeout self.oscServer.addMsgHandler('/marker', self.oscMarkerHandler) self.oscServer.addMsgHandler('/rigidbody', self.oscRigidBodyHandler) ColorTerminal().success("Server running") def destroy(self): if self.oscServer == None: return self.oscServer.close() self.oscServer = None def update(self): if self.oscServer == None: return # we'll enforce a limit to the number of osc requests # we'll handle in a single iteration, otherwise we might # get stuck in processing an endless stream of data limit = 10 count = 0 # clear timed_out flag self.oscServer.timed_out = False # handle all pending requests then return while not self.oscServer.timed_out and count < limit: self.oscServer.handle_request() count += 1 def oscMarkerHandler(self, addr, tags, data, client_address): if self.manager: self.manager.processMarkersData([data[0]]) def oscRigidBodyHandler(self, addr, tags, data, client_address): # readers can interface with the mocap data manager directly (most efficient) if self.manager: self.manager.processRigidBodyJson(data[0]) def handleTimeout(self): if self.oscServer != None: self.oscServer.timed_out = True def start(self): if not self.threaded: self.setup() return if self.thread and self.thread.isAlive(): ColorTerminal().warn("OscReader - Can't start while a thread is already running") return self._kill = False # threaded loop method will call setup self.thread = threading.Thread(target=self.threaded_loop) self.thread.start() def stop(self): if self.threaded: # threaded loop method will call destroy self._kill = True else: self.destroy() def threaded_loop(self): self.setup() while not self._kill: self.update() self.destroy()
class MuseIO(): def __init__(self, port=5001, signal=None, viewer=None): self.signal = signal self.viewer = viewer self.game = None self.port = port self.udp_ip = '127.0.0.1' self.server = OSCServer((self.udp_ip, self.port)) self.server.timeout = 0 # funny python's way to add a method to an instance of a class self.server.handle_timeout = types.MethodType(handle_timeout, self.server) # add message handlers if 'eeg' in self.signal: self.server.addMsgHandler('/muse/eeg', self.callback_eeg_raw) if 'concentration' in self.signal: self.server.addMsgHandler('/muse/elements/experimental/concentration', self.callback_concentration) if 'mellow' in self.signal: self.server.addMsgHandler('/muse/elements/experimental/mellow', self.callback_mellow) self.server.addMsgHandler("default", self.default_handler) def default_handler(self, addr, tags, stuff, source): # nothing to do here. This function is called for all messages that are not supported by the application. print "SERVER: No handler registered for ", addr return None def callback_eeg_raw(self, path, tags, args, source): # which user will be determined by path: # we just throw away all slashes and join together what's left # tags will contain 'ffff' # args is a OSCMessage with data # source is where the message came from (in case you need to reply) self.signal['eeg'].add_time() self.signal['eeg'].add_l_ear(args[0]) self.signal['eeg'].add_l_forehead(args[1]) self.signal['eeg'].add_r_forehead(args[2]) self.signal['eeg'].add_r_ear(args[3]) if 'eeg' in self.viewer: self.viewer['eeg'].refresh() #print args[0], args[1], args[2], args[3] def callback_concentration(self, path, tags, args, source): if 'concentration' in self.signal: self.signal['concentration'].add_time() self.signal['concentration'].add_concentration(args[0]) self.viewer['concentration-mellow'].refresh() #self.game.change_velocity(self.signal['concentration'].concentration) def callback_mellow(self, path, tags, args, source): if 'mellow' in self.signal: self.signal['mellow'].add_time() self.signal['mellow'].add_mellow(args[0]) self.viewer['concentration-mellow'].refresh() def handle_request(self): # clear timed_out flag self.server.timed_out = False # handle all pending requests then return while not self.server.timed_out: self.server.handle_request() def start(self, freq=220): update_timing = 1.0/float(freq) while True: sleep(update_timing) self.handle_request()
class OptiTrackReceiver(avg.Publisher): OSC_optitrack_MessageID = avg.Publisher.genMessageID() OSC_optitrack_KillMessageID = avg.Publisher.genMessageID() def __init__(self, ip="", port="5103"): avg.Publisher.__init__(self) try: rigidbody_format = config.optitrack_osc_format self.__index_id = rigidbody_format.index("id") self.__index_x = rigidbody_format.index("x") self.__index_y = rigidbody_format.index("y") self.__index_z = rigidbody_format.index("z") self.__index_roll = rigidbody_format.index("roll") self.__index_pitch = rigidbody_format.index("pitch") self.__index_yaw = rigidbody_format.index("yaw") self.__index_name = rigidbody_format.index("name") self.__index_quat_1 = rigidbody_format.index("quat_1") self.__index_quat_2 = rigidbody_format.index("quat_2") self.__index_quat_3 = rigidbody_format.index("quat_3") self.__index_quat_4 = rigidbody_format.index("quat_4") self.__osc_format_length = len(rigidbody_format) self.__server = OSCServer((ip, int(port))) # TODO check the ThreadingOSCServer class as possible alternative print "Optitrack:", self.__server self.__server.handle_timeout = types.MethodType( self.__handle_timeout, self.__server ) self.__server.timeout = 0 self.__server.addMsgHandler( "/tracking/optitrack/rigidbodies", self.__on_osc_rigidbody_message_received ) self.__server.addMsgHandler( "/kill", self.__on_osc_kill_message_received ) self.publish(self.OSC_optitrack_MessageID) self.publish(self.OSC_optitrack_KillMessageID) except OSCError: print "############################################" print "####### could not open OSCServer ###########" print "############################################" return def __handle_timeout(self, status): """Handle server timeouts.""" self.__server.timed_out = True def onFrame(self): """Stay active.""" self.__server.timed_out = False # handle all pending requests than return while not self.__server.timed_out: self.__server.handle_request() def run(self): """Start running the server.""" while True: self.__server.handle_request() self.__server.close() def __on_osc_rigidbody_message_received(self, addr, tags, data, client_address): """b Receives an OSC message, transforms the data and notifies subscribers by sending a message (type: list) containing skeleton_id and skeleton_joint (type: SkeletonJoint) Args: addr: the address (str e.g. /tracking/optitrack/rigidbodies) tags: tags (str with i for int32 and f for float, e.g. iiiifff) data: tracking data, containing id (0), position in space (1-3), and orientation in space (4-6) client_address: client address as (ip, port) tuple """ # check if length could actually be a rigid body message if len(data) < self.__osc_format_length: return data[self.__index_x] = data[self.__index_x] * 100 data[self.__index_y] = config.display_height_cm - data[self.__index_y] * 100 data[self.__index_z] = data[self.__index_z] * 100 # create RigidBody tuple rb = RigidBody( id=data[self.__index_id], name=data[self.__index_name], position=Point3D(data[self.__index_x], data[self.__index_y], data[self.__index_z]), orientation=(data[self.__index_roll], data[self.__index_pitch], data[self.__index_yaw]), orientation_quat=(data[self.__index_quat_1], data[self.__index_quat_2], data[self.__index_quat_3], data[self.__index_quat_4]), markers=None, mrk_ids=None, mrk_sizes=None, mrk_mean_error=None ) # send new rigidbody to subscriber self.notifySubscribers(self.OSC_optitrack_MessageID, [rb]) def __on_osc_kill_message_received(self, addr, tags, data, client_address): """ receives the kill event from oscserver and reacts ?? """ self.notifySubscribers(self.OSC_optitrack_KillMessageID, data)