Skip to content

Commit c5f0d40

Browse files
committed
refactor: switch Coral TPU deployment strategy back to Docker with USB passthrough
This reverts the deployment logic to the Docker-first approach originally introduced in commit 9137400 to bypass sudo and libedgetpu installation hurdles on macOS. The compiled tflite models added in recent commits remain.
1 parent 57dc976 commit c5f0d40

3 files changed

Lines changed: 161 additions & 265 deletions

File tree

skills/detection/yolo-detection-2026-coral-tpu/SKILL.md

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
---
22
name: yolo-detection-2026-coral-tpu
3-
description: "Google Coral Edge TPU — real-time object detection with LiteRT"
4-
version: 2.0.0
3+
description: "Google Coral Edge TPU — real-time object detection via Docker"
4+
version: 1.0.0
55
icon: assets/icon.png
66
entry: scripts/detect.py
77
deploy: deploy.sh
8+
runtime: docker
89

910
requirements:
10-
python: ">=3.9"
11-
ai-edge-litert: ">=2.1.0"
12-
system: "libedgetpu"
11+
docker: ">=20.10"
1312
platforms: ["linux", "macos", "windows"]
1413

1514
parameters:
@@ -79,56 +78,59 @@ mutex: detection
7978

8079
# Coral TPU Object Detection
8180

82-
Real-time object detection using Google Coral Edge TPU accelerator. Uses [ai-edge-litert](https://pypi.org/project/ai-edge-litert/) (LiteRT — the modern successor to TFLite/pycoral) with the `libedgetpu` delegate for hardware acceleration. Detects 80 COCO classes with ~4ms inference on 320×320 input.
81+
Real-time object detection using Google Coral Edge TPU accelerator. Runs inside Docker for cross-platform support. Detects 80 COCO classes (person, car, dog, cat, etc.) with ~4ms inference on 320×320 input.
8382

8483
## Requirements
8584

8685
- **Google Coral USB Accelerator** (USB 3.0 port recommended)
87-
- **Python 3.9+** (3.9–3.13 supported via ai-edge-litert)
88-
- **libedgetpu** system library (installed per platform, see below)
86+
- **Docker Desktop 4.35+** (all platforms — Linux, macOS, Windows)
87+
- USB 3.0 cable (the included cable is recommended)
8988
- Adequate cooling for sustained inference
9089

9190
## How It Works
9291

93-
1. `deploy.sh` creates a Python venv, installs `ai-edge-litert`, and checks for `libedgetpu`
94-
2. Aegis writes camera frame JPEG to shared `/tmp/aegis_detection/` directory
95-
3. Sends `frame` event via stdin JSONL to `detect.py`
96-
4. `detect.py` loads the Edge TPU delegate via `litert.load_delegate('libedgetpu')`
97-
5. Returns `detections` event via stdout JSONL
98-
6. Same protocol as `yolo-detection-2026` — Aegis sees no difference
92+
```
93+
┌─────────────────────────────────────────────────────┐
94+
│ Host (Aegis-AI) │
95+
│ frame.jpg → /tmp/aegis_detection/ │
96+
│ stdin ──→ ┌──────────────────────────────┐ │
97+
│ │ Docker Container │ │
98+
│ │ detect.py │ │
99+
│ │ ├─ loads _edgetpu.tflite │ │
100+
│ │ ├─ reads frame from volume │ │
101+
│ │ └─ runs inference on TPU │ │
102+
│ stdout ←── │ → JSONL detections │ │
103+
│ └──────────────────────────────┘ │
104+
│ USB ──→ /dev/bus/usb (Linux) or USB/IP (Mac/Win) │
105+
└─────────────────────────────────────────────────────┘
106+
```
107+
108+
1. Aegis writes camera frame JPEG to shared `/tmp/aegis_detection/` volume
109+
2. Sends `frame` event via stdin JSONL to Docker container
110+
3. `detect.py` reads frame, runs inference on Edge TPU
111+
4. Returns `detections` event via stdout JSONL
112+
5. Same protocol as `yolo-detection-2026` — Aegis sees no difference
99113

100114
## Platform Setup
101115

102116
### Linux
103117
```bash
104-
# 1. Install libedgetpu (deploy.sh auto-installs on Debian/Ubuntu)
105-
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | \
106-
sudo tee /etc/apt/sources.list.d/coral-edgetpu.list
107-
curl -fsSL https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
108-
sudo apt-get update && sudo apt-get install libedgetpu1-std
109-
110-
# 2. Connect Coral USB Accelerator, then:
118+
# USB Coral should be auto-detected
119+
# Docker uses --device /dev/bus/usb for direct access
111120
./deploy.sh
112121
```
113122

114-
### macOS
123+
### macOS (Docker Desktop 4.35+)
115124
```bash
116-
# 1. Install libedgetpu
117-
curl -LO https://github.com/google-coral/libedgetpu/releases/download/release-grouper/edgetpu_runtime_20221024.zip
118-
unzip edgetpu_runtime_20221024.zip && cd edgetpu_runtime && sudo bash install.sh
119-
120-
# 2. Connect Coral USB Accelerator, then:
125+
# Docker Desktop USB/IP handles USB passthrough
126+
# ARM64 Docker image builds natively on Apple Silicon
121127
./deploy.sh
122128
```
123129

124130
### Windows
125131
```powershell
126-
# 1. Install libedgetpu
127-
# Download edgetpu_runtime_20221024.zip from:
128-
# https://github.com/google-coral/libedgetpu/releases
129-
# Extract and run install.bat
130-
131-
# 2. Connect Coral USB Accelerator, then:
132+
# Docker Desktop 4.35+ with USB/IP support
133+
# Or WSL2 backend with usbipd-win
132134
.\deploy.bat
133135
```
134136

@@ -137,6 +139,7 @@ unzip edgetpu_runtime_20221024.zip && cd edgetpu_runtime && sudo bash install.sh
137139
Ships with pre-compiled `yolo26n_edgetpu.tflite` (YOLO 2026 nano, INT8 quantized, 320×320). To compile custom models:
138140

139141
```bash
142+
# Requires x86_64 Linux or Docker --platform linux/amd64
140143
python scripts/compile_model.py --model yolo26s --size 320
141144
```
142145

@@ -155,7 +158,7 @@ Same JSONL as `yolo-detection-2026`:
155158

156159
### Skill → Aegis (stdout)
157160
```jsonl
158-
{"event": "ready", "model": "yolo26n_edgetpu", "device": "coral", "format": "edgetpu_tflite", "runtime": "ai-edge-litert", "tpu_count": 1, "classes": 80}
161+
{"event": "ready", "model": "yolo26n_edgetpu", "device": "coral", "format": "edgetpu_tflite", "tpu_count": 1, "classes": 80}
159162
{"event": "detections", "frame_id": 42, "camera_id": "front_door", "objects": [{"class": "person", "confidence": 0.85, "bbox": [100, 50, 300, 400]}]}
160163
{"event": "perf_stats", "total_frames": 50, "timings_ms": {"inference": {"avg": 4.1, "p50": 3.9, "p95": 5.2}}}
161164
```
@@ -169,8 +172,4 @@ Same JSONL as `yolo-detection-2026`:
169172
./deploy.sh
170173
```
171174

172-
The deployer creates a Python venv, installs `ai-edge-litert` and dependencies, checks for the `libedgetpu` system library, probes for Edge TPU devices, and sets the native `run_command`.
173-
174-
### Docker (Optional)
175-
176-
A `Dockerfile` is provided for environments where native installation is impractical. Note: Docker requires USB/IP passthrough for Edge TPU access on macOS and Windows.
175+
The deployer builds the Docker image locally, probes for TPU devices, and sets the runtime command. No packages pulled from external registries beyond Docker base images and Coral apt repo.
Lines changed: 46 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -1,96 +1,71 @@
11
@echo off
2-
REM deploy.bat — Native bootstrapper for Coral TPU Detection Skill (Windows)
2+
REM deploy.bat — Docker-based bootstrapper for Coral TPU Detection Skill (Windows)
33
REM
4-
REM Installs ai-edge-litert in a Python venv and verifies Edge TPU connectivity.
4+
REM Builds the Docker image locally and verifies Edge TPU connectivity.
55
REM Called by Aegis skill-runtime-manager during installation.
66
REM
7-
REM Prerequisites:
8-
REM - Python 3.9+ installed and on PATH
9-
REM - libedgetpu installed (https://github.com/google-coral/libedgetpu/releases)
10-
REM
11-
REM Exit codes:
12-
REM 0 = success (Edge TPU detected)
13-
REM 1 = fatal error
14-
REM 2 = partial success (no TPU, CPU fallback)
15-
16-
setlocal EnableDelayedExpansion
7+
REM Requires: Docker Desktop 4.35+ with USB/IP support
178

18-
set SKILL_DIR=%~dp0
19-
set VENV_DIR=%SKILL_DIR%.venv
20-
set LOG_PREFIX=[coral-tpu-deploy]
9+
setlocal enabledelayedexpansion
2110

22-
REM ─── Step 1: Find Python ───────────────────────────────────────────────────
11+
set "SKILL_DIR=%~dp0"
12+
set "IMAGE_NAME=aegis-coral-tpu"
13+
set "IMAGE_TAG=latest"
14+
set "LOG_PREFIX=[coral-tpu-deploy]"
2315

24-
echo %LOG_PREFIX% Checking for Python 3.9+... >&2
16+
REM ─── Step 1: Check Docker ────────────────────────────────────────────────
2517

26-
where python >nul 2>&1
27-
if errorlevel 1 (
28-
echo {"event": "error", "stage": "python", "message": "Python not found. Install Python 3.9+"}
18+
where docker >nul 2>&1
19+
if %errorlevel% neq 0 (
20+
echo %LOG_PREFIX% ERROR: Docker not found. Install Docker Desktop 4.35+ 1>&2
21+
echo {"event": "error", "stage": "docker", "message": "Docker not found. Install Docker Desktop 4.35+"}
2922
exit /b 1
3023
)
3124

32-
for /f "tokens=2" %%v in ('python --version 2^>^&1') do set PY_VER=%%v
33-
echo %LOG_PREFIX% Found Python %PY_VER% >&2
34-
35-
REM ─── Step 2: Create virtual environment ────────────────────────────────────
36-
37-
if not exist "%VENV_DIR%\Scripts\python.exe" (
38-
echo {"event": "progress", "stage": "venv", "message": "Creating virtual environment..."}
39-
python -m venv "%VENV_DIR%"
40-
if errorlevel 1 (
41-
echo {"event": "error", "stage": "venv", "message": "Failed to create virtual environment"}
42-
exit /b 1
43-
)
25+
docker info >nul 2>&1
26+
if %errorlevel% neq 0 (
27+
echo %LOG_PREFIX% ERROR: Docker daemon not running. Start Docker Desktop. 1>&2
28+
echo {"event": "error", "stage": "docker", "message": "Docker daemon not running"}
29+
exit /b 1
4430
)
4531

46-
set VENV_PIP=%VENV_DIR%\Scripts\pip.exe
47-
set VENV_PYTHON=%VENV_DIR%\Scripts\python.exe
48-
49-
echo %LOG_PREFIX% Virtual environment ready >&2
50-
51-
REM ─── Step 3: Install dependencies ─────────────────────────────────────────
52-
53-
echo {"event": "progress", "stage": "install", "message": "Installing ai-edge-litert and dependencies..."}
54-
"%VENV_PIP%" install --upgrade pip -q 2>&1
55-
"%VENV_PIP%" install -r "%SKILL_DIR%requirements.txt" -q 2>&1
32+
for /f "tokens=*" %%v in ('docker version --format "{{.Server.Version}}" 2^>nul') do set "DOCKER_VER=%%v"
33+
echo %LOG_PREFIX% Using Docker (version: %DOCKER_VER%) 1>&2
34+
echo {"event": "progress", "stage": "docker", "message": "Docker ready (%DOCKER_VER%)"}
5635

57-
echo %LOG_PREFIX% Dependencies installed >&2
58-
echo {"event": "progress", "stage": "install", "message": "Dependencies installed"}
36+
REM ─── Step 2: Build Docker image ──────────────────────────────────────────
5937

60-
REM ─── Step 4: Check libedgetpu ──────────────────────────────────────────────
38+
echo %LOG_PREFIX% Building Docker image: %IMAGE_NAME%:%IMAGE_TAG% ... 1>&2
39+
echo {"event": "progress", "stage": "build", "message": "Building Docker image..."}
6140

62-
echo %LOG_PREFIX% Checking for libedgetpu... >&2
63-
echo {"event": "progress", "stage": "driver", "message": "Checking for Edge TPU driver..."}
64-
65-
where edgetpu.dll >nul 2>&1
66-
if errorlevel 1 (
67-
echo %LOG_PREFIX% WARNING: edgetpu.dll not found. >&2
68-
echo %LOG_PREFIX% Download the runtime from: >&2
69-
echo %LOG_PREFIX% https://github.com/google-coral/libedgetpu/releases/download/release-grouper/edgetpu_runtime_20221024.zip >&2
70-
echo %LOG_PREFIX% Extract and run install.bat >&2
71-
echo {"event": "progress", "stage": "driver", "message": "libedgetpu not found — install from Google releases"}
41+
docker build -t %IMAGE_NAME%:%IMAGE_TAG% "%SKILL_DIR%"
42+
if %errorlevel% neq 0 (
43+
echo %LOG_PREFIX% ERROR: Docker build failed 1>&2
44+
echo {"event": "error", "stage": "build", "message": "Docker image build failed"}
45+
exit /b 1
7246
)
7347

74-
REM ─── Step 5: Probe for Edge TPU ───────────────────────────────────────────
48+
echo {"event": "progress", "stage": "build", "message": "Docker image ready"}
7549

50+
REM ─── Step 3: Probe for Edge TPU ──────────────────────────────────────────
51+
52+
echo %LOG_PREFIX% Probing for Edge TPU devices... 1>&2
7653
echo {"event": "progress", "stage": "probe", "message": "Checking for Edge TPU devices..."}
7754

78-
set TPU_FOUND=false
79-
"%VENV_PYTHON%" "%SKILL_DIR%scripts\tpu_probe.py" > "%TEMP%\tpu_probe_result.json" 2>nul
80-
if not errorlevel 1 (
81-
set TPU_FOUND=true
55+
docker run --rm --privileged %IMAGE_NAME%:%IMAGE_TAG% python3 scripts/tpu_probe.py >nul 2>&1
56+
if %errorlevel% equ 0 (
57+
echo %LOG_PREFIX% Edge TPU detected 1>&2
58+
echo {"event": "progress", "stage": "probe", "message": "Edge TPU detected"}
59+
) else (
60+
echo %LOG_PREFIX% WARNING: No Edge TPU detected - CPU fallback 1>&2
61+
echo {"event": "progress", "stage": "probe", "message": "No Edge TPU detected - CPU fallback"}
8262
)
8363

84-
REM ─── Step 6: Complete ──────────────────────────────────────────────────────
64+
REM ─── Step 4: Set run command ──────────────────────────────────────────────
8565

86-
set RUN_CMD=%VENV_PYTHON% %SKILL_DIR%scripts\detect.py
66+
set "RUN_CMD=docker run -i --rm --privileged -v /tmp/aegis_detection:/tmp/aegis_detection --env AEGIS_SKILL_ID --env AEGIS_SKILL_PARAMS --env PYTHONUNBUFFERED=1 %IMAGE_NAME%:%IMAGE_TAG%"
8767

88-
if "%TPU_FOUND%"=="true" (
89-
echo {"event": "complete", "status": "success", "accelerator_found": true, "run_command": "%RUN_CMD%", "message": "Coral TPU skill installed — Edge TPU ready"}
90-
echo %LOG_PREFIX% Done! Edge TPU ready. >&2
91-
exit /b 0
92-
) else (
93-
echo {"event": "complete", "status": "partial", "accelerator_found": false, "run_command": "%RUN_CMD%", "message": "Coral TPU skill installed — no TPU detected (CPU fallback)"}
94-
echo %LOG_PREFIX% Done with warning: no TPU detected. >&2
95-
exit /b 2
96-
)
68+
echo {"event": "complete", "status": "success", "run_command": "%RUN_CMD%", "message": "Coral TPU skill installed"}
69+
70+
echo %LOG_PREFIX% Done! 1>&2
71+
exit /b 0

0 commit comments

Comments
 (0)