- VERSION (1.0.0) + build.sh: bump patch/minor/major e deploy via docker compose
- Dockerfile: ARG/ENV APP_VERSION + BUILD_TIME (iniettati come build-arg)
- version.build_info(): env in Docker, fallback file VERSION + '(local)' in dev
- GET /api/version; badge #appVersionPill nell'header (tooltip = build time)
- test_version.py: env vs fallback
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rimosso il modulo agent (LLM chat) e la relativa config OpenRouter.
La tab Pose 3D ora: espone i giunti reali via G1 /diagnostics per
specchiare l'URDF senza IK; acquisisce point cloud Nuwa+D435i
(/api/pose_3d/clouds); mostra il modello 3D della camera sul polso;
degrada gracefully a 200 (wrist=null) quando il robot è offline.
Il vecchio renderer canvas-2D (app.js view3d + diagnostic3d.js) è
stato consolidato nel viewport Three.js di pose_3d.js.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lavoro accumulato nella sessione 2026-05-21 prima del brainstorming
della tab Pose 3D:
- compute_delta_wrist generalizzato con cam_to_wrist_perm: la mappa
cam->polso non e' solo sign-flip ma una permutazione (default
identita' per backward compat). DeltaOversize ora espone X/Y/Z
nella stringa d'errore. Test aggiornati.
- G1Client.wrist_absolute / wrist_relative: precise=True di default
(era False). Stessa cosa per wrist_routes.AbsoluteReq Pydantic
e per agent.tools move_wrist_*. Movimenti reali ora chiedono
controllo accurato salvo override esplicito.
- Tab Braccio DX:
- /verify_tag endpoint: snapshot wrist FK + tag id=1 dalla front
camera. Per verifica relativa moveto vs marker (no calibrazione).
- GUI: pannello "Verifica tag id=1" + campi camera_offset_wrist_mm.
- markUserTouchedOnInput esteso a raOff/raSgn/raCamOff.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds CRUD for named wrist poses persisted in config.yaml under
pose_3d.named_poses. PUT validates the name against ^[A-Za-z0-9_-]{1,40}$
and normalizes the quaternion. DELETE returns 404 if the pose is missing.
Bypasses update_config's deep-merge for wholesale named_poses replacement
(deep-merge cannot remove nested keys) via a small helper that mutates
the in-memory singleton then persists with an empty patch.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tre miglioramenti al move-toward dopo il primo uso live:
1. checkbox "force" accanto a "Muovi": bypassa max_step_m quando
l'utente sa che il delta richiesto e' grande ma corretto (es. primo
avvicinamento all'oggetto).
2. camera_offset_wrist_mm: il modello assumeva camera e TCP coincidenti
(sole sign flips). La camera Nuwa e' invece montata con traslazione
costante rispetto al polso. La formula diventa:
delta_wrist = sign * (centroid_cam - offset_cam) + t_wrist_cam
Esposto in config (default 0,0,0), GUI (3 input "Camera rispetto a
polso (mm)") e in /state. Il termine compensa il fatto che muovere
il polso porta la camera, non il TCP, sul punto di presa.
3. filter_nearest_cluster: il centroide era media di tutti i punti
SAM21 della mask. In presenza di sfondo lontano visibile attraverso
buchi della depth del primo piano la media veniva trascinata a
metri di distanza. Ora si tiene il cluster piu' vicino:
z_near = p5(Z)
keep = punti con Z <= z_near + cluster_depth_window_m
Default window 0.20 m, configurabile. La risposta di /detect/wrist
espone n_sam21_points, n_centroid_points e z_near/z_cutoff per
diagnosi.
Aggiornata anche la persistenza: /offset accetta camera_offset_wrist_mm.
GUI: i campi Offset/Sign/CamOff rispettano "user touched" (refresh non
li cancella mentre l'utente digita).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Tre problemi della tab Braccio DX dopo il primo rodaggio:
1. /detect/front e /detect/wrist ritornavano bbox raw dal YOLO server,
che lo manda come lista [x1,y1,x2,y2]; la GUI legge bbox.x1 e mostra
NaN. Ora il router normalizza il payload via perception/detector
._normalize, allineandosi al resto del codice. Aggiunta regressione
con payload reale del server.
2. La tab gateava su robot.active==g1 && wrist_side==right con banner
"Attiva G1 right" e POST /activate. Confonde: la selezione del
robot e' globale e non si flippa per-feature. Rimossi banner,
bottone, endpoint /activate e _guard_g1_right(); gli endpoint
operano sul polso destro del robot attivo qualunque esso sia.
3. image_size: [0,0] perche' Nuwa /api/intrinsics non include
width/height; vivono in /api/status > data.resolution. Aggiunto
NuwaClient.image_size() e usato in detect_front. Aggiornato
docstring di intrinsics() per coerenza con il payload reale.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Open3DModel returns the same envelope for /api/recipes as for /api/pose;
the bare-list code path stays as a fallback for older mocks.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Owns WorkPlane (with new offset_mm field), fit_plane_svd, disk-backed
get/set, and the apply_below_plane_filter helper. WorkPlane.normal lives
in OpenCV RGB-camera frame and is oriented toward the camera. The filter
keeps points where signed_distance >= -offset_mm/1000.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Catch httpx.RequestError so DecodingError etc. trigger the bbox fallback
instead of propagating raw. Lock the intrinsics dict shape in the
happy-path test, drop unused imports.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Posts (rgb_png, depth_png, intrinsics, bbox) and returns (N,3) points in
meters in OpenCV RGB-camera frame. Normalises transport vs semantic errors
into Sam21Unavailable / Sam21Error.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 2× focal-length collision test wasn't actually colliding (adjacent IR
pixels rounded to different RGB columns). 4× makes them collapse, so the
np.minimum.at reduce is now exercised. Also drop unused H_ir, W_ir.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Forward-project IR depth pixels into the RGB pixel grid with a z-buffer.
Output uint16 mm at RGB resolution, ready to feed SAM21.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>