Commit Graph
39 Commits
Author SHA1 Message Date
AdrianoandClaude Sonnet 4.6 79f587567e feat(pose_3d): /state espone blocco cross_camera
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 12:28:52 +02:00
AdrianoandClaude Sonnet 4.6 5ab808accd feat(pose_3d): POST /align fit Umeyama cross-camera + persistenza
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 12:28:05 +02:00
AdrianoandClaude Sonnet 4.6 8b01ae123f feat(pose_3d): GET /tags multi-camera, rimuovi /front_tags
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 12:20:04 +02:00
AdrianoandClaude Sonnet 4.6 77fb0f8fc0 feat(geometry): umeyama_similarity (rot+trasl+scala uniforme)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-03 12:13:25 +02:00
Adriano Dal PastroandClaude Opus 4.7 6c2452fe20 refactor(pose_3d): rimuovi agent/chat, aggiungi cloud+diagnostics+camera polso
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>
2026-05-27 17:34:42 +02:00
Adriano Dal Pastro 0ab0e5691c feat(pose_3d): POST /unlock proxy + non-regression check 2026-05-21 15:46:24 +02:00
Adriano Dal PastroandClaude Opus 4.7 57954b5c8d feat(right_arm): perm assi cam->polso, precise=true default, verify_tag UI
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>
2026-05-21 15:44:48 +02:00
Adriano Dal PastroandClaude Opus 4.7 8d40ebaf89 feat(pose_3d): POST /poses/{name}/go
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-21 15:43:50 +02:00
Adriano Dal Pastro d124a7c896 refactor(config): add set_config_value for non-merge replacement 2026-05-21 15:42:14 +02:00
Adriano Dal PastroandClaude Opus 4.7 fb05409403 feat(pose_3d): named poses GET/PUT/DELETE
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>
2026-05-21 15:39:37 +02:00
Adriano Dal Pastro df949c6989 refactor(pose_3d): move normalize_quaternion to geometry module 2026-05-21 15:37:14 +02:00
Adriano Dal Pastro 40c3fff755 feat(pose_3d): POST /apply + quaternion normalization 2026-05-21 15:33:47 +02:00
Adriano Dal Pastro 71f2ef596e feat(pose_3d): router skeleton + GET /state 2026-05-21 15:27:43 +02:00
Adriano Dal PastroandClaude Opus 4.7 1fa7d12ad7 feat(right_arm): force, camera↔polso offset, cluster filter sul centroide
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>
2026-05-21 12:18:24 +02:00
Adriano Dal PastroandClaude Opus 4.7 2f6444c0a5 fix(right_arm): bbox dict, image_size da /api/status, tab non seleziona robot
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>
2026-05-21 11:43:05 +02:00
Adriano Dal Pastro 59f7f66d77 feat(right_arm): /home, /custom_pose, PUT /custom_pose, PUT /offset + fixture conftest 2026-05-20 12:33:03 +02:00
Adriano Dal Pastro afbfd55bca feat(right_arm): /move/toward con sign flips, max-step e z-floor 2026-05-20 12:27:38 +02:00
Adriano Dal Pastro bd4eb8b929 feat(right_arm): /detect/wrist con YOLO + SAM21 + centroide camera 2026-05-20 12:23:10 +02:00
Adriano Dal Pastro 3e4e8055db feat(right_arm): /detect/front con proxy fallback per YOLO 2026-05-20 12:20:02 +02:00
Adriano Dal Pastro 22e13435b1 feat(right_arm): endpoint /snapshot/{front,wrist} 2026-05-20 12:16:33 +02:00
Adriano Dal PastroandClaude Opus 4.7 dd2053cc47 feat(right_arm): router skeleton con /state e /activate
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 12:13:33 +02:00
Adriano Dal Pastro 55e84778d8 feat(right_arm): math puro per delta-toward (sign flips + z-floor) 2026-05-20 12:09:35 +02:00
Adriano Dal Pastro 757eb01200 feat(deps): aggiungi front_camera() e tab_right_arm_cfg() 2026-05-20 12:07:11 +02:00
Adriano Dal Pastro 04cc5fc345 feat(geometry): aggiungi conversioni RPY (deg) ↔ quaternion xyzw 2026-05-20 12:04:39 +02:00
Adriano Dal Pastro 64742479b1 feat(config): aggiungi services.front_camera e blocco tab_right_arm 2026-05-20 12:01:14 +02:00
Adriano Dal PastroandClaude Opus 4.7 cb940dc1cd fix(open3dmodel): unwrap {success,data,error} envelope from /api/recipes
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>
2026-05-13 10:17:48 +02:00
Adriano Dal PastroandClaude Opus 4.7 87abe26476 refactor(sam21_bridge): extract segment_with_sam21 (no plane filter)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 10:06:41 +02:00
Adriano Dal PastroandClaude Opus 4.7 684bd2de5e feat(clients): LRU mesh cache for Open3DModel recipes (etag-validated)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 10:05:05 +02:00
Adriano Dal PastroandClaude Opus 4.7 16ffe6ac20 feat(clients): Open3DModel client (list_recipes, estimate_pose, get_stl_bytes)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 10:03:41 +02:00
Adriano Dal PastroandClaude Opus 4.7 b85f4b9a48 feat(perception): project camera-frame 3D points to image pixels
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 10:02:20 +02:00
Adriano Dal PastroandClaude Opus 4.7 d1b27433d5 feat(perception): parse STL + uniform surface sampling
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 10:01:25 +02:00
Adriano Dal PastroandClaude Opus 4.7 876224a71d feat(perception): partition_by_plane returns accepted + excluded sets
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-13 10:00:09 +02:00
Adriano Dal PastroandClaude Opus 4.7 28ba0dd9f2 test(work_plane): drop unused imports
tempfile, Path, and unittest.mock.patch were imported but unused.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 16:50:05 +02:00
Adriano Dal PastroandClaude Opus 4.7 16e32bf1c1 feat(perception): work_plane module with below-plane filter
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>
2026-05-11 16:41:35 +02:00
Adriano Dal PastroandClaude Opus 4.7 0bc1e02f11 fix(sam21): broader httpx catch + tighter test assertions
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>
2026-05-11 14:42:18 +02:00
Adriano Dal PastroandClaude Opus 4.7 75da9add84 feat(clients): Sam21Client wrapper for /api/segment_pointcloud
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>
2026-05-11 14:30:16 +02:00
Adriano Dal PastroandClaude Opus 4.7 810a6102fb test(depth_align): real z-buffer collision + drop dead var
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>
2026-05-11 14:28:15 +02:00
Adriano Dal PastroandClaude Opus 4.7 5354c51d60 feat(perception): vectorised IR→RGB depth alignment
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>
2026-05-11 14:23:11 +02:00
Adriano Dal PastroandClaude Opus 4.7 f898d9b0da test: add pytest dev dep + tests scaffold
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-11 14:19:12 +02:00