bridge: findings export ATL + richiesta secondo script (ExportKinematicGraph_ATL)

This commit is contained in:
Marco
2026-06-18 18:50:22 +00:00
parent c3e506c22d
commit 3725b486a4

View File

@@ -436,3 +436,137 @@ Effetto collaterale **voluto**: i Component "container" (zero body propri, solo
4. Mentre ci sei: ricontrolla la tabella `swapPC` (X/Y/A/PEN/Z) che era ancora `(da verificare)` - una volta caricata la mesh pulita ha senso chiudere anche quel loop e marcare gli esiti. 4. Mentre ci sei: ricontrolla la tabella `swapPC` (X/Y/A/PEN/Z) che era ancora `(da verificare)` - una volta caricata la mesh pulita ha senso chiudere anche quel loop e marcare gli esiti.
Se ne emergono altre di geometrie fantasma su altri nodi, postale qui con il `fullPathName` del padre: il pattern e' lo stesso e dovrebbe essere coperto dal fix. Se ne emergono altre di geometrie fantasma su altri nodi, postale qui con il `fullPathName` del padre: il pattern e' lo stesso e dovrebbe essere coperto dal fix.
---
## Findings dal viewer ATL (2026-06-18) — richiesta secondo script export per ATL
Croce ha consegnato il primo export della **macchina ATL** (cartella `ATL/` sul mio server: `ATL.glb`, `hierarchy.json`, `joints.json`). Ho preparato la pagina consumer dedicata (`/atl`, login-protected) con drop GLB, tree gerarchia + hide/isolate per nodo, view presets top/front/side/iso, slider per i giunti animabili, diagnosi motion link.
**Premessa importante:** l'export del plotter (`ExportKinematicGraph.py` attuale) funziona bene, NON va toccato. La richiesta è quindi **affiancare un secondo script di export dedicato all'ATL** (es. `ExportKinematicGraph_ATL.py` o un parametro `--profile=atl`), così le specificità del nuovo modello non rischiano di rompere la pipeline plotter che ormai è stabile.
Sotto la lista dei problemi che ho trovato nel JSON ATL e che il nuovo script (o il profilo ATL) dovrebbe risolvere, in ordine di priorità.
### 🔴 Bloccanti
#### 1) `joints` array completamente vuoto
Conteggi ATL: `joints: 0`, `asBuiltJoints: 18`, `motionLinks: 3`, `rigidGroups: 6`. Per il plotter avevamo `329 joints + 28 asBuilt`. Qui invece **tutto finisce in `asBuiltJoints`**. È intenzionale? Domanda da girare a Croce: nel modello ATL ha creato solo "As-built Joint" e nessun "Joint" canonico? Se sì, il viewer si adatta. In ogni caso lo script per ATL dovrebbe **loggare a console quanti joint trova in ciascuna sezione** per accorgersi di un export incompleto.
#### 2) Nomi joint NON univoci → impossibile fare matching
Nel `joints.json` di ATL c'è il nome `"Rivoluzione 5"` ripetuto **3 volte** con parent/child diversi:
```
Rivoluzione 5 (revolute) | tubo silicone:1 -> cuscinetto:1
Rivoluzione 5 (revolute) | Componente45:1 -> cinesada:1
Rivoluzione 5 (revolute) | (terza occorrenza)
```
I motion link puntano ai joint per nome (`joint1`/`joint2: "<jointName>"`). Con duplicati il viewer non sa quale matchare e ne sceglie uno a caso.
**Fix richiesto:** disambigua automaticamente i duplicati nell'export, es. `Rivoluzione 5`, `Rivoluzione 5#2`, `Rivoluzione 5#3`. Oppure usa il `entityToken` del Joint come tie-breaker e aggiungilo come campo `_token` accanto al `name`.
#### 3) `origin` sempre `null` su tutti i revolute
Per i revolute serve l'**origine del giunto** (il punto attorno a cui ruotare). Senza, il viewer ruota il pezzo attorno alla sua origine locale → schizza via dal perno del cuscinetto. Sugli slider non serve.
Da estrarre per ogni `AsBuiltJoint` revolute:
- `joint.geometry.origin` se disponibile;
- altrimenti ricostruisci dalla `joint.entityOne` / `entityTwo` (centro del cilindro/cerchio) come fai già per i `Joint` canonici nello script plotter;
- converti in cm world consistenti con il resto (`internalUnit: cm`, `scaleFactor: 0.01`).
#### 4) Joint orfano con `parent: null` e `child: null`
```
portellina cinesada (revolute) | parent: null | child: null | parentFullPath: null
```
Riferisce entità non più presenti nel modello. Gestione richiesta: o **scarta** loggando un warning, oppure emetti con un flag esplicito `"_orphan": true` così il consumer lo ignora senza ambiguità.
### 🟡 Migliorabili
#### 5) `axis` con rumore numerico ~1e-16
```
Scorrimento 8 axis: [-1.388e-16, -5.169e-32, -1.0]
```
Snap a zero per componenti `|x| < 1e-9`. Altrimenti il viewer interpola jitter visibile sui movimenti lunghi.
#### 6) `rotationLimits`/`slideLimits` ambigui
Molti revolute (`Rivoluzione 5`, `feed`, ...) hanno `isMinimumValueEnabled=False`, `isMaximumValueEnabled=False` ma `minimumValue=0, maximumValue=0`. Significa "limiti disattivati" → il joint è libero, ma il consumer ingenuo legge `0..0` e lo crede bloccato.
**Fix:** quando entrambi i flag `isMinimum/MaximumValueEnabled` sono false, emetti `rotationLimits: null` (o `{free: true, restValue: ...}`) invece di un range `0..0`. Il viewer attualmente filtra fuori i joint con `max - min < 1e-6`, quindi questi joint scompaiono dalla lista degli animabili pur essendo concettualmente liberi.
#### 7) `motionLinks` tutti con `joint1: null` AND `joint2: null`
Per il plotter almeno `joint2` (il driver) era valorizzato. Per ATL **tutti e 3** i motion link hanno entrambi i campi null → record completamente inutilizzabili:
```
Collegamento movimento 6 | joint1: null | joint2: null | reversed: true
Collegamento movimento 14 | joint1: null | joint2: null
Collegamento movimento 15 | joint1: null | joint2: null
```
Conferma con Croce: nel modello ATL i motion link sono stati creati e poi le entità rinominate? Se sì, niente è recuperabile da Python (limite API noto). Suggerimento minimo per lo script ATL: emetti almeno `entityOneToken` ed `entityTwoToken` come stringhe hex grezze, così l'utente che conosce il modello può fare matching manuale invece di vedere tre record vuoti.
#### 8) Materiali: la fibra di carbonio nel GLB non rende bene
Nel GLB i material complessi di Fusion arrivano appiattiti a baseColor + metallic/roughness di default. Per la fibra di carbonio servirebbe almeno:
- una **normal map** del weave (procedurale o tile texture)
- estensione `KHR_materials_anisotropy`
- baseColor `#1c1c1f`, metallic ~0.0, roughness ~0.4
Capisco che mappare 1:1 i material Fusion al PBR GLB è grosso. Workaround minimale richiesto: **emetti il nome del material Fusion originale** nel `hierarchy.json`, campo `materialName`, accanto al `color` che già c'è. Così il viewer fa il mapping nominale (`materialName == "Carbon Fiber" → PBR custom`) come faccio già per l'alluminio brushed. Senza il nome originale non posso distinguere "alluminio anonimo" da "fibra di carbonio anonima".
#### 9) Body-per-body: conferma stato
Il fix di body-per-body (sezione del 2026-06-10 in questo file) è attivo anche per questo export ATL? Sull'ATL non vedo geometrie fantasma evidenti, ma meglio sapere se la pipeline è quella aggiornata o no. Una linea di log in cima all'export del tipo `[export] body-per-body mode: ON` aiuta.
#### 10) Nomi nodi GLB ↔ occurrence JSON: garanzia di match esatto
Il viewer cerca l'`Object3D` nella scena per `name === occurrenceName` (es. `"Linear Guide Block LML9B(Specchio)(Specchio)(Specchio):1"`). Se Blender sanitizza i nomi (parentesi → underscore, spazi rimossi, ecc.) il match fallisce silenziosamente e lo slider non muove nulla.
**Richiesta:** documenta esplicitamente che convenzione applica il pipeline ATL ai nomi nel GLB (sanitizzazione o byte-per-byte identici). Se ci sono trasformazioni, **emetti nel `hierarchy.json` un campo `glbNodeName`** con il nome effettivo del nodo nel GLB, così posso usarlo per fare lookup invece di indovinare.
### ✅ OK così
- Schema generale `hierarchy.json` (53 nodi, `parentFullPathName` coerenti) ✓
- `transform` per ogni nodo presente ✓
- `rigidGroups[].occurrenceNames` valorizzato (6 gruppi, 57 occorrenze ciascuno) ✓
- Tipi joint: 8 rigid + 6 slider + 4 revolute → modello esportato
### Priorità suggerita
1. **#2 (nomi unici)** — impedisce qualunque motion link, anche manuale
2. **#3 (origin sui revolute)** — senza non si animano correttamente
3. **#1 + #7** — chiarisci con Croce perché ATL ha `joints=[]` e tutti i motion link vuoti (modello incompleto vs limite API)
4. **#5, #6** — quality-of-life dell'export
5. **#10** — chiarimento sulla sanitizzazione nomi GLB
6. **#8** — render fibra di carbonio (non urgente)
### Forma proposta per il secondo script
- Nome: `ExportKinematicGraph_ATL.py` (oppure aggiungi a `ExportKinematicGraph.py` un parametro `--profile=atl` se preferisci tenere un unico file).
- Output dell'utente: cartella `C:\Users\croce\OneDrive\Desktop\export_ATL\` (per non sovrascrivere quella del plotter).
- Consegna sul mio server: cartella `/home/marco/automation_kriz/ATL/` (stessa dove sono ora i file attuali). GLB → vado avanti a tenere il symlink `frontend/public/atl.glb -> ATL/ATL.glb` che ho già preparato.
- Le path lato Django sono già pronte: `/api/atl/hierarchy/`, `/api/atl/joints/`, `/atl.glb`.
### Cosa NON serve fare
- ❌ Toccare `ExportKinematicGraph.py` (versione plotter) — funziona bene così, niente regressioni richieste.
- ❌ Modifiche al GLB del plotter o ai suoi JSON.
- ❌ Modifiche al contratto `FUSION_GLB_CONTRACT.md`: le voci ATL stanno nello stesso schema, solo l'estrazione cambia.
### TODO #3 — Aggiorna note dopo il fix
Quando hai applicato i fix nel nuovo script ATL, aggiungi qui sotto una sezione "Verifica export ATL del 2026-06-XX" con:
- quali punti hai chiuso
- eventuali nuovi limiti API trovati
- conferma del re-export consegnato in `ATL/`
Io rifaccio il giro su `/atl` e marco gli esiti.
Grazie 🙏