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 @@
|
||||
"""Tests for ``arautopilot.library.loader`` and the seed assets shipped in Sprint 0."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from arautopilot.core.actuator_config import ActuatorType
|
||||
from arautopilot.library.loader import (
|
||||
list_actuator_profiles,
|
||||
list_default_tunings,
|
||||
load_actuator_profile,
|
||||
load_default_tuning,
|
||||
)
|
||||
|
||||
|
||||
def test_seed_actuators_present() -> None:
|
||||
profiles = list_actuator_profiles()
|
||||
assert "hydraulic_reversible" in profiles
|
||||
assert "electric_dc_reversible" in profiles
|
||||
assert len(profiles) >= 2
|
||||
|
||||
|
||||
def test_seed_tunings_present() -> None:
|
||||
tunings = list_default_tunings()
|
||||
assert "yacht_motor_planeo_30m" in tunings
|
||||
assert "yacht_motor_planeo_40m" in tunings
|
||||
assert len(tunings) >= 2
|
||||
|
||||
|
||||
def test_load_hydraulic_actuator_profile() -> None:
|
||||
cfg = load_actuator_profile("hydraulic_reversible")
|
||||
assert cfg.type is ActuatorType.HYDRAULIC_REVERSIBLE
|
||||
assert cfg.feedback_required is True
|
||||
assert 0 < cfg.deadband_pct < 30
|
||||
|
||||
|
||||
def test_load_electric_dc_actuator_profile() -> None:
|
||||
cfg = load_actuator_profile("electric_dc_reversible")
|
||||
assert cfg.type is ActuatorType.ELECTRIC_DC_REVERSIBLE
|
||||
assert cfg.feedback_required is True
|
||||
|
||||
|
||||
def test_load_30m_tuning_has_three_point_schedule() -> None:
|
||||
pid = load_default_tuning("yacht_motor_planeo_30m")
|
||||
assert len(pid.gain_schedule) == 3
|
||||
# Brief: outer kp should drop as speed goes up.
|
||||
speeds = [p.speed_knots for p in pid.gain_schedule]
|
||||
kps = [p.gains.kp for p in pid.gain_schedule]
|
||||
assert speeds == sorted(speeds)
|
||||
assert kps[0] > kps[-1]
|
||||
# Inner loop faster than outer.
|
||||
assert pid.inner_loop_freq_hz > pid.outer_loop_freq_hz
|
||||
# Adaptive disabled at ship time.
|
||||
assert pid.adaptive_enabled is False
|
||||
|
||||
|
||||
def test_load_40m_tuning_is_more_damped_than_30m() -> None:
|
||||
"""Larger vessel should have higher kd at cruise speed (more anticipation)."""
|
||||
pid30 = load_default_tuning("yacht_motor_planeo_30m")
|
||||
pid40 = load_default_tuning("yacht_motor_planeo_40m")
|
||||
# Cruise-speed point (~15 kn) is the second entry in both schedules.
|
||||
assert pid40.gain_schedule[1].gains.kd > pid30.gain_schedule[1].gains.kd
|
||||
# And kp at cruise should not be higher than 30 m.
|
||||
assert pid40.gain_schedule[1].gains.kp <= pid30.gain_schedule[1].gains.kp
|
||||
Reference in New Issue
Block a user