Skip to content

Commit c98f118

Browse files
committed
fix: fmt
1 parent 1a48e4b commit c98f118

File tree

1 file changed

+45
-55
lines changed
  • src/arduino/app_bricks/hand_gesture_detection

1 file changed

+45
-55
lines changed

src/arduino/app_bricks/hand_gesture_detection/__init__.py

Lines changed: 45 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -25,18 +25,18 @@ def __init__(self, camera: BaseCamera | None = None):
2525
if camera is None:
2626
camera = Camera(fps=30)
2727
self.camera = camera
28-
28+
2929
# Callbacks
3030
self._gesture_callbacks = {} # {(gesture, hand): callback}
3131
self._enter_callback = None
3232
self._exit_callback = None
3333
self._frame_callback = None
3434
self._callbacks_lock = threading.Lock()
35-
35+
3636
# State tracking
3737
self._had_hands = False
3838
self._running = False
39-
39+
4040
self._camera_frame_queue = queue.Queue(maxsize=2)
4141

4242
# WebSocket endpoints
@@ -50,22 +50,22 @@ def __init__(self, camera: BaseCamera | None = None):
5050
self._host = resolve_address(self._host)
5151
if not self._host:
5252
raise RuntimeError("Host address could not be resolved. Please check your configuration.")
53-
53+
5454
self._ws_send_url = f"ws://{self._host}:5050"
5555
self._ws_recv_url = f"ws://{self._host}:5051"
56-
56+
5757
def start(self):
5858
"""Start the capture thread and asyncio event loop."""
5959
self._running = True
60-
60+
6161
def stop(self):
6262
"""Stop all tracking and close connections."""
6363
self._running = False
6464

6565
def on_gesture(self, gesture: str, callback: Callable[[dict], None], hand: Literal["left", "right", "both"] = "both"):
6666
"""
6767
Register or unregister a gesture callback.
68-
68+
6969
Args:
7070
gesture (str): The gesture name to detect
7171
callback (Callable[[dict], None]): Function to call when gesture is detected. None to unregister.
@@ -77,7 +77,7 @@ def on_gesture(self, gesture: str, callback: Callable[[dict], None], hand: Liter
7777
x and y are pixel coordinates and z is normalized depth)
7878
- "bounding_box_xyxy": [x_min, y_min, x_max, y_max] of the detected hand bounding box
7979
hand (Literal["left", "right", "both"]): Which hand(s) to track
80-
80+
8181
Raises:
8282
ValueError: If 'hand' argument is not valid
8383
"""
@@ -95,7 +95,7 @@ def on_gesture(self, gesture: str, callback: Callable[[dict], None], hand: Liter
9595
def on_enter(self, callback: Callable[[], None]):
9696
"""
9797
Register a callback for when hands become visible.
98-
98+
9999
Args:
100100
callback (Callable[[], None]): Function to call when at least one hand is detected
101101
"""
@@ -105,7 +105,7 @@ def on_enter(self, callback: Callable[[], None]):
105105
def on_exit(self, callback: Callable[[], None]):
106106
"""
107107
Register a callback for when hands are no longer visible.
108-
108+
109109
Args:
110110
callback (Callable[[], None]): Function to call when no hands are detected anymore
111111
"""
@@ -115,13 +115,13 @@ def on_exit(self, callback: Callable[[], None]):
115115
def on_frame(self, callback: Callable[[np.ndarray], None]):
116116
"""
117117
Register a callback that receives each camera frame.
118-
118+
119119
Args:
120120
callback (Callable[[np.ndarray], None]): Function to call with camera frame data. None to unregister.
121121
"""
122122
with self._callbacks_lock:
123123
self._frame_callback = callback
124-
124+
125125
@brick.loop
126126
def _capture_loop(self):
127127
"""Continuously capture frames from camera (runs in dedicated thread)."""
@@ -130,15 +130,15 @@ def _capture_loop(self):
130130
if frame is None:
131131
time.sleep(0.01)
132132
return
133-
133+
134134
with self._callbacks_lock:
135135
frame_cb = self._frame_callback
136136
if frame_cb:
137137
try:
138138
frame_cb(frame)
139139
except Exception as e:
140140
print(f"Error in frame callback: {e}")
141-
141+
142142
jpeg_frame = compress_to_jpeg(frame)
143143
if jpeg_frame is None:
144144
time.sleep(0.01)
@@ -153,57 +153,47 @@ def _capture_loop(self):
153153
self._camera_frame_queue.put(jpeg_frame, block=False)
154154
except:
155155
pass
156-
156+
157157
except Exception as e:
158158
if self._running:
159159
print(f"Error capturing frame: {e}")
160-
160+
161161
@brick.execute
162162
def _send_receive_loop(self):
163163
"""Run the asyncio event loop in a dedicated thread."""
164164
loop = asyncio.new_event_loop()
165165
asyncio.set_event_loop(loop)
166-
166+
167167
try:
168-
tasks = asyncio.gather(
169-
self._send_frames_task(),
170-
self._receive_detections_task(),
171-
return_exceptions=True
172-
)
168+
tasks = asyncio.gather(self._send_frames_task(), self._receive_detections_task(), return_exceptions=True)
173169
loop.run_until_complete(tasks)
174170

175171
except Exception as e:
176172
print(f"Error in asyncio loop: {e}")
177173
finally:
178174
loop.close()
179-
175+
180176
async def _send_frames_task(self):
181177
"""Send frames to the processing container via WebSocket."""
182178
while self._running:
183179
try:
184180
async with websockets.connect(self._ws_send_url) as ws:
185181
while self._running:
186182
try:
187-
frame = await asyncio.get_event_loop().run_in_executor(
188-
None, self._camera_frame_queue.get, True, 0.1
189-
)
183+
frame = await asyncio.get_event_loop().run_in_executor(None, self._camera_frame_queue.get, True, 0.1)
190184
except queue.Empty:
191185
continue
192-
193-
b64_frame = base64.b64encode(frame.tobytes()).decode('utf-8')
194-
payload = {
195-
"frame": b64_frame,
196-
"width": 640,
197-
"height": 480
198-
}
199-
186+
187+
b64_frame = base64.b64encode(frame.tobytes()).decode("utf-8")
188+
payload = {"frame": b64_frame, "width": 640, "height": 480}
189+
200190
await ws.send(json.dumps(payload))
201-
191+
202192
except Exception as e:
203193
if self._running:
204194
print(f"Error in send frames task: {e}. Reconnecting...")
205195
await asyncio.sleep(3)
206-
196+
207197
async def _receive_detections_task(self):
208198
"""Receive detection results and dispatch events."""
209199
while self._running:
@@ -212,71 +202,71 @@ async def _receive_detections_task(self):
212202
while self._running:
213203
data = await ws.recv()
214204
detection = json.loads(data)
215-
216-
self._process_detection(detection.get('metadata', {}))
217-
205+
206+
self._process_detection(detection.get("metadata", {}))
207+
218208
except Exception as e:
219209
if self._running:
220210
print(f"Error in receive detections task: {e}. Reconnecting...")
221211
await asyncio.sleep(3)
222-
212+
223213
def _process_detection(self, metadata: dict):
224214
"""Process detection data and dispatch appropriate events."""
225-
hands_data = metadata.get('hands', [])
215+
hands_data = metadata.get("hands", [])
226216
has_hands = bool(hands_data)
227-
217+
228218
# Dispatch hand enter/exit events
229219
if has_hands and not self._had_hands:
230220
self._dispatch_enter()
231221
elif self._had_hands and not has_hands:
232222
self._dispatch_exit()
233-
223+
234224
self._had_hands = has_hands
235-
225+
236226
# Dispatch hand gesture events
237227
for hand_data in hands_data:
238-
hand = hand_data.get('hand', '')
239-
gesture = hand_data.get('gesture', '')
240-
if hand in ('left', 'right') and gesture:
228+
hand = hand_data.get("hand", "")
229+
gesture = hand_data.get("gesture", "")
230+
if hand in ("left", "right") and gesture:
241231
self._dispatch_gesture(gesture, hand, metadata)
242-
232+
243233
def _dispatch_enter(self):
244234
"""Dispatch hand enter event."""
245235
with self._callbacks_lock:
246236
callback = self._enter_callback
247-
237+
248238
if callback:
249239
try:
250240
callback()
251241
except Exception as e:
252242
print(f"Error in enter callback: {e}")
253-
243+
254244
def _dispatch_exit(self):
255245
"""Dispatch hand exit event."""
256246
with self._callbacks_lock:
257247
callback = self._exit_callback
258-
248+
259249
if callback:
260250
try:
261251
callback()
262252
except Exception as e:
263253
print(f"Error in exit callback: {e}")
264-
254+
265255
def _dispatch_gesture(self, gesture: str, hand: Literal["left", "right"], metadata: dict):
266256
"""Dispatch gesture event to registered callbacks."""
267257
callbacks_to_call = []
268-
258+
269259
with self._callbacks_lock:
270260
# Check for exact hand match
271261
exact_key = (gesture, hand)
272262
if exact_key in self._gesture_callbacks:
273263
callbacks_to_call.append(self._gesture_callbacks[exact_key])
274-
264+
275265
# Check for "both" wildcard
276266
both_key = (gesture, "both")
277267
if both_key in self._gesture_callbacks:
278268
callbacks_to_call.append(self._gesture_callbacks[both_key])
279-
269+
280270
for callback in callbacks_to_call:
281271
try:
282272
callback(metadata)

0 commit comments

Comments
 (0)