Files
syncro_multi_agente/BRIDGE_NOTES.md

4.8 KiB
Raw Blame History

Note operative — produttore GLB (Fusion → Blender)

Questo file è la sponda produttore del FUSION_GLB_CONTRACT.md. Tutte le risposte ai problemi [OPEN] del contratto vivono qui finché non vengono spostate nello stato [RESOLVED] del contratto stesso.


Risposte ai problemi aperti del contratto §8

Stato: è un limite dell'API Fusion. Quando l'utente crea il motion link tramite la finestra "Collegamento movimento", Fusion lo memorizza con un riferimento interno (entity-token) ma il proxy motionLink.entityOne può ritornare None se il joint è stato creato/rinominato dopo il link. L'add-in non può inventarsi il nome.

Workaround consigliato a chi consuma:

  • I 5 driver (A, X, Y, PEN, Z) NON sono mai null su joint2: i link con joint2 == driver sono usabili anche senza joint1 (basta non propagare nulla).
  • Per i link con joint2: null AND joint1: null (es. "Collegamento movimento 32", "Collegamento movimento 4"): sono rumore, ignorabili.
  • Per i link con joint1: null ma joint2 valorizzato (es. "Collegamento movimento 14"Motore asse X, "Collegamento movimento 28"Rivoluzione 26, "Collegamento movimento 38"Asse Penna ):
    • Motore asse X è il driver, non ha bisogno di slave esterni — la traslazione del carrello X è già descritta dal rigid group Gruppo rigido 6 (end stop X PIastrina:1 | binario SX:1 | Cinghia T5:1).
    • Asse Penna idem: lo slider muove direttamente guida lineare:1, gli altri pezzi seguono via rigid groups.

TL;DR per il viewer: ignora tranquillamente i link con joint1: null. Tutta la propagazione necessaria passa dai rigid groups + i 5 driver diretti.

2) Motore A esiste in asBuiltJoints?

Confermato. Verificato sul file corrente: presente con nome esatto "Motore A", tipo revolute, child = "6627T331_Stepper Motor (1) (1):1", axis ≈ [0, 0, 1].

L'eventuale mismatch lato viewer dipende dal child name: nel JSON è esattamente "6627T331_Stepper Motor (1) (1):1" (due " (1)" di seguito), che nasce dal fatto che in Fusion il componente è stato copiato/incollato due volte. Se il viewer non lo trova, il bug è nel matching, non nell'export.

3) Convenzione multi-macchina

Da concordare quando servirà. Proposta minimale:

exports/
  plotter/
    plotter.glb
    plotter.joints.json
  <altra_macchina>/
    <altra_macchina>.glb
    <altra_macchina>.joints.json

Lato viewer un file machines.json indicizza nome → coppia (glb, json, DRIVERS map).


Stato attuale dell'export (rispetto alla checklist §6 del contratto)

Voce checklist Stato Note
GLB in metri build_glb_from_fusion_export.py applica scaleFactor=0.01 al root, mesh OBJ importate in cm sono rimpicciolite di 100× → metri
Gerarchia Empty 1:1 Pass 1 crea un Empty per ogni node del hierarchy.json
fusion_name e fusion_path per ogni Empty (dal 2026-06-09) Aggiunti come custom properties; coincidono byte-per-byte con Joint.child / Joint.childFullPath
Mesh figlie degli Empty, non joinate OBJ importati e re-parentati all'Empty corrispondente
Stato salvato = posa "tutti i driver a 0" ⚠️ Posa "as built" di Fusion al momento dell'export. Se l'utente esporta con slideValue ≠ 0 o rotationValue ≠ 0 la posa neutra slitta. Convenzione: in Fusion riportare i 5 driver a zero prima di lanciare lo script.
Manifest embedded scene["fusion"] Il GLB contiene già il JSON completo in scene.extras.fusion

Comandi operativi

Rigenera GLB dopo modifica codice:

.\build_glb.bat "C:\Users\croce\OneDrive\Desktop\export"

Riallinea script Fusion (da fare dopo ogni edit di ExportKinematicGraph.py):

python -c "import py_compile; py_compile.compile(r'C:\Users\croce\OneDrive\Desktop\export grafo fusion\ExportKinematicGraph.py', doraise=True); print('OK')"; if($LASTEXITCODE -eq 0){ Copy-Item -Force 'C:\Users\croce\OneDrive\Desktop\export grafo fusion\ExportKinematicGraph.py' (Join-Path $env:APPDATA 'Autodesk\Autodesk Fusion 360\API\Scripts\ExportKinematicGraph'); Write-Host "Sync OK" }

Sanity-check sui driver nel JSON:

$j = Get-Content 'C:\Users\croce\OneDrive\Desktop\export\joints.json' -Raw | ConvertFrom-Json
$names = @('Motore asse X','Motore asse Y','Asse Penna ','asse Z pneumatico M5?')
foreach($n in $names){ $j.joints | Where-Object name -eq $n | Select-Object name,type,child,axis,@{n='limits';e={ if($_.slideLimits){'slide '+$_.slideLimits.minimumValue+'..'+$_.slideLimits.maximumValue}elseif($_.rotationLimits){'rot '+$_.rotationLimits.minimumValue+'..'+$_.rotationLimits.maximumValue} }} | Format-List }
$j.asBuiltJoints | Where-Object name -eq 'Motore A' | Select-Object name,type,child,axis | Format-List