sprint-0: foundations -- data model, seed library, tests, demo
Initial commit. Delivers what the brief calls 'Sprint 0 - Foundations' (see docs/AR_Autopilot_brief.md section 12): - Complete repository structure (arautopilot package + firmware, display, installer, tools placeholders + docs). - Core data model (Pydantic v2): modes, alarms, actuator config, PID config + gain scheduling, vessel config, knob state machine, project config with YAML/JSON serialisation. - Seed library: 2 actuator profiles (hydraulic & electric DC reversible) and 2 default tunings (yacht motor planeo 30 m and 40 m). Conservative literature values, NOT the integrator's production tuning IP. - Firmware skeleton: only src/hal/pinout.h with the 21 I/O contract for the AR-NMEA-IO v1.0 board. No drivers, no main loop. - Studio stubs (real PySide6 app starts in Sprint 4). - pytest suite (80 tests, all green): modes, alarms, actuator, PID (incl. gain interpolation and the +/-50% adaptive bound from brief section 6), vessel, knob state, project config, library loader, end-to-end roundtrip. - examples/sprint0_demo.py - the acceptance demo from the brief. Acceptance criteria met: - pytest green (80/80) - demo creates, saves (YAML + JSON), reloads, and verifies a full ProjectConfig using the seed library - repository ready for tag `sprint-0-approved` See CHANGELOG.md for the detailed scope. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
"""Per-vessel configuration: identification + actuator + PID.
|
||||
|
||||
Composes the lower-level configs into one object that lives at the heart
|
||||
of every ``ProjectConfig``.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from enum import Enum
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
from arautopilot.core.actuator_config import ActuatorConfig
|
||||
from arautopilot.core.ids import VesselId, new_vessel_id
|
||||
from arautopilot.core.pid_config import PidConfig
|
||||
|
||||
|
||||
class VesselType(str, Enum):
|
||||
"""Vessel classes targeted by Phase 1 of the product (brief section 3)."""
|
||||
|
||||
YACHT_MOTOR_PLANEO = "yacht_motor_planeo"
|
||||
"""Planing motor yacht, 30-40 m."""
|
||||
|
||||
YACHT_MOTOR_DESPLAZAMIENTO = "yacht_motor_desplazamiento"
|
||||
"""Displacement motor yacht, 30-40 m."""
|
||||
|
||||
SAILBOAT_MOTOR = "sailboat_motor"
|
||||
"""Sailing yacht under motor (no sail trim). Phase 1 only."""
|
||||
|
||||
FISHING_BOAT = "fishing_boat"
|
||||
"""Fishing vessel, 30 m class."""
|
||||
|
||||
SMALL_FERRY = "small_ferry"
|
||||
"""Small ferry, 30 m class."""
|
||||
|
||||
PATROL_BOAT = "patrol_boat"
|
||||
"""Coastal patrol boat, 30 m class."""
|
||||
|
||||
|
||||
class VesselConfig(BaseModel):
|
||||
"""Identification, geometry, and control configuration of one vessel."""
|
||||
|
||||
model_config = ConfigDict(extra="forbid", validate_assignment=True)
|
||||
|
||||
vessel_id: VesselId = Field(default_factory=new_vessel_id)
|
||||
name: str = Field(min_length=1, max_length=120)
|
||||
type: VesselType
|
||||
length_m: float = Field(gt=0.0, le=200.0, description="Length overall, metres.")
|
||||
displacement_t: float = Field(
|
||||
default=0.0,
|
||||
ge=0.0,
|
||||
le=10_000.0,
|
||||
description="Loaded displacement, tonnes. 0 means unknown.",
|
||||
)
|
||||
max_speed_kn: float = Field(
|
||||
gt=0.0,
|
||||
le=80.0,
|
||||
description="Maximum design speed over ground, knots.",
|
||||
)
|
||||
|
||||
actuator: ActuatorConfig
|
||||
pid: PidConfig
|
||||
Reference in New Issue
Block a user