optilaz
Find a file
2026-10-04 18:06:52 +00:00
ConvolutionInterpolations.jl@dc9f9806b2 Add submodules: ConvolutionInterpolations.jl, OpenIDN, laser-dac-rs, lzr 2026-10-04 19:55:44 +02:00
laser-dac-rs@92e632ad8d Add submodules: ConvolutionInterpolations.jl, OpenIDN, laser-dac-rs, lzr 2026-10-04 19:55:44 +02:00
laser-optimizer Update README: clarify goal (Rust DAC-agnostic galvo-aware optimizer), add roadmap phases, add laser-optimizer/ placeholder folder 2026-10-04 19:59:08 +02:00
lzr@e19b5b3b82 Add submodules: ConvolutionInterpolations.jl, OpenIDN, laser-dac-rs, lzr 2026-10-04 19:55:44 +02:00
OpenIDN-Laser-DAC-Framework@437e7a245c Add submodules: ConvolutionInterpolations.jl, OpenIDN, laser-dac-rs, lzr 2026-10-04 19:55:44 +02:00
.gitignore Initial commit: laser optimization comparison doc + README 2026-10-04 19:55:10 +02:00
.gitmodules Add submodules: ConvolutionInterpolations.jl, OpenIDN, laser-dac-rs, lzr 2026-10-04 19:55:44 +02:00
COMPARAISON_OPTIMISATION.md Initial commit: laser optimization comparison doc + README 2026-10-04 19:55:10 +02:00
README.md idem 2026-10-04 18:06:52 +00:00

optilaz — Laser Optimisation & Interpolation Toolkit.

Objectif final : Une implémentation Rust de la meilleure optimisation possible de traces laser, indépendante du DAC (via laser-dac-rs), mais dépendante de la vitesse/physique des galvos (velocity planning curvature-aware).

État actuel : État de l'art — revue complète des composants existants, problèmes physiques, algorithmes de référence (lzr v2, papier Abderyim), et moteurs math (convinterp).

Prochaine étape : Digérer toute cette doc/code → implémenter dans laser-optimizer/ (crate Rust autonome, DAC-agnostique).


Structure du repo

lasoptidn/
├── COMPARAISON_OPTIMISATION.md          # Doc complète : problème, matrice 7 composants, annexes
├── README.md                            # Ce fichier (résumé + roadmap)
├── Abderyim_2008_Accurate_Efficient_Laser_Projection.pdf  # Papier référence (4 MB, .gitignore)
├── .gitmodules                          # Submodules
├── OpenIDN-Laser-DAC-Framework/         # Submodule: C++ — Récepteur IDN → DAC (transport pur)
├── laser-dac-rs/                        # Submodule: Rust — Backbone DAC + hooks (TransitionFn, OutputFilter)
├── lzr/                                 # Submodule: C++ — liblzr optimizer v1/v2 + ILDA parser
├── ConvolutionInterpolations.jl/        # Submodule: Julia — Interpolation haute ordre, lazy=true
└── laser-optimizer/                     # 🎯 FUTUR : Crate Rust finale (DAC-agnostique, galvo-aware)

Résumé des 4 composants existants (état de l'art)

Composant Langage Rôle Force Gap critique pour l'objectif
OpenIDN C++17 Récepteur IDN réseau → DAC Transport natif IDN, 4 DACs Pas d'optimisation (points bruts)
laser-dac-rs Rust Backbone DAC : abstraction unifiée + hooks 7 DACs, Frame/Stream API, TransitionFn, OutputFilter, reconnect, watchdog Pas d'optimizer (par design) — cible d'intégration
lzr optimizer v2 C++17 Algo référence : Path discovery + TSP angle-aware + cycles natifs Architecture modulaire, traversal solve temps/énergie Interpolation manquante (étape 5), LGPL v3, 1 seul DAC
convinterp Julia/Python/Rust Moteur math : B-spline ≤13e degré, lazy O(1), dérivées exactes 7e ordre Seul avec lazy + dérivées + degré élevé Zéro notion laser/DAC/blanking — moteur à brancher

Architecture cible (Rust pur, DAC-agnostique)

┌────────────────────────────────────────────────────────────────────────────────────┐
│                    laser-optimizer (crate Rust autonome)                           │
│  ┌──────────────────────────────────────────────────────────────────────────────┐  │
│  │                        OPTIMIZATION PIPELINE                                 │  │
│  │                                                                              │  │
│  │  INPUT (Frame)                                                               │  │
│  │    │                                                                         │  │
│  │    ▼                                                                         │  │
│  │  1. PATH DISCOVERY        ← Port lzr v2: split lit/blank/angle              │  │
│  │    │                                                                         │  │
│  │    ▼                                                                         │  │
│  │  2. TRAVERSAL SOLVE       ← Port lzr v2: TSP angle-aware + cycles natifs    │  │
│  │    │                    (Path, PathTraversal, TraversalSolve, cache)        │  │
│  │    ▼                                                                         │  │
│  │  3. KEYFRAME EXTRACTION   ← Points réordonnés + sens parcours par cycle     │  │
│  │    │                                                                         │  │
│  │    ▼                                                                         │  │
│  │  4. LAZY INTERPOLATION    ← convinterp: Spline1D::builder().lazy(true)     │  │
│  │    │                    B-spline degré 7 (C⁶), dérivées 1 & 2 exactes       │  │
│  │    ▼                                                                         │  │
│  │  5. VELOCITY PLANNING     ← κ = |d²p/ds²| → v_max = √(a_max/κ)              │  │
│  │    │                    Resampling adaptatif PPS-driven                     │  │
│  │    ▼                                                                         │  │
│  │  6. BLANKING (intra-frame)← lasy: blank_delay_points + angle delay (Eq.1)   │  │
│  │    │                                                                         │  │
│  │    ▼                                                                         │  │
│  │  OUTPUT (OptimizedFrame)  ← Points denses, PPS-correct, galvo-safe         │  │
│  │                                                                              │  │
│  └──────────────────────────────────────────────────────────────────────────────┘  │
└────────────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼ (via laser-dac-rs hooks)
┌────────────────────────────────────────────────────────────────────────────────────┐
│                    laser-dac-rs (BACKBONE — ne pas modifier)                       │
│  • TransitionFn  → inter-frame blanking courbe (C² via même interpolant lazy)     │
│  • OutputFilter  → safety clamp, color delay, final PPS resample                  │
│  • 7 DACs        → Helios, EtherDream, IDN, LaserCube, AVB, Oscilloscope, DaisyDAC│
│  • Reconnect, watchdog, metrics                                                   │
└────────────────────────────────────────────────────────────────────────────────────┘

Séparation des responsabilités

Couche Responsabilité Implémentation
laser-optimizer Algo pur : path discovery, TSP, cycles, interpolation lazy, velocity planning, blanking intra-frame Nouveau crate — DAC-agnostique, galvo-aware
laser-dac-rs Transport : DAC abstraction, inter-frame transition, output filter, reconnect, watchdog Existant — ne pas modifier
lasy Papier Abderyim : blanking delay, angle delay linéaire, Eulerian graph min blanks Dépendance (déjà Rust)
convinterp Math : B-spline lazy, dérivées exactes, resampling Dépendance (wrapper Rust)

Problème physique → Contraintes d'implémentation

4 modes de failure (points bruts → galvos)

  1. Segments longs → coins coupés (galvos trop lents)
  2. Sauts blank longs → flicker, perte luminosité
  3. Angles brusques → overshoot/ringing
  4. Vitesse excessive → distorsion, chauffe, usure

Contrainte fondamentale : Velocity planning curvature-aware

v_max_curvature = √(a_max / κ)        (κ = courbure = |d²p/ds²|)
v_target = min(v_max, v_max_curvature)

→ Il faut insérer des points où κ est forte (coins serrés). → Résolution : interpolation lazy (convinterp) + dérivée 2 → κ → resampling adaptatif.

Paramètres galvo (configurables par profil matériel)

Paramètre Symbole Unité Typique Source
Points/sec DAC PPS pts/s 30 000 DAC spec
Accélération max a_max rad/s² ~10⁶ Galvo spec
Vitesse max v_max rad/s ~10⁴ Galvo spec
Délai blanking blank_delay_points pts 10–50 Papier Abderyim + calibration
Délai angulaire radians_per_point rad/pt ~0.001 Papier Abderyim Eq.1 + calibration

Roadmap d'implémentation (phases)

Phase 0 — Préparation (maintenant)

  • Repo git + submodules + doc complète
  • Lire lzr/lzr/optimizer2/optimizer2.cpp + optimizer2.hpp (algo référence)
  • Lire lasy/src/lib.rs (implémentation papier Abderyim)
  • Expérimenter convinterp (Python: pip install convinterp)
  • Tester laser-dac-rs examples (cargo run --example frame -- circle)

Phase 1 — Port lzr v2 → Rust (lzr-v2-ported)

  • Structures : Point, Path (avec is_cycle), PathTraversal (entry + direction)
  • Path discovery : split par blank toggle + angle threshold (135°)
  • Traversal Solve : coût temps/énergie, multi-entry pour cycles, cache angles
  • Eulerian graph + min blanks (Eq.2: r = p + n/2) via lasy ou réimplémenté
  • Output : Vec<Path> réordonnés + parcours optimal par cycle
  • Tests : comparer sortie vs lzr C++ sur frames ILDA de test

Phase 2 — Intégration convinterp + velocity planning (laser-optimizer core)

  • Spline1D::builder().degree(7).lazy(true).build(keyframes)
  • Dérivée 1 → vitesse, dérivée 2 → accélération/courbure κ
  • v_target = min(v_max, √(a_max/κ)) par point
  • Resampling adaptatif : dt = ds / v_target → plus de points où κ fort
  • convolution_resample ou boucle manuelle PPS-driven
  • Tests : visualiser courbure + densité points sur formes test (cercle, carré, spirale)

Phase 3 — Blanking intra-frame + papier Abderyim

  • blank_delay_points : points fixes avant "laser on" après saut (P1)
  • radians_per_point : délai linéaire en radians = angle / radians_per_point (P2, Eq.1)
  • Intégrer lasy::blank_segment_points + corner_point_count
  • Eulerian graph pour min blanks inter-paths (P3, Eq.2)
  • Tests : comparer rendu vs papier Fig. 7, 10, 12, 16

Phase 4 — API unifiée + intégration laser-dac-rs

  • pub fn optimize_frame(input: &Frame, config: &OptimizerConfig) -> OptimizedFrame
  • OptimizerConfig : tous paramètres galvo + papier + PPS
  • Brancher dans laser-dac-rs via OutputFilter (intra-frame) + TransitionFn (inter-frame)
  • Inter-frame blanking courbe : même interpolant lazy → C² continu
  • Tests : end-to-end avec EtherDream/Helios réel

Phase 5 — Polish & production

  • Profiling / benchmarks (allocation, latence, PPS soutenu)
  • Profils galvo prédéfinis (CT6210, CT6215, DT40, etc.)
  • Documentation + exemples
  • Publier laser-optimizer sur crates.io

Quick start (pour commencer le développement)

# 1. Explorer l'algo de référence (C++)
cat lzr/lzr/optimizer2/optimizer2.cpp
cat lzr/lzr/optimizer2/optimizer2.hpp

# 2. Comprendre l'implémentation papier Abderyim (Rust)
cat laser-dac-rs/../lasy/src/lib.rs  # ou depuis crates.io

# 3. Tester le backbone DAC
cd laser-dac-rs
cargo run --example frame -- circle
cargo run --example transitions -- default

# 4. Expérimenter convinterp (Python le plus simple)
pip install convinterp
python -c "
import convinterp as ci
import numpy as np
x = np.linspace(0, 1, 20)
y = np.sin(2*np.pi*x)
itp = ci.convolution_interpolation(x, y, kernel='b7', lazy=True)
print(itp(0.5))  # évaluation lazy
print(itp.derivative(1, 0.5))  # vitesse
print(itp.derivative(2, 0.5))  # accélération/courbure
"

# 5. Lire la doc complète
cat COMPARAISON_OPTIMISATION.md

Fichiers clés à connaître pour l'implémentation

Fichier Contenu Utilité pour laser-optimizer
lzr/lzr/optimizer2/optimizer2.hpp/.cpp Optimizer v2 complet (5 étapes) Source principale Phase 1
lzr/lzr/interpolator.hpp Interpolator simple (lin/quad/quart) Référence interpolation basique
lasy/src/lib.rs Pipeline papier Abderyim (5 étapes) Blanking/angle delays, Eulerian graph
laser-dac-rs/src/stream/frame.rs FrameStream + hooks TransitionFn/OutputFilter Points d'intégration Phase 4
ConvolutionInterpolations.jl/src/convolution/ Kernels, lazy, dérivées, resampling Spécifications convinterp
COMPARAISON_OPTIMISATION.md Annexes A–E complètes Référence complète

Liens utiles


Notes pour le futur laser-optimizer/

# Structure attendue une fois créé :
laser-optimizer/
├── Cargo.toml
├── src/
│   ├── lib.rs              # API publique: optimize_frame(), OptimizerConfig
│   ├── path_discovery.rs   # Port lzr v2: split lit/blank/angle
│   ├── traversal_solve.rs  # Port lzr v2: TSP angle-aware + cycles
│   ├── interpolation.rs    # Wrapper convinterp lazy + velocity planning
│   ├── blanking.rs         # Blanking intra-frame (lasy + papier)
│   └── types.rs            # Frame, OptimizedFrame, Path, PathTraversal
├── benches/
│   └── optimizer_bench.rs  # Criterion benches
├── tests/
│   ├── integration_test.rs # End-to-end avec laser-dac-rs
│   └── test_frames/        # Fichiers ILDA de test
└── examples/
    └── basic_usage.rs

Dépendances Cargo.toml (prévisionnel) :

[dependencies]
lasy = "0.4"                    # Papier Abderyim implémenté
convinterp = { git = "https://github.com/JuliaMath/ConvolutionInterpolations.jl" }
petgraph = "0.6"                # Graphes Euler (déjà dans lasy)
nalgebra = "0.32"               # Math vectoriel
serde = { version = "1.0", features = ["derive"] }
thiserror = "1.0"