feat(lidar): add dataset gateway boundary
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
Reference in New Issue
Block a user