700756c16f
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>
71 lines
2.0 KiB
Python
71 lines
2.0 KiB
Python
"""Shared pytest fixtures for the AR-Autopilot Sprint 0 test suite."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import pytest
|
|
|
|
from arautopilot.core import (
|
|
ActuatorConfig,
|
|
ActuatorType,
|
|
GainSchedulePoint,
|
|
PidConfig,
|
|
PidGains,
|
|
ProjectConfig,
|
|
VesselConfig,
|
|
VesselType,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def hydraulic_actuator() -> ActuatorConfig:
|
|
"""A realistic hydraulic reversible actuator config for fixture composition."""
|
|
return ActuatorConfig(
|
|
type=ActuatorType.HYDRAULIC_REVERSIBLE,
|
|
name="Test Hynautic-class pump",
|
|
deadband_pct=7.0,
|
|
min_useful_pwm_pct=12.0,
|
|
asymmetry_stbd_over_port=1.0,
|
|
max_rudder_angle_deg=35.0,
|
|
max_rate_dps=4.0,
|
|
max_current_a=20.0,
|
|
feedback_required=True,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def basic_pid() -> PidConfig:
|
|
"""A minimal valid cascaded PID with a 3-point gain schedule."""
|
|
return PidConfig(
|
|
inner_loop_base=PidGains(kp=2.5, ki=0.15, kd=0.30),
|
|
outer_loop_base=PidGains(kp=0.90, ki=0.02, kd=1.20),
|
|
gain_schedule=[
|
|
GainSchedulePoint(speed_knots=5.0, gains=PidGains(kp=1.20, ki=0.03, kd=0.80)),
|
|
GainSchedulePoint(speed_knots=15.0, gains=PidGains(kp=0.90, ki=0.02, kd=1.20)),
|
|
GainSchedulePoint(speed_knots=28.0, gains=PidGains(kp=0.55, ki=0.01, kd=1.80)),
|
|
],
|
|
rot_feedforward_gain=1.5,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def basic_vessel(hydraulic_actuator: ActuatorConfig, basic_pid: PidConfig) -> VesselConfig:
|
|
return VesselConfig(
|
|
name="M/Y Test 30",
|
|
type=VesselType.YACHT_MOTOR_PLANEO,
|
|
length_m=30.0,
|
|
displacement_t=120.0,
|
|
max_speed_kn=28.0,
|
|
actuator=hydraulic_actuator,
|
|
pid=basic_pid,
|
|
)
|
|
|
|
|
|
@pytest.fixture
|
|
def basic_project(basic_vessel: VesselConfig) -> ProjectConfig:
|
|
return ProjectConfig(
|
|
client_name="Test Client S.L.",
|
|
project_name="Sprint 0 demo project",
|
|
notes="Generated by conftest fixture.",
|
|
vessel=basic_vessel,
|
|
)
|