From ea986427aa6eac44e97afd919f5be3188d935ff2 Mon Sep 17 00:00:00 2001 From: Jonah Snider Date: Thu, 27 Mar 2025 15:51:13 -0700 Subject: [PATCH] [wpiutil] Add Kaitai Struct definition for data log format (#7882) Adds a Kaitai Struct definition for the WPILOG format. This can be used to generate code to read/write data log files without needing to build out a parser/serializer by hand. Or just an additional resource for readers to help understand the WPILOG format. --- wpiutil/doc/datalog.adoc | 6 ++ wpiutil/doc/wpilog.ksy | 130 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 136 insertions(+) create mode 100644 wpiutil/doc/wpilog.ksy diff --git a/wpiutil/doc/datalog.adoc b/wpiutil/doc/datalog.adoc index 9fd6f6f980..a6ea78c98e 100644 --- a/wpiutil/doc/datalog.adoc +++ b/wpiutil/doc/datalog.adoc @@ -190,3 +190,9 @@ Each entry's data type is an arbitrary string. The following data types are stan === Metadata Each entry has an associated metadata string. If not blank, the metadata should be <>, but may be arbitrary text. Metadata is intended to convey additional information about the entry beyond what the type conveys--for example the source of the data. + +[[additional-resources]] +== Additional Resources + +A https://kaitai.io/[Kaitai Struct] definition for the data log format is included in link:./wpilog.ksy[wpilog.ksy]. +Kaitai Struct is a declarative language used to describe various binary data structures. diff --git a/wpiutil/doc/wpilog.ksy b/wpiutil/doc/wpilog.ksy new file mode 100644 index 0000000000..efba8116cd --- /dev/null +++ b/wpiutil/doc/wpilog.ksy @@ -0,0 +1,130 @@ +meta: + id: wpilog + title: WPILib Data Log + file-extension: wpilog + ks-version: "0.10" + encoding: UTF-8 + endian: le + bit-endian: le +seq: + - id: header + type: header + - id: records + type: record + repeat: eos +types: + version_number: + seq: + - id: minor + type: u1 + - id: major + type: u1 + header: + seq: + - id: magic + contents: WPILOG + - id: version + type: version_number + - id: extra_header_length + type: u4 + - id: extra_header + size: extra_header_length + type: str + record: + seq: + - id: header_length + type: record_header_length + - id: entry_id + type: + switch-on: header_length.len_entry_id + cases: + 0: u1 + 1: u2 + 2: b24 + 3: u4 + - id: len_payload + type: + switch-on: header_length.len_payload_size + cases: + 0: u1 + 1: u2 + 2: b24 + 3: u4 + - id: timestamp + type: + switch-on: header_length.len_timestamp + cases: + 0: u1 + 1: u2 + 2: b24 + 3: u4 + 4: b40 + 5: b48 + 6: b56 + 7: u8 + - id: payload + size: len_payload + type: + switch-on: entry_id + cases: + # ID 0 is reserved for control records + 0: control_record_payload + record_header_length: + seq: + - id: len_entry_id + type: b2 + - id: len_payload_size + type: b2 + - id: len_timestamp + type: b3 + - id: spare_bit + type: b1 + control_record_payload: + seq: + - id: type + type: u1 + enum: control_record_type + - id: data + type: + switch-on: type + cases: + "control_record_type::start": control_record_start_data + "control_record_type::finish": control_record_finish_data + "control_record_type::set_metadata": control_record_set_metadata_data + control_record_start_data: + seq: + - id: entry_id + type: u4 + - id: len_entry_name + type: u4 + - id: entry_name + size: len_entry_name + type: str + - id: len_entry_type + type: u4 + - id: entry_type + size: len_entry_type + type: str + - id: len_entry_metadata + type: u4 + - id: entry_metadata + size: len_entry_metadata + type: str + control_record_finish_data: + seq: + - id: entry_id + type: u4 + control_record_set_metadata_data: + seq: + - id: entry_id + type: u4 + - id: len_entry_metadata + type: u4 + - id: entry_metadata + size: len_entry_metadata + type: str +enums: + control_record_type: + 0: start + 1: finish + 2: set_metadata