source: trunk/src/testing/dim/hwcapture/pucks.py @ 4

Revision 4, 5.9 KB checked in by ajaworski, 13 years ago (diff)

Added modified SAGE sources

Line 
1############################################################################
2#
3# DIM - A Direct Interaction Manager for SAGE
4# Copyright (C) 2007 Electronic Visualization Laboratory,
5# University of Illinois at Chicago
6#
7# All rights reserved.
8#
9# Redistribution and use in source and binary forms, with or without
10# modification, are permitted provided that the following conditions are met:
11#
12#  * Redistributions of source code must retain the above copyright
13#    notice, this list of conditions and the following disclaimer.
14#  * Redistributions in binary form must reproduce the above
15#    copyright notice, this list of conditions and the following disclaimer
16#    in the documentation and/or other materials provided with the distribution.
17#  * Neither the name of the University of Illinois at Chicago nor
18#    the names of its contributors may be used to endorse or promote
19#    products derived from this software without specific prior written permission.
20#
21# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
25# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
26# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
27# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
28# PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
29# LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
30# NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
31# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32#
33# Direct questions, comments etc about SAGE UI to www.evl.uic.edu/cavern/forum
34#
35# Author: Ratko Jagodic
36#       
37############################################################################
38
39
40
41####  lambdatable pucks
42
43from managerConn import ManagerConnection
44import sys, socket, os
45from threading import Thread
46
47
48TRACKING_PORT = 7000  # where the tracker will send UDP data to
49#DEVICE_TYPE = "puck"   # a plugin for this type must exist in "devices" called puck.py
50
51os.chdir(sys.path[0])
52
53class Puck:
54    """ describes one puck """
55   
56    def __init__(self, puckId, x, y, angle, puckType):
57        self.puckId = puckId
58        self.puckType = puckType  # not covered
59        self.x = x   # normalized coords
60        self.y = y   # normalized coords
61        self.angle = angle  # in degrees
62        self.name = "puck"+str(puckId)
63
64       
65    def setAll(self, x, y, angle, puckType):
66        """ returns True if there was a change in any data
67            False otherwise
68        """
69        change = False
70       
71        if self.puckType != puckType: change=True
72        self.puckType = puckType
73
74        if self.x != x: change=True
75        self.x = x
76
77        if self.y != y: change=True
78        self.y = y
79
80        if self.angle != angle: change=True
81        self.angle = angle
82
83        return change
84       
85   
86
87
88class CapturePucks:
89   
90    def __init__(self, manager):
91        self.manager = manager
92        self.pucks = {}  # keyed by ID, value=Puck object
93
94        # create the tracker server for receiving puck data
95        self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
96        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
97        self.socket.bind(('', TRACKING_PORT))
98        self.socket.settimeout(0.1)
99
100        # some vars
101        self.threadKilled = False
102
103        # start listening for connections in a thread
104        self.t = Thread(target=self.receiver, args=())
105        self.t.start()
106
107
108    def stop(self):
109        self.threadKilled = True
110        self.t.join()
111
112
113    def receiver(self):
114        MSG_SIZE = 60
115        while not self.threadKilled:
116            try:
117               
118                msgString = ""
119                while len(msgString) < MSG_SIZE:
120                    msgString += self.socket.recv(MSG_SIZE)      # receive the fixed message size
121
122                if len(msgString) < 2:
123                    self.stop()
124                    break
125
126                # record only the first reported position OR
127                # record all of them based on the callback variable
128                elif len(msgString) == MSG_SIZE:
129                    msg = msgString.replace('\x00', '').strip()   # remove the NULLs
130                    self.processPuckData(msg)                   
131                   
132            except socket.timeout:
133                pass    # do nothing since it's just a timeout...
134            except socket.error:
135                #print "socket error in connection with the tracker..."
136                #self.stop()
137                continue
138               
139        self.socket.close()
140
141
142    def processPuckData(self, msg):
143        #print "msg = ", msg
144        tokens = msg.split()
145        ## puckId =   int(msg[ 11:21 ].strip())
146##         x =      float(msg[ 21:31 ].strip())
147##         y =      float(msg[ 31:41 ].strip())
148##         angle =  float(msg[ 41:51 ].strip())
149##         puckType = int(msg[ 51:61 ].strip())
150
151        puckId =   int(tokens[1].strip())
152        x =      float(tokens[2].strip())
153        y =      float(tokens[3].strip())
154        angle =  float(tokens[4].strip())
155        puckType = int(tokens[5].strip())
156
157        # send a message to the manager only if it's a new puck or the state of
158        # an existing one changed
159        if not puckId in self.pucks:
160            p = Puck(puckId, x, y, angle, puckType)
161            self.pucks[puckId] = p
162            self.manager.sendMessage(p.name, "puck", msg)
163        else:
164            p = self.pucks[puckId]
165            if p.setAll(x, y, angle, puckType):
166                self.manager.sendMessage(p.name, "puck", msg)
167
168       
169
170# you can optionally pass in a port number of the manager on command line
171port = 20005
172if len(sys.argv) > 2:
173    port = int(sys.argv[2])
174
175# start everything off
176CapturePucks( ManagerConnection(sys.argv[1], port) )
177   
Note: See TracBrowser for help on using the repository browser.