From 665d25e5747744ffc92bed477eab7cfb8a58712d Mon Sep 17 00:00:00 2001 From: Adriano Date: Mon, 14 Sep 2026 12:45:59 +0200 Subject: [PATCH] docs: la V1 e' fatta, e due cose che la specifica dava per buone non reggevano MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Il ponte e' in VisionSuite (6f5990c, issue #2 chiusa). Corretti due punti di questo documento: PyTorch in vs-dxf non c'e' piu' da L2, quindi quel lavoro non esisteva; e la posa iniziale non serve, misurato — l'ICP converge da solo fino a 45 gradi. Aggiunta la trappola dell'angolo ambiguo sui pezzi simmetrici, che e' esattamente il caso dei profilati di Trafilo, e il limite degli ingressi di scansione non collegabili. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_01JyL1sTGpFxx7Qw3xP58eoZ --- .../2026-09-14-visione-stato-e-specifica.md | 74 +++++++++++++------ 1 file changed, 53 insertions(+), 21 deletions(-) diff --git a/docs/specs/2026-09-14-visione-stato-e-specifica.md b/docs/specs/2026-09-14-visione-stato-e-specifica.md index a76417e..b61bd72 100644 --- a/docs/specs/2026-09-14-visione-stato-e-specifica.md +++ b/docs/specs/2026-09-14-visione-stato-e-specifica.md @@ -151,30 +151,54 @@ uscite** dei due motori, perché è quella forma che decide la firma degli strum dell'ambiente del worker è un numero misurato; esiste una nota di due pagine con le firme reali dei due motori. -### V1 — Il ponte: pattern matching e DXF compare diventano strumenti del grafo +### V1 — Il ponte — ✅ **fatta il 14/09/2026** (VisionSuite `6f5990c`, issue #2 chiusa) -**Si lavora in VisionSuite, non in TieMeasureFlow.** In `vs-task` nascono gli strumenti nuovi, con la -stessa forma dei dieci esistenti: +**Il lavoro è stato fatto in VisionSuite**, come questo documento prescriveva. Gli strumenti non sono +finiti in `vs-task` insieme ai dieci geometrici, ma **ciascuno nel pacchetto del proprio motore** — +`visionsuite.pm2d.task_tools` e `visionsuite.dxf.task_tools` — perché altrimenti il livello-task avrebbe +ereditato numba, opencv e fastapi da `pm2d` e scipy ed ezdxf da `dxf`, e se li sarebbe portati dietro +ogni consumatore che voleva soltanto una distanza fra due punti. Si dichiarano con l'extra `task`. -- `MatchPattern` — ingresso: immagine più modello; uscite: presenza, punteggio, posizione e rotazione - dell'istanza trovata. È anche ciò che fornisce la posa alle quote successive, invece di pretendere che - il pezzo sia appoggiato sempre uguale. -- `CompareDXF` — ingressi: immagine, disegno di riferimento, fattore di scala; uscite: scarto massimo, - scarto medio, numero di zone fuori tolleranza, e l'esito zona per zona. +- `MatchPattern` — ingressi: la scena dal contesto, il modello per chiave o per percorso, punteggio + minimo, intervallo di angolo e di scala. Uscite: `found`, `score`, `row`, `col`, `angle_deg`, `scale`, + `n_matches`. +- `CompareDXF` — ingressi: immagine, `dxf_path`, `px_per_mm` (o la calibrazione dal contesto), + `tolerance_mm`. Uscite: `max_deviation_mm`, `mean_deviation_mm`, `n_points`, `overlay`. -Due vincoli che decidono se il ponte è fatto bene: +**Il vincolo che ha retto:** gli strumenti espongono numeri, non verdetti. `CompareResult.passed` esiste +e resta fuori dalle uscite, e un test lo sorveglia. La `tolerance_mm` serve **solo a colorare l'overlay**: +è un parametro di disegno, non una soglia di accettazione. -1. **Gli strumenti espongono numeri, non verdetti.** `vs-dxf` ha di suo un `ToleranceChecker` e un - `CompareResult` con il proprio giudizio: quel giudizio va ignorato, esattamente come la decisione 7 - impone già per le quote di `vs-measure`. Due giudici sullo stesso valore è il modo più rapido per - ottenere un CSV che si contraddice. -2. **`vs-dxf` si porta dietro PyTorch (~2,5 GB) per una riga** (`config.py:53`, annotato nella scheda - VisionSuite). Prima di aggiungerlo agli extra del worker, quella riga va tolta: altrimenti il container - della visione triplica, e con lui i tempi di ogni deploy a Tràfilo. +⚠️ **Due cose che questo documento dava per buone non hanno retto alla prova, ed è il motivo per cui una +specifica si verifica invece di eseguirla.** -In TieMeasureFlow cambia **soltanto** `pyproject.toml`: `vs-dxf` entra negli extra `vision` e -`vision-worker`, il pin del sottomodulo avanza al commit che contiene i due strumenti nuovi. Nessuna riga -di algoritmo entra in questo repository. +1. **«`vs-dxf` si porta dietro PyTorch per una riga» era falso.** Torch è stato tolto in L2 insieme al + rilevatore DexiNed che non aveva mai girato, e il `pyproject.toml` di `vs-dxf` lo dice per esteso. La + nota veniva dalla scheda VisionSuite in AI-OS, che su quel punto era invecchiata. Il lavoro non + esisteva: il container della visione non triplica. +2. **La posa iniziale non serve, ed è misurato.** Questo documento dava per scontato che `CompareDXF` + dovesse partire allineato dalla posa di `MatchPattern`. Ruotando la scena e lasciando l'ICP senza + aiuto, sul rettangolo forato a 4 px/mm: **0°** → 0,285 mm, **5°** → 0,346, **20°** → 0,288, **45°** → + 0,243. Converge da solo, e a 45° meglio che a zero. In più `DXFCompare._pose_to_transform` non ha + chiamanti né test e trasla le **righe** dove il nome dice colonne: l'ingresso non è stato esposto, + perché chi lo avesse collegato al match avrebbe ottenuto una traslazione di centinaia di pixel + credendo di aver fatto la cosa giusta. Un test parametrico su 0°, 20° e 45° tiene ferma la scelta. + +⚠️⚠️ **E una trappola nuova, da sapere prima di comporre ricette: su un pezzo simmetrico l'angolo del +match è ambiguo.** Sulla scena non ruotata il rettangolo torna `angle_deg = -180` con punteggio 0,924, +perché a 180° è identico a sé stesso. `row` e `col` restano affidabili; l'angolo, su un pezzo senza un +riferimento che rompa la simmetria, non è una risposta. I profilati di Tràfilo sono esattamente il genere +di pezzo in cui questo si presenta. + +*Verificato:* `tests/test_visione_nel_grafo.py` carica una ricetta JSON che contiene **entrambi** gli +strumenti con `Task.from_dict`, la esegue e ottiene le uscite attese. 21 test nuovi; **1242 verdi** su +tutto il monorepo. + +**Quello che resta da fare qui, in TieMeasureFlow** (è ciò che la issue #8 della lista lavori chiedeva, e +non è cambiato): `vs-dxf` entra negli extra `vision` e `vision-worker` di `pyproject.toml`, il pin del +sottomodulo avanza a `6f5990c`, e il runner **importa i due moduli** `visionsuite.pm2d.task_tools` e +`visionsuite.dxf.task_tools` — senza quell'import il registro non li conosce e una ricetta che li nomina +non si carica. Nessuna riga di algoritmo entra in questo repository. *Fatto quando:* un grafo JSON che contiene `MatchPattern` e `CompareDXF` viene eseguito da `POST /api/vision/preview` su un'immagine caricata, e restituisce le uscite attese. Senza camera, senza @@ -186,8 +210,8 @@ La schermata che oggi non esiste. Si compone con un **editor visuale a nodi** (d 14/09). Il Maker, alla scrivania: - carica o sceglie un'**immagine di riferimento** per il task (l'API esiste già); -- compone il grafo collegando gli strumenti — l'immagine entra, `MatchPattern` dà la posa, da lì scendono - le quote e il `CompareDXF`; +- compone il grafo collegando gli strumenti — l'immagine entra, e da lì scendono il riconoscimento, le + quote e il confronto col disegno; - preme **prova** e vede le uscite (`/preview` esiste già); - **aggancia** ciascuna uscita a una quota della ricetta, scrivendo `vision_output` sulla subtask (il campo esiste già), e su quella quota mette nominale e tolleranze come su qualunque altra; @@ -200,6 +224,14 @@ applicate. È la storia che vende: il confronto DXF **dentro il flusso di produz Restano fuori dalla fiera, e si fanno dopo, la promozione a `expected_json` e la prova di non regressione: valgono per la robustezza, ma allo stand non si mostrano. +⚠️ **Un limite dell'editor, emerso il 14/09 costruendo gli strumenti.** Negli strumenti geometrici di +`vs-task` gli ingressi di scansione — `start_row`, `start_col`, `end_row`, `end_col` di `DetectLine` e +compagnia — **non sono collegabili**: si impostano a mano. Finché restano così, la posa che +`MatchPattern` trova non può spostare le scansioni delle quote, e il pezzo va appoggiato dove la ricetta +si aspetta. Renderli collegabili è un lavoro in VisionSuite, piccolo ma non nullo, ed è **il passo che +rende utile il riconoscimento dentro una ricetta di misura**: senza, `MatchPattern` serve a dire se il +pezzo c'è ed è quello giusto, non a inseguirlo. + *Fatto quando:* una ricetta con un task di visione si compone interamente dall'interfaccia, senza scrivere JSON a mano, e un operatore la esegue ottenendo un esito vero. La prova di non regressione — rieseguire l'intero parco ricette su immagini di riferimento e vedere quali quote si sono mosse — è il criterio della