UADIA · Système EAAE Gaze — version convergée V8.3 · Mr So Olveson System
Description formelle du pilote oculaire de bout en bout : du maillage facial à la vitesse de défilement, avec une couche vocale optionnelle de contrôle Pause / Play raccordée au même état moteur.
Équation maîtresse — sortie unique
où ℓ intègre le profil de taux Ly(ŷ), Ŝ le champ documentaire, Č la continuité de lecture, Û la rétroaction d'intention. Aucun de ces facteurs n'émet de commande : chacun module la seule et même vitesse.
Le système obéit à une contrainte architecturale unique dont tout le reste découle : à chaque instant, le moteur produit une et une seule grandeur de mouvement, la vitesse de défilement vertical vY (et, sur les conteneurs horizontaux, son homologue vX). Tous les termes du modèle sont des modulateurs multiplicatifs de ce champ ; aucun n'ouvre une seconde trajectoire, aucun ne recentre indépendamment la position, aucun n'additionne sa propre vitesse.
Cette discipline écarte par construction le défaut classique des interfaces oculaires : deux contrôleurs qui se disputent la position et entrent en oscillation. Ici le champ documentaire, la continuité de lecture et l'intention gestuelle sont des gains bornés appliqués en cascade ; leur produit reste, dimensionnellement et sémantiquement, une vitesse. La lisibilité du comportement est un théorème plutôt qu'un réglage.
Le flux va de l'image caméra à l'écriture du défilement en six étages séquentiels. Chaque étage transforme une représentation dans le repère de la précédente et ne réintroduit jamais une unité déjà quittée — en particulier, la position filtrée du regard demeure adimensionnelle jusqu'à la toute dernière projection.
Le point de bascule conceptuel se situe à l'étage 4 : le regard y devient une coordonnée normalisée stable, indépendante du format d'affichage. Tout ce qui précède vit dans l'image caméra ; tout ce qui suit vit dans un espace de taux adimensionnel, converti en pixels seulement au dernier geste.
Pour chaque œil, la position de l'iris est ramenée à un ratio entre les commissures et entre les paupières, ce qui absorbe la taille apparente de l'œil :
avec (o, i) les coins externe/interne et (t, b) les paupières. On moyenne les deux yeux : gazeX = (xR+xL)/2, gazeY = (yR+yL)/2. La pose de tête découle de l'écart du nez au centre du visage, normalisé par ses dimensions :
Le poids relatif de l'iris et de la pose de tête n'est pas fixe : il suit la fiabilité instantanée de chaque source. On mesure l'ouverture palpébrale, la gigue (écart-type glissant sur huit trames) et la qualité lumineuse L, puis :
ReOeil et ReTete décrivent la fiabilité instantanée des deux sources ; PoOeil et PoTete déterminent ensuite leur poids dans la fusion — ces variables ne constituent aucune catégorie morphologique et ne sont jamais mémorisées. Lorsque l'iris devient instable, la pose de tête gagne du poids au lieu de forcer un point oculaire incertain.
Une confiance scalaire κ agrège trois qualités — signal, calibration, lumière :
où qcal = clamp(1 − 2,5×rmse, 0,3, 1) relie la confiance à l'erreur résiduelle de calibration (Partie 4). L'incertitude spatiale σ est exprimée comme une fraction du plus petit côté visible, donc invariante au format : σvp = max(24/m, (1−κ)×0,16 + 24/m), m = min(Wvis, Hvis). Plus la confiance chute, plus la distribution du regard s'élargit — ce qui adoucit mécaniquement le champ documentaire.
La calibration mappe les attributs bruts vers une coordonnée écran normalisée par une régression ridge sur un plongement quadratique de dimension 14 :
Les termes croisés yaw×x et pitch×y couplent la pose de tête au regard oculaire ; les termes pondérés par PoOeil, PoTete laissent la fusion moduler continûment la contribution de chaque source dans le mapping lui-même. Pour chaque axe a ∈ {X,Y}, on résout :
soit, en équations normales, (ΦᵀΦ + λI) wa = Φᵀta. La régularisation λ maintient le conditionnement du système 14×14 malgré la corrélation des monômes quadratiques. La prédiction est affine dans le plongement :
Le modèle (poids, rmse, horodatage) est stocké localement sous uadia.gaze.calibration.v2 ; aucune donnée biométrique persistante ne quitte l'appareil, et la rmse réinjecte sa qualité dans κ.
Le regard prédit est filtré par un One-Euro — un passe-bas dont la fréquence de coupure croît avec la vitesse du signal, ce qui résout le compromis gigue/latence mieux qu'une constante fixe : en fixation le seuil descend et étouffe le bruit, en saccade il monte et efface le retard.
Le filtre agit dans le repère normalisé [0,1]², avant toute projection pixel : le lissage porte sur la grandeur invariante, non sur des pixels dont l'échelle change avec le viewport. Les métadonnées (κ, σ, poids) sont lissées séparément pour ne pas appliquer deux passe-bas successifs à la position.
| Paramètre | Axe X | Axe Y | Rôle |
|---|---|---|---|
| f_min | 1.18 Hz | 1.05 Hz | coupure au repos (gigue de fixation) |
| β | 0.055 | 0.045 | réactivité à la vitesse (latence de saccade) |
| d_cutoff | 1.0 | 1.0 | lissage de la dérivée |
L'état filtré du regard v = (x̂, ŷ) ∈ [0,1]² ne mémorise aucun pixel. La conversion vers l'écran n'intervient qu'en fin de chaîne, contre le viewport visuel courant :
où (oL, oT) et (Wvis, Hvis) proviennent de window.visualViewport, et suivent donc l'apparition des barres du navigateur, le clavier virtuel, le pincement-zoom ou la rotation. Il en résulte un invariant qui fonde tout l'étage cinématique :
Corollaire opératoire : la cinématique est calculée en viewport par seconde (grandeur sans dimension d'écran), la conversion en pixels par seconde étant la dernière opération. La vitesse angulaire de lecture reste ainsi constante quel que soit le format.
Le cœur du système compose quatre facteurs en un seul taux, borné puis projeté. En notant ℓ l'intégrateur lissé du profil de taux :
avec gL = 1,16, TbVP = 0,086 (fraction de viewport parcourue par seconde pour |Ly| = 1) et ρmax = 2,10. Les quatre facteurs sont détaillés ci-après.
Le profil Ly : [0,1] → ℝ mappe la hauteur du regard vers un taux de défilement (et non vers une position cible). Il est interpolé par splines PCHIP monotones — continuité C¹ sans dépassement, garantissant qu'un regard porté un peu plus haut ne produit jamais un recul parasite. Une zone morte [0,27 ; 0,64] annule le taux : c'est la bande de lecture confortable, où l'œil peut résider sans déclencher de mouvement.
Sous la zone morte, Ly < 0 (remontée) ; au-dessus, Ly > 0 (progression), avec une pente croissante vers les bords qui donne une réserve d'accélération volontaire.
SDoc pondère la vitesse selon ce que le regard recouvre réellement dans le document. Le regard est traité comme une masse de probabilité ; pour chaque surface, on mesure le recouvrement relatif ρ = aire(boîte regard ∩ élément) / aire(boîte regard), dont on tire un score :
où aᵢ est l'aire visible normalisée et νᵢ le taux de visibilité de l'élément. Une activation par seuil, douce en deçà et saturante au-delà, évite tout basculement brusque :
La valeur documentaire est la moyenne pondérée des cinq surfaces dominantes, puis atténuée par la confiance :
Cread maintient le mouvement pendant les micro-interruptions du regard de lecture — les retours-ligne saccadiques qui, sans lui, provoqueraient un bégaiement à chaque ligne. C'est un intégrateur à fuite asymétrique : montée rapide (145 ms), descente lente (820 ms), piloté par la cohérence de la demande et la confiance :
Cread agit à deux endroits, toujours comme modulateur du champ unique : un facteur direct Čf = 0,86 + 0,14×Č ∈ [0,86 ; 1], et un plancher de continuité sous SDoc entre deux éléments :
La lecture engagée ne « retombe » donc pas dans le fond documentaire entre deux paragraphes : elle conserve un socle de vitesse le temps que le regard rejoigne la surface suivante.
Uintent lit le geste du regard — la dérivée de la position oculaire et de la pose de tête — pour confirmer ou contredire le sens en cours, sans jamais émettre de commande propre. Chaque source passe par une tangente hyperbolique bornée, puis est fusionnée par les mêmes poids œil/tête :
L'accord entre le geste et le sens du taux, a = sign(ℓ) × σI, module un gain d'intention borné :
Point clé de la version convergée : l'autorité de l'intention décroît quand la lecture s'engage. Le geste ne doit pas injecter de gigue pendant une lecture continue :
Quand Č → 1 (lecture établie), A → 0,12 et Û → 1 : l'intention gestuelle s'efface presque entièrement, supprimant le bruit de dérivée là où il gênait le plus. En exploration (Č faible), l'autorité remonte et le geste retrouve son pouvoir de confirmation. Ce conditionnement croisé Cread–Uintent est ce qui distingue un simple empilement de gains d'un modèle dont les termes se déterminent mutuellement.
Tous les lissages emploient la forme indépendante du framerate α = 1 − e^(−Δt/τ). Le profil est intégré (τℓ = 86 ms), puis la vitesse suit sa cible (τout = 108 ms). En zone morte, la vitesse glisse vers zéro au lieu d'être téléportée :
Chaque incursion du regard dans la zone morte — retour-ligne, micro-saccade — produit ainsi une décélération continue, non une coupure sèche. C'est l'un des deux correctifs majeurs du bégaiement perçu.
L'intégration de position vit dans un flottant interne, découplé de la quantification pixel du navigateur. On n'intègre jamais depuis un scrollTop relu et arrondi ; on se resynchronise seulement si un écart franc trahit une reprise manuelle :
À vitesse de lecture, où l'incrément par trame est inférieur au pixel, cet accumulateur supprime le motif de battement de la troncature répétée. Il subsiste un plancher irréductible : le rendu de scrollTop reste quantifié au pixel physique ; l'accumulateur amène exactement à ce plancher.
Pendant l'actuation, le défilement doux CSS (scroll-behavior: smooth) est neutralisé sur l'axe vertical et horizontal : sans cela, l'animation d'inertie du navigateur poursuit une cible que l'intégrateur réécrit soixante fois par seconde — deux boucles de contrôle en conflit, source majeure de saccade et de latence. Enfin, une garde de confiance à mémoire (temporisation de 420 ms avant abandon) évite qu'une trame sous le seuil ne détruise instantanément l'état : le signal fluctue, le mouvement non.
La version convergée résout la classe fluidité/contrôle. Le chantier ouvert relève d'un autre axe — la précision — et se distingue par un symptôme différent : non pas un à-coup, mais une visée qui dérive lorsque la tête se déplace.
Le plongement de calibration φ ne contient que la rotation de tête (yaw, pitch) ; il n'a ni proxy de distance ni terme de translation. Or l'extraction brute calcule déjà la largeur fW et le centre f̄ = (f̄x, f̄y) du visage — le substrat est présent, seulement non consommé. L'extension naturelle augmente le plongement :
où fW agit comme surrogat de distance (angle visuel) et (f̄x, f̄y) capturent la translation latérale ; les interactions avec x, y corrigent la déformation du mapping quand l'utilisateur s'approche, recule ou se décale. Le surcoût est de quelques dimensions, trivial pour la résolution ridge, et rétrocompatible avec la calibration existante.
Deux réserves mineures complètent le tableau : le modèle temporel exporté vers ONNX reste à l'état d'échafaudage et, s'il était activé, hériterait d'un biais de distribution (fenêtres d'apprentissage restreintes aux fixations, alors que le régime réel est la lecture) ; et le plancher de rendu de scrollTop ne peut être franchi qu'en abandonnant le défilement natif au profit d'une transformation translateY — changement lourd rarement justifié.
Le moteur n'exige pas que la page soit reconstruite autour de lui. Une landing existante reste receveuse si elle conserve le défilement vertical natif du document, charge le dossier gaze/, puis expose au moteur les surfaces particulières qu'elle souhaite qualifier. Les éléments éditoriaux standards — titres, paragraphes et listes — sont déjà détectés automatiquement.
Le moteur V8.3 pilote document.scrollingElement. La page peut conserver sa mise en page, ses sections et ses effets visuels, mais ne doit pas remplacer le scroll principal par un conteneur vertical privé sans adaptation du runtime.
Conserver la balise viewport. Le moteur travaille en coordonnées normalisées puis projette via visualViewport, ce qui maintient la même logique sur Desker, mobile, rotation et changement de hauteur visible.
Placer le dossier gaze/ à côté de la page ou adapter explicitement les chemins d'import. Le CSS, le contrôleur, l'estimateur, la calibration et l'interface restent ainsi modulaires.
La caméra reste nécessaire au gaze. Le microphone est facultatif et n’est demandé que si le Voice Control est activé. Les deux accès passent par navigator.mediaDevices.getUserMedia() et restent soumis au consentement explicite de l’utilisateur.
La landing receveuse charge d'abord le style du moteur, puis le contrôleur de scroll global, puis le module principal. L'ordre est volontaire : UadiaGazeEngine détecte window.UadiaGazeScrollScale lors de son montage.
En V8.3, UadiaGazeEngine importe automatiquement UadiaGazeVoiceControl.js. Aucun second script vocal n’est à ajouter dans la landing receveuse.
Une landing peut conserver scroll-behavior: smooth pour son usage normal. Pendant l'actuation gaze, il faut toutefois laisser l'intégrateur V8.3 être l'unique contrôleur de position. La classe uadia-gaze-actuating est posée par le moteur ; la page receveuse doit lui donner priorité.
scrollTop ou scrollLeft pendant l'actuation recrée un second contrôleur. Elle doit être suspendue, neutralisée ou explicitement intégrée au moteur.Les balises h1 à h4, p et li sont déjà reconnues par le champ documentaire. Une landing simple n'a donc pas besoin d'annoter chaque paragraphe. Les attributs data-gaze-* servent à préciser les composants particuliers : cartes, CTA, carrousels, sections éditoriales ou zones à ignorer.
| Attribut | Fonction | Usage |
|---|---|---|
| data-gaze-zone | Déclare une surface documentaire explicite. | Carte, bloc ou composant personnalisé. |
| data-gaze-anchor | Déclare un repère structurel dans la page. | Section principale ou point de lecture. |
| data-gaze-sdoc | Fixe la valeur SDoc propre à la surface. | Moduler l'influence documentaire sans changer le moteur. |
| data-gaze-threshold | Fixe le seuil de recouvrement/activation. | Ajuster la sensibilité d'un composant. |
| data-gaze-priority | Fixe sa priorité dans l'agrégation. | Distinguer un élément principal d'un conteneur parent. |
| data-gaze-hold | Transforme la zone en surface de maintien faible. | CTA ou zone où le scroll doit être fortement réduit. |
| data-gaze-ignore | Exclut l'élément et ses descendants. | UI flottante, décor ou contenu non sémantique. |
| data-gaze-slide="x" | Autorise l'actuation horizontale du conteneur. | Carrousel avec overflow-x. |
Une page est compatible lorsque le moteur peut conserver son regard en [0,1]², lire la géométrie documentaire, être seul à écrire le déplacement pendant l'actuation et projeter la vitesse sur le viewport courant. Elle est à adapter lorsqu'un framework remplace le scroll du document, lorsqu'un autre moteur d'inertie réécrit continuellement la position, ou lorsqu'un composant personnalisé n'est ni sémantique ni déclaré par data-gaze-zone.
La V8.3 ajoute une couche vocale facultative appelée Mr So Olveson System. Son rôle est volontairement limité : résoudre une phrase parlée vers l’un des deux états Pause ou Play. Elle ne constitue pas un moteur de défilement supplémentaire.
scrollTop. Une commande vocale appelle exactement le même état Pause / Play que le bouton visuel.Les commandes par défaut sont « scroll pause » et « scroll play ». Elles peuvent être remplacées dans le panneau sans modifier le moteur. Les deux expressions doivent rester différentes. La langue acoustique de reconnaissance peut être choisie indépendamment entre Français · fr-FR et English · en-US.
| Paramètre | Valeur V8.3 | Fonction |
|---|---|---|
| Pause | scroll pause | Place immédiatement l’état de scroll en pause après résolution. |
| Play | scroll play | Réactive le scroll seulement si caméra, calibration et runtime sont prêts. |
| Langue | fr-FR / en-US | Préférence acoustique transmise à SpeechRecognition. |
| Alternatives | ≤ 5 | Compare plusieurs hypothèses retournées par le navigateur. |
| Cooldown | 900 ms | Évite le double déclenchement immédiat d’une même commande. |
L’égalité exacte reste prioritaire. Lorsque la transcription diffère légèrement, Mr So Olveson applique une similarité de Levenshtein normalisée sur la phrase complète, et non sur un mot isolé. Une résolution tolérante n’est acceptée que si le meilleur score atteint 0,82 et conserve au moins 0,10 d’avance sur la commande opposée.
Les seuils de confiance diffèrent selon le type de résolution : une correspondance exacte peut être acceptée à partir de 0,18 lorsque la confiance est fournie, tandis qu’une correspondance tolérante exige 0,45. Si l’API ne fournit pas de confiance exploitable, la commande n’est pas rejetée pour cette seule raison.
La V8.3 expose toutes les transcriptions finales utiles, y compris lorsqu’elles sont rejetées. Le panneau sépare ainsi les étapes qui étaient auparavant confondues :
Le microphone reste facultatif. Lorsqu’il est activé, le système demande l’accès audio avec réduction d’écho, réduction de bruit et contrôle automatique du gain. Le flux ouvert pour l’autorisation est refermé après la demande, puis SpeechRecognition gère la reconnaissance selon les capacités du navigateur.
SpeechRecognition / webkitSpeechRecognition peut dépendre d’un service fourni par le navigateur ou son éditeur. La documentation ne doit donc pas présenter cette reconnaissance comme nécessairement locale tant que le runtime utilisé ne le garantit pas explicitement.La V8.3 est retenue comme jalon stable : la commande vocale est reconnue, résolue et raccordée au même état moteur que le bouton. Le prochain incrément ne concerne plus la compréhension de la voix mais la latence de rupture entre le début de la commande Pause et l’arrêt effectif du scroll.
Dans la V8.3 actuelle, interimResults = false : seule une transcription finale peut déclencher la commande. L’optimisation future devra donc prioriser la rupture Pause — par exemple en évaluant prudemment un résultat intermédiaire suffisamment certain — sans réintroduire de faux positifs ni créer un second contrôleur.