feat(lidar): add ground segmentation diagnostic benchmark
This commit is contained in:
@@ -9,14 +9,21 @@ from typing import Any, Final
|
||||
from fastapi import APIRouter, HTTPException, Query
|
||||
|
||||
from k1link.compute import (
|
||||
LidarGroundBenchmarkV1,
|
||||
LidarGroundError,
|
||||
LidarReplayError,
|
||||
LidarReplayPackV2,
|
||||
lidar_ground_benchmark_catalog_item,
|
||||
lidar_pack_catalog_item,
|
||||
lidar_pack_detail,
|
||||
)
|
||||
|
||||
LIDAR_CATALOG_SCHEMA: Final = "missioncore.lidar-replay-pack-catalog/v1"
|
||||
LIDAR_GROUND_CATALOG_SCHEMA: Final = (
|
||||
"missioncore.lidar-ground-benchmark-catalog/v1"
|
||||
)
|
||||
_PACK_ID = re.compile(r"^lidar-replay-pack-[a-f0-9]{64}$")
|
||||
_BENCHMARK_ID = re.compile(r"^ground-benchmark-[a-f0-9]{64}$")
|
||||
RootProvider = Callable[[], Path | None]
|
||||
|
||||
|
||||
@@ -25,9 +32,15 @@ def configured_lidar_replay_root() -> Path | None:
|
||||
return Path(value).expanduser().absolute() if value else None
|
||||
|
||||
|
||||
def configured_lidar_ground_root() -> Path | None:
|
||||
value = os.environ.get("MISSIONCORE_LIDAR_GROUND_ROOT", "").strip()
|
||||
return Path(value).expanduser().absolute() if value else None
|
||||
|
||||
|
||||
def build_lidar_router(
|
||||
*,
|
||||
root_provider: RootProvider = configured_lidar_replay_root,
|
||||
ground_root_provider: RootProvider = configured_lidar_ground_root,
|
||||
) -> APIRouter:
|
||||
router = APIRouter(prefix="/api/v1/lidar", tags=["lidar"])
|
||||
|
||||
@@ -107,4 +120,95 @@ def build_lidar_router(
|
||||
detail="LiDAR replay pack не прошёл проверку целостности",
|
||||
) from exc
|
||||
|
||||
@router.get("/ground-benchmarks")
|
||||
def list_lidar_ground_benchmarks(
|
||||
pack_id: str | None = Query(default=None),
|
||||
limit: int = Query(default=20, ge=1, le=100),
|
||||
) -> dict[str, Any]:
|
||||
if pack_id is not None and _PACK_ID.fullmatch(pack_id) is None:
|
||||
raise HTTPException(status_code=404, detail="LiDAR replay pack не найден")
|
||||
root = ground_root_provider()
|
||||
if root is None or not root.is_dir():
|
||||
return {
|
||||
"schema_version": LIDAR_GROUND_CATALOG_SCHEMA,
|
||||
"configured": root is not None,
|
||||
"items": [],
|
||||
"valid_total": 0,
|
||||
"invalid_total": 0,
|
||||
"access": "read-only",
|
||||
}
|
||||
items: list[dict[str, object]] = []
|
||||
invalid_total = 0
|
||||
candidates = sorted(
|
||||
(
|
||||
candidate
|
||||
for candidate in root.iterdir()
|
||||
if candidate.is_dir()
|
||||
and _BENCHMARK_ID.fullmatch(candidate.name) is not None
|
||||
),
|
||||
key=lambda candidate: candidate.stat().st_mtime_ns,
|
||||
reverse=True,
|
||||
)
|
||||
for candidate in candidates:
|
||||
try:
|
||||
benchmark = LidarGroundBenchmarkV1(candidate)
|
||||
try:
|
||||
if (
|
||||
pack_id is None
|
||||
or benchmark.identity.get("replay_pack_id") == pack_id
|
||||
):
|
||||
items.append(
|
||||
lidar_ground_benchmark_catalog_item(benchmark)
|
||||
)
|
||||
finally:
|
||||
benchmark.close()
|
||||
except (LidarGroundError, OSError):
|
||||
invalid_total += 1
|
||||
return {
|
||||
"schema_version": LIDAR_GROUND_CATALOG_SCHEMA,
|
||||
"configured": True,
|
||||
"items": items[:limit],
|
||||
"valid_total": len(items),
|
||||
"invalid_total": invalid_total,
|
||||
"access": "read-only",
|
||||
}
|
||||
|
||||
@router.get("/ground-benchmarks/{benchmark_id}")
|
||||
def get_lidar_ground_benchmark(benchmark_id: str) -> dict[str, object]:
|
||||
if _BENCHMARK_ID.fullmatch(benchmark_id) is None:
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="LiDAR ground benchmark не найден",
|
||||
)
|
||||
root = ground_root_provider()
|
||||
if root is None or not root.is_dir():
|
||||
raise HTTPException(
|
||||
status_code=503,
|
||||
detail="LiDAR ground storage не настроен",
|
||||
)
|
||||
candidate = root / benchmark_id
|
||||
if not candidate.is_dir():
|
||||
raise HTTPException(
|
||||
status_code=404,
|
||||
detail="LiDAR ground benchmark не найден",
|
||||
)
|
||||
try:
|
||||
benchmark = LidarGroundBenchmarkV1(candidate)
|
||||
try:
|
||||
return {
|
||||
"schema_version": (
|
||||
"missioncore.lidar-ground-benchmark-detail/v1"
|
||||
),
|
||||
"benchmark": lidar_ground_benchmark_catalog_item(benchmark),
|
||||
"report": benchmark.report,
|
||||
"access": "read-only",
|
||||
}
|
||||
finally:
|
||||
benchmark.close()
|
||||
except (LidarGroundError, OSError) as exc:
|
||||
raise HTTPException(
|
||||
status_code=409,
|
||||
detail="LiDAR ground benchmark не прошёл проверку целостности",
|
||||
) from exc
|
||||
|
||||
return router
|
||||
|
||||
Reference in New Issue
Block a user