feat(simulation): add Gaussian UGV runtime pipeline
This commit is contained in:
@@ -4,7 +4,7 @@ from __future__ import annotations
|
||||
|
||||
from typing import Any, Literal
|
||||
|
||||
from fastapi import APIRouter, BackgroundTasks, Header, HTTPException, Request, Response
|
||||
from fastapi import APIRouter, Header, HTTPException, Request, Response
|
||||
from fastapi.responses import FileResponse
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
@@ -46,11 +46,18 @@ class SimulationProjectUpdate(BaseModel):
|
||||
scene_type: Literal["interior", "outdoor", "object"]
|
||||
|
||||
|
||||
class SimulationEulerRotation(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid", frozen=True)
|
||||
|
||||
x: float = Field(ge=-360, le=360)
|
||||
y: float = Field(ge=-360, le=360)
|
||||
z: float = Field(ge=-360, le=360)
|
||||
|
||||
|
||||
class SimulationLayerViewerSettings(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid", frozen=True)
|
||||
|
||||
inverted: bool
|
||||
axis: Literal["x", "y", "z"]
|
||||
rotation_degrees: SimulationEulerRotation
|
||||
|
||||
|
||||
class SimulationCameraViewerSettings(BaseModel):
|
||||
@@ -60,14 +67,35 @@ class SimulationCameraViewerSettings(BaseModel):
|
||||
invert_vertical: bool
|
||||
|
||||
|
||||
class SimulationUgvDimensions(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid", frozen=True)
|
||||
|
||||
length: float = Field(ge=0.01, le=1_000_000_000)
|
||||
width: float = Field(ge=0.01, le=1_000_000_000)
|
||||
height: float = Field(ge=0.07, le=1_000_000_000)
|
||||
ground_clearance: float = Field(ge=0.01, le=1_000_000_000)
|
||||
|
||||
|
||||
class SimulationUgvViewerSettings(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid", frozen=True)
|
||||
|
||||
preset_name: str = Field(min_length=1, max_length=80)
|
||||
mass_kg: float = Field(ge=0.01, le=1_000_000_000)
|
||||
dimensions_m: SimulationUgvDimensions
|
||||
max_speed_mps: float = Field(ge=0, le=1_000_000_000)
|
||||
max_turn_rate_degrees: float = Field(ge=0, le=1_000_000_000)
|
||||
invert_steering: bool
|
||||
|
||||
|
||||
class SimulationViewerSettings(BaseModel):
|
||||
model_config = ConfigDict(extra="forbid", frozen=True)
|
||||
|
||||
schema_version: Literal["missioncore.simulation-viewer-settings/v1"] = VIEWER_SETTINGS_SCHEMA
|
||||
schema_version: Literal["missioncore.simulation-viewer-settings/v3"] = VIEWER_SETTINGS_SCHEMA
|
||||
quality: Literal["low", "medium", "high", "ultra", "maximum"]
|
||||
visual: SimulationLayerViewerSettings
|
||||
collision: SimulationLayerViewerSettings
|
||||
camera: SimulationCameraViewerSettings
|
||||
ugv: SimulationUgvViewerSettings
|
||||
|
||||
|
||||
class SimulationProjectDocument(BaseModel):
|
||||
@@ -162,11 +190,14 @@ def build_simulation_projects_router(
|
||||
def source_upload_state(project_id: str, file_id: str) -> Response:
|
||||
try:
|
||||
offset, byte_length = store.upload_state(project_id, file_id)
|
||||
return Response(status_code=204, headers={
|
||||
"Upload-Offset": str(offset),
|
||||
"Upload-Length": str(byte_length),
|
||||
"Cache-Control": "no-store",
|
||||
})
|
||||
return Response(
|
||||
status_code=204,
|
||||
headers={
|
||||
"Upload-Offset": str(offset),
|
||||
"Upload-Length": str(byte_length),
|
||||
"Cache-Control": "no-store",
|
||||
},
|
||||
)
|
||||
except SimulationProjectNotFoundError as exc:
|
||||
raise HTTPException(status_code=404, detail="Исходный файл не найден.") from exc
|
||||
|
||||
@@ -199,11 +230,14 @@ def build_simulation_projects_router(
|
||||
source_file = next(
|
||||
item for item in project["source"]["files"] if item["file_id"] == file_id
|
||||
)
|
||||
return Response(status_code=204, headers={
|
||||
"Upload-Offset": str(source_file["uploaded_bytes"]),
|
||||
"Upload-Length": str(source_file["byte_length"]),
|
||||
"Cache-Control": "no-store",
|
||||
})
|
||||
return Response(
|
||||
status_code=204,
|
||||
headers={
|
||||
"Upload-Offset": str(source_file["uploaded_bytes"]),
|
||||
"Upload-Length": str(source_file["byte_length"]),
|
||||
"Cache-Control": "no-store",
|
||||
},
|
||||
)
|
||||
except SimulationProjectNotFoundError as exc:
|
||||
raise HTTPException(status_code=404, detail="Исходный файл не найден.") from exc
|
||||
except SimulationProjectConflictError as exc:
|
||||
@@ -212,13 +246,10 @@ def build_simulation_projects_router(
|
||||
raise HTTPException(status_code=400, detail=str(exc)) from exc
|
||||
|
||||
@router.post("/projects/{project_id}/build", response_model=SimulationProjectDocument)
|
||||
def build_project(
|
||||
project_id: str,
|
||||
background_tasks: BackgroundTasks,
|
||||
) -> dict[str, Any]:
|
||||
def build_project(project_id: str) -> dict[str, Any]:
|
||||
try:
|
||||
project = service.begin_build(project_id)
|
||||
background_tasks.add_task(service.process, project_id)
|
||||
service.enqueue(project_id)
|
||||
return project
|
||||
except SimulationProjectNotFoundError as exc:
|
||||
raise HTTPException(status_code=404, detail="Проект симуляции не найден.") from exc
|
||||
|
||||
Reference in New Issue
Block a user