mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-09-30 03:13:48 +08:00
Ferd Long
This commit is contained in:
@@ -57,6 +57,7 @@ FORD_LIGHTNING_FAR_FOLLOW_RELEASE_SLEW_RATE = 1.75
|
||||
FORD_LIGHTNING_STANDSTILL_GUARD_DISTANCE_MARGIN = 5.0
|
||||
FORD_LIGHTNING_STANDSTILL_GUARD_MAX_LEAD_SPEED = 0.60
|
||||
FORD_LIGHTNING_GAP_SETTLE_MAX_EXTRA_GAP = 3.0
|
||||
FORD_MACH_E_GAP_SETTLE_MAX_EXTRA_GAP = 2.5
|
||||
TOYOTA_SIENNA_POST_DEPARTURE_RESTOP_MAX_EGO_SPEED = 2.0
|
||||
TOYOTA_SIENNA_POST_DEPARTURE_RESTOP_MAX_LEAD_SPEED = 0.45
|
||||
TOYOTA_SIENNA_POST_DEPARTURE_RESTOP_MAX_LEAD_DELTA = 0.35
|
||||
@@ -329,6 +330,8 @@ def get_standstill_gap_settle_max_extra_gap(CP):
|
||||
return HONDA_CRV_5G_GAP_SETTLE_MAX_EXTRA_GAP
|
||||
if is_ford_f150_lightning(CP):
|
||||
return FORD_LIGHTNING_GAP_SETTLE_MAX_EXTRA_GAP
|
||||
if getattr(CP, "brand", "") == "ford" and str(getattr(CP, "carFingerprint", "")) == "FORD_MUSTANG_MACH_E_MK1":
|
||||
return FORD_MACH_E_GAP_SETTLE_MAX_EXTRA_GAP
|
||||
return 1.5
|
||||
|
||||
|
||||
|
||||
@@ -858,6 +858,21 @@ def test_lightning_stopped_lead_guard_tune_is_vehicle_specific():
|
||||
assert get_tracked_lead_catchup_bias_gain(civic) is None
|
||||
|
||||
|
||||
def test_mach_e_standstill_gap_settle_covers_observed_gap_without_changing_other_cars():
|
||||
mach_e = FordCarInterface.get_non_essential_params(FORD_CAR.FORD_MUSTANG_MACH_E_MK1)
|
||||
civic = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
|
||||
lead = make_lead(status=True, d_rel=7.7, v_lead=0.0, radar=True, model_prob=1.0, y_rel=0.0)
|
||||
|
||||
assert get_standstill_gap_settle_max_extra_gap(mach_e) == pytest.approx(2.5)
|
||||
assert get_standstill_gap_settle_max_extra_gap(civic) == pytest.approx(1.5)
|
||||
assert LongitudinalPlanner.is_radar_standstill_gap_settle_candidate(
|
||||
lead, 0.0, 5.5, max_extra_gap=get_standstill_gap_settle_max_extra_gap(mach_e))
|
||||
assert not LongitudinalPlanner.is_radar_standstill_gap_settle_candidate(
|
||||
lead, 0.0, 5.5, max_extra_gap=get_standstill_gap_settle_max_extra_gap(civic))
|
||||
assert not LongitudinalPlanner.is_radar_standstill_gap_settle_candidate(
|
||||
lead, 0.5, 5.5, max_extra_gap=get_standstill_gap_settle_max_extra_gap(mach_e))
|
||||
|
||||
|
||||
def test_lightning_stopped_radar_lead_handoff_is_narrow_and_vehicle_specific():
|
||||
lightning = FordCarInterface.get_non_essential_params(FORD_CAR.FORD_F_150_LIGHTNING_MK1)
|
||||
civic = CarInterface.get_non_essential_params(CAR.HONDA_CIVIC)
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import json
|
||||
import sys
|
||||
from contextlib import contextmanager
|
||||
from types import SimpleNamespace
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
@@ -788,6 +790,38 @@ def test_reset_defaults_requires_confirmed_offroad_without_side_effects(monkeypa
|
||||
assert reboots == []
|
||||
|
||||
|
||||
def test_reset_defaults_preserves_detected_vehicle_for_vehicle_settings(monkeypatch):
|
||||
client, params = _client(monkeypatch, {
|
||||
"CarMake": "Ford", "CarModel": "FORD_MUSTANG_MACH_E_MK1", "CarModelName": "Mustang Mach-E",
|
||||
"FordHandsFreeCluster": True,
|
||||
})
|
||||
monkeypatch.setattr(params, "all_keys", lambda: ["CarMake", "CarModel", "CarModelName", "FordHandsFreeCluster"], raising=False)
|
||||
monkeypatch.setattr(params, "get_default_value", lambda key: "mock" if key == "CarMake" else False, raising=False)
|
||||
monkeypatch.setattr(the_galaxy, "_params_raw", params)
|
||||
monkeypatch.setattr(the_galaxy, "update_starpilot_toggles", lambda: None)
|
||||
monkeypatch.setattr(the_galaxy.HARDWARE, "reboot", lambda: None)
|
||||
|
||||
assert client.post("/api/toggles/reset_default").status_code == 200
|
||||
assert params.values["CarMake"] == "Ford"
|
||||
assert params.values["CarModel"] == "FORD_MUSTANG_MACH_E_MK1"
|
||||
assert params.values["CarModelName"] == "Mustang Mach-E"
|
||||
assert params.values["FordHandsFreeCluster"] is False
|
||||
|
||||
|
||||
def test_vehicle_make_recovers_from_persistent_car_params_after_reset(monkeypatch):
|
||||
@contextmanager
|
||||
def ford_params(_):
|
||||
yield SimpleNamespace(brand="ford", carFingerprint="FORD_MUSTANG_MACH_E_MK1")
|
||||
|
||||
client, params = _client(monkeypatch, {"CarMake": "mock", "CarParamsPersistent": b"saved-ford-params"})
|
||||
monkeypatch.setattr(the_galaxy, "_safe_params_get_live_raw", lambda key, default=None, block=False: params.values.get(key, default))
|
||||
monkeypatch.setattr(the_galaxy.car.CarParams, "from_bytes", ford_params)
|
||||
|
||||
assert the_galaxy._get_effective_car_make("mock") == "Ford"
|
||||
assert the_galaxy._get_effective_car_make("Toyota") == "Toyota"
|
||||
assert client.get("/api/params/all").get_json()["CarMake"] == "Ford"
|
||||
|
||||
|
||||
@pytest.mark.parametrize("device_state", [
|
||||
{"IsOnroad": True, "IsOffroad": False},
|
||||
{"IsOnroad": False, "IsOffroad": False},
|
||||
|
||||
@@ -3762,6 +3762,23 @@ def _get_detected_truck_tuning():
|
||||
return False
|
||||
|
||||
|
||||
def _get_effective_car_make(stored_make):
|
||||
if isinstance(stored_make, bytes):
|
||||
stored_make = stored_make.decode("utf-8", errors="replace")
|
||||
if str(stored_make or "").strip().lower() not in ("", "mock"):
|
||||
return stored_make
|
||||
cp_bytes = _safe_params_get_live_raw("CarParamsPersistent")
|
||||
if cp_bytes:
|
||||
try:
|
||||
with car.CarParams.from_bytes(cp_bytes) as cp:
|
||||
if cp.brand and cp.brand != "mock":
|
||||
make_key = str(cp.carFingerprint).split("_", 1)[0]
|
||||
return next((make for make in FINGERPRINT_MAKE_LABELS if make.lower() == make_key.lower()), cp.brand.title())
|
||||
except Exception:
|
||||
pass
|
||||
return stored_make
|
||||
|
||||
|
||||
def _get_effective_legacy_custom_accel_curve(
|
||||
ev_tuning: bool, truck_tuning: bool, *, acceleration_profile=None, custom_enabled: bool | None = None,
|
||||
) -> list[float]:
|
||||
@@ -6773,6 +6790,8 @@ def setup(app):
|
||||
if request_key == "IsRHD" and not params.get_bool("IsRHDOverride"):
|
||||
return ("1" if params.get_bool("IsRhdDetected") else "0"), 200
|
||||
value = params.get(request_key) or ""
|
||||
if request_key == "CarMake":
|
||||
return _get_effective_car_make(value), 200
|
||||
if request_key in ("Model", "DrivingModel"):
|
||||
if isinstance(value, bytes):
|
||||
value = value.decode("utf-8", errors="replace")
|
||||
@@ -6813,6 +6832,7 @@ def setup(app):
|
||||
except Exception:
|
||||
result[key] = None
|
||||
|
||||
result["CarMake"] = _get_effective_car_make(result.get("CarMake"))
|
||||
result["TeslaCANWakeAvailable"] = supports_tesla_can_wake(params)
|
||||
result["HasRadar"] = _get_has_radar()
|
||||
result["VehicleParked"] = _get_vehicle_parked()
|
||||
@@ -10546,7 +10566,7 @@ def setup(app):
|
||||
|
||||
for raw_key in _params_raw.all_keys():
|
||||
key = raw_key.decode() if isinstance(raw_key, bytes) else str(raw_key)
|
||||
if key in EXCLUDED_KEYS:
|
||||
if key in EXCLUDED_KEYS or key in ("CarMake", "CarModel", "CarModelName"):
|
||||
continue
|
||||
|
||||
default_value = _params_raw.get_default_value(raw_key)
|
||||
|
||||
Reference in New Issue
Block a user