feat(lidar): add point-aligned ground review

This commit is contained in:
DCCONSTRUCTIONS
2026-07-25 09:44:38 +03:00
parent 75a3e669d9
commit 2dfb34ef21
15 changed files with 1548 additions and 140 deletions
+15
View File
@@ -24,6 +24,21 @@ read-only `/api/v1/lidar/ground-benchmarks` surface therefore publishes
`production_promotion=false` until an independent annotation generation or an
admitted raw scan closes the input gate.
The companion read-only
`/api/v1/lidar/ground-benchmarks/{benchmark_id}/frames/{frame_index}` endpoint
returns one bounded, path-free point-aligned frame. The Control Station renders
that evidence in Three.js with unrestricted orbit, pan and zoom plus
intensity/current/candidate/disagreement color modes. The browser never runs
Patchwork++, parses private firmware or receives a filesystem path.
Static K1 3.0.2 firmware evidence confirms that the appliance internally uses
a Livox MID-360 point/IMU path with richer timestamp/ring semantics and a
configured MQTT point-cloud downsample factor of four. This creates a concrete
next integration target—an admitted onboard export or bag contract—but does
not change the authority or input acceptance of existing `lio_pcl` recordings.
The 1.27 m operator-height profile is likewise explicit and reproducible, but
remains `operator-estimated` rather than runtime-calibrated.
## Boundary
```text
+44 -6
View File
@@ -34,7 +34,28 @@ The firmware-3 `lio_pcl` stream currently exposes:
- a frame header with sequence, stamp and scaler;
- a separate `T_map_from_lidar` pose stream.
It does not currently expose an admitted:
The recorded XYZ values are metric. With the independent pose they can be
expressed relative to the reported LiDAR pose and produce useful local
distance diagnostics. What is not proven by that inverse transform is that the
result is the original unregistered sweep with preserved beam origin,
acquisition order and motion timing.
Static, read-only analysis of the K1 3.0.2 deployment artifacts additionally
shows that the appliance internally:
- selects a Livox MID-360 adapter;
- consumes `/livox/lidar` and `/imu`;
- carries XYZ, intensity, timestamp and ring in its internal point type;
- supports raw-packet and point/IMU callbacks in its MID-360 library;
- publishes the external cloud after the LIO/modeling path;
- configures the external MQTT point-cloud sample factor to four.
This proves a richer onboard data path exists. It does not prove that the
current external MQTT contract preserves those fields, and private firmware
artifacts remain outside Git. The redacted evidence is recorded in
`docs/lab/005_K1_FW302_LIDAR_PIPELINE_20260725.redacted.md`.
The external contract does not currently expose an admitted:
- raw sensor-frame sweep;
- per-point firing time;
@@ -170,8 +191,10 @@ memory, zero-copy or batching optimizations are accepted.
host capture/receive times.
- [x] Record explicitly absent ring, per-point time and IMU fields.
- [x] Add immutable reports for sequence gaps, arrival jitter, points/frame,
intensity distribution and pose coverage. Sensor-frame range remains
explicitly unavailable because the source is a vendor map increment.
intensity distribution and pose coverage. The sealed source report keeps
native sensor-frame range explicitly unavailable because the source is a
vendor map increment; later diagnostics may separately report pose-derived
local distances without relabeling them as raw beam ranges.
- [x] Compare source native capture vs persisted replay fields byte-for-byte on
a frozen real slice.
- [x] Publish the report to the React observation view without bundling a
@@ -201,6 +224,12 @@ quality line. It is not repaired or hidden by replay.
E19 local-percentile ground proposal.
- [x] Retain separate current/candidate ground and assigned masks for every
source point; raw replay remains unchanged.
- [x] Add a bounded point-aligned frame API and browser 3D review for
intensity, current ground, candidate ground and disagreement.
- [x] Record the K1 3.0.2 internal MID-360/LIO field path from static,
redacted firmware evidence without changing device state.
- [x] Bind physical height, applied vertical-origin offset and evidence class
into every new benchmark identity.
- [x] Seal latency, ground-fraction, algorithm-IoU and disagreement
distributions in `missioncore.lidar-ground-benchmark/v1`.
- [x] Create an immutable eight-frame annotation template in which every point
@@ -218,12 +247,21 @@ Patchwork++ classified only 0.53% ground at p50 with 0.26 ms p95 host latency.
Their point-aligned ground IoU was 2.90% p50 and disagreement was 17.92% p50.
These last two values compare algorithms; they are not accuracy metrics.
An additional operator-height diagnostic,
`ground-benchmark-87cb3150701f7e21756f46ef5b6ce110df1e07720ef6dc2303c95520932cf43f`,
binds the measured 1.27 m handheld height and applies the same explicit map-Z
offset. Patchwork++ ground fraction rises from 0.53% to 2.47% p50; its p95
latency remains 0.42 ms. Algorithm IoU is 4.07% p50 and disagreement is 19.13%
p50. The run is useful for visual review, but its evidence class is
`operator-estimated`, so input acceptance and production promotion stay false.
The result is an evidence-backed **do-not-promote** decision for the current K1
feed. Patchwork++ is fast, but its input model assumes a sensor-centric scan
and physical sensor height. K1 `lio_pcl` is a vendor-mapped increment, its
physical sensor height is not encoded by the best-effort pose, and scan
geometry remains unknown. Translating the cloud until Patchwork++ looks
plausible would tune against the candidate and invalidate the comparison.
physical sensor height is not encoded by the best-effort pose, and raw scan
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
@@ -13,6 +13,20 @@ independent best-effort pose and no admitted raw sweep or scan geometry. The
pose describes vendor odometry; it does not prove the physical height of the
LiDAR above terrain.
Static, read-only analysis of the K1 3.0.2 deployment artifacts narrows this
boundary. K1 selects a Livox MID-360 adapter internally, consumes
`/livox/lidar` plus `/imu`, and its point type carries XYZ, intensity,
timestamp and ring. The configured external MQTT point-cloud sample factor is
four, while the externally recorded `lio_pcl` is emitted after the LIO/modeling
path. The scanner therefore measures real metric ranges and the appliance has a
richer internal source; Mission Core has not yet admitted that internal source
through a versioned export or bag contract.
For the handheld capture, the operator measured approximately 1.27 m from the
LiDAR head to the ground. This is useful evidence, but it is neither a
runtime-attested extrinsic nor proof that the vendor map Z origin coincides with
terrain. It may be used only in an explicitly marked diagnostic normalization.
Treating a successful Patchwork++ call as a valid baseline would conflate API
compatibility with input-domain compatibility. Choosing a synthetic Z
translation until the output looks plausible would use the candidate itself to
@@ -34,7 +48,13 @@ define the normalization.
8. Create an all-ignore, content-bound annotation template; only a separate
human-reviewed generation may unlock ground IoU, curb/low-obstacle recall
and reflection-noise rejection.
9. Keep command, navigation and safety authority false.
9. Bind sensor height, applied map vertical-origin offset and evidence class
(`missing`, `operator-estimated` or `runtime-calibrated`) into the immutable
benchmark identity.
10. Publish one bounded, path-free point-aligned frame endpoint and render it
in React/Three.js with current, candidate and disagreement masks. Heavy
processing remains in the worker.
11. Keep command, navigation and safety authority false.
## Consequences
@@ -45,6 +65,11 @@ define the normalization.
threshold tuning around a mis-specified sensor model.
- The same immutable benchmark/API/React surface can compare a future raw scan,
replay or simulation provider without moving C++ processing into React.
- Firmware evidence justifies implementing an admitted onboard raw
point/IMU exporter or bag reader; it does not retroactively upgrade existing
MQTT recordings to raw scans.
- The 1.27 m run makes the effect of the operator estimate visible and
repeatable, but remains diagnostic-only.
## Real diagnostic evidence
@@ -60,10 +85,26 @@ processed 66 frames and 226,963 points:
Algorithm ground IoU was 2.90% p50 and point disagreement was 17.92% p50.
Neither is an accuracy metric. Independent labels are still missing.
The explicit operator-height variant
`ground-benchmark-87cb3150701f7e21756f46ef5b6ce110df1e07720ef6dc2303c95520932cf43f`
applied a 1.27 m map-Z offset and processed the same 66 frames and 226,963
points:
| Measurement | Current local percentile | Patchwork++ |
| --- | ---: | ---: |
| Ground fraction p50 | 18.31% | 2.47% |
| Host latency p95 | 11.85 ms | 0.42 ms |
Algorithm ground IoU was 4.07% p50 and point disagreement was 19.13% p50.
This is evidence that height/origin normalization materially changes the
candidate result, not evidence that either algorithm is accurate.
## References
- `src/k1link/compute/lidar_ground.py`
- `experiments/perception/run_lidar_ground_benchmark.py`
- `src/k1link/web/lidar_api.py`
- `apps/control-station/src/workspaces/LidarQualityWorkspace.tsx`
- `apps/control-station/src/workspaces/LidarGroundPointCloud.tsx`
- `docs/lab/005_K1_FW302_LIDAR_PIPELINE_20260725.redacted.md`
- `docs/13_LIDAR_WORKER_PRODUCT_AND_ROADMAP.md`
@@ -0,0 +1,61 @@
# K1 firmware 3.0.2 LiDAR pipeline — redacted static analysis
Date: 2026-07-25
Scope: owner-controlled LixelKity K1 firmware 3.0.2 full archive
Method: offline configuration, ELF symbol and string inspection only
Device writes, firmware upload, runtime process changes and network probes: none
## Evidence boundary
The retained firmware package contains deployable ARM64 binaries, libraries and
configuration files, not the original C++ source tree. Non-stripped symbols,
embedded build paths and protobuf descriptors still provide stronger pipeline
evidence than the external MQTT contract alone. The private firmware archive
and extracted filesystem remain outside Git; this note contains only sanitized
derived facts and content hashes.
## Proven static facts
1. K1 selects `livox_mid360` as its LiDAR driver.
2. The driver configuration exposes separate point and IMU inputs. The K1 LIO
configuration consumes `/livox/lidar` and `/imu`.
3. The internal converter uses a `PointIRT` representation containing XYZ,
intensity, per-point timestamp and ring fields. The MID-360 library exposes
raw packet processing, `PointXyzlt`, `PointFrame` and IMU callbacks.
4. The K1 LIO preprocess contract admits `0.3200 m`, a `0.1 s` sweep and
`use_single_pcl: false`.
5. The external MID-360 MQTT point-cloud branch declares
`mqtt_pcl_samples: 4`; it is deliberately downsampled before transport.
6. The modeling application receives raw `PointCloudMsg`, feeds `SlamCore`,
and later sends point clouds from `LioResultMsg`. This supports classifying
external `lio_pcl` as an LIO product rather than the original MID-360 scan.
7. The firmware contains a K1 calibration candidate
`lidar_imu_trans: [0.01176, -0.01865, 0.075]` with zero initial rotation.
Static presence does not prove that this exact file was active in the
recorded session, and it is not the sensor-to-ground installation height.
## Consequences for Mission Core
- Metric range is present in the scanner and internal point path.
- The current MQTT `lio_pcl` evidence is useful for visualization, derived
ground proposals and detector experiments, but must not be relabeled as raw.
- A future raw-scan gate should capture the existing internal point and IMU
products through an admitted onboard exporter or recorded bag boundary. It
does not require replacing the physical scanner.
- The operator-estimated `1.27 m` height belongs only to the handheld recording
and remains diagnostic until a runtime calibration binds the optical origin,
axes and installation.
- Patchwork++ comparison must remain diagnostic on MQTT evidence even after
applying the height estimate.
## Evidence hashes
| Evidence role | SHA-256 |
| --- | --- |
| LiDAR configuration | `cafca05b230dececfde45917f21eaad973491de4cbc2a9668b2fc01a6f79d0b2` |
| K1 LIO configuration | `2b8f06bf95e429862a5559b1aefb39591e5a97cd41dbda89016faf8d05ab7471` |
| K1 calibration configuration | `52db698b80d870b018461501a8582a84dee1aa0f269a9d96cdf96c4169dca95c` |
| MID-360 driver library | `0a9266a337c8112f84728c9c7ae6a4a282e0c92e8ffefc1d43f2d2d54ef55c25` |
| K1 LiDAR adapter library | `e1b8756474098d3a51e08e0690abc5397ea3e7422c16f0ef7f22d81509a96d85` |
| ROS/internal message converter | `225d83fb2468f686a0382324aba595982e34d1dd1e5dc8d0959e1c15d3678c67` |
| Modeling application | `780c9194a749b84b2f8e4c0ea7b297be24f5d8b5946f0315c6c9b74861425ec0` |