fix(lab): stabilize recorded spatial playback
This commit is contained in:
@@ -276,6 +276,13 @@ class RecordedGeometryStore:
|
||||
points.setflags(write=False)
|
||||
return points
|
||||
|
||||
@property
|
||||
def maximum_current_point_count(self) -> int:
|
||||
"""Return the immutable source-pack upper bound for one recorded increment."""
|
||||
|
||||
counts = np.diff(np.asarray(self._source["cloud_offsets"], dtype=np.int64))
|
||||
return int(counts.max(initial=0))
|
||||
|
||||
def pose_values_for_frame(
|
||||
self,
|
||||
frame_id: str,
|
||||
@@ -946,7 +953,10 @@ def _camera_unavailable_observation(
|
||||
)
|
||||
|
||||
|
||||
def _load_npz(path: Path, label: str) -> dict[str, npt.NDArray[np.generic]]:
|
||||
def _load_npz(
|
||||
path: Path,
|
||||
label: str,
|
||||
) -> dict[str, npt.NDArray[np.generic]]:
|
||||
try:
|
||||
with np.load(path, allow_pickle=False) as archive:
|
||||
return {name: np.asarray(archive[name]) for name in archive.files}
|
||||
|
||||
@@ -14,6 +14,7 @@ from threading import RLock
|
||||
from typing import Final
|
||||
|
||||
from .geometry import RecordedGeometryStore
|
||||
from .recorded_source import RECORDED_REPRESENTATION_ID
|
||||
from .spatial_evidence import (
|
||||
project_metric_obstacles_to_body,
|
||||
sample_points_in_body_frame,
|
||||
@@ -32,7 +33,7 @@ from .threat_replay import (
|
||||
RECORDED_SPATIAL_TIMELINE_SCHEMA: Final = "missioncore.recorded-spatial-evidence-timeline/v1"
|
||||
RECORDED_SPATIAL_CHUNK_SCHEMA: Final = "missioncore.recorded-spatial-evidence-chunk/v1"
|
||||
RECORDED_SPATIAL_FRAME_SCHEMA: Final = "missioncore.recorded-spatial-evidence-frame/v1"
|
||||
RECORDED_SPATIAL_POINT_LIMIT: Final = 2_000
|
||||
RECORDED_SPATIAL_POINT_LIMIT: Final = 4_096
|
||||
RECORDED_SPATIAL_MAX_CHUNK_FRAMES: Final = 24
|
||||
_EXPECTED_FRAME_COUNT: Final = 4_489
|
||||
_SOURCE_TIME = re.compile(rb'"source_time_ns":([0-9]+)')
|
||||
@@ -80,6 +81,10 @@ class RecordedThreatTimeline:
|
||||
or self.store.profile.frame_count != _EXPECTED_FRAME_COUNT
|
||||
):
|
||||
raise RecordedThreatTimelineError("recorded timeline geometry identity changed")
|
||||
if self.store.maximum_current_point_count > RECORDED_SPATIAL_POINT_LIMIT:
|
||||
raise RecordedThreatTimelineError(
|
||||
"recorded timeline exact point delivery exceeds its declared bound"
|
||||
)
|
||||
self.body_frames = RecordedReplayBodyFrameResolver(
|
||||
self.store,
|
||||
profile=self.profile.body_frame,
|
||||
@@ -99,6 +104,7 @@ class RecordedThreatTimeline:
|
||||
"recorded_source": {
|
||||
"session_id": self.profile.session_id,
|
||||
"source_id": self.profile.source_id,
|
||||
"representation_id": RECORDED_REPRESENTATION_ID,
|
||||
"synchronization": "host-arrival-best-effort",
|
||||
},
|
||||
"frame_count": len(times),
|
||||
@@ -109,6 +115,8 @@ class RecordedThreatTimeline:
|
||||
"nominal_rate_hz": 1 / nominal_interval,
|
||||
"max_chunk_frames": RECORDED_SPATIAL_MAX_CHUNK_FRAMES,
|
||||
"point_sample_limit": RECORDED_SPATIAL_POINT_LIMIT,
|
||||
"point_delivery": "exact-current-increment",
|
||||
"maximum_source_points_per_frame": self.store.maximum_current_point_count,
|
||||
"image_width": 800,
|
||||
"image_height": 600,
|
||||
"rig": {
|
||||
@@ -119,6 +127,7 @@ class RecordedThreatTimeline:
|
||||
"corridor": {
|
||||
"forward_length_m": self.profile.corridor.forward_length_m,
|
||||
"rear_margin_m": self.profile.corridor.rear_margin_m,
|
||||
"occupied_voxel_size_m": self.profile.corridor.occupied_voxel_size_m,
|
||||
"half_width_m": (
|
||||
self.profile.rig.body_width_m / 2 + self.profile.corridor.lateral_clearance_m
|
||||
),
|
||||
|
||||
@@ -13,6 +13,7 @@ from fastapi.exceptions import RequestValidationError
|
||||
from fastapi.responses import JSONResponse
|
||||
from fastapi.staticfiles import StaticFiles
|
||||
from pydantic import ValidationError
|
||||
from starlette.middleware.gzip import GZipMiddleware
|
||||
|
||||
from k1link import __version__
|
||||
from k1link.artifact_gateway import configured_artifact_gateway
|
||||
@@ -414,6 +415,7 @@ app = FastAPI(
|
||||
openapi_url="/api/openapi.json",
|
||||
lifespan=app_lifespan,
|
||||
)
|
||||
app.add_middleware(GZipMiddleware, minimum_size=1_024, compresslevel=5)
|
||||
|
||||
|
||||
@app.exception_handler(RequestValidationError)
|
||||
|
||||
Reference in New Issue
Block a user