## 용어 정의
| 용어 | 의미 | 예시 |
|---|---|---|
| **트랙 (track)** | 하나의 차트에 함께 표시되는 채널들의 그룹. 서로 다른 센서의 채널을 자유롭게 조합할 수 있다. | GPS 고도 + 기압 고도 + EKF 고도를 하나의 차트에 표시 |
| **채널 (channel)** | 하나의 값 배열을 가진 개별 데이터 시리즈. timestamps와 동일한 길이의 숫자 배열이다. | `battery_status__voltage_v` |
| **채널 메타 (channelMeta)** | 채널의 표시 정보 (이름, 단위, 색상, 차트 타입). | `{ name: "전압", unit: "V", color: "#ab47bc", chartType: "line" }` |
:::tip[PX4 ULog와의 관계]
ULog의 **토픽(topic)** 은 여러 필드를 가진 메시지 타입이고, dm_schema의 **채널(channel)** 은 토픽의 개별 필드에 대응합니다.
하나의 토픽이 여러 인스턴스를 가질 수 있으며(예: `sensor_accel[0]`, `sensor_accel[1]`), 각 인스턴스의 필드가 개별 채널이 됩니다.
트랙은 PX4에 없는 개념으로, 어떤 토픽의 어떤 필드든 자유롭게 조합하여 하나의 차트로 묶을 수 있습니다.
| PX4 ULog | dm_schema | 관계 |
|---|---|---|
| topic (예: `battery_status`) | — | 직접 대응 없음 (채널의 출처) |
| topic.field (예: `battery_status.voltage_v`) | channel | 1:1 대응 |
| — | track | PX4에 없는 개념 (사용자 정의 그룹) |
:::
---
## 프로젝트 카테고리
| `project.category` |
| --- |
| `time_series_annotation` |
## 지원 도구
| `project.annotation_types[]` | 설명 |
| --- | --- |
| `time_range` | 시간 범위 어노테이션 |
---
:::warning[초안]
⬇️ ⬇️ 아래 **데이터 유닛** 섹션부터 문서 끝까지는 작성 중인 내용으로, 확정되지 않았습니다.
:::
---
## 데이터 유닛
시계열 데이터 유닛은 동일한 시간 범위를 공유하는 센서 채널들의 집합입니다.
### task.data_unit.files
```jsonc
{
"timeSeriesData": {
"url": "https://storage.example.com/timeseries-data.json",
"is_primary": true,
"file_type": "json",
"meta": {
"channels": {
"채널ID": {
"name": "채널 표시 이름",
"unit": "단위 (예: m/s², deg)",
"color": "#3b82f6",
"chartType": "line", // → ChartType
"sampleRate": 100
}
},
"timeRange": {
"start": 1704067200000, // epoch_ms
"end": 1704069600000, // epoch_ms
"unit": "epoch_ms"
}
}
}
}
```
### url이 가리키는 시계열 데이터 JSON
ULG(ULog) 형식을 차용합니다.
`timestamps` 및 `meta.startTime` / `endTime`은 **Unix Epoch 기준 밀리초(epoch_ms)** 를 사용합니다.
`timeAxis.origin`으로 timestamps의 기준을 명시하며, 컨버터를 통해 다른 기준으로 변환할 수 있습니다.
화면 표시 형식은 `timeAxis.format`으로 지정합니다.
```jsonc
{
"meta": {
"startTime": 1613693139891, // epoch_ms
"endTime": 1613693426291, // epoch_ms
"duration": 286.4, // 초(s)
"sampleRate": 10, // Hz
"nSamples": 2865,
"timeAxis": {
"origin": "absolute", // → TimeAxisOrigin
"format": "HH:mm" // → TimeAxisFormat
}
},
"timestamps": [1613693139891, 1613693139991, "..."], // epoch_ms 배열
"tracks": [
{
"id": "altitude-estimate", // 임의의 문자열 (kebab-case 권장)
"name": "트랙 이름",
"chartType": "line", // → ChartType
"channels": ["채널ID_1", "채널ID_2"],
"yRange": { "min": -30, "max": 30 }, // Y축 클리핑 (선택)
"thresholds": [ // 배경색 구간 (선택)
{ "max": 4.905, "color": "rgba(34,197,94,0.15)", "label": "Good" },
{ "min": 4.905, "max": 9.81, "color": "rgba(253,203,110,0.15)", "label": "Warning" }
]
}
],
"channels": {
"채널ID_1": [0.1, 0.2, "..."], // timestamps와 길이 동일
"채널ID_2": [1.0, 1.1, "..."]
},
"channelMeta": {
"채널ID_1": {
"name": "채널 표시 이름",
"unit": "m/s²",
"color": "#cc6600",
"chartType": "line" // → ChartType
}
}
}
```
## 타입 상세
### ChartType
| 값 | 설명 |
| --- | --- |
| `line` | 라인 차트 |
| `scatter` | 산점도 |
| `psd` | Power Spectral Density |
| `fft` | Fast Fourier Transform |
### TimeAxisOrigin
timestamps의 기준점을 지정합니다.
**프로그램은 `absolute` 기준으로만 동작합니다.** 다른 origin의 데이터는 별도 컨버터를 통해 `absolute`로 변환한 후 사용해야 합니다.
| 값 | 설명 |
| --- | --- |
| `absolute` | Unix Epoch 기준 밀리초 (**프로그램 기본 작동 기준**) |
| `relative` | 시작 시간으로부터의 경과 밀리초 (컨버터 필요) |
| `boot` | 시스템 부팅 시간 기준 밀리초 (컨버터 필요) |
### ChannelThreshold
트랙의 Y축에 표시되는 배경색 구간입니다. `tracks[].thresholds` 배열의 각 요소입니다.
| 필드 | 타입 | 필수 | 설명 |
| --- | --- | --- | --- |
| `color` | `string` | O | 배경색 (rgba 권장) |
| `label` | `string` | X | 구간 라벨 |
| `min` | `number` | X | Y축 최소값 (미지정 시 -∞) |
| `max` | `number` | X | Y축 최대값 (미지정 시 +∞) |
### YRange
트랙의 Y축 표시 범위를 고정합니다. `tracks[].yRange` 객체입니다.
| 필드 | 타입 | 필수 | 설명 |
| --- | --- | --- | --- |
| `min` | `number` | O | Y축 하한 |
| `max` | `number` | O | Y축 상한 |
### TimeAxisFormat
화면에 표시할 시간 형식을 지정합니다. [Day.js 포맷](https://day.js.org/docs/en/display/format) 문자열을 사용합니다.
| 예시 | 출력 |
| --- | --- |
| `HH:mm:ss` | 14:05:32 |
| `HH:mm` | 14:05 |
| `s.SSS` | 5.320 |
| `MM-DD HH:mm` | 02-18 14:05 |