/
Controller_Listener.py
196 lines (142 loc) · 7.69 KB
/
Controller_Listener.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
# *------------------------------------------------------------ *
# * Class: Controller_Listener
# * --------------------------
# * Main class for this application; does all of the following:
# * - receives frames from the leap
# * - discerns gestures via Leap_Gesture object
# * - sends gesture events to Max via Max_Interface object
# *------------------------------------------------------------ *
#--- Standard ---
import sys
#--- Leap ---
sys.path.append ('/Users/jayhack/CS/NI/LeapDeveloperKit/LeapSDK/lib')
import Leap
from Leap import CircleGesture, KeyTapGesture, ScreenTapGesture, SwipeGesture
#--- My Files ---
from common_utilities import print_message, print_error, print_status, print_inner_status
from Max_Interface import Max_Interface
class Controller_Listener(Leap.Listener):
#--- Member Objects ---
max_interface = None # Interface w/ max
leap_gesture = None # Recognition of gestures
#--- Gestures ---
available_gestures = ["no_hands", "one_hand", "two_hands"] # list of available gestures
# Function: Constructor
# ---------------------
# creates max_interface and leap_gesture
def on_init(self, controller):
### Step 1: create max interface ###
self.max_interface = Max_Interface ()
### Step 2: notify of initialization ###
print_status ("Controller Listener", "controller initialized")
########################################################################################################################
##############################[ --- Initialization/Finalization --- ]###################################################
########################################################################################################################
# Function: on_connect
# --------------------
# callback function for when the controller is connected
def on_connect(self, controller):
print_status ("Controller Listener", "controller connected")
# Enable gestures
controller.enable_gesture(Leap.Gesture.TYPE_CIRCLE);
controller.enable_gesture(Leap.Gesture.TYPE_KEY_TAP);
controller.enable_gesture(Leap.Gesture.TYPE_SCREEN_TAP);
controller.enable_gesture(Leap.Gesture.TYPE_SWIPE);
# Function: on_disconnect
# -----------------------
# callback function for when the controller is disconnected
def on_disconnect(self, controller):
print_status ("Controller Listener", "Controller disconnected")
# Function: on_exit
# -----------------
# callback function for exit of the program
def on_exit(self, controller):
print_status ("Controller Listener", "Exiting")
########################################################################################################################
##############################[ --- Frame Processing --- ]##############################################################
########################################################################################################################
# Function: print_frame
# ---------------------
# prints a user-readable format of the current frame
def print_frame (self, frame):
print "Frame id: %d, timestamp: %d, hands: %d, fingers: %d, tools: %d, gestures: %d" % (
frame.id, frame.timestamp, len(frame.hands), len(frame.fingers), len(frame.tools), len(frame.gestures()))
# Function: on_frame
# ------------------
# this function is called for every frame that is observed from the leap.
def on_frame(self, controller):
frame = controller.frame()
if len(frame.hands) == 0:
self.max_interface.send_gesture ("no_hands")
elif len(frame.hands) == 1:
self.max_interface.send_gesture ("one_hand")
elif len(frame.hands) == 2:
self.max_interface.send_gesture ("two_hands")
self.print_frame (frame)
if not frame.hands.is_empty:
# Get the first hand
hand = frame.hands[0]
# Check if the hand has any fingers
fingers = hand.fingers
if not fingers.is_empty:
# Calculate the hand's average finger tip position
avg_pos = Leap.Vector()
for finger in fingers:
avg_pos += finger.tip_position
avg_pos /= len(fingers)
print "Hand has %d fingers, average finger tip position: %s" % (
len(fingers), avg_pos)
# Get the hand's sphere radius and palm position
print "Hand sphere radius: %f mm, palm position: %s" % (
hand.sphere_radius, hand.palm_position)
# Get the hand's normal vector and direction
normal = hand.palm_normal
direction = hand.direction
# Calculate the hand's pitch, roll, and yaw angles
print "Hand pitch: %f degrees, roll: %f degrees, yaw: %f degrees" % (
direction.pitch * Leap.RAD_TO_DEG,
normal.roll * Leap.RAD_TO_DEG,
direction.yaw * Leap.RAD_TO_DEG)
# Gestures
for gesture in frame.gestures():
if gesture.type == Leap.Gesture.TYPE_CIRCLE:
circle = CircleGesture(gesture)
# Determine clock direction using the angle between the pointable and the circle normal
if circle.pointable.direction.angle_to(circle.normal) <= Leap.PI/4:
clockwiseness = "clockwise"
else:
clockwiseness = "counterclockwise"
# Calculate the angle swept since the last frame
swept_angle = 0
if circle.state != Leap.Gesture.STATE_START:
previous_update = CircleGesture(controller.frame(1).gesture(circle.id))
swept_angle = (circle.progress - previous_update.progress) * 2 * Leap.PI
print "Circle id: %d, %s, progress: %f, radius: %f, angle: %f degrees, %s" % (
gesture.id, self.state_string(gesture.state),
circle.progress, circle.radius, swept_angle * Leap.RAD_TO_DEG, clockwiseness)
if gesture.type == Leap.Gesture.TYPE_SWIPE:
swipe = SwipeGesture(gesture)
print "Swipe id: %d, state: %s, position: %s, direction: %s, speed: %f" % (
gesture.id, self.state_string(gesture.state),
swipe.position, swipe.direction, swipe.speed)
if gesture.type == Leap.Gesture.TYPE_KEY_TAP:
keytap = KeyTapGesture(gesture)
print "Key Tap id: %d, %s, position: %s, direction: %s" % (
gesture.id, self.state_string(gesture.state),
keytap.position, keytap.direction )
if gesture.type == Leap.Gesture.TYPE_SCREEN_TAP:
screentap = ScreenTapGesture(gesture)
print "Screen Tap id: %d, %s, position: %s, direction: %s" % (
gesture.id, self.state_string(gesture.state),
screentap.position, screentap.direction )
if not (frame.hands.is_empty and frame.gestures().is_empty):
print ""
def state_string(self, state):
if state == Leap.Gesture.STATE_START:
return "STATE_START"
if state == Leap.Gesture.STATE_UPDATE:
return "STATE_UPDATE"
if state == Leap.Gesture.STATE_STOP:
return "STATE_STOP"
if state == Leap.Gesture.STATE_INVALID:
return "STATE_INVALID"