Traduction automatique, non relue par un locuteur natif. L'anglais fait foi.

Compliance et test benchModifier sur GitHubSource : docs/TEST-BENCH.md

Faire fonctionner un récepteur sur un scénario exporté

Un fabricant de récepteurs qui possède un simulateur GNSS de laboratoire peut y rejouer le mouvement du véhicule d'un scénario Kshana, enregistrer ce que fait le récepteur soumis à l'essai, et noter ce journal avec kshana receiver-trust par rapport à des événements énoncés avant l'exécution. Kshana fournit le mouvement, les instants des événements et la notation. Il n'écrit aucun signal : rien de ce qui est exporté ici ne synthétise, ne modélise ni ne transmet de forme d'onde radiofréquence ou en bande de base, et un événement exporté est un intervalle de temps étiqueté, et non une recette pour produire des interférences. Le simulateur et son opérateur fournissent les signaux, et l'opérateur est responsable de ne les exécuter que là où c'est autorisé (en conduit ou blindé, selon les consignes de sécurité propres au simulateur).

Cette page est une méthode. Elle ne publie aucun résultat.

1. Exporter#

kshana bench-export scenarios/gnss-ins.toml --out run1 --epoch 2025-03-01T10:00:00Z

S'applique au type de scénario gnss-ins (un profil de conduite avec attitude ; les coupures de l'état de navigation sont les événements), et à jamming et gnss-sim (un récepteur immobile pendant la durée du scénario ; le brouilleur d'un scénario jamming est un seul événement sur toute l'exécution). Les autres types de scénario disent pourquoi ils n'ont pas de trajectoire de véhicule. --epoch est l'instant UTC du temps de mouvement zéro (par défaut 2024-01-01T00:00:00Z) ; les scénarios ne portent aucune date calendaire propre pour le mouvement du véhicule. Ce doit être un véritable instant UTC, YYYY-MM-DDTHH:MM:SS (un Z final est accepté), avec l'année entre 2000 et 2099 et chaque champ dans sa plage ; tout le reste est refusé. La sortie est identique octet pour octet pour le même scénario et la même époque.

Fichier Contenu
run1.motion.csv une ligne par échantillon : time_s, x_m,y_m,z_m dans le repère terrestre, vx_m_s,vy_m_s,vz_m_s, lat_deg,lon_deg,h_m géodésiques, heading_deg,pitch_deg,roll_deg, utc, kshana_row
run1.motion.json l'époque, les référentiels, les unités, les colonnes et les tolérances d'aller-retour de ce CSV
run1.nmea NMEA 0183 phrases GGA et RMC par échantillon, avec sommes de contrôle
run1.waypoints.txt une ligne RESOLUTION: <ms> puis des lignes longitude,latitude,altitude (écrit seulement lorsque tous les intervalles d'échantillonnage sont un même nombre entier de millisecondes ; en cas d'omission, la commande en donne la raison sur l'erreur standard)
run1.events.csv label,kind,onset_s,end_s,description
run1.events.toml les mêmes événements sous forme de blocs [[events]] pour un scénario receiver-trust
run1.conditions.json l'exécution sous forme de document kshana.test-conditions/1 pour un enregistrement receiver-log : les événements comme vérité déclarée, avec recording.path, recording.sha256, receiver.*, le type de chaque événement et la puissance laissés au laboratoire à renseigner

Référentiels et conventions#

  • Position : WGS 84, repère terrestre (ECEF : x à travers l'équateur au méridien d'origine, z à travers le pôle) ; lat_deg, lon_deg, h_m donnent la même position en coordonnées géodésiques, h_m au-dessus de l'ellipsoïde.
  • Vitesse : axes liés à la Terre, relative à la Terre.
  • Attitude: heading_deg dans le sens horaire à partir du nord vrai dans [0, 360), pitch_deg positif nez vers le haut, roll_deg positif aile droite vers le bas ; lacet-tangage-roulis (3-2-1) du repère local nord-est-bas vers les axes du corps x vers l'avant, y vers la droite, z vers le bas. Une source immobile écrit des zéros. NMEA et le texte des points de passage ne portent aucune attitude.
  • Le cap est le lacet du corps, et non la direction de déplacement. Dans le profil de conduite gnss-ins, le corps tourne en lacet par créneaux tandis que la vitesse suit, de sorte que le cap et la route sur le fond peuvent différer de dizaines de degrés (jusqu'à environ 77 degrés dans le scénario automotive-urban-canyon fourni). La route NMEA RMC est la route sur le fond, la direction du vecteur vitesse ; un simulateur qui lit le cap dans le fichier de mouvement et un autre qui lit la route dans le fichier NMEA voient donc des angles différents. La route sur le fond issue du CSV est atan2(v_east, v_north) de sa vitesse tournée vers le nord-est-bas.
  • La hauteur suit le scénario. Pour gnss-ins, h_m est le pas de plan tangent propre au type de scénario, appliqué à sa vérité terrain, et n'est pas maintenu constant (environ 7 m sur les 180 s de automotive-urban-canyon) ; c'est le mouvement du scénario, écrit tel quel.
  • Valeurs de remplissage NMEA GGA. La qualité de la position (1), les satellites utilisés (12) et le HDOP (1,0) ne sont écrits que pour que la phrase soit bien formée. Ils ne disent rien de la géométrie du scénario ni d'un état quelconque du récepteur.
  • Time: time_s après l'époque, UTC, secondes intercalaires non modélisées.
  • Les hauteurs NMEA sont ellipsoïdales. L'altitude GGA contient la hauteur ellipsoïdale et la séparation du géoïde est écrite comme 0,0. Un simulateur qui traite l'altitude comme une hauteur au-dessus du niveau moyen de la mer placera le véhicule à côté, de l'ondulation locale du géoïde.
  • Tolérances d'aller-retour (testées en relisant chaque fichier) : position CSV 0,1 mm, latitude et longitude 1e-9 degré, vitesse 0,1 mm/s, angles 1e-6 degré ; NMEA position horizontale 5 mm, hauteur 1 mm, vitesse 0,001 nœud, route 0,001 degré.

Charger les fichiers dans un simulateur#

Les simulateurs de laboratoire diffèrent, et ce dépôt ne reproduit le manuel d'aucun simulateur. Vérifiez lequel des formats ci-dessus le vôtre lit, et ses exigences déclarées :

  • De nombreux importateurs de mouvement attendent une cadence de mise à jour fixe, couramment 10 Hz. Le scénario gnss-ins avance par pas de 0,1 s ; pour un scénario immobile, réglez [time] step_s sur la cadence que veut votre simulateur.
  • Certains importateurs sautent les échantillons situés entre des secondes entières, ou ignorent la colonne de temps et utilisent l'ordre des lignes. Démarrez le mouvement à une seconde entière et gardez la grille régulière.
  • Un importateur CSV qui permet d'associer les colonnes peut lire run1.motion.csv directement : choisissez les colonnes du repère terrestre ou géodésiques et réglez leurs unités d'après run1.motion.json. Tronquer les décimales produit de fausses accélérations ; conservez donc la précision écrite.
  • Le fichier ne contient que le mouvement. Configurez la constellation, l'interférence et le frontal du récepteur dans le simulateur, et calez-les sur les événements de run1.events.csv.

Kshana n'écrit aucune interface de script propre à un fournisseur.

Vérifié avec les lecteurs d'un simulateur libre

Les lecteurs de mouvement de gps-sdr-sim (MIT, commit 28ca29a6) ont reçu les exports de huit scénarios fournis. Chaque lecteur a restitué la trajectoire exportée (tests/testbench_gpssdrsim_oracle.rs, préenregistré dans xval/testbench-gpssdrsim/PREREGISTRATION.md) :

option de gps-sdr-sim Lui donner Pire écart par rapport au CSV
-g (NMEA GGA) run1.nmea tel qu'écrit 1,2 mm
-x (temps, latitude, longitude, hauteur) tail -n +2 run1.motion.csv | cut -d, -f1,8,9,10 0,15 mm
-u (temps, x, y, z) tail -n +2 run1.motion.csv | cut -d, -f1-4 exact
  • Ne donnez pas à -u le CSV de mouvement complet. Son lecteur retient 100 caractères par ligne, et une ligne de CSV compte environ 160 caractères ; chaque ligne est donc lue comme deux échantillons. La ligne d'en-tête est lue comme un échantillon de plus sans aucun nombre.
  • gps-sdr-sim retient au plus 3000 échantillons, soit 300 s à sa cadence fixe de 10 Hz, et ignore la colonne de temps. Les exports de gnss-ins avancent par pas d'exactement 0,1 s. Les scénarios plus longs, tels que gnss-ins-maritime de 20 minutes, ne sont lus que sur leurs 300 premières secondes.
  • Cela vérifie que les fichiers sont lus tels qu'écrits. Cela ne vérifie ni la physique du scénario ni rien de ce que le simulateur transmet.

2. Énoncer ce que vous noterez avant l'exécution#

Le fichier d'événements donne les intervalles que définit le scénario. Copiez run1.events.toml dans un scénario receiver-trust, ajoutez toute prédiction que vous voulez voir vérifiée, et fixez les seuils des moniteurs et les tolérances avant que le récepteur ne s'exécute. Ne les ajustez pas après avoir vu le journal ; le scénario, les seuils et le SHA-256 du journal figurent tous dans le hachage du résultat.

kind = "receiver-trust"
name = "bench session 1"

[log]
format = "ubx"                 # ubx, rinex, android or nmea
path = "receiver-log.ubx"

[monitors]
calibration_s = 60.0

# paste run1.events.toml here, and shift onsets by the log offset (step 4)
[[events]]
label = "gnss-denied-1"
kind = "other"
onset_s = 100.0
end_s = 160.0

Les événements exportés portent le type propre au scénario : le brouilleur d'un scénario jamming est jamming ; une coupure de l'état de navigation est other, parce que le scénario énonce que le GNSS était indisponible, et non comment. Modifiez kind pour qu'il corresponde à ce que vous configurez le simulateur pour faire.

3. Exécuter le récepteur#

Démarrez le récepteur et son enregistreur, démarrez le scénario du simulateur avec le fichier de mouvement, et laissez l'exécution couvrir l'intervalle d'étalonnage, chaque événement, et une marge après le dernier. Conservez le journal propre au récepteur (UBX, observations RINEX 3, un CSV d'enregistreur Android, ou NMEA avec des phrases d'état des satellites). Un journal sans puissance de signal par satellite peut quand même être noté sur la position propre du récepteur, mais les moniteurs de rapport porteuse sur bruit en ont besoin.

4. Aligner les horloges#

receiver-trust compte les instants des événements à partir de la première époque du journal du récepteur ; le fichier de mouvement compte à partir de son premier échantillon. Si le journal démarre d secondes avant le premier échantillon du mouvement, ajoutez d à chaque onset_s et end_s. Consignez le décalage et la manière dont vous l'avez mesuré, et énoncez-le dans le name du scénario ou dans un commentaire, car un mauvais décalage déplace chaque note. Les instants des événements seuls ne peuvent pas vous donner le décalage ; utilisez le marqueur de début de scénario du simulateur ou les horodatages propres du récepteur.

5. Noter#

kshana receiver-trust bench-session.toml

écrit bench-session.result.json, .trust.csv et .trust.svg. Pour chaque événement, le résultat donne les fausses alarmes avant le début, la première alarme et ses moniteurs, la latence, et l'issue (detected, late, missed, not-evaluable), plus une baisse prédite et observée du rapport porteuse sur bruit lorsque vous avez énoncé une prédiction. Un désaccord est rapporté, jamais corrigé en ajustant. Voir RECEIVER-TRUST.md.

Pour voir en faveur de quelles lignes de cadres publics la session apporte des éléments de preuve :

kshana compliance-report bench-session.result.json

Voir compliance/README.md. Ce rapport décrit les preuves contenues dans les exécutions que vous lui donnez ; il ne conclut rien sur le récepteur ni sur un cadre quelconque.

Après la notation, kshana evidence round-trip relie les quatre enregistrements : le scénario que vous avez exporté, les conditions d'essai du laboratoire, le journal du récepteur et la note. Renseignez run1.conditions.json (le chemin et le SHA-256 du journal, le récepteur soumis à l'essai, le type et la puissance déclarée de chaque événement), puis :

kshana evidence keygen --out lab.key
kshana evidence round-trip bench-session.toml --scenario scenarios/gnss-ins.toml \
    --conditions run1.conditions.json --from 0 --to 180 --key lab.key --out round-trip-pack
kshana evidence verify round-trip-pack --pubkey <signer public key>

round-trip-pack/config.json porte un bloc round_trip (kshana.round-trip/1) avec scenario_sha256, conditions_hash, log_sha256, et la note (événements détectés parmi les événements évaluables, première alarme), couvert par les hachages du manifeste et par la signature. La commande refuse un paquet dont les conditions et les événements de notation sont en désaccord, ou dont le hachage de journal déclaré n'est pas celui du journal. Comme tout paquet de preuves, c'est un enregistrement technique, et non un avis juridique.

Exemple détaillé : gps-sdr-sim écrivant un fichier#

Cet exemple utilise le simulateur libre gps-sdr-sim uniquement pour écrire un fichier en bande de base à partir du mouvement exporté. Kshana ne transmet rien, et rien dans cette page n'automatise la lecture de ce fichier par une radio. Si votre laboratoire joue un tel fichier dans un récepteur, cela relève de la responsabilité de votre opérateur, et ne se fait que là où c'est autorisé (en câblé ou blindé, en suivant les consignes de sécurité du simulateur et de la radio), et Kshana ne le documente ni ne l'enveloppe.

kshana bench-export scenarios/gnss-ins.toml --out run1 --epoch 2025-03-01T10:00:00Z
tail -n +2 run1.motion.csv | cut -d, -f1-4 > run1.xyz          # time, x, y, z (see above)
gps-sdr-sim -e brdc0600.25n -u run1.xyz -b 8 -o run1.iq        # writes a file, nothing else

Tout ce que le laboratoire fait ensuite de run1.iq se passe en dehors de Kshana. Le journal propre du récepteur, quelle que soit la façon dont il est obtenu, est ce que l'étape 5 note et ce que l'étape 6 relie. Les fichiers et les contrôles que Kshana fait sur ses propres exports sont testés sur des données synthétiques seulement (tests/round_trip_pack.rs) ; aucune exécution de laboratoire n'est revendiquée ici.

Ce que cette méthode ne fait pas#

  • Elle ne produit pas de signal, et elle ne dit pas quelle interférence un simulateur doit générer. Les événements disent quand, non quoi.
  • Une seule session est un seul point de données. Le résultat décrit ce journal sous cette configuration, et ne dit rien d'autres récepteurs, micrologiciels, antennes, ni d'interférences réelles.
  • Les hauteurs, les cadences et l'alignement temporel sont à vérifier par l'opérateur par rapport au simulateur ; l'export énonce ses propres conventions et tolérances, et rien de plus.