ArduPilot DataFlash#
Nominal reads ArduPilot DataFlash logs (.bin). Each field of each log message becomes a channel named <message>.<field>, such as IMU.GyrX. The vehicle’s parameters become channels named PARM.<parameter>, such as PARM.ARMING_CHECK.
Upload a file#
In the sidebar, click + (New), then Upload data. Drop the
.binfile onto Upload files, or click SELECT FILES.Click SELECT A DESTINATION and choose Standalone dataset. Pick a dataset, or click NEW DATASET, enter a name and click CREATE DATASET.
Click CONFIRM & INGEST.
from nominal.core import NominalClient
client = NominalClient.from_profile("default")
dataset = client.create_dataset("Flight 42")
file = dataset.add_ardupilot_dataflash("flight.bin")
file.poll_until_ingestion_completed() # raises if ingestion fails
nomctl ingest ardupilot-dataflash --name "Flight 42" flight.bin
Options#
Setting |
Nominal app |
Python |
nomctl |
|---|---|---|---|
A tag on every point |
Tags |
|
|
Logs with invalid timestamps#
If a log fails with INVALID_TIMESTAMPS, because a timestamp can’t be represented, run Nominal’s first-party ArduPilot DataFlash extractor on it with Ignore invalid timestamps (IGNORE_INVALID_TIMESTAMPS) set to true. The extractor drops the records with those timestamps and keeps the rest. Its input, INPUT_FILE_1, also takes logs compressed with zstd, gzip, bzip2 or xz.
If ArduPilot DataFlash isn’t in the File extraction menu, enable it first: in the sidebar, open Data > File extractors, click NEW EXTRACTOR > Native extractor, choose ArduPilot DataFlash and click ENABLE EXTRACTOR.
In the sidebar, click + (New), then Upload data.
On the File extraction card, click SELECT and choose ArduPilot DataFlash.
Click SELECT A DESTINATION and choose Standalone dataset. Pick a dataset, or click NEW DATASET, enter a name and click CREATE DATASET.
Next to INPUT_FILE_1, click Select file and choose the
.binfile. Entertruein Ignore invalid timestamps.Click CONFIRM & INGEST.
Select the extractor’s row on the File extractors page to see its RID.
from nominal.core import NominalClient
client = NominalClient.from_profile("default")
extractor = client.get_containerized_extractor("<EXTRACTOR_RID>")
dataset = client.create_dataset("Flight 42")
job = dataset.add_containerized(
extractor,
sources={"INPUT_FILE_1": "flight.bin"},
arguments={"IGNORE_INVALID_TIMESTAMPS": "true"},
)
for file in job.as_files_ingested(): # waits for ingestion
print(file.name, file.ingest_status.name)