| from pydantic import BaseModel, field_validator |
| from typing import Dict, List, Optional, Any |
|
|
| |
| class MapInfo(BaseModel): |
| name: str |
| grid_size: str |
| resolution: float | str |
| materials: List[str] |
| loaded: bool |
| is_active: bool |
|
|
|
|
| class RobotMapsResponse(BaseModel): |
| robot_id: str |
| map_count: int |
| maps: Dict[str, MapInfo] |
|
|
|
|
| class RegisteredMapInfo(BaseModel): |
| description: str |
| loaded: bool |
| grid_size: Optional[str] = None |
| has_grid: bool |
| has_graph: bool |
| source: str |
|
|
|
|
| class MapRegistryResponse(BaseModel): |
| map_count: int |
| maps: Dict[str, RegisteredMapInfo] |
|
|
|
|
| class MapUploadResponse(BaseModel): |
| status: str |
| map_id: str |
| grid_size: Optional[str] = None |
| has_graph: bool |
|
|
|
|
| |
| class RobotSpec(BaseModel): |
| id: Optional[str] = None |
| start: list[int] |
| goal: list[int] |
| start_time: int = 0 |
| priority: float = 1.0 |
| safety_radius: float = 0.5 |
| coordinate_format: str = "matrix" |
| |
|
|
|
|
| class StatelessPlanRequest(BaseModel): |
| map_id: str |
| solver: str |
| format: str = "grid" |
| robots: List[RobotSpec] |
| penalty_set: str = "crash" |
| T: Optional[int] = None |
| details: bool = False |
| render: bool = False |
| clip_at_goal: bool = False |
|
|
| @field_validator("robots") |
| @classmethod |
| def _non_empty_robots(cls, robots: List[RobotSpec]) -> List[RobotSpec]: |
| if not robots: |
| raise ValueError("'robots' must contain at least one entry.") |
| return robots |
|
|
| @field_validator("T") |
| @classmethod |
| def _positive_T(cls, T: Optional[int]) -> Optional[int]: |
| if T is not None and T < 1: |
| raise ValueError( |
| "'T' must be a positive number of timesteps, or omitted/null to " |
| "auto-compute from robot start/goal distances." |
| ) |
| return T |
|
|
|
|
| class RobotPathResult(BaseModel): |
| robot_id: str |
| path: List[List[int]] |
| coordinate_format: str = "matrix" |
|
|
|
|
| class StatelessPlanResponse(BaseModel): |
| paths: List[RobotPathResult] |
| cost: float |
| map_id: str |
| solver_used: str |
| solver_details: Optional[Dict[str, Any]] = None |
| metrics: Optional[Dict[str, Any]] = None |
| figure: Optional[Dict[str, Any]] = None |
|
|
|
|
| |
| class PlanRequest(BaseModel): |
| map_id: str |
| start: list[int] |
| goal: list[int] |
| solver: Optional[str] = None |
| details: bool = False |
| coordinate_format: str = "matrix" |
| clip_at_goal: bool = False |
|
|
| class PlanResponse(BaseModel): |
| |
| path: List[List[int]] |
| coordinate_format: str = "matrix" |
| cost: float |
| |
| map_id: str |
| |
| solver_used: str |
| |
| |
| solver_details: Optional[Dict[str, Any]] = None |
| |
| |
| metrics: Optional[Dict[str, Any]] = None |