gen_flight_replay.py¶
Convert a recorded AURORA flight CSV into a generated C source file that
embeds the samples as constant arrays. The generated file is compiled into
the firmware and consumed by the replay backend of fake_sensors, so
that simulated runs (e.g. on native_sim or with the sim snippet) can be
driven by real flight data instead of the analytic profile.
Background¶
When CONFIG_AURORA_FAKE_SENSORS=y is set, the IMU and baro polling
threads are replaced by a synthetic data source. There are two backends:
Backend |
Kconfig |
What it publishes |
|---|---|---|
Analytic profile |
|
An ISA-troposphere ascent/descent curve generated on the fly. |
Replay |
|
Samples from a previously recorded flight, embedded at build time. |
The replay backend (fake_sensors_replay.c) expects three arrays:
struct replay_imu_sample { uint64_t t_ns; float x, y, z; };
struct replay_baro_sample { uint64_t t_ns; float pres_kpa, temp_c; };
const struct replay_imu_sample replay_accel[];
const struct replay_imu_sample replay_gyro[];
const struct replay_baro_sample replay_baro[];
gen_flight_replay.py is the small code-generator that produces the C file
holding these arrays. It is invoked automatically from the sensor_board
CMakeLists.txt whenever the replay backend is enabled — you normally do
not call it by hand.
Inputs¶
The script reads the flights.csv file produced by the data logger’s
CSV converter. Each row is expected to carry a timestamp_ns column plus
optional accel_{x,y,z}, gyro_{x,y,z} and baro_pres / baro_temp
columns. Empty cells are simply skipped, which is convenient because the
logger only fills the columns of the sensor that produced a given row.
Optionally, a state_audit file from the same flight may be passed in.
This is the human-readable transition log written by the flight state
machine. The script parses the BOOST and LANDED transitions out of it
and trims the sample arrays to a window of:
[BOOST - 4 s, LANDED + 4 s]
Trimming keeps the embedded array small (and therefore the firmware image small) while still leaving enough margin on either side for attitude calibration and post-landing checks.
Note
Despite the Time (ms) header in the audit file, the recorded values are
actually in nanoseconds and match timestamp_ns in the CSV one-to-one.
Output¶
A single C source file with:
A header comment listing the source CSV, the sample counts and the total time span (and, if applicable, the trim window).
Three array definitions:
replay_accel,replay_gyro,replay_baro.A
<name>_lenconstant for each array (computed viaARRAY_SIZE).
All timestamps in the generated file are rebased to start at zero — the smallest timestamp across all three streams is subtracted from every sample. This way the replay engine can work in elapsed time without caring about the absolute uptime of the original flight.
Usage¶
python3 tools/gen_flight_replay.py \
--input flights.csv \
--output replay_data.c \
[--state-audit state_audit]
Argument |
Description |
|---|---|
|
Path to a |
|
Destination path for the generated C source file. |
|
Optional. State machine audit log from the same flight. When present, samples are trimmed to |
The script exits with a non-zero status (and a message on stderr) if:
the CSV is missing accelerometer, gyroscope or barometer samples, or
a
--state-auditis supplied but contains noBOOST/LANDEDtransition, orthe trim window ends up empty (typically a sign that the audit and CSV timestamps come from different runs).
Build integration¶
You usually do not run gen_flight_replay.py directly. The
sensor_board CMakeLists.txt adds a custom command that re-runs it
whenever the input CSV (or, if present, the sibling state_audit file)
changes:
add_custom_command(
OUTPUT ${REPLAY_OUT}
COMMAND ${PYTHON_EXECUTABLE} ${REPLAY_GEN}
--input ${REPLAY_INPUT}
--output ${REPLAY_OUT}
${REPLAY_AUDIT_ARGS}
DEPENDS ${REPLAY_INPUT} ${REPLAY_GEN} ${REPLAY_AUDIT_DEPS}
COMMENT "Generating replay_data.c from ${REPLAY_INPUT_REL}"
)
To swap recordings, change the Kconfig string
CONFIG_AURORA_FAKE_SENSORS_REPLAY_INPUT (path is relative to the aurora
module root). If a state_audit file sits next to the chosen CSV, it is
picked up automatically.
Example¶
Generate a replay source file from a recorded multimeter flight and trim it to the powered-flight window:
python3 ./tools/gen_flight_replay.py \
--input flight_logs/multimeter/2026-05-03/flight1/flights.csv \
--output /tmp/replay_data.c \
--state-audit flight_logs/multimeter/2026-05-03/flight1/state_audit
To then build a native_sim image that replays this flight:
west build -p -b native_sim -S sim aurora/sensor_board \
-- -DCONFIG_AURORA_FAKE_SENSORS_REPLAY=y
./build/zephyr/zephyr.exe
# in the Zephyr shell:
uart:~$ sim launch
Requirements¶
Python 3.10+
No third-party packages (uses
argparse,csvandreonly).