The find_model response now returns plane_polygon_px (4 corners of a
30 cm square anchored at the work plane centroid, projected to RGB
pixels via the same K used for the SAM21 cloud). The GUI gains a
'Piano (viola)' checkbox that draws the polygon as a translucent
violet quad with an outline, helping the operator see whether the
plane sits where expected relative to the object.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a 4th checkbox 'Punti SAM21 (gialli)' that draws the full SAM21
segmentation (input to both the plane partition and Open3DModel) on
the RGB result canvas. The backend now returns sam21_points_px and
n_sam21 alongside the existing accepted/excluded splits.
Useful as a sanity check: visualise what was actually segmented vs
what the plane filter kept/rejected vs where the STL got placed.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 0.4x0.4 PlaneGeometry square was a fixed-size proxy that did not
reflect the actual ROI extent — visually misleading. Replace it with
an explicit blue point cloud of the inliers fed to fit_plane_svd, so
the user can see *exactly* which depth pixels the plane was fit on.
- Backend: fit response now returns fit_points_camera (CV frame) instead
of the (parallax-shifted) RGB pixel projection.
- Frontend: drop the purple plane mesh; new three.setFitInliers paints
the inliers in blue. The RGB overlay no longer carries blue dots.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Drop the ge=0 constraint on FitReq.offset_mm (negative values are a
documented usage: aggressive noise cull above the plane).
- HTML input min lowered to -200 to match.
- Render FastAPI 422 validation arrays as a human-readable string in the
status chip (was showing "[object Object]").
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Camera at origin (CV frame) looking at +Z with screen-up = CV −Y, so
the rendered scene matches the camera's vantage point. OrbitControls
retargets to the plane centroid on fit so rotation feels natural.
- Simplify scatter coloring to two tones: red for filter-excluded points
(signed_distance < −offset_mm/1000), cyan-white for everything kept.
Matches the backend filter contract exactly.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
User asked for "2 punti" — replace the drag-to-rectangle interaction with
two discrete clicks: first click places corner A (cross marker), second
click defines the rectangle, third click starts a new selection.
Rectangles smaller than 10×10 px are rejected. Status chip guides the
flow.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
- Rename "TrovaUtensile" tab → "Cerca modello".
- Remove the "Precisione (ultime 5 detection)" stats panel and the
"Dettagli" JSON dump from the grasp tab; keep hidden stubs so the
existing app.js continuous-loop code doesn't null-deref.
- Add work_plane_routes to api/__init__.py imports + __all__ (consistency
with the other routers).
- Trim the misleading "drag = pan · wheel = zoom · doppio click = reset"
hint from the Calibrazione Piano RGB label — pan/zoom isn't wired.
- Disable wpClearBtn initially so it doesn't flash clickable before
fetchSaved() resolves.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
New tab replaces the removed Servo Visuale. Shift+drag on the RGB image
defines a rectangle, 'Calcola piano' calls POST /api/work_plane/fit and
renders the plane + a colored scatter in 3D. Adjusting the offset slider
re-colors the scatter client-side. 'Salva piano' persists; 'Rimuovi piano
salvato' clears.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The marker-relative servo (endpoints /api/grasp/visual_servo/{plan,step,
plane/*}, helpers in grasp_routes.py, the bulk of grasp/visual_servo.py,
web/servo.js, and the Servo Visuale GUI tab) is gone. Plane fitting now
lives in /api/work_plane/* and perception/work_plane.py; Task 5 wires the
new Calibrazione Piano tab.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Elimina il flusso di acquisizione griglia automatica: tab GUI, modulo
autocal3d.js, AutoRunner/auto_job, e gli endpoint /auto/* + /auto_grid.
La calibrazione resta operabile via sample manuali + /solve.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
GUI:
- Rimossa tab "Calibrazione" (sostituita dalla calibrazione via AI con saved
task `calibrazione_dx`/`calibrazione_sx`, oppure dalla tab "Auto-
Calibrazione" per il flusso a griglia automatica). Backend
calibration_routes invariato — tool AI continuano a usarlo.
AI tools:
- Esposto `precise` su `move_wrist_absolute` e `move_wrist_relative`
(forwarded al campo omonimo del bridge robot, controlla la modalità di
controllo: false=veloce/tolleranza ampia, true=lento/posa accurata).
- Aggiunto `arms_go_neutral` come tool dedicato (POST /arms/go_neutral del
bridge): usato dall'AI per "torna a casa / posizione di riposo". Niente
side, agisce su entrambe le braccia.
- Fix `device_status`: ora wrappa la risposta con `_ok(...)` così il
dispatcher la classifica correttamente.
Prompt:
- System prompt aggiornato: l'AI ora passa SEMPRE `precise=true` di default
sui movimenti, escluso quando l'utente chiede esplicitamente velocità.
Sezione dedicata su come tornare a riposo (arms_go_neutral).
- Documentato che `measured_side_mm` (ritornato da get_marker_3d) viene
distorto dalla correzione affine sul depth — non usarlo per validare la
size_mm dichiarata.
Saved tasks:
- `calibrazione_dx` e `calibrazione_sx` ora partono e finiscono con
`arms_go_neutral`, cancellano i sample preesistenti per quel lato, e
acquisiscono ≥10 sample con `precise=true` su una griglia ±80mm + ±15° di
rotazione attorno alla posa home.
Config:
- Marker corrente: id=10, size=40mm (cambiato il tag fisico sul polso).
- Addendum prompt allentato: niente più "max 3 righe", ora chiede di
riportare il risultato di OGNI tool chiamato.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Pipeline completa per calibrazione hand-eye e grasp planning su robot
Unitree G1/H1 con camera depth Nuwa-HP60C. Esposta come FastAPI + GUI vanilla
JS, con assistente AI (OpenRouter + tool calling curato) per pilotare il
sistema in linguaggio naturale.
Architettura:
- FastAPI orchestrator (porta da .env, default 8890) che coordina 4
microservizi upstream: Nuwa-HP60C, marker-finder, YOLO, robot bridge.
- Dual-robot: services.g1 e services.h1 in config.yaml; switchabili a
runtime via PUT /api/home/robot.
- Calibrazione hand-eye eye-to-hand split per-side (right/left).
- Marker pose: marker-finder riceve gli intrinseci RGB della Nuwa al boot,
PnP server-side con quei dati. Nessun re-PnP locale richiesto.
- Depth-to-RGB: registrazione iterativa IR↔RGB per back-projection 3D
corretta (Nuwa /api/measure usa coords IR; il nostro /api/perception/
measure_rgb prende pixel RGB e ritorna 3D nel frame RGB OpenCV).
- Correzione affine sul depth bias (calibrabile via marker come
ground-truth) — riduce errore Z da ~6% a ~1.5% nei test.
- AI assistant: 16 tool curati (move_wrist_*, hand_action, get_marker[_3d],
detect_object, calibration_*, set_active_robot…), system prompt
dinamico che riflette robot attivo + marker config + addendum
customizzabile da GUI. Temperature di default 0.1 per evitare invenzioni.
GUI (7 tab):
- Home: stato comunicazione device + selettore robot attivo G1/H1
- Assistente AI: chat con OpenRouter, history persistita lato browser,
task riutilizzabili (prompt salvati), trace tool calls
- Impostazioni AI: modello da combo curata, temperature, max iterations,
prompt addendum, anteprima system prompt
- Calibrazione, Auto-Calibrazione, TrovaUtensile, Servo Visuale, Vista 3D,
Movimento EE — invariate dalle versioni precedenti
Setup:
- Variabili in presa-mano/.env (template in .env.example)
- OPENROUTER_API_KEY richiesta solo per il tab Assistente AI
- PRESA_MANO_PORT configurabile
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>