Move PX4 Guide source into /docs (#24490)

* Add vitepress tree

* Update existing workflows so they dont trigger on changes in the docs path

* Add nojekyll, package.json, LICENCE etc

* Add crowdin docs upload/download scripts

* Add docs flaw checker workflows

* Used docs prefix for docs workflows

* Crowdin obvious fixes

* ci: docs move to self hosted runner

runs on a beefy server for faster builds

Signed-off-by: Ramon Roche <mrpollo@gmail.com>

* ci: don't run build action for docs or ci changes

Signed-off-by: Ramon Roche <mrpollo@gmail.com>

* ci: update runners

Signed-off-by: Ramon Roche <mrpollo@gmail.com>

* Add docs/en

* Add docs assets and scripts

* Fix up editlinks to point to PX4 sources

* Download just the translations that are supported

* Add translation sources for zh, uk, ko

* Update latest tranlsation and uorb graphs

* update vitepress to latest

---------

Signed-off-by: Ramon Roche <mrpollo@gmail.com>
Co-authored-by: Ramon Roche <mrpollo@gmail.com>
This commit is contained in:
Hamish Willee
2025-03-13 16:08:27 +11:00
committed by GitHub
co-authored by Ramon Roche
parent 8e6d2ebe4a
commit 88d623bedb
5176 changed files with 558771 additions and 2 deletions
+8
View File
@@ -0,0 +1,8 @@
# 비행 로그 분석
비행 로그 수집과 분석 방법에 대하여 설명합니다.
- [Flight Reporting](../getting_started/flight_reporting.md) - How to download a log and report/discuss issues about a flight.
- [Log Analysis using Flight Review](../log/flight_review.md) - How to analyse many common vehicle problems using the [Flight Review](https://logs.px4.io/) online tool.
- [Flight Log Analysis](../log/flight_log_analysis.md) - Introduction to flight analysis and links to a number of analysis tools.
- [Statistical Analysis](flight_log_analysis_statistical.md) - Information & resources for statistical analysis (including Flight Review logs).
@@ -0,0 +1,23 @@
# Statistical Flight Log Analysis
This topic contains information and resources related to statistical flight log analysis.
## Flight Review Public Logs
[Flight Review](../log/flight_log_analysis.md#flight-review-online-tool) hosts a large set of publicly available log files that can be used for statistical analysis, machine learning, or other purposes.
The dataset contains a set of different:
- vehicle types
- PX4 versions (including development versions)
- boards
- flight modes
The logs are accessible on [logs.px4.io/browse](https://logs.px4.io/browse) and are licensed under [CC-BY PX4](https://creativecommons.org/licenses/by/4.0/).
Log files can also be downloaded in bulk with the [download_logs.py](https://github.com/PX4/flight_review/blob/main/app/download_logs.py) script.
The script allows to filter by different attributes (like flight modes, airframe name or type).
Use the `--help` flag for a full list.
The newest logs will be downloaded first, and downloads can be interrupted and resumed later on.
There are different parsing libraries, for example [pyulog](../log/flight_log_analysis.md#pyulog) can be used to read logs with Python.
+256
View File
@@ -0,0 +1,256 @@
# Log Encryption
<Badge type="tip" text="PX4 v1.13" />
The [System Logger](../modules/modules_system.md#logger) can be used to create encrypted logs, which may then be decrypted manually before analysis.
The default encryption algorithm is XChaCha20, and the default wrapping algorithm is RSA2048-OAEP.
:::warning
Log encryption is not enabled by default in PX4 firmware builds.
To use it you will need to build firmware with this feature enabled and then upload it to the flight controller (see instructions below).
:::
:::tip
Log encryption was has been improved in PX4 main (v1.16+) to generate a single encrypted log file that contains both encrypted log data, and an encrypted symmetric key that you can use to decrypt it (provided you can decrypt the symmetric key).
In earlier versions the encrypted symmetric key was stored in a separate file.
For more information see the [Log Encryption (PX4 v1.15)](https://docs.px4.io/v1.15/en/dev_log/log_encryption.html).
:::
## How ULog Encryption Works
:::info
The encryption algorithm used is set in [SDLOG_ALGORITHM](../advanced_config/parameter_reference.md#SDLOG_ALGORITHM).
At time of writing, only `XChaCha20` is supported (AES can be selected, but there is no implementation).
If another algorithm is supported in future, the process is _likely_ to remain the same as documented here.
:::
The encryption process for each new ULog is:
1. A XChaCha20 symmetric key is generated and encrypted using an RSA2048 public key.
This wrapped (encrypted) key is stored on the SD card in the beginning of a file that has the suffix `.ulge` ("ulog encrypted").
2. When a log is captured, the ULog data is encrypted with the unwrapped symmetric key and the resulting data is appended into the end of the `.ulge` file immediately after the wrapped key data.
After the flight, the `.ulge` file containing both the wrapped symmetric key and the encrypted log data can be found on the SD card.
In order to extract the log file, a user must first decrypt the wrapped symmetric key, which can then be used to decrypt the log.
Decrypting the wrapped symmetric key file is only possible if the user has the corresponding RSA private key for the public key that was used to wrap it.
This process is covered in more detail in [Download & Decrypt Log Files](#download-decrypt-log-files) below.
## File Structure
Encrypted `.ulge` file contains following sections:
```plain
-------------------------
| Header |
-------------------------
| Wrapped symmetric key |
-------------------------
| Encrypted ulog data |
-------------------------
```
Header section (22 bytes) contains following fields:
| Bytes | Field |
| -------------------------------------- | --------------------- |
| 0..6 | File magic identifier |
| 7 | Header version |
| 8..15 | Timestamp |
| 16 | exchange algorithm |
| 17 | exchange key index |
| 18..19 | key size |
| 20..21 | nonce size |
The header part begins with magic string: `"ULogEnc"`, which identifies this is encrypted ulog file.
The file offset of the symmetric key section is `22` and the file offset of the log data section is `22 + key_size + nonce_size` (`key_size` and `nonce_size` are taken from the header section).
## Custom PX4 Firmware with Log Encryption
You will need to build custom firmware that contains your own public RSA key and the required Crypto API modules to support log encryption.
This section shows how to do this using the `px4-fmu-v5` board as an example.
:::tip
We show you how to generate your own keys in the [Generate RSA Public & Private Keys](#generate-rsa-public-private-keys) section below.
:::
:::info
The modules in a PX4 build are defined in configuration files, which may be modified either manually or using the `menuconfig` tool.
For more information see: [PX4 Board Configuration (Kconfig)](../hardware/porting_guide_config.md).
:::
### Cryptotest Make Target
Crypto uses large amounts of flash memory, and is therefore not included in the default PX4 make targets for each board (such as `make px4-fmu-v5`).
The easiest way to add support for encrypted logs is to define a custom `make` target that includes the required modules and your public RSA keys.
:::warning
Many builds are close to their maximum capacity.
If you run into a build error telling you that you have gone above the maximum flash memory, you will need to disable other features in the `.px4board` file you are working on, or in the `default.px4board` file.
Be careful not to disable something you need.
For example, if you found you were running out of memory on FMUv4 boards you could disable SIH mode by setting `CONFIG_MODULES_SIMULATION_SIMULATOR_SIH=n` in [boards/px4/fmu-v4/default.px4board](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v4/default.px4board#L76), which may free up enough flash memory to allow crypto to be added.
:::
#### Pixhawk FMUv5 boards
The FMUv5 board already has a custom make target `px4-fmu-v5_cryptotest` that you can use to build custom firmware with the required modules and "test" RSA keys.
The configuration file that enables the above make target is [`cryptotest.px4board`](https://github.com/PX4/PX4-Autopilot/blob/main/boards/px4/fmu-v5/cryptotest.px4board) file in `boards/px4/fmu-v5`.
The relevant keys in that file are reproduced below:
```plain
CONFIG_BOARD_CRYPTO=y
CONFIG_DRIVERS_STUB_KEYSTORE=y
CONFIG_DRIVERS_SW_CRYPTO=y
CONFIG_PUBLIC_KEY1="../../../Tools/test_keys/rsa2048.pub"
```
:::info
The file also sets `CONFIG_PUBLIC_KEY0` to a key named `key0.pub`.
This is not used in the current PX4 implementation and can be ignored.
:::
:::details
Overview of crypto-relevant keys
| Argument | 설명 |
| ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| CONFIG_BOARD_CRYPTO | Include crypto module in firmware.<br>= `y`: Enable log encryption.<br>= `n`: Disable log encryption. |
| CONFIG_DRIVERS_SW_CRYPTO | Include the PX4 crypto backend library (used by above library).<br>= `y`: Enable<br>= `n`: Disable |
| CONFIG_DRIVERS_STUB_KEYSTORE | Includes the PX4 stub keystore driver.<br>= `y`: Enable<br>= `n`: Disable |
| CONFIG_PUBLIC_KEY0 | Location of public key for keystore index 0. |
| CONFIG_PUBLIC_KEY1 | Location of public key for keystore index 1.<br>= `{path to key1}` |
| CONFIG_PUBLIC_KEY2 | Location of public key for keystore index 2.<br>= `{path to key2}` |
| CONFIG_PUBLIC_KEY3 | Location of public key for keystore index 3.<br>= `{path to key3}` |
The stub keystore is a keystore implementation that can store up to four keys.
The initial values of these keys are set in the locations defined by `CONFIG_PUBLIC_KEY0` to `CONFIG_PUBLIC_KEY3`.
The keys can be used for different cryptographic purposes, which are determined by parameters.
The _exchange key_, which is the public key used for encrypting the symmetric key stored in the beginning of the `.ulge` file, is specified using [SDLOG_EXCH_KEY](../advanced_config/parameter_reference.md#SDLOG_EXCH_KEY) as an index value into the key store.
The value is `1` by default, which maps to the key defined in `CONFIG_PUBLIC_KEY1`.
The _logging key_ is the unencrypted symmetric key.
This is specified using [SDLOG_KEY](../advanced_config/parameter_reference.md#SDLOG_KEY) as an index value into the key store, and default to `2`.
Note that the value is generated fresh for each log, and any value specified in `CONFIG_PUBLIC_KEY2` would be overwritten.
You can use choose different locations for your keys as long as they aren't used by anything else.
:::
The key in `CONFIG_PUBLIC_KEY1` is the public key used to wrap the symmetric key in the the beginning of `.ulge` file (by default: see [SDLOG_EXCH_KEY](../advanced_config/parameter_reference.md#SDLOG_EXCH_KEY)).
You can use the `rsa2048.pub` key for testing, or replace it with the path to your own public key in the file (see [Generate RSA Public & Private Keys](#generate-rsa-public-private-keys)).
Build the firmware like this:
```sh
make px4-fmu-v5_cryptotest
```
#### 기타 보드
For other boards you will need to first copy `cryptotest.px4board` into the root of the target board directory.
For example, for FMUv6 you would copy the board to [/boards/px4/fmu-v6x](https://github.com/PX4/PX4-Autopilot/tree/main/boards/px4/fmu-v6x).
Then you will need to add a few more configuration settings that are present in FMUv5 default configuration but not in the other boards.
We do add these using the `menuconfig` tool.
To use `menuconfig` you will need to add these dependencies:
```sh
sudo apt-get install libncurses-dev flex bison openssl libssl-dev dkms libelf-dev libudev-dev libpci-dev libiberty-dev autoconf
```
Now, in PX4, run the normal `make` command you would use to build the board you are targeting, but add "menuconfig" at the end of it.
Here we use `px4_fmu-v5_cryptotest` as an example, because that already has the settings that we want to copy:
```sh
make px4_fmu-v5_cryptotest menuconfig
```
Navigate to `Crypto API` and use the **Y** key to select it.
![Menuconfig Crypto API Main Menu Option](../../assets/hardware/kconfig-crypto-1.png)
This will open the menu below.
Enable the settings: `Blake2s hash algorithm`, `Entropy pool and strong random number generator`, and `Use interrupts to feed timing randomness to entropy pool`.
![Menuconfig Crypto Options Set](../../assets/hardware/kconfig-crypto-2.png)
:::tip
Some of these options can be tweaked if desired.
:::
After enabling encryption settings, exit `menuconfig`.
You can now build and test.
## Download & Decrypt Log Files
Encrypted log files are downloaded using the QGroundControl [Log Download](https://docs.qgroundcontrol.com/master/en/qgc-user-guide/analyze_view/log_download.html) view (**Analyze Tools > Log Download**) just like ordinary log files.
Note that the encrypted files will be downloaded with the `.ulg` suffix, instead of `.ulge`.
### Decrypt ULogs
Before you can analyze your encrypted logs, you will need to decrypt them.
There is a Python script that can be used to decrypt logs in `Tools/decrypt_ulog.py`.
When decrypting a `.ulge` file the script takes 3 arguments:
1. The encrypted log file.
2. An empty string `''`.
3. The decryption key (the RSA2048 `.pem` private key which is used to unwrap the symmetric key).
예:
```sh
python3 decrypt_ulog.py \
/home/john/Downloads/log_24_2024-10-6-23-39-50.ulg '' \
new_keys/private_key.pem
```
On success the decrypted log file is created with the `.ulog` suffix.
:::info
The script can be used with both `.ulge` logs and the `.ulgc`/`.ulgk` files used in [PX4 v1.15 Log Encryption](https://docs.px4.io/v1.15/en/dev_log/log_encryption.html).
The full command line syntax is given below:
```sh
usage: decrypt_ulog.py [-h] [ulog_file] [ulog_key] [rsa_key]
CLI tool to decrypt an ulog file
positional arguments:
ulog_file .ulge/.ulgc, encrypted log file
ulog_key .ulgk, legacy encrypted key (give empty string '' to ignore for .ulge)
rsa_key .pem format key for decrypting the ulog key
optional arguments:
-h, --help show this help message and exit
```
:::
## Generate RSA Public & Private Keys
To generate a RSA2048 private and public key, you can use OpenSSL:
```sh
openssl genpkey -algorithm RSA -out private_key.pem -pkeyopt rsa_keygen_bits:2048
```
Then you can create a public key from this private key:
```sh
# Convert private_key.pem to a DER file
openssl rsa -pubout -in private_key.pem -outform DER -out public_key.der
# From the DER file, generate a public key in hex format, separated by commas
xxd -p public_key.der | tr -d '\n' | sed 's/\(..\)/0x\1, /g' > public_key.pub
```
To use this key you would modify your `.px4board` file to point `CONFIG_PUBLIC_KEY1` to the file location of `public_key.pub`.
The private key generated should be stored safely and used when you need to decrypt log files.
+189
View File
@@ -0,0 +1,189 @@
# 로깅
The [system logger](../modules/modules_system.md#logger) is able to log any ORB topic with all included fields.
Everything necessary is generated from the `.msg` file, so that only the topic name needs to be specified.
선택적 간격 매개변수는 특정 주제의 최대 로깅 속도를 지정합니다.
주제의 모든 기존 인스턴스가 기록됩니다.
The output log format is [ULog](../dev_log/ulog_file_format.md).
[Encrypted logging](../dev_log/log_encryption.md) is also supported.
## 사용법
기본적으로, 로깅은 시동을 걸었을 때 시작하며, 제동 후 중지합니다.
새 로그 파일은 시동을 걸 때마다 SD 카드에 생성됩니다.
To display the current state, use `logger status` on the console.
If you want to start logging immediately, use `logger on`.
이 명령은 시동을 걸었을 때, 시동 동작보다 우선합니다.
`logger off` undoes this.
If logging stops due to a write error, or reaching the [maximum file size](#file-size-limitations), PX4 will automatically restart logging in a new file.
For a list of all supported logger commands and parameters, use:
```
logger help
```
## 설정
The logging system is configured by default to collect sensible logs for [flight reporting](../getting_started/flight_reporting.md) with [Flight Review](http://logs.px4.io).
Logging may further be configured using the [SD Logging](../advanced_config/parameter_reference.md#sd-logging) parameters.
변경할 가능성이 높은 매개변수가 아래에 설명되어 있습니다.
| 매개변수 | 설명 |
| --------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [SDLOG_MODE](../advanced_config/parameter_reference.md#SDLOG_MODE) | Logging Mode. Defines when logging starts and stops.<br />- `-1`: Logging disabled.<br />- `0`: Log when armed until disarm (default).<br />- `1`: Log from boot until disarm.<br />- `2`: Log from boot until shutdown.<br />- `3`: Log based on the [AUX1 RC channel](../advanced_config/parameter_reference.md#RC_MAP_AUX1).<br />- `4`: Log from first armed until shutdown. |
| [SDLOG_PROFILE](../advanced_config/parameter_reference.md#SDLOG_PROFILE) | 로깅 프로파일. Use this to enable less common logging/analysis (e.g. for EKF2 replay, high rate logging for PID & filter tuning, thermal temperature calibration). |
| [SDLOG_MISSION](../advanced_config/parameter_reference.md#SDLOG_MISSION) | Create very small additional "Mission Log".<br>This log can _not_ be used with [Flight Review](../log/flight_log_analysis.md#flight-review-online-tool), but is useful when you need a small log for geotagging or regulatory compliance. |
Useful settings for specific cases:
- Raw sensor data for comparison: [SDLOG_MODE=1](../advanced_config/parameter_reference.md#SDLOG_MODE) and [SDLOG_PROFILE=64](../advanced_config/parameter_reference.md#SDLOG_PROFILE).
- Disabling logging altogether: [SDLOG_MODE=`-1`](../advanced_config/parameter_reference.md#SDLOG_MODE)
### Logger module
_Developers_ can further configure what information is logged via the [logger](../modules/modules_system.md#logger) module.
This allows, for example, logging of your own uORB topics.
### 진단SD 카드 설정
Separately, the list of logged topics can also be customized with a file on the SD card.
Create a file `etc/logging/logger_topics.txt` on the card with a list of topics (For SITL, it's `build/px4_sitl_default/rootfs/fs/microsd/etc/logging/logger_topics.txt`):
```plain
<topic_name> <interval> <instance>
```
The `<interval>` is optional, and if specified, defines the minimum interval in ms between two logged messages of this topic.
지정하지 않으면, 주제가 최대 속도로 기록됩니다.
The `<instance>` is optional, and if specified, defines the instance to log.
지정하지 않으면, 토픽의 모든 인스턴스를 로깅합니다.
To specify `<instance>`, `<interval>` must be specified. 0 값을 설정하면 최대 기록율로 지정할 수 있습니다.
이 파일의 주제는 기본적으로 기록된 모든 주제를 대체합니다.
예 :
```plain
sensor_accel 0 0
sensor_accel 100 1
sensor_gyro 200
sensor_mag 200 1
```
이 구성은 최대 속도에서 sensor_accel 0, 10Hz에서 sensor_accel 1, 5Hz에서 모든 sensor_gyro 인스턴스 및 5Hz에서 sensor_mag 1을 기록합니다.
## 스크립트
There are several scripts to analyze and convert logging files in the [pyulog](https://github.com/PX4/pyulog) repository.
## File size limitations
The maximum file size depends on the file system and OS.
The size limit on NuttX is currently around 2GB.
## 손실
로깅 드롭아웃은 바람직하지 않으며, 드롭아웃의 양에 영향을 미치는 몇 가지 요소가 있습니다.
- 테스트한 대부분의 SD 카드는 분당 여러 번 일시 중지되었습니다.
이는 기록 명령을 처리함에 있어 수 100ms 정도의 지연이 있음을 보여줍니다.
이런 현상으로 인해 그동안 기록 버퍼가 차면 손실을 유발합니다.
(아래와 같이) SD 카드에 따라 영향을 받습니다.
- SD 카드를 포맷하면, 손실을 어느정도 예방할 수 있습니다.
- 로그 버퍼 크기를 늘리면 도움이 됩니다.
- Decrease the logging rate of selected topics or remove unneeded topics from being logged (`info.py <file>` is useful for this).
## SD 카드
다음은 다양한 SD 카드에 대한 성능 테스트 결과입니다.
The **SanDisk Extreme U3 32GB** and **Samsung EVO Plus 32** are known to be reliable cards (do not exhibit write-time spikes, and thus virtually no dropouts).
The table below shows the **mean sequential write speed [KB/s]** / **maximum write time per block (average) [ms]** for F4- (Pixracer), F7-, and H7-based flight controllers.
| SD 카드 | F4 | 최대 기록 시간 / 블록 (평균) [ms] | H7 |
| -------------------------------------------------------------------------------- | ------------- | ---------------------------------------------------------------------------------------------- | --------- |
| SanDisk Extreme U3 32GB | 1500 / **15** | 1800/10 | 2900/8 |
| Samsung EVO Plus 32GB | 348 | 40 | 1900/9-60 |
| Sandisk Ultra Class 10 8GB | 212 | 60 | 60 |
| Sandisk Class 4 8GB | 331 | 60 | 60 |
| SanDisk Class 10 32 GB (High Endurance Video Monitoring Card) | 209 | 60 | 60 |
| Lexar U1 (Class 10), 16GB High-Performance | 196 | 60 | 60 |
| Sandisk Ultra PLUS Class 10 16GB | 334 | 60 | 60 |
| Sandisk Pixtor Class 10 16GB | 332 | 60 | 60 |
| Sandisk Extreme PLUS Class 10 32GB | 332 / 150 | 60 | 60 |
Logging bandwidth with the default topics is around 50 KB/s, which almost all SD cards satisfy in terms of their mean sequential write speed.
More important than the mean write speed is spikes (or generally high values) in the maximum write time per block (of 4 KB) or `fsync` times, as a long write time means a larger log buffer is needed to avoid dropouts.
PX4 uses bigger buffers on F7/H7 and read caching, which is enough to compensate for spikes in many poor cards.
That said, if your card has an `fsync` or write duration of several 100ms it is should not be preferred for use with PX4.
You can check the value by running [sd_bench](../modules/modules_command.md#sd-bench) should be run with more iterations (around 100 should do).
```sh
sd_bench -r 100
```
이것은 최소 버퍼 크기를 정의합니다. 이 최대값이 클수록 드롭아웃을 피하기 위하여 더 큰 로그 버퍼가 필요합니다.
PX4 uses bigger buffers on F7/H7 and read caching to make up for some of these issues.
:::info
If you have concerns about a particular card you can run the above test and report the results to https://github.com/PX4/PX4-Autopilot/issues/4634.
:::
## 로그 스트리밍
로깅을 수행하는 전통적인 완벽한 방법은 FMU에서 SD 카드를 사용하는 것입니다.
그러나, MAVLink를 통하여 동일한 로깅 데이터를 보내는 대체 로그 스트리밍이 있습니다.
이 방법은 예를 들어 FMU에 SD 카드 슬롯이 없는 경우(예: Intel® Aero Ready to Fly Drone) 또는 단순히 SD 카드를 처리할 필요가 없는 경우에 사용할 수 있습니다.
두 방법 모두 독립적으로 동시에 사용할 수 있습니다.
요구 사항은 최소 ~50KB/s 네트웍 속도입니다(예: WiFi 링크).
그리고, 한 클라이언트만 동시에 로그 스트리밍을 요청할 수 있습니다.
연결이 안정적일 필요는 없으며, 프로토콜은 드롭을 처리하도록 설계되었습니다.
ulog 스트리밍을 지원하는 다양한 클라이언트가 있습니다.
- `mavlink_ulog_streaming.py` script in PX4-Autopilot/Tools.
- QGroundControl:
![QGC Log Streaming](../../assets/gcs/qgc-log-streaming.png)
- [MAVGCL](https://github.com/ecmnet/MAVGCL)
### 진단
- If log streaming does not start, make sure the `logger` is running (see above), and inspect the console output while starting.
- 그래도 작동하지 않으면, MAVLink 2를 사용하고 있는지 확인하십시오.
Enforce it by setting `MAV_PROTO_VER` to 2.
- Log streaming uses a maximum of 70% of the configured MAVLink rate (`-r` parameter).
더 큰 전송율이 요구되는 상황에서는, 메세지가 사라집니다.
The currently used percentage can be inspected with `mavlink status` (1.8% is used in this example):
```sh
instance #0:
GCS heartbeat: 160955 us ago
mavlink chan: #0
type: GENERIC LINK OR RADIO
flow control: OFF
rates:
tx: 95.781 kB/s
txerr: 0.000 kB/s
rx: 0.021 kB/s
rate mult: 1.000
ULog rate: 1.8% of max 70.0%
accepting commands: YES
MAVLink version: 2
transport protocol: UDP (14556)
```
Also make sure `txerr` stays at 0.
만약 이 값이 올라간다면, NuttX 전송 버퍼가 너무 작거나, 물리 링크 대역폭이 포화 상태이거나, 하드웨어가 데이터를 처리하기에 너무 느린 상황을 의미합니다.
## See Also
- [Encrypted logging](../dev_log/log_encryption.md)
+512
View File
@@ -0,0 +1,512 @@
# ULog 파일 포맷
ULog is the file format used for logging messages. The format is self-describing, i.e. it contains the format and [uORB](../middleware/uorb.md) message types that are logged.
This document is meant to be the ULog File Format Spec Documentation.
It is intended especially for anyone who is interested in writing a ULog parser / serializer and needs to decode / encode files.
PX4 uses ULog to log uORB topics as messages related to (but not limited to) the following sources:
- **Device inputs:** Sensors, RC input, etc.
- **Internal states:** CPU load, attitude, EKF state, etc.
- **String messages:** `printf` statements, including `PX4_INFO()` and `PX4_ERR()`.
The format uses [little endian](https://en.wikipedia.org/wiki/Endianness) memory layout for all binary types (the least significant byte (LSB) of data type is placed at the lowest memory address).
## 데이터 형식
The following binary types are used for logging. They all correspond to the types in C.
| 형식 | 바이트 크기 |
| ----------------------------------------------------------- | ------ |
| int8_t, uint8_t | 1 |
| int16_t, uint16_t | 2 |
| int32_t, uint32_t | 4 |
| int64_t, uint64_t | 8 |
| float | 4 |
| double | 8 |
| bool, char | 1 |
Additionally the types can be used as a fixed-size array: e.g. `float[5]`.
Strings (`char[length]`) do not contain the termination NULL character `'\0'` at the end.
:::info
String comparisons are case sensitive, which should be taken into account when comparing message names when [adding subscriptions](#a-subscription-message).
:::
## ULog File Structure
ULog files have the following three sections:
```
----------------------
| Header |
----------------------
| Definitions |
----------------------
| Data |
----------------------
```
A description of each section is provided below.
### 헤더 섹션
헤더는 고정 크기 섹션이며, 다음 형식(16바이트)을 갖습니다.
```plain
----------------------------------------------------------------------
| 0x55 0x4c 0x6f 0x67 0x01 0x12 0x35 | 0x01 | uint64_t |
| File magic (7B) | Version (1B) | Timestamp (8B) |
----------------------------------------------------------------------
```
- **File Magic (7 Bytes):** File type indicator that reads "ULogXYZ where XYZ is the magic bytes sequence `0x01 0x12 0x35`"
- **Version (1 Byte):** File format version (currently 1)
- **Timestamp (8 Bytes):** `uint64_t` integer that denotes when the logging started in microseconds.
### Definition & Data Section Message Header
The _Definitions and Data_ sections contain a number of **messages**. Each message is preceded by this header:
```c
struct message_header_s {
uint16_t msg_size;
uint8_t msg_type;
};
```
- `msg_size` is the size of the message in bytes without the header.
- `msg_type` defines the content, and is a single byte.
:::info
Message sections below are prefixed with the character that corresponds to it's `msg_type`.
:::
### 정의 섹션
The definitions section contains basic information such as software version, message format, initial parameter values, and so on.
The message types in this section are:
1. [Flag Bits](#b-flag-bits-message)
2. [Format Definition](#f-format-message)
3. [Information](#i-information-message)
4. [Multi Information](#m-multi-information-message)
5. [Parameter](#p-parameter-message)
6. [Default Parameter](#q-default-parameter-message)
#### 'B': Flag Bits Message
:::info
This message must be the **first message** right after the header section, so that it has a fixed constant offset from the start of the file!
:::
This message provides information to the log parser whether the log is parsable or not.
```c
struct ulog_message_flag_bits_s {
struct message_header_s header; // msg_type = 'B'
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`: compatible flag bits
- These flags indicate the presence of features in the log file that are compatible with any ULog parser.
- `compat_flags[0]`: _DEFAULT_PARAMETERS_ (Bit 0): if set, the log contains [default parameters message](#q-default-parameter-message)
The rest of the bits are currently not defined and must be set to 0.
이 비트는 향후 기존 파서와 호환되는 ULog 변경에 사용할 수 있습니다.
For example, adding a new message type can be indicated by defining a new bit in the standard, and existing parsers will ignore the new message type.
이는 알 수 없는 비트 중 하나가 설정되어 있으면, 파서가 해당 비트를 무시할 수 있음을 의미합니다.
- `incompat_flags`: incompatible flag bits.
- `incompat_flags[0]`: _DATA_APPENDED_ (Bit 0): if set, the log contains appended data and at least one of the `appended_offsets` is non-zero.
The rest of the bits are currently not defined and must be set to 0.
이것은 기존 파서가 처리할 수 없는 주요 변경 사항을 도입하는 데 사용할 수 있습니다. For example, when an old ULog parser that didn't have the concept of _DATA_APPENDED_ reads the newer ULog, it would stop parsing the log as the log will contain out-of-spec messages / concepts.
If a parser finds any of these bits set that isn't specified, it must refuse to parse the log.
- `appended_offsets`: File offset (0-based) for appended data.
데이터가 추가되지 않은 경우에는 모든 오프셋은 0이어야 합니다.
이것은 메시지 중간에 멈출 수 있는 로그에 대한 데이터를 안정적으로 추가할 수 있습니다.
For example, crash dumps.
데이터를 추가하는 프로세스는 다음과 같습니다.
- set the relevant `incompat_flags` bit
- set the first `appended_offsets` that is currently 0 to the length of the log file without the appended data, as that is where the new data will start
- append any type of messages that are valid for the Data section.
향후 ULog 사양에서 이 메시지 끝에 추가 필드가 존재할 수 있습니다.
이것은 파서가 이 메시지의 고정된 길이를 가정해서는 안 된다는 것을 의미합니다.
If the `msg_size` is bigger than expected (currently 40), any additional bytes must be ignored/discarded.
#### 'F': Format Message
Format message defines a single message name and its inner fields in a single string.
```c
struct message_format_s {
struct message_header_s header; // msg_type = 'F'
char format[header.msg_size];
};
```
- `format` is a plain-text string with the following format: `message_name:field0;field1;`
- There can be an arbitrary amount of fields (minimum 1), separated by `;`.
- `message_name`: an arbitrary non-empty string with these allowed characters: `a-zA-Z0-9_-/` (and different from any of the [basic types](#data-types)).
A `field` has the format: `type field_name`, or for an array: `type[array_length] field_name` is used (only fixed size arrays are supported).
`field_name` must consist of the characters in the set `a-zA-Z0-9_`.
A `type` is one of the [basic binary types](#data-types) or a `message_name` of another format definition (nested usage).
- 유형은 정의되기 전에 사용할 수 있습니다.
- e.g. The message `MessageA:MessageB[2] msg_b` can come before the `MessageB:uint_8[3] data`
- There can be arbitrary nesting but **no circular dependencies**
- e.g. `MessageA:MessageB[2] msg_b` & `MessageB:MessageA[4] msg_a`
일부 필드 이름은 특별합니다.
- `timestamp`: every message format with a [Subscription Message](#a-subscription-message) must include a timestamp field (for example a message format only used as part of a nested definition by another format may not include a timestamp field)
- Its type must be `uint64_t`.
- The unit is microseconds.
- The timestamp must always be monotonic increasing for a message series with the same `msg_id` (same subscription).
- `_padding{}`: field names that start with `_padding` (e.g. `_padding[3]`) should not be displayed and their data must be ignored by a reader.
- 이 필드는 올바른 정렬을 보장하기 위하여 작성자가 삽입할 수 있습니다.
- If the padding field is the last field, then this field may not be logged, to avoid writing unnecessary data.
- This means the `message_data_s.data` will be shorter by the size of the padding.
- 그러나 메시지가 중첩 정의에서 사용될 때 패딩은 여전히 필요합니다.
- In general, message fields are not necessarily aligned (i.e. the field offset within the message is not necessarily a multiple of its data size), so a reader must always use appropriate memory copy methods to access individual fields.
#### 'I': Information Message
The Information message defines a dictionary type definition `key` : `value` pair for any information, including but not limited to Hardware version, Software version, Build toolchain for the software, etc.
```c
struct ulog_message_info_header_s {
struct message_header_s header; // msg_type = 'I'
uint8_t key_len;
char key[key_len];
char value[header.msg_size-1-key_len]
};
```
- `key_len`: Length of the key value
- `key`: Contains the key string in the form`type name`, e.g. `char[value_len] sys_toolchain_ver`. Valid characters for the name: `a-zA-Z0-9_-/`. The type may be one of the [basic types including arrays](#data-types).
- `value`: Contains the data (with the length `value_len`) corresponding to the `key` e.g. `9.4.0`.
:::info
A key defined in the Information message must be unique. Meaning there must not be more than one definition with the same key value.
:::
파서는 정보 메시지를 사전으로 저장할 수 있습니다.
사전 정의된 정보 메시지는 다음과 같습니다.
| 키 | 설명 | 예제 값 |
| ----------------------------------- | ------------------------------------------------------- | ----------------------------------------------------------------- |
| `char[value_len] sys_name` | 시스템 이름 | "PX4" |
| `char[value_len] ver_hw` | 하드웨어 버전 (보드) | "PX4FMU_V4" |
| `char[value_len] ver_hw_subtype` | 보드 하위 버전(변형판) | "V2" |
| `char[value_len] ver_sw` | 소프트웨어 버전(git tag) | "7f65e01" |
| `char[value_len] ver_sw_branch` | git branch | "master" |
| `uint32_t ver_sw_release` | 소프트웨어 버전 (아래 참고) | 0x010401ff |
| `char[value_len] sys_os_name` | 운영체제 이름 | "Linux" |
| `char[value_len] sys_os_ve`r | 운영체제 버전 (git tag) | "9f82919" |
| `uint32_t ver_os_release` | 운영체제 버전 (아래 참고) | 0x010401ff |
| `char[value_len] sys_toolchain` | 툴체인 이름 | "GNU GCC" |
| `char[value_len] sys_toolchain_ver` | 툴체인 버전 | "6.2.1" |
| `char[value_len] sys_mcu` | 칩 이름과 버전 | "STM32F42x, rev A" |
| `char[value_len] sys_uuid` | 차량 고유 식별자(예: MCU ID) | "392a93e32fa3"... |
| `char[value_len] log_type` | 로그 형식(지정하지 않으면 전체 기록) | "mission" |
| `char[value_len] replay` | 재생 모드인 경우 재생된 로그의 파일 이름 | "log001.ulg" |
| `int32_t time_ref_utc` | UTC 시간 오프셋(초) | -3600 |
:::info
`value_len` represents the data size of the `value`. This is described in the `key`.
:::
- The format of `ver_sw_release` and `ver_os_release` is: 0xAABBCCTT, where AA is **major**, BB is **minor**, CC is patch and TT is the **type**.
- **Type** is defined as following: `>= 0`: development, `>= 64`: alpha version, `>= 128`: beta version, `>= 192`: RC version, `== 255`: release version.
- For example, `0x010402FF` translates into the release version v1.4.2.
이 메시지는 데이터 섹션에서도 사용할 수 있습니다(그러나 선호하는 섹션임).
#### 'M': Multi Information Message
Multi information message serves the same purpose as the information message, but for long messages or multiple messages with the same key.
```c
struct ulog_message_info_multiple_header_s {
struct message_header_s header; // msg_type = 'M'
uint8_t is_continued; // can be used for arrays
uint8_t key_len;
char key[key_len];
char value[header.msg_size-2-key_len]
};
```
- `is_continued` can be used for split-up messages: if set to 1, it is part of the previous message with the same key.
파서는 다중 메시지를 로그에서 발생하는 메시지와 동일한 순서를 사용하여 2D 목록으로 저장할 수 있습니다.
Valid names and types are the same as for the Information message.
#### 'P': Parameter Message
Parameter message in the _Definitions_ section defines the parameter values of the vehicle when logging is started. It uses the same format as the [Information Message](#i-information-message).
```c
struct message_info_s {
struct message_header_s header; // msg_type = 'P'
uint8_t key_len;
char key[key_len];
char value[header.msg_size-1-key_len]
};
```
If a parameter dynamically changes during runtime, this message can also be [used in the Data section](#messages-shared-with-the-definitions-section) as well.
The data type is restricted to `int32_t` and `float`. Valid characters for the name: `a-zA-Z0-9_-/`.
#### 'Q': Default Parameter Message
The default parameter message defines the default value of a parameter for a given vehicle and setup.
```c
struct ulog_message_parameter_default_header_s {
struct message_header_s header; // msg_type = 'Q'
uint8_t default_types;
uint8_t key_len;
char key[key_len];
char value[header.msg_size-2-key_len]
};
```
- `default_types` is a bitfield and defines to which group(s) the value belongs to.
- 최소한 하나의 비트가 설정되어야 합니다.
- `1<<0`: system wide default
- `1<<1`: default for the current configuration (e.g. an airframe)
로그에는 모든 매개변수에 대한 기본값이 포함되어 있지 않을 수 있습니다.
이러한 경우 기본값은 매개변수 값과 같고, 다른 기본 유형은 독립적으로 처리됩니다.
This message can also be used in the Data section, and the same data type and naming applies as for the Parameter message.
This section ends before the start of the first [Subscription Message](#a-subscription-message) or [Logging](#l-logged-string-message) message, whichever comes first.
### 데이터 섹션
The message types in the _Data_ section are:
1. [Subscription](#a-subscription-message)
2. [Unsubscription](#r-unsubscription-message)
3. [Logged Data](#d-logged-data-message)
4. [Logged String](#l-logged-string-message)
5. [Tagged Logged String](#c-tagged-logged-string-message)
6. [Synchronization](#s-synchronization-message)
7. [Dropout Mark](#o-dropout-message)
8. [Information](#i-information-message)
9. [Multi Information](#m-multi-information-message)
10. [Parameter](#p-parameter-message)
11. [Default Parameter](#q-default-parameter-message)
#### `A`: Subscription Message
Subscribe a message by name and give it an id that is used in [Logged data Message](#d-logged-data-message).
This must come before the first corresponding [Logged data Message](#d-logged-data-message).
```c
struct message_add_logged_s {
struct message_header_s header; // msg_type = 'A'
uint8_t multi_id;
uint16_t msg_id;
char message_name[header.msg_size-3];
};
```
- `multi_id`: the same message format can have multiple instances, for example if the system has two sensors of the same type. 기본 및 첫 번째 인스턴스는 0이어야 합니다.
- `msg_id`: unique id to match [Logged data Message](#d-logged-data-message) data. 처음 사용할 때는 이것을 0으로 설정한 다음 증가시켜야 합니다.
- The same `msg_id` must not be used twice for different subscriptions.
- `message_name`: message name to subscribe to.
Must match one of the [Format Message](#f-format-message) definitions.
#### `R`: Unsubscription Message
Unsubscribe a message, to mark that it will not be logged anymore (not used currently).
```c
struct message_remove_logged_s {
struct message_header_s header; // msg_type = 'R'
uint16_t msg_id;
};
```
#### 'D': Logged Data Message
```c
struct message_data_s {
struct message_header_s header; // msg_type = 'D'
uint16_t msg_id;
uint8_t data[header.msg_size-2];
};
```
- `msg_id`: as defined by a [Subscription Message](#a-subscription-message)
- `data` contains the logged binary message as defined by [Format Message](#f-format-message)
패딩 필드의 특수 처리에 대해서는 위를 참고하십시오.
#### 'L': Logged String Message
Logged string message, i.e. `printf()` output.
```c
struct message_logging_s {
struct message_header_s header; // msg_type = 'L'
uint8_t log_level;
uint64_t timestamp;
char message[header.msg_size-9]
};
```
- `timestamp`: in microseconds
- `log_level`: same as in the Linux kernel:
| 명칭 | 레벨 | 설명 |
| ------- | --- | ------------- |
| EMERG | '0' | 시스템 사용 불가 |
| ALERT | '1' | 즉시 조치 |
| CRIT | '2' | 임계 조건 |
| ERR | '3' | 오류 조건 |
| WARNING | '4' | 경고 조건 |
| NOTICE | '5' | 정상적이지만 중요한 상태 |
| INFO | '6' | 정보 제공 |
| DEBUG | '7' | 디버그 수준 메시지 |
#### 'C': Tagged Logged String Message
```c
struct message_logging_tagged_s {
struct message_header_s header; // msg_type = 'C'
uint8_t log_level;
uint16_t tag;
uint64_t timestamp;
char message[header.msg_size-11]
};
```
- `tag`: id representing source of logged message string. 시스템 아키텍처에 따라 프로세스, 스레드 또는 클래스를 나타낼 수 있습니다.
- For example, a reference implementation for an onboard computer running multiple processes to control different payloads, external disks, serial devices etc can encode these process identifiers using a `uint16_t enum` into the `tag` attribute of struct as follows:
```c
enum class ulog_tag : uint16_t {
unassigned,
mavlink_handler,
ppk_handler,
camera_handler,
ptp_handler,
serial_handler,
watchdog,
io_service,
cbuf,
ulg
};
```
- `timestamp`: in microseconds
- `log_level`: same as in the Linux kernel:
| 명칭 | 레벨 | 설명 |
| ------- | --- | ------------- |
| EMERG | '0' | 시스템 사용 불가 |
| ALERT | '1' | 즉시 조치 |
| CRIT | '2' | 임계 조건 |
| ERR | '3' | 오류 조건 |
| WARNING | '4' | 경고 조건 |
| NOTICE | '5' | 정상적이지만 중요한 상태 |
| INFO | '6' | 정보 제공 |
| DEBUG | '7' | 디버그 수준 메시지 |
#### 'S': Synchronization message
Synchronization message so that a reader can recover from a corrupt message by searching for the next sync message.
```c
struct message_sync_s {
struct message_header_s header; // msg_type = 'S'
uint8_t sync_magic[8];
};
```
- `sync_magic`: [0x2F, 0x73, 0x13, 0x20, 0x25, 0x0C, 0xBB, 0x12]
#### 'O': Dropout message
Mark a dropout (lost logging messages) of a given duration in ms.
장치가 충분히 빠르지 않은 경우에는 손실이 발생할 수 있습니다.
```c
struct message_dropout_s {
struct message_header_s header; // msg_type = 'O'
uint16_t duration;
};
```
#### Messages shared with the Definitions Section
Since the Definitions and Data Sections use the same message header format, they also share the same messages listed below:
- [Information Message](#i-information-message).
- [Multi Information Message](#m-multi-information-message)
- [Parameter Message](#p-parameter-message)
- For the _Data_ section, the Parameter Message is used when the parameter value changes
- [Default Parameter Message](#q-default-parameter-message)
## 파서 요구 사항
유효한 ULog 파서는 요구 사항은 다음과 같습니다.
- Must ignore unknown messages (but it can print a warning)
- 미래의/알 수 없는 파일 형식 버전도 구문 분석합니다(하지만 경고를 인쇄할 수 있음).
- Must refuse to parse a log which contains unknown incompatibility bits set (`incompat_flags` of [Flag Bits Message](#b-flag-bits-message)), meaning the log contains breaking changes that the parser cannot handle.
- 파서는 메시지 중간에 갑자기 끝나는 로그를 올바르게 처리할 수 있어야 합니다.
완료되지 않은 메시지는 무시하여야 합니다.
- 추가된 데이터의 경우: 파서는 데이터 섹션이 존재한다고 가정할 수 있습니다. 즉 오프셋은 정의 섹션 뒤의 위치를 가리킵니다.
- 추가된 데이터는 일반 데이터 섹션의 일부인 것처럼 처리하여야 합니다.
## Known Parser Implementations
- PX4-오토파일럿: C++
- [logger module](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/logger)
- [replay module](https://github.com/PX4/PX4-Autopilot/tree/main/src/modules/replay)
- [hardfault_log module](https://github.com/PX4/PX4-Autopilot/tree/main/src/systemcmds/hardfault_log): append hardfault crash data.
- [pyulog](https://github.com/PX4/pyulog): python, ULog reader and writer library with CLI scripts.
- [ulog_cpp](https://github.com/PX4/ulog_cpp): C++, ULog reader and writer library.
- [FlightPlot](https://github.com/PX4/FlightPlot): Java, log plotter.
- [MAVLink](https://github.com/mavlink/mavlink): Messages for ULog streaming via MAVLink (note that appending data is not supported, at least not for cut off messages).
- [QGroundControl](https://github.com/mavlink/qgroundcontrol): C++, ULog streaming via MAVLink and minimal parsing for GeoTagging.
- [mavlink-router](https://github.com/01org/mavlink-router): C++, ULog streaming via MAVLink.
- [MAVGAnalysis](https://github.com/ecmnet/MAVGCL): Java, ULog streaming via MAVLink and parser for plotting and analysis.
- [PlotJuggler](https://github.com/facontidavide/PlotJuggler): C++/Qt application to plot logs and time series. 버전 2.1.3부터 ULog를 지원합니다.
- [ulogreader](https://github.com/maxsun/ulogreader): Javascript, ULog reader and parser outputs log in JSON object format.
- [Foxglove Studio](https://github.com/foxglove/studio): an integrated visualization and diagnosis tool for robotics
(Typescript ULog parser: https://github.com/foxglove/ulog).
## 파일 형식 버전 이력
### 버전 2의 변경 사항
- Addition of [Multi Information Message](#m-multi-information-message) and [Flag Bits Message](#b-flag-bits-message) and the ability to append data to a log.
- 기존 로그에 충돌 데이터를 추가하는 데 사용됩니다.
- 메시지 중간에 잘린 로그에 데이터가 추가되면, 버전 1 파서로 파싱할 수 없습니다.
- 그 외의 파서가 알 수 없는 메시지를 무시하면, 순방향 및 역방향 호환성이 제공됩니다.