# Vérification — Le solveur balistique 3-DOF Fiche de traçabilité de `BallisticsGuide/src/CompetitionBallistics.js` (943 lignes), le solveur qui alimente le [calculateur balistique](https://www.tireur.org/calculateur-balistique.php) et les [outils de balistique](https://www.tireur.org/techniques/balistique/outils.php). Voir [[verification:start|la méthode]]. **Pourquoi ce code passe avant le reste.** Il ne s'agit pas d'une page de plus : c'est l'**arbitre**. Plusieurs fiches de cette passe — [[verification:technique:tir_en_pente|tir en pente]], [[verification:technique:rayon_moyen_dispersion|mesure d'un groupement]], le dossier balistique intérieure — appuient leurs conclusions sur ses sorties. Un solveur faux ferait certifier des erreurs par des fiches qui se croient rigoureuses. Il était donc contrôlé partout, et vérifié nulle part. Le solveur est un **point-masse à 3 degrés de liberté**. Le passage à 6-DOF, dont le code Julia existe, est un chantier distinct ; cette fiche porte sur la version en service. ## Ce qui a été fait Cinq contrôles indépendants, choisis pour ne pas dépendre les uns des autres : * **intégration de référence réécrite** d'après le manuel, avec la même table de traînée, pour confronter les deux résultats ; * **boucle fermée** sur le coefficient balistique : injecter un CB, produire une trajectoire, en réextraire le CB ; * **cas analytiques** : atmosphère normalisée, densité, vitesse du son, pression barométrique ; * **convergence** sur le pas d'intégration, puis distinction entre erreur d'intégration et artefact d'échantillonnage ; * **grandeurs dérivées** confrontées aux pages du wiki qui les publient. ## L'erreur trouvée : le calculateur public de CB rendait n'importe quoi `bcFromTwoChronographs()` déduit un coefficient balistique de deux vitesses mesurées à deux distances. Elle est **exposée aux utilisateurs** par la page d'outils. Elle appliquait la relation $$\frac{1}{v_2} - \frac{1}{v_1} = k\,t$$ qui est l'intégration de la traînée en $v^2$ **contre le temps** — en lui passant une **distance**. Or contre la distance, la relation est logarithmique : $$\ln\frac{v_1}{v_2} = k\,x$$ Le résultat était faux de cinq ordres de grandeur. Boucle fermée sur trois valeurs, avant correction : | CB injecté | CB rendu | | :---: | :---: | | $0{,}180$ | $68\,474$ | | $0{,}243$ | $96\,375$ | | $0{,}320$ | $130\,359$ | Après correction — forme logarithmique, constante d'unités explicitée, et suppression d'une renormalisation par $\rho_0$ qui n'avait pas lieu d'être puisque la densité de la mesure est déjà dans le calcul : | CB injecté | CB rendu | Écart | | :---: | :---: | :---: | | $0{,}180$ | $0{,}179$ | −0,8 % | | $0{,}243$ | $0{,}242$ | −0,4 % | | $0{,}320$ | $0{,}319$ | −0,2 % | | $0{,}500$ | $0{,}500$ | −0,0 % | Le résidu est celui qu'on attend d'une méthode qui prend le $C_d$ à la vitesse moyenne de l'intervalle : il décroît quand la perte de vitesse diminue. Le texte de l'outil a suivi : il annonçait une valeur « ramenée aux conditions standards ICAO », ce qui n'est plus — ni nécessaire. ## Le facteur qui ressemblait à un bug et n'en est pas La chaîne de traînée porte un `* (4.0 / Math.PI)` qui multiplie l'aire frontale $\pi d^2/4$ pour rendre $d^2$. Au premier regard, c'est 27 % de traînée en trop, les tables BRL référençant bien $C_d$ à l'aire frontale. **C'est pourtant correct**, et le test l'établit sans ambiguïté. La densité sectionnelle du monde du tir se définit sur $d^2$, non sur l'aire frontale — $SD = m/d^2$, en lb/in². Comme le facteur de forme vaut $i = SD/CB$, la surface qui doit apparaître dans l'équation de traînée est **celle qui a servi à définir $SD$**, soit $d^2$. Le `4/π` réalise exactement cet appariement. L'intégration écrite d'après la formule naïve — celle qui garde $\pi d^2/4$ — donne une .308 de 175 gr, $G7 = 0{,}243$, arrivant à 1000 yards à **1 462 fps** au lieu de 1 153. Une .308 transsonique à cette distance ne vole pas à 1 462 fps ; c'est la version « naïve » qui est fausse. Le code ne portait aucun commentaire sur ce point. Il en porte un désormais, avec le contre-exemple chiffré — cette ligne est un piège pour quiconque voudra « simplifier ». ## Ressorti intact | Contrôle | Résultat | | :--- | :--- | | Densité de l'air, atmosphère normalisée | $1{,}2250$ kg/m³ — exact | | Vitesse du son à 15 °C | $340{,}29$ m/s — exact | | Pression barométrique à 0 et 5 000 m | $101\,325$ et $54\,020$ Pa — exact | | Recherche du zéro (100, 300, 600 yd) | écart à la ligne de visée $\le 0{,}19$ mm | | Facteur de stabilité de Miller, .308 175 gr en 1:10 | $2{,}40$ — identique à [[technique:stabilite_gyroscopique|la page wiki]] | | Densité sectionnelle .308 175 gr | $0{,}2635$ — valeur publiée | | Facteur de forme quand $CB = SD$ | exactement 1 | | Convergence RK4 | stable ; le résidu observé n'est pas de l'intégration (voir ci-dessous) | | Effet Eötvös | signe correct — haut vers l'est, bas vers l'ouest | **Les quatre chiffres publiés dans [[technique:tir_en_pente|le tir en pente]] ont été recalculés** avec un banc durci : 3,86 / 3,04 / 3,22 / 3,34 MRAD, identiques au centième. Ce qui a été certifié cette semaine sur la foi de ce solveur tient. ## Deux réserves, sans conséquence pratique mais à connaître **Les points de report ne sont pas interpolés.** Le solveur retourne les pas d'intégration bruts ; `trajectoryTable()` prend le premier pas atteignant la distance voulue, sans interpoler entre les deux qui l'encadrent. À 800 m/s et $dt = 5\times10^{-4}$, cela fait jusqu'à 40 cm d'erreur de distance, soit quelques millimètres de chute à 500 m. Négligeable pour le tireur, mais c'est cela — et non l'erreur d'intégration — qu'on mesure en croyant tester la convergence : le déficit de distance suit exactement le pas. **Le solveur s'arrête à la distance demandée**, sans le signaler. Interroger la trajectoire au-delà rend silencieusement le dernier point calculé. Ce n'est pas un défaut du code — mais tout banc de test doit vérifier que le point obtenu atteint bien la distance visée, faute de quoi il compare des trajectoires tronquées en croyant faire varier un paramètre. C'est arrivé pendant cet audit, et cela a d'abord ressemblé à un bug du solveur. ## Ce qui n'a pas été vérifié * **La dérive gyroscopique** n'est pas reproductible à partir des données publiées : le portail annonce « ≈ 31 cm à 1 000 m » pour une .308 en 1:10 sans préciser la balle ni la vitesse. Le solveur donne 29 à 43 cm selon le projectile — et 31 cm correspond bien mieux à **1 000 yards** qu'à 1 000 mètres. La formule empirique de Litz n'a pas pu être confrontée à sa source, et la vignette n'a **pas** été corrigée faute de savoir laquelle des deux valeurs elle visait. * **Les tables de traînée BRL** ont été contrôlées sur six points de repère par modèle, pas dépouillées intégralement. Les valeurs vues sont les valeurs canoniques. * **Le saut aérodynamique et la dérive gyroscopique** sont ajoutés a posteriori, hors intégration. C'est la limite structurelle d'un point-masse, assumée par le code ; elle disparaîtra avec le passage au 6-DOF. * **Aucune confrontation à un solveur tiers** n'a été faite. Le manuel du site invoque JBM comme référence de validation ; cette validation-là n'a pas été rejouée ici.