Référence
Format de projet (YAML)
Un projet est un seul fichier YAML, éventuellement découpé avec includes:. Les chemins sont relatifs au fichier de projet. Le schéma JSON (arnodiqa schema, également fourni dans docs/arnodiqa.schema.json) apporte l'autocomplétion et la validation dans VS Code grâce à la première ligne du fichier. Voici le projet de démonstration tel qu'il est livré :
# yaml-language-server: $schema=../../docs/arnodiqa.schema.json # # Arnodiqa demo project: two virtual CAN channels with a remaining bus # simulation built from the databases (every database node runs the CAN # interaction layer), so it runs without hardware: # # arnodiqa run examples/demo/demo.yaml --simulated --duration 10s # version: 21 name: Demo description: PowerTrain (CAN FD) and Comfort (CAN) on virtual networks. includes:2 system_variables: sysvars.yaml networks:3 - name: PowerTrain channel: 1 bus: can_fd4 bitrate: 500000 data_bitrate: 2000000 hardware:5 virtual: network: vcan1 databases:6 - powertrain.dbc - name: Comfort channel: 2 bitrate: 500000 hardware: virtual: network: vcan2 databases: - comfort.dbc measurement:7 working_mode: simulated_bus duration: 10s measurement_setup:8 blocks: - logging: id: Logging file: logs/{ConfigName}_{MeasurementIndex}.blf9 - filter: id: PowerTrainOnly action: pass rules: - channels: [1] # Fires on the first EngineData frame with EngineSpeed = 800 rpm (the # database start value); later ones are ignored while the block is open. - trigger: id: HighRpm input: PowerTrainOnly10 mode: single pre_trigger: 50ms11 post_trigger: 200ms conditions: - event: signal: message: EngineData signal: EngineSpeed op: '==' value: 800 max_triggers: 1 - logging: id: HighRpmLog input: HighRpm file: logs/high_rpm_{IncMeasurement}.asc - view: id: Trace kind: trace - view: id: Statistics kind: statistics simulation:12 # All nodes of both databases become IL nodes. To test a real ECU, list it # under `exclude` (e.g. `exclude: [ECM]`) and connect the hardware. restbus: il: counters: - message: EngineData signal: AliveCounter
versionindique la version du format (actuellement 2). Les projets plus anciens sont migrés automatiquement, les plus récents sont refusés avec un message d'erreur.includesplace une section (ici les variables système) dans un fichier distinct, ce qui réduit les conflits de fusion au sein d'une équipe.networksdéfinit un réseau par canal applicatif (channel: 1= CAN1), avec son nom et son débit.bus: can_fds'accompagne dedata_bitrate. Les champssample_point,fd_mode: iso|non_isoetlisten_onlysont facultatifs.hardwaredéfinit l'affectation du canal :virtual(réseau virtuel nommé), une forme propre au back-end telle quepcan,vector,kvaser,socketcan,slcanougs_usb(voirarnodiqa hw list), ou la forme génériquedevice. En mode bus simulé, tous les réseaux sont virtuels, quelle que soit l'affectation.databasesliste les fichiers DBC utilisés pour le décodage, les déclencheurs sur valeurs de signaux et la couche d'interaction.measurementregroupemode: online|offline,working_mode: real_bus|simulated_bus,duration, le tri des événements, les sources hors ligne et la cadence de relecture (pacing).measurement_setup.blocksdécrit le flux de données d'analyse ; voir Measurement Setup.- Les noms de fichiers peuvent contenir des field codes. Un bloc sans
inputest rattaché àsource(tous les événements). inputenchaîne les blocs, ou en fusionne plusieurs lorsqu'il contient une liste d'identifiants.- Les durées s'écrivent
50ms,1.5s,2min(unités ns, us, ms, s, min, h, d). simulation.restbusconfigure la simulation de bus résiduel. Chaque nœud des bases de données devient un nœud de la couche d'interaction, qui émet ses messages selon les types d'envoi et les temps de cycle définis dans le DBC.exclude: [ECM]retire un nœud afin de tester un calculateur réel ;il.countersdéfinit les compteurs de vie. S'y ajoutentsimulation.nodespour des nœuds individuels, par exemple un programme CAPL (kind: capl,file: capl/gateway.can), et les blocs replay. Les panneaux sont déclarés souspanels:sous forme de fichiers YAML.
Types de valeurs
| Type | Notation |
|---|---|
| TimeSpan | 250ms, 1.5s, 10s, 2min; nombre seul = millisecondes |
| FrameId | "0x123" (standard), "0x18FEF100x" (étendu), ou un entier (étendu si > 0x7FF) |
| Types SysVar | int32 uint32 int64 uint64 float string data int_array float_array |
Measurement Setup
Le Measurement Setup est un arbre (DAG) de blocs fonctionnels dont la racine est la source de mesure (source). Les branches s'exécutent en parallèle. Un bloc à plusieurs entrées les fusionne dans l'ordre chronologique et ne transmet qu'une seule fois un événement arrivé par deux branches. Voici le projet de démonstration sous forme de graphe :
Types de blocs
| Bloc | Rôle | Champs principaux |
|---|---|---|
filter | Filtre pass ou stop. Un événement correspond dès qu'une règle correspond (OU) ; au sein d'une règle, tous les critères doivent correspondre (ET). Désactivé, le filtre laisse tout passer. | action: pass|stop, rules: [{channels, ids, id_ranges, messages, directions, event_types, signal}], enabled |
trigger | Ne laisse passer les données qu'autour des instants de déclenchement, avec pré-déclenchement et post-déclenchement. | mode: single|toggle|entire_measurement, conditions (start, stop, event, sysvar), pre_trigger, post_trigger, max_triggers, retrigger: ignore|extend, stop_measurement, buffer_size |
logging | Écrit en BLF ou ASC dans son propre thread ; peut contenir son propre déclencheur. | file (field codes), format: blf|asc, compression 0-9, asc_decimals: 6|9, max_file_size, max_file_duration, log_sysvars, trigger, queue_capacity |
view | Sortie vers une fenêtre ; transmet exactement ce que la fenêtre reçoit. | kind: trace|data|graphics|statistics |
break | Bloque tout ce qui se trouve en aval (pour désactiver temporairement une branche). | id, input |
Tous les blocs ont id, input (source par défaut, ou une liste pour fusionner) et comment.
Field codes
Les noms de fichiers des blocs de journalisation acceptent les field codes suivants :
{MeasurementStart} {MeasurementIndex} {IncMeasurement} {IncTrigger} {IncSize} {IncTime} {LoggingBlock} {ConfigName} {TriggerCondition} {@NS::Var}.
Surcharge
En temps réel, la mesure n'attend jamais. Les files pleines sont comptabilisées (mainQueueDropped, lost) et donnent le code de sortie 5. En mode simulé ou hors ligne (« as fast as possible »), les producteurs attendent et rien n'est perdu. Les abonnements de l'interface abandonnent toujours les événements les plus anciens, avec un compteur.
Architecture
Le diagramme figure dans Fonctionnement. En résumé, le produit se compose de crates Rust (bf-core, bf-hw, bf-db, bf-log, bf-project, bf-engine, bf-cli, bf-diag, bf-test, la machine virtuelle de script) et d'une application Tauri/React qui communique avec le moteur uniquement via la façade Session.
Contrat IPC (interface ↔ moteur)
| Commande | Résultat |
|---|---|
load_project(path) | ProjectInfo (networks, messages + signals, blocks) |
start_measurement / stop_measurement | () / MeasurementReport |
measurement_status | state, time, load 0..1, stopRequested |
pause / resume / step(size) | bus simulé et hors ligne |
transmit(req) | Interactive Generator: channel, id, data, fd, brs |
subscribe_events(tap, interval, capacity) | lots binaires toutes les 16 à 33 ms, drop-oldest avec compteur |
statistics / block_statistics(id) | StatisticsSnapshot |
sysvars / set_sysvar | SysVarInfo[] / bool |
messages / subscribe_messages | messages pour la fenêtre Write |
Les champs JSON sont en camelCase, les temps sont exprimés en nanosecondes depuis le début de la mesure (i64) et les identifiants CAN sont des chaînes ("0x123", "0x18FEF100x").