
Lab · Simulation · En cours
Trafic
Simulateur de trafic microscopique temps réel, en JavaScript, rendu avec three.js. Chaque véhicule a son modèle de conduite, son itinéraire et ses réservations aux carrefours. Moteur indépendant du rendu, validé sous Node par un banc de vingt scénarios ; réseaux décrits en JSON ; véhicule pilotable.
- Moteur
- JavaScript
- Rendu
- three.js r128
- Banc
- 20 scénarios
- Feuille de route
- 28 / 50
- Lecture
- 18 min
Trafic calcule chaque véhicule individuellement, à pas fixe de 1/30 s, et three.js l’affiche dans le navigateur. Le réseau de démonstration est une grille de 3 × 3 carrefours ; le moteur lit aussi d’autres réseaux, décrits en JSON.
Objectif de la feuille de route : approcher le réalisme des simulateurs de référence (SUMO, PTV Vissim, Aimsun) en restant temps réel. Le développement suit cinquante fonctionnalités ordonnées par taille et dépendances, une par commit ; chacune est mesurée par un banc de tests headless et documentée par une figure générée par le moteur. Cette page décrit l’état au n° 28.
Log 01 / 10
Base du moteur
Modèle de suivi, pas fixe, aléatoire à graine, banc de tests headless, index spatial.
Réseau de démonstration : grille de 3 × 3 carrefours espacés de 60 m, une voie par sens, douze entrées-sorties. Chaque véhicule suit l’IDM : son accélération dépend de l’écart et de la vitesse relative avec le premier obstacle sur sa trajectoire, véhicule, ligne d’arrêt ou véhicule engagé dans le carrefour. Il réserve le carrefour avant de s’y engager. Le pas de simulation est fixe, découplé de l’affichage ; au démarrage, 25 s de trafic sont pré-simulées.

Déterminisme : tout l’aléatoire du trafic passe par un générateur à graine (mulberry32) au lieu de Math.random : apparitions, destinations, paramètres des conducteurs, couleurs. Même graine, mêmes trajectoires. La graine se passe dans l’adresse (?seed=42).

Banc de tests : npm run bench exécute la simulation headless sous Node sur vingt scénarios de référence, six graines chacun, et compare les moyennes des indicateurs à une référence ; un écart n’est signalé qu’au-delà de trois erreurs-types, la variance entre graines étant de 5 à 15 %. Une empreinte exacte de l’état final valide au bit près les refontes sans effet attendu. La graine 1 tourne en trois copies simultanées : empreintes comparées pour le déterminisme, meilleur temps retenu pour le coût du pas.
- 1/30 s
- Pas de simulation fixe ; le rendu interpole entre les deux derniers pas.
- 20 × 6
- Scénarios de référence × graines par scénario.
- 0,20 ms
- Coût d’un pas en saturation, environ 170 véhicules.
Index spatial : grille de cases de 50 m reconstruite à chaque pas (lecture des 3 × 3 cases voisines), puis test de boîte englobante sur les 22 points échantillonnés devant le véhicule. Les deux filtres sont exacts : empreintes inchangées. En saturation, le pas passe de 0,25-0,29 ms à 0,20 ms ; le gain servira surtout aux grands réseaux, au-delà de la limite actuelle de 400 véhicules.
Log 02 / 10
Modèle de conducteur
Profils tirés au hasard, décision à l’orange, temps de réaction et anticipation (HDM).
Trois profils : prudent (25 %), normal (55 %), pressé (20 %). Chaque conducteur tire ses paramètres autour des valeurs de son profil, avec un écart-type relatif de 8 % borné à ±2σ. Effet en saturation par rapport à des conducteurs identiques : sorties −4 %, vitesse moyenne −6 %.
| Paramètre | Prudent | Normal | Pressé |
|---|---|---|---|
| Accélération max | 1,7 m/s² | 2,3 m/s² | 2,9 m/s² |
| Freinage confortable | 2,0 m/s² | 2,6 m/s² | 3,2 m/s² |
| Temps intervéhiculaire | 1,1 s | 0,8 s | 0,6 s |
| Distance minimale | 2 m | 1,8 m | 1,5 m |
| Vitesse souhaitée | 86 % de la limite | 95 % | 108 % |
| Temps de réaction | 0,75 s | 0,6 s | 0,5 s |
| Retard toléré au rouge | 0 s | 0,4 s | 1 s |

Zone de dilemme : à l’apparition de l’orange, chaque conducteur tire une seule fois sa décision selon son temps jusqu’à la ligne, sur une logistique calée sur Zegeer et Deen (1978) : 10 % d’arrêts à 2,5 s et 90 % à 5,5 s pour un normal, décalage de ±0,5 s selon le profil. Il passe si l’arrêt exige plus de 4,5 m/s², et renonce s’il ne peut pas franchir la ligne avant la fin de son retard toléré au rouge. Mesuré : 0,5 à 0,6 % des passages pendant le rouge intégral.
Human Driver Model, actif par défaut : chaque conducteur applique la décision prise un temps de réaction plus tôt (0,5 à 0,75 s) en anticipant sa position au moment où elle porte ; il estime les distances à ±10 % et la vitesse d’approche avec une erreur corrélée sur 20 s ; il réagit au plus contraignant des véhicules visibles devant lui. L’anticipation part des accélérations déjà décidées, pas d’une vitesse constante : 1 à 2 ‰ de freinages brusques. Les paramètres ont été recalés pour garder un débit de saturation de 1 803 ± 34 véh/h. Une case du panneau ramène à l’IDM seul.

Log 03 / 10
Carrefours et feux
Cinq régimes de carrefour, acceptation de créneau, trois commandes de feux.
| Régime | Règle |
|---|---|
| Feux tricolores | Vert, orange 3 s, rouge intégral 1,5 s, en alternance entre les axes est-ouest et nord-sud. |
| Stop 4 voies | Arrêt complet obligatoire, puis priorité au premier arrivé. |
| Stop sur la secondaire | Arrêt, puis attente d’un créneau suffisant dans le trafic de la principale. |
| Cédez-le-passage | Approche à 16 km/h, engagement si le créneau suffit. |
| Priorité à droite | Chacun cède au véhicule qui arrive de sa droite. |
Acceptation de créneau : le conducteur qui cède estime l’arrivée du prochain véhicule prioritaire dont la trajectoire croise ou rejoint la sienne, jusqu’à deux tronçons en amont et en supposant une accélération franche. Il ne s’engage que si le créneau dépasse le créneau critique du HCM : depuis la secondaire, 6,2 s à droite, 6,5 s tout droit, 7,1 s à gauche ; depuis la principale, 4,1 s à gauche ; le tout × √(T / 1,1) selon son temps intervéhiculaire T. Les conflits sont calculés sur les courbes de virage.

Feux actionnés : détection sur les 35 m en amont des lignes d’arrêt, appel de phase par un véhicule au rouge, vert minimum de 6 s, prolongé tant que des véhicules arrivent, terminé après 2 s sans arrivée ou 30 s après l’appel opposé. À demande égale avec l’onde verte à temps fixe : attente −7 %, sorties +4 %.

Coordination Webster : toutes les 5 min, cycle commun C₀ = (1,5 L + 5) / (1 − Y) calculé sur les débits des boucles, avec un temps perdu L de 6 s par phase et un cycle borné entre 30 et 120 s ; verts répartis selon les charges ; décalages de la forme a·colonne + b·ligne, choisis pour maximiser la largeur totale des bandes vertes à 40 km/h dans les deux sens. Sur cette grille (îlots de 60 m, cycle d’environ 40 s), l’optimum est une onde dans un seul sens par axe. À 70 véh/min : retard de contrôle de 27,0 s contre 28,4 s pour l’onde verte à cycle fixe, CO₂ −4,5 %.
Max-pressure : la pression d’une phase est la somme, sur ses mouvements demandés, des véhicules en attente moins la file présente sur leur sortie. Décision toutes les 2 s, après un vert minimum de 12 s ; la phase opposée prend le vert si sa pression dépasse celle de la phase en cours d’au moins 3 véhicules. Un seuil plus bas (vert minimum de 6 s, bascule au moindre écart) coûte plus en changements de phase qu’il ne rapporte : retard de 39,5 s.
Log 04 / 10
Instrumentation
Inspecteur de véhicule, carte de chaleur, capteurs, niveaux de service, calibration.
Inspecteur : un clic sur un véhicule ouvre sa fiche, avec profil et paramètres du conducteur, trajet, itinéraire prévu (tracé au sol), intention et réservation au prochain carrefour ou raison de l’attente, termes de l’accélération IDM et leur cause, émissions. Carte de chaleur : vitesse moyenne de chaque voie rapportée à sa limite, sur 20 s glissantes. L’adresse ?debug expose l’état complet dans la console.

Capteurs : boucle de comptage virtuelle au milieu de chaque voie (débit, taux d’occupation, vitesse, agrégés par minute) ; retard de contrôle par véhicule et par carrefour, converti en niveau de service A à F aux seuils du HCM ; débit de saturation mesuré aux feux à partir du 5e véhicule d’une file ; diagramme débit-densité.
Calibration : la première mesure donnait 1 250 véh/h par voie, pour 1 800 à 1 900 observés en ville. Corrections : écart au véhicule de devant sous-estimé de 0,7 m, règle anti-blocage du carrefour trop stricte, paramètres IDM ramenés dans les plages publiées pour la conduite urbaine. Effet secondaire : attente par trajet −30 à −38 %.
- 1 250
- Véh/h par voie, débit de saturation avant calibration.
- 1 824
- Véh/h par voie après calibration (± 49), voitures seules.
- 1 640
- Véh/h par voie avec 7 % de poids lourds et de bus, cohérent avec la correction du HCM.

Log 05 / 10
Demande et flotte
Matrice origine-destination, plus court chemin, cinq types de véhicules, émissions.
Itinéraires : chaque véhicule reçoit à l’entrée une destination tirée dans une matrice origine-destination et suit le chemin le plus rapide, en temps à vitesse limite plus 3 s par virage à droite et 8 s par virage à gauche ; tirage au hasard entre chemins à moins de 1 s du meilleur. Répartition obtenue : 58 % tout droit, 22 % à droite, 20 % à gauche. Mode journée accélérée (1 min = 1 h) : pointes à 8 h et 17 h, destinations orientées vers l’est le matin et vers l’ouest le soir.

Flotte : voitures 80 %, utilitaires 8 %, poids lourds 4 % (10 m), bus 3 % (12 m), deux-roues 5 %. Chaque type a ses dimensions, son accélération, son freinage, son créneau critique (+1 s pour les lourds) et sa classe d’émissions ; la constante de longueur unique a disparu du moteur. Un véhicule lourd garde la réservation du carrefour jusqu’à ce que son arrière en soit sorti. Validation : aucun blocage sur six graines à 70, 110 et 140 véh/min ; débit de saturation de 1 643 véh/h sur l’onde verte.

Émissions : CO₂, NOx et carburant calculés à chaque pas à partir de la vitesse et de l’accélération, avec les coefficients HBEFA3 de SUMO et coupure d’injection en décélération. Contrôle à 50 km/h stabilisés : 168 g/km de CO₂ et 7,2 L/100 km (essence Euro 4). Sur la grille, les moyennes (500 à 1 400 g/km) sont dominées par le ralenti ; elles servent à comparer des réglages. Exemple, les zones 30 sur les axes périphériques : vitesse moyenne −3 %, trajets +3 %, CO₂ par kilomètre −7 %.

Log 06 / 10
Véhicule pilotable
Dynamique bicyclette, collisions, code de la route, GPS et missions.
Dynamique : modèle bicyclette avec adhérence des pneus ; 1 300 kg, empattement 2,6 m, 75 kW, traction avant ; 0 à 100 km/h en 8,4 s, 50 à 0 km/h en 11 m ; perte d’adhérence au freinage ou à l’accélération en virage. Clavier ou manette ; caméras poursuite, cockpit et libre.
Collisions : véhicules approchés par trois cercles le long de leur axe, bâtiments par leurs boîtes. Résolution de la pénétration, puis impulsion de corps rigide : rebond, rotation selon le point d’impact, glissement le long des murs (frottement 0,2). Un véhicule IA percuté absorbe le choc le long de sa trajectoire et s’arrête.

Code de la route : permis de 12 points, barème ANTAI. La position libre du joueur est rattachée à chaque pas au tronçon dont la chaussée la contient et dont le sens suit son cap (map matching) ; ce tronçon donne la limite, le prochain carrefour et son régime. Le franchissement d’une ligne est détecté entre deux pas sur la position de l’avant du véhicule ; la vitesse est contrôlée en continu, en km/h entiers, marge de 5 km/h déduite.
| Infraction | Détection | Points |
|---|---|---|
| Feu rouge | L’avant passe la ligne au rouge. | 4 |
| Feu orange évitable | À l’allumage, freinage nécessaire v² / 2d inférieur à 4,5 m/s². | 4 |
| Stop non marqué | Pas d’arrêt complet (< 1 km/h) dans les 15 derniers mètres. | 4 |
| Refus de priorité | Prioritaire à moins de 3 s de la ligne, ou déjà engagé. | 4 |
| Excès de vitesse | Vitesse retenue = mesurée − 5 km/h, au maximum de l’excès. | 0 à 6 |

GPS : graphe dont les nœuds sont les tronçons et les arêtes les mouvements autorisés (pas de demi-tour), avec les mêmes coûts que les itinéraires des IA. Le temps restant jusqu’à la destination est calculé pour chaque tronçon, à rebours (Bellman-Ford, quelques passes sur 48 tronçons) ; à chaque carrefour, le guidage prend la branche qui minimise virage + temps restant. Un écart d’itinéraire ne demande donc aucun recalcul. Le ruban affiché est mis à jour au changement de tronçon et quatre fois par seconde.
Missions : trajet, livraison, contre-la-montre. Étapes tirées sur un flux aléatoire séparé, sans effet sur le trafic ; arrêt validé à moins de 6 m, sous 1 m/s pendant 1 s ; contre-la-montre jugé à 1, 1,2 et 1,5 fois le temps estimé, 10 s de pénalité par infraction.

Log 07 / 10
Perturbations
Distraction et accrochages, météo et visibilité, événements programmés.
Distraction (option) : épisodes d’inattention en roulant (un toutes les 40 s en moyenne, × 0,6 pour un prudent, × 1,5 pour un pressé ; durée lognormale de médiane 1,1 s, 4 s au plus) et à l’arrêt (après 2 s d’attente, un toutes les 12 s, médiane 2,5 s, pied sur le frein). Pendant l’épisode, la perception est figée. Le retour sur la route est déclenché par un temps avant collision sous un seuil de médiane 1,8 s ou par le départ du véhicule de devant (4 m), puis le temps de réaction s’applique.
Accrochage : contact à 1 m/s ou plus sur un même tronçon. Les deux véhicules s’immobilisent, feux de détresse allumés, pour la durée du constat (médiane 2 min 30 s, de 1 à 6 min), et bloquent la voie ; la file amont déclenche les changements d’itinéraire aux carrefours précédents.

- 1,49 → 1,92 s
- Démarrage en tête de file, sans puis avec distraction.
- 16,8 → 19,9 s
- Retard de contrôle moyen.
- ≈ 3 / h
- Accrochages, volontairement au-dessus du réel. Option désactivée : banc identique au bit près.

Météo : pluie, brouillard et nuit agissent sur les paramètres de tous les conducteurs, en plus de leur profil. Pluie : adhérence × 0,7, vitesses × 0,92, écarts × 1,15, accélération × 0,9, freinage confortable × 0,85. Brouillard : visibilité 30 m. Nuit : visibilité 80 m. L’adhérence borne tous les freinages (urgence, zone de dilemme, véhicule du joueur), et la vitesse souhaitée est plafonnée pour pouvoir s’arrêter dans la visibilité : Tr·v + v² / 2b ≤ visibilité, soit 40 km/h au plus dans le brouillard. Par beau temps de jour, tous les facteurs valent 1 et le banc est inchangé au bit près.

Événements : travaux (20 km/h sur 32 m), fermeture et accident, programmés par tronçon avec heure de début et durée. Chaque événement modifie le coût du tronçon dans le calcul d’itinéraires partagé avec le GPS : infini pour une fermeture, temps perdu pour des travaux, pénalité de 90 s pour un accident. À chaque début et fin d’événement, les temps restants sont recalculés ; les conducteurs qui n’ont pas encore réservé leur prochain carrefour choisissent à nouveau leur branche, et ceux dont la sortie devient inatteignable en changent. Les reports de trafic découlent de ces seuls coûts.

Log 08 / 10
Architecture et données
Moteur sans état global, formats JSON versionnés, tronçons courbes.
Le moteur (src/sim/) est du JavaScript pur, sans three.js ni DOM : il tourne sous Node pour le banc et les figures, et dans le navigateur pour l’application. Son état est regroupé dans un objet monde créé par createWorld() : réglages, réseau, trafic, capteurs, coordination des feux, événements, météo. Les modules sont des fabriques qui reçoivent un monde et en lisent les parties sous leurs noms habituels ; le code des fonctions n’a pas changé. Le rendu et l’interface lisent le monde de l’application via src/world.js. La refonte conserve les empreintes des 18 scénarios et les figures octet pour octet.
Format de réseau : fichier JSON de nœuds (position en mètres ; régime et axe prioritaire pour un carrefour, rien pour une extrémité) et de rues (nom, vitesse limite, suite de nœuds). Le moteur en dérive les tronçons (un par sens, raccourcis de 6 m pour la ligne d’arrêt), les courbes de virage, les entrées, les sorties et les tables de temps restants. Le format de scénario ajoute réglages, plans de feux, pondération des entrées et sorties, et événements. Le chargeur reproduit l’ordre de création de l’ancienne grille codée en dur : même numérotation, mêmes tirages, empreintes identiques.
{
"format": "trafic-scenario",
"version": 1,
"network": "boulevard",
"settings": { "preset": "mixed", "control": "fixed", "coord": "plan", "rate": 24 },
"plans": {
"J1": { "green": [35, 16], "offset": 0 },
"J2": { "green": [35, 16], "offset": 5 },
"J3": { "green": [35, 16], "offset": 10 },
"J4": { "green": [35, 16], "offset": 15 }
},
"demand": { "entries": { "O": 4, "E": 4 }, "exits": { "O": 8, "E": 8 } }
}Réseau de test : boulevard est-ouest de 252 m à quatre feux, plan à décalages de 5 s (onde à 43 km/h). Vers l’est, bande verte de 36 s par cycle et 42 % de trajets sans arrêt ; vers l’ouest, 6 s et 5 %.
Validation : les deux formats sont versionnés ; npm run datas vérifie un fichier avant toute construction et liste toutes ses erreurs, une par faute, y compris ce que la version du moteur ne sait pas encore rouler.
✗ casse.json
Réseau « Réseau cassé » : 9 erreurs
- rue « rue haute » : nœud inconnu « X9 »
- rue « rue basse » : vitesse limite 200 hors de 10 à 130 km/h
- rue « rue basse », de J1 à J2 : ce tronçon existe déjà
- rue « impasse », de J1 à J3 : 8 m entre lignes d’arrêt, il en faut au moins 20
- il faut au moins deux extrémités, pour entrer et sortir (1 trouvée)Tronçons courbes (format v2) : des points de forme, raccordés par des arcs de cercle tangents aux deux segments, au rayon indiqué. Les véhicules restent repérés par leur abscisse curviligne s : distances, files, boucles et zones de travaux sont inchangées, seule la conversion s → position change (inverse précise à 3 × 10⁻¹⁴ m, utilisée pour le véhicule du joueur). Les quelque vingt lectures de « direction du tronçon » distinguent désormais direction d’arrivée et de départ. Vitesse de confort √(2,5 R), visée 1 s avant l’entrée du virage pour compenser le retard de l’IDM à rejoindre sa vitesse souhaitée ; le temps perdu en virage entre dans les coûts d’itinéraire et sort du retard de contrôle.
Log 09 / 10
Rendu
three.js r128 : interpolation, feux des véhicules, asphalte procédural.
Le rendu lit l’état de la simulation sans le modifier. Véhicules en InstancedMesh ; position et cap interpolés entre les deux derniers pas, avec un pas (33 ms) de latence, pour un mouvement fluide à 60 Hz et plus. Feux stop au freinage, clignotants 40 m avant le virage (intention portée par la simulation), feux de détresse ; la nuit, phares avec faisceau au sol, feux de position et halos à l’échelle métrique. Les ombres des bâtiments portent sur les véhicules.


Asphalte : le sol est une texture canvas de 2 048 px pour 256 m (8 px/m, 28 px par voie), insuffisante à hauteur d’œil ; il faudrait 256 px/m pour le grain d’un enrobé. Une tuile de 4 m (1 024 px) répétée 64 fois par direction apporte ce grain. Elle sort d’un graphe procédural MaterialCraft (liant, gravillons de 1 à 2 cm, gros gravillons, ondulation et usure), périodique par construction : chaque générateur a une échelle entière sur la tuile. Elle ne contient aucun motif identifiable, pour que la répétition ne se voie pas.
Fig. 35 · basecolor
Fig. 36 · normalTuile de 4 m, couleur et normales, exportées du graphe (asphalte.mcraft, 2 ko).
Shader du sol : l’asphalte n’est appliqué que sur l’enrobé nu, détecté par la distance à sa couleur dans le canvas (fondu entre 0,03 et 0,08), si bien que les marquages restent intacts. La tuile module la couleur au lieu de la remplacer : couleur × tuile / moyenne de la tuile, la moyenne étant lue dans le dernier niveau de mipmap ; de loin, la teinte d’origine est conservée. La carte de normales est lue en coordonnées de tuile en remplaçant le bloc normal_fragment_maps de three.js, avec un avertissement console si le bloc visé change. Le sol passe de Lambert (éclairage aux sommets) à Phong sans spéculaire (éclairage par pixel). Coût : trois lectures de texture de plus par pixel du sol.


Log 10 / 10
Feuille de route
28 fonctionnalités faites sur 50 ; palier 1 terminé, palier 2 jusqu’au n° 28.
Cinquante fonctionnalités en quatre paliers, classées par taille (S à XL) puis par valeur, dépendances respectées. L’application lit ROADMAP.md et affiche l’avancement sur sa page #roadmap : fait, en cours, prêt à démarrer.

Suite du palier 2 : enregistrement et replay à partir de la graine et des entrées (n° 29), état en tableaux typés lus sans copie par le rendu (n° 30), simulation dans un Web Worker (n° 31). Principaux chantiers du palier 3 :
- 01
#32 Zones de conflit
Points de conflit par paire de trajectoires ; réservation des seuls points traversés au lieu du carrefour entier.
- 02
#33 Joueur dans le trafic
Les IA perçoivent le véhicule du joueur, ses clignotants et ses insertions ; le joueur réserve les carrefours comme elles.
- 03
#34–37 Voies multiples
Plusieurs voies par sens avec mouvements autorisés, changements de voie MOBIL, placement anticipé selon l’itinéraire, insertions et fermeture éclair.
- 04
#38 Calibration
Ajustement sur comptages et temps de parcours réels, comparaison avec SUMO sur les mêmes scénarios.
Puis : carrefours à branches et angles quelconques, plans de feux multi-phases (NEMA), affectation dynamique jusqu’à l’équilibre de Wardrop, cinématique à braquage pour les IA, stationnement, transports en commun, cyclistes, éditeur de réseau, giratoires, véhicules d’urgence. Palier 4 : import OpenStreetMap (un extrait d’environ 1,65 × 1 km près de Nagoya est déjà dans le dépôt) et piétons selon un modèle de forces sociales (Helbing et Molnár, 1995).
- Projet
- Personnel, en cours
- Version
- Prototype 0.1, n° 28, 5 novembre 2026
- Modèles
- IDM · HDM · HCM · Webster · Max-pressure · HBEFA3
- Émissions
- Coefficients HBEFA3 repris de SUMO (© DLR, EPL 2.0)
- JavaScript
- three.js r128
- GLSL
- Vite
- Node
- playwright-core
- SVG
- JSON
- MaterialCraft
