feat(lidar): add dataset gateway boundary

This commit is contained in:
DCCONSTRUCTIONS
2026-07-25 11:21:22 +03:00
parent 3333e9ac0f
commit f57d64bf52
14 changed files with 1314 additions and 17 deletions
+48 -17
View File
@@ -1,8 +1,8 @@
# LiDAR worker: product value, evidence boundary and implementation roadmap
Date: 2026-07-25
Status: accepted architecture plan; L0/L1 implemented; L2 diagnostic A/B complete,
independent labels pending
Status: accepted architecture plan; L0/L1 implemented; L2 diagnostic A/B complete;
Dataset Gateway S0 implemented, first real GOOSE import pending worker D storage
Scope: real scanner records, replay and future live shadow processing
Explicitly out of scope: Unreal U0/U1, Gaussian assets and simulator rendering
@@ -110,7 +110,9 @@ unknown, camera-only velocity is not metric, 374 conflicts remain, and the
benchmark is not independent ground truth.
The next work must therefore improve the LiDAR-native input and evaluation
surface, not add another visual smoothing pass.
surface, not add another visual smoothing pass. Mission Core will use
independently labeled public datasets before requesting any new manual K1
annotation. The current K1 evidence stays an unlabeled out-of-domain smoke test.
## 4. Market and stack assessment
@@ -236,10 +238,10 @@ quality line. It is not repaired or hidden by replay.
distributions in `missioncore.lidar-ground-benchmark/v1`.
- [x] Create an immutable eight-frame annotation template in which every point
starts as `ignore-unreviewed`; it is explicitly not ground truth.
- [ ] Complete independent human review for ground, curb, low obstacle,
reflection noise and other non-ground points.
- [ ] Measure accepted ground IoU, curb/low-obstacle recall and
reflection-noise rejection against that reviewed generation.
- [ ] Keep the K1 annotation template frozen as an optional later
domain-adaptation asset; do not make manual review the current critical path.
- [ ] Measure accepted ground IoU and obstacle recall first against an admitted
GOOSE native scan and its published point-wise labels.
The real diagnostic run is
`ground-benchmark-68cfd7a8f1dd4c0006183bb4f63a23f9ff1dd7459317ff0886e995f6c320d984`.
@@ -285,16 +287,43 @@ geometry is not exported. The measured 1.27 m estimate can be reproduced as a
named diagnostic profile; tuning that offset until Patchwork++ merely looks
plausible would still invalidate the comparison.
The independent-label exit remains open. It can be closed by reviewing the
content-bound template
`ground-annotation-template-12e12eab0756c14f5e06adcaf13189e93188df9bb6d31224cb9b7d566ec15b18`,
or by acquiring an admitted raw sensor scan with known physical sensor height
and then producing a new benchmark generation.
The K1-specific independent-label exit remains open, but it is no longer the
next step. The Dataset Gateway provides a labeled public-domain evaluation
path. K1 manual review or a new real vehicle dataset is reserved for later
domain adaptation after a public baseline proves that the pipeline and metric
harness work.
### L2.5 — Dataset Gateway — S0 complete, real import pending
- [x] Define separate `native-scan`, `normalized-scan` and
`rolling-local-map` representations.
- [x] Add a lossless GOOSE/SemanticKITTI XYZI + packed semantic/instance label
reader with point-alignment and finite-value gates.
- [x] Publish the read-only Dataset Gateway contract in React.
- [x] Refuse to relabel current `lio_pcl` as a native scan or to invent missing
per-point time and line/ring fields.
- [x] Require operator-admitted storage under
`D:\NDC_MISSIONCORE\datasets`.
- [ ] Configure the worker dataset root and record disk/resource baseline.
- [ ] Download only the 3.3 GB GOOSE validation archive first and record its
hash/license/provenance.
- [ ] Show one real labeled revolution in React with native remission and
ground-truth superclass coloring.
- [ ] Admit an explicit frame/mounting profile before normalization.
- [ ] Run current ground and Patchwork++ against GOOSE ground truth.
- [ ] Add named range/FOV/density/noise/dropout degradation profiles without
overwriting the native frame.
The architectural contract and run sequence are fixed in
`docs/14_LIDAR_DATASET_GATEWAY.md` and ADR 0021. GOOSE is first because its
published 3D format is one LiDAR revolution with point-wise semantic and
instance labels in off-road environments. RELLIS-3D remains the second-source
cross-check after the GOOSE harness is stable.
### L3 — LiDAR-native 3D detection
- [ ] Freeze independent 3D annotations covering people, vehicles, cyclists,
stroller groups, vegetation and confusing static structures.
- [ ] Establish the public-dataset baseline first; freeze K1-specific 3D
annotations only when a measured domain gap justifies them.
- [ ] Run NVIDIA PointPillars through the existing external worker/Triton seam.
- [ ] Treat pretrained output as a baseline, not an accepted product model.
- [ ] Measure class precision/recall, center/range/yaw error, distance-bucket
@@ -358,6 +387,8 @@ The near-term value is not a prettier point cloud:
- hardware selection becomes evidence-driven: a future vehicle LiDAR is
accepted by its timing/fields/profile, not by vendor marketing.
The highest-value immediate work is L1, followed by L2 and L3. Nvblox and
alternative SLAM are useful, but starting them before their input gates would
produce attractive demos with unqualified geometry.
The highest-value immediate work is the worker-side GOOSE validation import,
the first labeled native scan in React and an accuracy-bearing ground A/B.
LiDAR-native detection follows on the same gateway. Nvblox and alternative
SLAM remain later because their timing, pose and scan-geometry gates are not yet
satisfied.
+140
View File
@@ -0,0 +1,140 @@
# LiDAR Dataset Gateway
## Product value
The Dataset Gateway gives Mission Core a repeatable perception laboratory
before the production vehicle and its final sensor installation exist. It
separates four questions that were previously mixed together:
- whether the transport preserved the sensor evidence;
- whether preprocessing produces a valid one-scan perception input;
- whether an algorithm is accurate against independent labels;
- whether several scans form a stable local map for an operator or planner.
This prevents tuning an algorithm until a visually dense vendor map merely
looks plausible. It also keeps work reusable across Gazebo, Unreal, public
datasets and future real onboard sensors.
## Current S0 slice
Implemented now:
- `missioncore.dataset-gateway-catalog/v1`, exposed read-only at
`GET /api/v1/lidar/dataset-gateway`;
- explicit `native-scan`, `normalized-scan` and `rolling-local-map`
representations;
- a lossless GOOSE/SemanticKITTI frame reader for little-endian float32 XYZI
and packed uint32 semantic/instance labels;
- count, finite-value and maximum-point safety gates;
- immutable point-aligned arrays;
- a fail-closed K1 `lio_pcl` boundary;
- worker storage admission for `D:\NDC_MISSIONCORE\datasets` and
`/mnt/d/NDC_MISSIONCORE/datasets`;
- a visible Dataset Gateway panel in **Данные → Качество LiDAR**.
Not implemented in S0:
- no automatic 3.3 GB validation archive download;
- no implicit coordinate conversion;
- no fake ring/timestamp reconstruction for K1 MQTT evidence;
- no model training or production promotion;
- no rolling-map implementation yet.
## Why public recordings look different
GOOSE stores one VLS-128 revolution per annotated `.bin` file. A rotating
multi-channel sensor produces discrete scan lines, so a single sensor-frame
view looks like sparse rings.
The current field review is explicitly an accumulated map-frame window. It
combines many source publications after pose registration. This fills surfaces
and hides the original scan pattern. The external K1 stream is also already a
post-LIO/modeling product and lacks the raw driver fields needed to reconstruct
an original scan.
Livox sensors additionally use a scan pattern that differs from classic fixed
vertical channels. Time integration therefore changes their visual density in
a different way. “Ring-like” is a sensor geometry property, not a universal
quality target.
## Canonical processing profiles
### P0 — native evidence
Required:
- source ID and immutable frame ID;
- XYZ and the original return/remission/intensity field;
- semantic and instance labels when present;
- calibration/mounting/timing evidence as separate metadata;
- no accumulation and no hidden world transform.
Output: `native-scan`.
### P1 — normalized perception scan
Ordered operations:
1. decode and apply only evidenced factory calibration;
2. assign an explicit sensor coordinate frame;
3. deskew when per-point time and synchronized motion are available;
4. apply bounded range and field-of-view policy;
5. remove the vehicle/self mask;
6. apply named outlier and voxel policies;
7. retain a reversible index/provenance map to the native frame.
Output: `normalized-scan`.
### P2 — inference
Ground, semantic and object providers consume P1. Patchwork++ belongs here. It
does not own P0/P1 or P3.
Output: point-aligned predictions and reproducible metrics against labels.
### P3 — rolling local map
Ordered operations:
1. bind each normalized scan to an evidenced pose;
2. transform to `odom` or a declared local-map frame;
3. deduplicate with a named voxel policy;
4. expire points by TTL or travelled distance;
5. keep dynamic points short-lived or track them separately;
6. publish bounded map state and its contributing frame identities.
Output: `rolling-local-map`.
This is the stage that should stop static geometry from “jumping”. Deskew
reduces within-scan motion distortion; registration stabilizes scans across
time; TTL/dynamic filtering prevents stale ghosts.
## First dataset sequence
1. Configure `MISSIONCORE_DATASET_ROOT=/mnt/d/NDC_MISSIONCORE/datasets` on the
Windows/WSL worker.
2. Verify free space and record archive size/hash/license.
3. Download only the GOOSE 3D validation archive first (published size 3.3 GB).
4. Import one labeled frame and expose it in React as `native-scan`.
5. Show native remission and ground-truth superclass coloring.
6. Add a declared GOOSE frame/mounting profile and produce `normalized-scan`.
7. Run current ground heuristic and Patchwork++ against independent labels.
8. Add sensor-degradation profiles for range, FOV, density, noise and dropout.
9. Only after the one-frame contract passes, expand to the validation split and
add a rolling-map sequence with localization evidence.
## Acceptance checklist
- [x] Representations cannot be silently interchanged.
- [x] Large artifacts require operator-admitted D-only storage.
- [x] GOOSE XYZI and labels remain point aligned.
- [x] Invalid length and non-finite frames fail closed.
- [x] K1 mapped increments cannot claim raw-scan fields.
- [x] React exposes the architectural truth before dataset bytes exist.
- [ ] Worker D root configured.
- [ ] GOOSE validation archive hash recorded.
- [ ] First real labeled frame visible in React.
- [ ] Coordinate and mounting profile admitted.
- [ ] Patchwork++ accuracy measured against ground truth.
- [ ] Sensor-degradation matrix qualified.
- [ ] Rolling local map with pose/TTL/dynamic policy qualified.
@@ -0,0 +1,90 @@
# ADR 0021: separate native scans, normalized scans and rolling local maps
Status: accepted
Date: 2026-07-25
## Context
Public autonomous-driving and field-robotics dataset viewers commonly display
one LiDAR revolution. Fixed-channel rotating sensors therefore produce the
familiar sparse rings. The current XGRIDS K1 MQTT `lio_pcl` evidence is a
different product: firmware evidence places it after LIO/modeling, and the
field-review UI accumulates multiple already registered increments in the map
frame.
Point count alone does not make these representations comparable. A cloud can
be sparse per publication and still look dense after several seconds of pose
registration. Conversely, voxel downsampling does not restore timing, scan
lines or raw sensor geometry that the source no longer carries.
Patchwork++ is a ground classifier. It does not decode sensor packets, deskew
motion distortion, estimate pose, stabilize a rolling map or remove ghosts
from stale/dynamic observations. A successful Patchwork++ call against
`lio_pcl` remains diagnostic and does not repair the input domain.
## Decision
Mission Core defines three non-interchangeable LiDAR products:
1. `native-scan`: one losslessly decoded source scan/frame with its native
point-aligned fields and labels. It is never accumulated.
2. `normalized-scan`: one sensor-frame scan after an explicit transform,
deskew and bounded cleanup profile. Every transformation retains source
identity and point alignment.
3. `rolling-local-map`: normalized scans registered by pose into a bounded
local map with explicit TTL, voxel deduplication and dynamic-point policy.
The Dataset Gateway is the first producer of this contract. GOOSE 3D is the
first admitted source because it publishes off-road point-wise semantic and
instance labels in SemanticKITTI-compatible `XYZI + uint32 label` files. Its
annotated point-cloud file represents one LiDAR revolution.
The gateway:
- preserves the native GOOSE frame before adaptation;
- never transforms labels independently of their points;
- does not assume a coordinate convention, mounting transform or sensor height
unless source metadata supplies it;
- refuses automatic downloads of large archives;
- admits storage only under `D:\NDC_MISSIONCORE\datasets` or its WSL mirror;
- never promotes K1 `lio_pcl` to `native-scan`.
The normalized pipeline is:
```text
native packet/source frame
-> decode + calibration
-> per-point-time deskew
-> range/self/outlier/voxel policy
-> normalized-scan
-> ground/object inference
-> pose registration + TTL + voxel deduplication
-> rolling-local-map
```
Deskew is conditional: it requires per-point time plus synchronized IMU or
odometry. If those fields are missing, the gateway reports the stage as
unavailable rather than inventing timestamps.
## Consequences
- The UI must label accumulated K1 evidence as a map product, not a scan.
- Dataset and device inputs can share downstream algorithms only after their
normalized contracts match.
- Sensor adaptation may change range, FOV, point density, noise and dropout for
robustness experiments, but it cannot recreate lost timestamps, occlusions
or material response.
- Patchwork++ becomes eligible for a real quality gate only on a sensor-centric
scan with declared scan geometry and physical mounting height plus
independent labels.
- Stable operator visualization is owned by rolling-map policy, not by the
ground classifier.
## Primary references
- [GOOSE dataset structure](https://goose-dataset.de/docs/dataset-structure/)
- [GOOSE setup and archive sizes](https://goose-dataset.de/docs/setup/)
- [GOOSE 3D challenge ontology](https://goose-dataset.de/docs/3d-semantic-segmentation-challenge/)
- [Livox ROS Driver 2 point formats](https://github.com/Livox-SDK/livox_ros_driver2)
- [Livox LIO motion-distortion handling](https://github.com/Livox-SDK/LIO-Livox)
- [ROS FilterDeskew timestamp requirement](https://docs.ros.org/en/noetic/api/mp2p_icp/html/classmp2p__icp__filters_1_1FilterDeskew.html)