Add real ship flight fuel/cost model (puga/shipping.py)
Calibrated from a controlled slider sweep across 5 real destinations, read from the live APEX Ship Flight Control DOM. Covers STL cruise, FTL jumps/charges, gateway hops (measured LOCK fees for ANT<->HRT/BEN), and per-planet landing fuel. Scoped to this account's one hull/reactor; open gaps (gravity dependence, hull generalization, gateway one-way links, per-gateway volume caps) are documented in the module docstring. tools/shiptrip.py is the simple entry point (ship + from + to, works out jumps/charges/landing itself); tools/shipcost.py takes explicit physics params for when the breakdown is already known. puga/route.py now also resolves CX station codes (ANT, HRT, ...), not just planets/systems - this was needed for the gateway-aware lookups to work at all. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
"""Expected values from the real APEX Ship Flight Control DOM reads, 2026-10-09 calibration
|
||||
sweep (AVI-07JFB). Raw data in empire/data/shipping_calibration/."""
|
||||
import pytest
|
||||
from puga import shipping
|
||||
|
||||
|
||||
@pytest.mark.parametrize("v0,actual", [(0.01, 3), (0.34, 83), (0.67, 162), (1.0, 242)])
|
||||
def test_cruise_leg_fuel_matches_dep(v0, actual):
|
||||
assert shipping.cruise_leg_fuel(v0) == pytest.approx(actual, abs=5)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("v1,actual", [(0.303, 8), (0.535, 15), (0.768, 21), (1.0, 28)])
|
||||
def test_jump_fuel(v1, actual):
|
||||
assert shipping.jump_fuel(v1) == pytest.approx(actual, abs=1)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("v1,actual", [(0.303, 6), (0.535, 12), (0.768, 17), (1.0, 22)])
|
||||
def test_charge_fuel(v1, actual):
|
||||
assert shipping.charge_fuel(v1) == pytest.approx(actual, abs=1)
|
||||
|
||||
|
||||
def test_charge_cheaper_than_jump():
|
||||
for v1 in (0.3, 0.5, 0.7, 1.0):
|
||||
assert shipping.charge_fuel(v1) < shipping.jump_fuel(v1)
|
||||
|
||||
|
||||
def test_landing_fuel_lookup():
|
||||
assert shipping.landing_fuel("ZV-759c") == 38 # Deimos
|
||||
assert shipping.landing_fuel("ZV-759b") == 38 # Vulcan
|
||||
assert shipping.landing_fuel("ZV-194a") == 48 # Nike
|
||||
|
||||
|
||||
def test_landing_fuel_unmeasured_returns_none():
|
||||
assert shipping.landing_fuel("ZV-307") is None
|
||||
|
||||
|
||||
def test_gateway_hop_is_fuel_free_plus_fixed_fee():
|
||||
g = shipping.gateway_hop_cost(6000, "AIC")
|
||||
assert g["fee_amount"] == 6000
|
||||
assert g["fee_currency"] == "AIC"
|
||||
assert g["stl_fuel"] == shipping.GATEWAY_HOP_FIXED_STL + shipping.SHORT_TRA_FIXED_STL + shipping.DCAY_FIXED_STL
|
||||
|
||||
|
||||
def test_sliders_additive_no_cross_term():
|
||||
# cruise fuel must not depend on v1, jump fuel must not depend on v0 - the whole point
|
||||
# of the independence finding this model is built on.
|
||||
base = shipping.cruise_leg_fuel(0.5)
|
||||
assert shipping.cruise_leg_fuel(0.5) == base
|
||||
Reference in New Issue
Block a user