Px4 ULog文件详解

简介

ULog 是用于记录数据的文件格式,该格式是自解析的,即它包含了自己记录的消息格式。
Ulog可以用于记录输入、内部状态、和log消息。所有二进制数据使用小端格式。

数据类型

ULog使用C语言中的数据类型

TypeBytes
int8_t,uint8_t1
int16_t, uint16_t1
int32_t, uint32_t4
int64_t, uint64_t8
float4
double8
bool, char1

所有以上类型都可以以数组形式使用,比如float[5],所有的字符串char[length]都不包含\0,字符串是大小写敏感的。

文件组织

ULog文件有以下三个部分组成

文件头
定义段
数据段

文件头

文件头固定16字节长度,数据如下:

0x55 0x4c 0x6f 0x67 0x01 0x12 0x350x01uint64_t
File magic (7B)Version (1B)Timestamp (8B)

Timestamp是一个64位整型数据,标记了日记记录的开始时间,单位是毫秒。

定义段

定义部分是变长的,包含了版本信息、数据格式定义和参数值。
定义部分和数据部分都由消息流组成。

消息

每个消息都由消息头开始

struct message_header_s {
    uint16_t msg_size;
    uint8_t msg_type
};

msg_size是消息除去头部分后的字节数(头部分占3字节)。
msg_type有如下定义:

  • ‘B’: 标记位消息
  • ‘F’ :单个(复合)类型的格式定义,可以在另一个定义中作为嵌套类型记录或使用。
  • ‘I’:信息消息
  • ‘M’:复合信息消息
  • ‘P’:参数消息
标记位消息
struct ulog_message_flag_bits_s {
  uint8_t compat_flags[8];
  uint8_t incompat_flags[8];
  uint64_t appended_offsets[3]; ///< file offset(s) for appended data if appending bit is set
};

该消息必须作为第一条消息,紧跟在文件头后面,所以它有确定的偏移量;

  • compat_flags:
    目前没有任何定义,设置为0
  • incompat_flags:
    如果日志包含数据并且appended_offsets数组有非零值,则incompat_flags[0]的LSB设置为1
  • appended_offsets:
    数据的文件偏移量,如果没有数据段,appended_offsets必须全部设为0。附加数据使用以下流程:
    1、设置incompat_flags位
    2、将第一个attachment_offsets设置为0到日志文件的长度。
    3、添加有效消息
格式定义消息
struct message_format_s {
  struct message_header_s header;
  char format[header.msg_size-hdr_size];
};

header是上文中的消息头。
format具有以下格式的纯文本字符串:
message_name:field0;field1;…
他可以有任意字段的field,每个field以;分隔。field具有以下格式:
type field_name / type[array_length] field_name

type是上文中提到的数据类型,或者是嵌套类型。
field_name是用户自定义的名称,但是有一些名称是特殊的:

  • timestamp 每条记录的消息必须包含一个时间戳字段,但不需要是第一个字段。目前使用的类型是uint64_t,单位是微秒。对于相同的消息,时间戳必须是单调递增的。
  • Padding如果名称以_padding开头的字段名称,解析器会忽略其数据。 这些字段用于确保正确对齐。
信息消息
struct message_info_s {
  struct message_header_s header;
  uint8_t key_len;
  char key[key_len];
  char value[header.msg_size-hdr_size-1-key_len]
};

header是上文中的消息头。
key_lenkey的长度。
key是一个纯字符串:
message_name:field
field类似于格式定义消息,不同的是它只有一个field且不需要;结尾。
value包含key中描述的数据
特定的信息消息在整个日志最多出现一次,解析器可以将其存储为字典
预定义的信息消息是:

keyDescriptionExample for value
char[value_len] sys_nameName of the system“PX4”
char[value_len] ver_hwHardware version (board)“PX4FMU_V4”
char[value_len] ver_hw_subtypeBoard subversion (variation)“V2”
char[value_len] ver_swSoftware version (git tag)“7f65e01”
char[value_len] ver_sw_branchgit branch“master”
uint32_t ver_sw_releaseSoftware version (see below)0x010401ff
char[value_len] sys_os_nameOperating System Name“Linux”
char[value_len] sys_os_verOS version (git tag)“9f82919”
uint32_t ver_os_releaseOS version (see below)0x010401ff
char[value_len] sys_toolchainToolchain Name“GNU GCC”
char[value_len] sys_toolchain_verToolchain Version“6.2.1”
char[value_len] sys_mcuChip name and revision“STM32F42x, rev A”
char[value_len] sys_uuidUnique identifier for vehicle (eg. MCU ID)“392a93e32fa3”
char[value_len] replayFile name of replayed log if in replay mode“log001.ulg”
int32_t time_ref_utcUTC Time offset in seconds-3600

ver_sw_release和ver_os_release的格式为:0xAABBCCTT,其中AA为major,BB为minor,CC为patch,TT为类型。 类型定义如下:> = 0:开发,> = 64:alpha版本,> = 128:beta版本,> = 192:RC版本,== 255:发布版本。 因此,例如0x010402ff转换为发行版v1.4.2。

复合信息消息
struct ulog_message_info_multiple_header_s {
  uint8_t is_continued; ///< can be used for arrays
  uint8_t key_len;
  char key[key_len];
  char value[header.msg_size-hdr_size-2-key_len]
};

与信息消息相同,但是它可以有多个具有相同key的消息(解析器将它们存储为列表)。 is_continued可用于拆分消息:如果设置为1,则它是具有相同key的上一消息的一部分。

参数消息
struct message_info_s {
  struct message_header_s header;
  uint8_t key_len;
  char key[key_len];
  char value[header.msg_size-hdr_size-1-key_len]
};

如果一个参数在运行时动态改变,该条消息也可出现在数据段。它的数据格式必须是int32_t/float.

数据段

下列消息会出现在数据段:

  • ‘A’:订阅消息
  • ‘R’:取消订阅消息
  • ‘D’:日志数据
  • ‘L’:字符串消息
  • ‘S’:同步消息
  • ‘O’:丢失
  • ‘I’:信息消息
  • ‘M’:复合信息消息
  • ‘P’:参数消息

订阅消息

struct message_add_logged_s {
  struct message_header_s header;
  uint8_t multi_id;
  uint16_t msg_id;
  char message_name[header.msg_size-hdr_size-3];
};

该消息必须出现在message_data_s前,用于登记message_data_s消息的id和名称。
header:上文中定义的消息头。
multi_id:相同的消息可以有多个实例,比如有两个相同的传感器,则默认第一个为0。
msg_id:用于匹配message_data_s的唯一id。
message_name:消息名称,必须与message_format_s定义中:
message_name:field0;field1;…
的名称message_name保持一致。

取消订阅消息

目前没有使用

日志数据消息

struct message_data_s {
  struct message_header_s header;
  uint16_t msg_id;
  uint8_t data[header.msg_size-hdr_size];
};

header:上文中定义的消息头。
msg_id:message_add_logged_s定义的唯一id。
data:message_format_s中定义的二进制数据部分。

字符串消息

struct message_logging_s {
  struct message_header_s header;
  uint8_t log_level;
  uint64_t timestamp;
  char message[header.msg_size-hdr_size-9]
};

header:上文中定义的消息头。
log_level:类似linux中的消息级别:

NameLevel valueMeaning
EMERG‘0’System is unusable
ALERT‘1’Action must be taken immediately
CRIT‘2’Critical conditions
ERR‘3’Error conditions
WARNING‘4’Warning conditions
NOTICE‘5’Normal but significant condition
INFO‘6’Informational
DEBUG‘7’Debug-level messages

timestamp:微妙时间戳。
message:消息内容。

同步消息

目前未使用

丢失

标记给定持续时间的丢失(丢失的日志消息),以ms为单位。 丢失可能发生在设备不够快时。

struct message_dropout_s {
  struct message_header_s header;
  uint16_t duration;
};

header:上文中定义的消息头。
duration:持续时间

附录

要将PX4飞行数据提取到Matlab中,可以按照以下步骤进行操作: 1. 首先,确保你已经安装了Matlab软件,并且已经安装了pyulog库。你可以在https://github.com/PX4/pyulog找到pyulog的安装教程。 2. 将存储有PX4飞行数据的存储卡插入读卡器,并将读卡器连接到计算机上。在存储卡中找到以.ulg结尾的日志文件,例如log001.ulg,并将其复制到计算机上。 3. 打开Matlab软件,并在命令窗口中导航到存储日志文件文件夹。 4. 使用pyulog库中的ulog2csv命令将.ulg文件转换为.csv文件。在Matlab命令窗口中输入以下命令: ``` ulog2csv log001.ulg ``` 5. 执行上述命令后,将在当前文件夹中生成一系列导出的.csv文件,包含了各种飞行数据。 6. 使用Matlab的csvread函数或readmatrix函数来读取感兴趣的.csv文件中的数据。例如,要读取原始加速度计数据,可以使用以下命令: ``` data = csvread('log001_sensor_combined_0.csv', 1, 0); ``` 7. 现在,你可以在Matlab中使用data变量来处理和分析飞行数据了。 请注意,上述步骤中的文件名和变量名可能需要根据你的实际情况进行调整。此外,你还可以根据你的需求选择其他感兴趣的飞行数据进行提取和分析。 #### 引用[.reference_title] - *1* *2* [PX4日志读取并转化为.scv文件、MATLAB显示](https://blog.csdn.net/weixin_41869763/article/details/112617357)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值