Related: 15_services.md | 03_signal_backplane.md | 04_lifecycle.md
1. Recording Format
The .icarec format captures all simulation data:
icarec file structure:
├── schema.json # Signal map, types, units
├── static_signals.bin # Static signals (one-time)
├── dynamic_signals.bin # Dynamic signals (per-frame)
└── metadata.json # Scenario, timestamps, version
2. Versioned Recording Schema
Every recording includes a versioned schema for forward/backward compatibility:
{
"schema_version": "2.3.1",
"icarus_version": "1.5.0",
"created_at": "2024-12-22T10:30:00Z",
"signals": [
{
"name": "Vehicle.Nav.position",
"type": "Vec3<double>",
"units": "m",
"lifecycle": "dynamic",
"offset": 0,
"size": 24
},
{
"name": "Vehicle.Aero.alpha",
"type": "double",
"units": "rad",
"lifecycle": "dynamic",
"offset": 24,
"size": 8
}
],
"components": [
{
"name": "Vehicle.EOM",
"type": "RigidBody6DOF",
"state_offset": 0,
"state_size": 13
}
],
"compatibility": {
"min_icarus_version": "1.0.0",
"warmstart_compatible": true,
"breaking_changes": []
},
"checksum": "sha256:a1b2c3d4..."
}
2.1 Time System Specification
For aerospace applications, the simulation time system must be explicit for ephemeris lookups, ground track calculations, and correlation with real-world events:
{
"time": {
"epoch": "2024-12-22T00:00:00Z",
"system": "MET",
"units": "seconds"
}
}
| Time System | Description | Use Case |
| MET | Mission Elapsed Time (t=0 at sim start) | Default, simplest |
| UTC | Coordinated Universal Time | Correlation with wall-clock |
| TAI | International Atomic Time | Ephemeris, precise timing |
| GPS | GPS Time (TAI - 19 seconds) | Navigation, GPS correlation |
- Note
- Internal simulation always uses double t as seconds from epoch. The time.system field specifies how to interpret that value when correlating with external data.
3. Schema Compatibility Rules
| Scenario | Behavior |
| Same schema version | Full compatibility, warmstart works |
| Newer schema, additive changes | Compatible—new signals ignored on load |
| Newer schema, removed signals | Warning—missing signals set to defaults |
| Breaking schema change | Error with clear message |
Compatibility Validation
ValidationResult Simulator::ValidateRecording(const std::string& path) {
auto recording_schema = Recording::LoadSchema(path);
auto current_schema = GetCurrentSchema();
ValidationResult result;
if (recording_schema.version < current_schema.min_compatible_version) {
result.AddError("Recording schema {} is too old (min: {})",
recording_schema.version, current_schema.min_compatible_version);
}
for (const auto& input : GetAllRequiredInputs()) {
if (!recording_schema.HasSignal(input.name)) {
if (input.has_default) {
result.AddWarning("Signal '{}' missing, using default: {}",
input.name, input.default_value);
} else {
result.AddError("Required signal '{}' not in recording", input.name);
}
}
}
for (const auto& sig : recording_schema.signals) {
if (current_schema.HasSignal(sig.name)) {
auto current = current_schema.GetSignal(sig.name);
if (sig.type != current.type) {
result.AddError("Type mismatch for '{}': recording={}, current={}",
sig.name, sig.type, current.type);
}
}
}
return result;
}
4. Default Recording Policy
services:
recording:
enabled: true
format: ICAREC
path: "output/run_{timestamp}.icarec"
# Record ALL signals by default
policy: ALL
# Exclude only high-frequency noise (optional)
exclude:
- "Debug.*"
- "*.raw_sensor_*"
# Ensure warmstart compatibility
warmstart_compatible: true # Validates all inputs are recorded
5. Telemetry → .icarec Pipeline
Live telemetry (UDP) and recording share the same data path. Recording is enabled via Services config:
services:
recording:
enabled: true
format: ICAREC # or HDF5, CSV
path: "output/run_{timestamp}.icarec"
6. Warmstart from Recording
To warmstart from any point in a recording:
sim.provision();
auto validation = sim.ValidateRecording("recording.icarec");
if (!validation.IsValid()) {
for (const auto& error : validation.errors) {
ICARUS_ERROR("{}", error);
}
throw WarmstartError("Recording incompatible with current simulation");
}
sim.warmstart_from("recording.icarec", t_warmstart);
sim.step(dt);
- Warning
- Warmstart requires all input signals to be recorded. If a component reads an external input that wasn't recorded, warmstart will fail. Use warmstart_compatible: true in recording config to catch this at recording time.
7. Recording Formats
| Format | Pros | Cons | Use Case |
| ICAREC | Native, fast, warmstart-compatible | Icarus-specific | Default |
| HDF5 | Industry standard, Python/MATLAB friendly | Larger files | Analysis |
| CSV | Human-readable, universal | Very large, slow | Debugging |
| Parquet | Columnar, efficient queries | Complex | Big data analysis |