1537a9e38952a0198c34439874d01623f857ae65
When grasp.use_sam21=true (default), _object_points_in_base feeds the YOLO
bbox to SAM21 and uses the segmented cloud directly. Any failure
(transport, segmentation empty, no valid depth, payload bug) logs and falls
back to the legacy bbox path. Response meta includes source ∈ {sam21,
bbox_roi} and sam21_fallback_reason when applicable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
presa-mano
Microservizio Python (FastAPI) che orchestra:
- Calibrazione hand-eye (eye-to-hand) tra la Nuwa depth camera (fissa) e la base del robot, usando un ArUco sul polso. Supporta G1 e H1.
- Riconoscimento oggetto via YOLO server + point cloud Nuwa.
- Pianificazione presa: asse dell'oggetto (PCA) + posa polso per il robot attivo.
Microservizi usati
| Servizio | URL (default) | Scopo |
|---|---|---|
| Nuwa-HP60C | http://localhost:8877 | RGB, depth, point cloud, intrinsics |
| Marker-finder | http://localhost:8082 | Detection 2D ArUco (corners + pose) |
| YOLO Server | http://localhost:8879 | Bbox oggetto da prendere |
| G1 API Server | http://localhost:8765 | Controllo polso/mano G1 (dry-run se down) |
| H1 API Server | http://localhost:8767 | Controllo polso/mano H1 (network host, 4 DoF) |
Il servizio presa-mano espone GUI + API su http://localhost:8890. Il robot attivo
è scelto da config.yaml > robot.active (g1 | h1); l'orchestrator fa routing
automatico verso il bridge corrispondente.
Quick start
docker compose up -d presa-mano
# Apri http://localhost:8890
GUI
Tre tab:
- Calibrazione: muovi il polso in varie pose, Acquisisci sample, poi Risolvi.
Salva
data/calibration_<side>.yaml. - Grasp: rileva oggetto, visualizza bbox + asse, esegui (toggle dry-run).
- Movimento EE: lettura pose correnti, invio pose assolute/relative, apri/chiudi mano, emergency stop.
Calibrazione automatica via script
In scripts/:
| Script | Cosa fa |
|---|---|
explore_and_calibrate.py |
Probe assiale dell'envelope di visibilità tag → workspace JSON + PNG → N sample random nel workspace → solve. |
extend_calibration.py |
Estende la calibrazione esistente fino a n_used >= TARGET_GOOD (default 30). Riusa il workspace, NON cancella i sample. |
repeatability.py |
N detection consecutive a polso fermo per misurare σ del marker-finder (diagnostica bias vs noise). |
Tutti producono file in data/: workspace_<side>.json, workspace_<side>.png,
samples_<side>.json, calibration_<side>.yaml.
Configurazione
config.yaml contiene i default; l'API espone GET/PUT /api/config per override
runtime (es. cambiare ID/size ArUco, robot attivo, side di default).
Default rilevanti:
calibration.method: DANIILIDIS— sui dati H1+Nuwa con bias intrinsics di marker-finder, DANIILIDIS dà ~4× meno residuo di TSAI (default OpenCV).robot.active: h1/robot.wrist_side: right.
Caveat noti
- Wrist passthrough: i campi
speed_mm_setraj_step_mmnon sono nello schema di/api/wrist/{absolute,relative}. Per move "precisi" (closed-loop, slow, waypoint fitti) bisogna chiamare direttamente il bridge robot, es.POST http://localhost:8767/wrist/absolutesu H1. - Marker-finder intrinsics: il sibling service usa intrinsics D435i bakeate che
non corrispondono alla Nuwa → bias sistematico in
T_cam_marker. È il floor del residuo hand-eye (~14 mm su H1+Nuwa). Per scendere serve ricalibrare quel servizio. - H1 4 DoF: nessun polso articolato. Si comanda solo posizione; l'orientamento del polso è output dell'IK e drifta con la posa (fino a ~30° su Y ai bordi dell'envelope). I solver hand-eye risentono della scarsa diversità rotazionale.
/api/arms/go_neutral: il proxy nell'orchestrator non è montato (404). Per riportare le braccia H1 a home:POST http://localhost:8767/arms/go_neutraldiretto.
Vedi CLAUDE.md per i dettagli di architettura e per le frame conventions
(Nuwa native vs OpenCV vs Nuwa ROI).
Languages
Python
62.6%
JavaScript
27%
HTML
5.1%
CSS
4.8%
Shell
0.3%
Other
0.2%