mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-15 06:12:11 +08:00
nighty night
This commit is contained in:
Binary file not shown.
@@ -323,7 +323,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"FLMActiveProfileId", {PERSISTENT, STRING, "", "", 2}},
|
||||
{"FLMTrialBaseline", {PERSISTENT | DONT_LOG, JSON, "{}", "{}"}},
|
||||
{"FLMTrialApplied", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||
{"FPSCounter", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||
{"FPSCounter", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
{"GalaxyDashboardStats", {PERSISTENT | DONT_LOG, JSON, "{}", "{}"}},
|
||||
{"StarPilotApiToken", {PERSISTENT | DONT_LOG, STRING, "", "", 0}},
|
||||
{"StarPilotCarParams", {CLEAR_ON_MANAGER_START | CLEAR_ON_ONROAD_TRANSITION, BYTES, "", ""}},
|
||||
@@ -448,7 +448,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"NoUploads", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||
{"NudgelessLaneChange", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||
{"NudgelessLaneChangeOnlyWhenEngaged", {PERSISTENT, BOOL, "0", "0", 1}},
|
||||
{"NumericalTemp", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||
{"NumericalTemp", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
{"Offset1", {PERSISTENT, FLOAT, "5.0", "0.0", 0}},
|
||||
{"Offset2", {PERSISTENT, FLOAT, "5.0", "0.0", 0}},
|
||||
{"Offset3", {PERSISTENT, FLOAT, "5.0", "0.0", 0}},
|
||||
@@ -520,11 +520,11 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"SetSpeedOffset", {PERSISTENT, FLOAT, "0.0", "0.0", 2}},
|
||||
{"ShowCEMStatus", {PERSISTENT, BOOL, "1", "0", 2}},
|
||||
{"ShowCCMStatus", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||
{"ShowCPU", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||
{"ShowCPU", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
{"ShowCSCStatus", {PERSISTENT, BOOL, "1", "0", 2}},
|
||||
{"ShowGPU", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
{"ShowIP", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
{"ShowMemoryUsage", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||
{"ShowMemoryUsage", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
{"ShowModeStatusBanner", {PERSISTENT, BOOL, "1", "0", 2}},
|
||||
{"ShownToggleDescriptions", {PERSISTENT, JSON, "{}", "{}"}},
|
||||
{"ShowSLCOffset", {PERSISTENT, BOOL, "1", "0", 0}},
|
||||
@@ -534,7 +534,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"ShowStoppingPointMetrics", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||
{"ShowStorageLeft", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
{"ShowStorageUsed", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
{"SidebarMetrics", {PERSISTENT, BOOL, "1", "0", 3}},
|
||||
{"SidebarMetrics", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
{"SidebarOpen", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||
{"SignalAnimation", {PERSISTENT, STRING, "stock", "stock", 0}},
|
||||
{"SignalMetrics", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
@@ -567,7 +567,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"SpeedLimitSources", {PERSISTENT, BOOL, "0", "0", 3}},
|
||||
{"VisionSpeedLimitAutoBookmark", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||
{"VisionSpeedLimitAutoPreserveSegment", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||
{"VisionSpeedLimitDetection", {PERSISTENT, BOOL, "0", "0", 0}},
|
||||
{"VisionSpeedLimitDetection", {PERSISTENT, BOOL, "1", "0", 0}},
|
||||
{"VisionSpeedLimitTrainingCollector", {PERSISTENT, BOOL, "1", "1", 0}},
|
||||
{"StandardFollow", {PERSISTENT, FLOAT, "1.45", "1.45", 2}},
|
||||
{"StandardFollowHigh", {PERSISTENT, FLOAT, "1.2", "1.2", 2}},
|
||||
|
||||
Binary file not shown.
@@ -52,12 +52,18 @@ LOCK_CMD = b"\x40\x05\x30\x11\x00\x80\x00\x00"
|
||||
UNLOCK_CMD = b"\x40\x05\x30\x11\x00\x40\x00\x00"
|
||||
|
||||
|
||||
def is_ths_hybrid(CP) -> bool:
|
||||
return CP.carFingerprint == CAR.TOYOTA_PRIUS or (
|
||||
CP.carFingerprint == CAR.TOYOTA_CAMRY and bool(CP.flags & ToyotaFlags.HYBRID.value)
|
||||
)
|
||||
|
||||
|
||||
def get_long_tune(CP, params):
|
||||
kiBP = [2., 5.]
|
||||
kiV = [0.5, 0.25]
|
||||
k_f = 1.0
|
||||
|
||||
if CP.carFingerprint == CAR.TOYOTA_PRIUS:
|
||||
if is_ths_hybrid(CP):
|
||||
k_f = 0.8
|
||||
elif CP.carFingerprint not in TSS2_CAR:
|
||||
kiBP = [0., 5., 35.]
|
||||
@@ -440,7 +446,7 @@ class CarController(CarControllerBase):
|
||||
else:
|
||||
# constantly slowly unwind integral to recover from large temporary errors
|
||||
unwind_rate = ACCEL_PID_UNWIND
|
||||
if self.CP.carFingerprint == CAR.TOYOTA_PRIUS and pcm_accel_cmd * self.long_pid.i < 0.0:
|
||||
if is_ths_hybrid(self.CP) and pcm_accel_cmd * self.long_pid.i < 0.0:
|
||||
unwind_rate *= PRIUS_INTEGRAL_MISMATCH_UNWIND
|
||||
self.long_pid.i -= unwind_rate * float(np.sign(self.long_pid.i))
|
||||
|
||||
|
||||
@@ -158,6 +158,8 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.minEnableSpeed = -1. if (stop_and_go or ret.enableGasInterceptorDEPRECATED) else MIN_ACC_SPEED
|
||||
|
||||
prius_long_defaults = candidate == CAR.TOYOTA_PRIUS and ret.openpilotLongitudinalControl
|
||||
camry_hybrid_long_defaults = (candidate == CAR.TOYOTA_CAMRY and ret.openpilotLongitudinalControl and
|
||||
bool(ret.flags & ToyotaFlags.HYBRID.value))
|
||||
|
||||
if candidate in TSS2_CAR or ret.enableGasInterceptorDEPRECATED or prius_long_defaults:
|
||||
ret.flags |= ToyotaFlags.RAISED_ACCEL_LIMIT.value
|
||||
@@ -170,6 +172,13 @@ class CarInterface(CarInterfaceBase):
|
||||
if ret.flags & ToyotaFlags.HYBRID.value:
|
||||
ret.longitudinalActuatorDelay = 0.05
|
||||
|
||||
if camry_hybrid_long_defaults:
|
||||
# The THS eCVT responds much faster than the legacy non-TSS2 ICE tune.
|
||||
ret.longitudinalActuatorDelay = 0.05
|
||||
ret.vEgoStopping = 0.25
|
||||
ret.vEgoStarting = 0.25
|
||||
ret.stoppingDecelRate = 0.3
|
||||
|
||||
if ret.enableGasInterceptorDEPRECATED:
|
||||
# Pedal/SDSU Toyotas feel best with a softer final stop clamp.
|
||||
ret.longitudinalActuatorDelay = max(ret.longitudinalActuatorDelay, 0.2)
|
||||
|
||||
@@ -8,7 +8,7 @@ from opendbc.can import CANPacker, CANParser
|
||||
from opendbc.car.structs import CarParams
|
||||
from opendbc.car.fw_versions import build_fw_dict
|
||||
from opendbc.car.toyota import toyotacan
|
||||
from opendbc.car.toyota.carcontroller import CarController, get_prius_positive_feedforward_scale, limit_interceptor_pcm_accel, \
|
||||
from opendbc.car.toyota.carcontroller import CarController, get_long_tune, get_prius_positive_feedforward_scale, limit_interceptor_pcm_accel, \
|
||||
limit_interceptor_stopping_accel, limit_no_lead_cruise_sign_flip, \
|
||||
limit_prius_stopping_accel, update_permit_braking
|
||||
from opendbc.car.toyota.carstate import calculate_interceptor_gas_pressed
|
||||
@@ -82,7 +82,7 @@ class TestToyotaInterfaces:
|
||||
assert abs(car_params.vEgoStopping - 0.25) < 1e-6
|
||||
assert abs(car_params.vEgoStarting - 0.25) < 1e-6
|
||||
|
||||
def test_camry_continental_radar_keeps_standard_longitudinal_tune(self):
|
||||
def test_camry_hybrid_continental_radar_uses_ths_longitudinal_tune(self):
|
||||
fingerprint = {bus: ({0x2FF: 8} if bus == 0 else {}) for bus in range(8)}
|
||||
hybrid_fw = [CarParams.CarFw(ecu=Ecu.hybrid, address=0x7D2, fwVersion=b"test")]
|
||||
car_params = CarInterface.get_params(
|
||||
@@ -98,17 +98,44 @@ class TestToyotaInterfaces:
|
||||
assert car_params.openpilotLongitudinalControl
|
||||
assert not car_params.radarUnavailable
|
||||
assert abs(car_params.radarTimeStepDEPRECATED - 0.1) < 1e-6
|
||||
assert abs(car_params.longitudinalActuatorDelay - 0.15) < 1e-6
|
||||
assert abs(car_params.vEgoStopping - 0.5) < 1e-6
|
||||
assert abs(car_params.vEgoStarting - 0.5) < 1e-6
|
||||
assert abs(car_params.stoppingDecelRate - 0.8) < 1e-6
|
||||
assert abs(car_params.longitudinalActuatorDelay - 0.05) < 1e-6
|
||||
assert abs(car_params.vEgoStopping - 0.25) < 1e-6
|
||||
assert abs(car_params.vEgoStarting - 0.25) < 1e-6
|
||||
assert abs(car_params.stoppingDecelRate - 0.3) < 1e-6
|
||||
assert not car_params.flags & ToyotaFlags.NO_STOP_TIMER.value
|
||||
|
||||
controller = get_long_tune(car_params, SimpleNamespace(ACCEL_MIN=-3.5, ACCEL_MAX=2.0))
|
||||
controller.speed = 0.0
|
||||
assert controller.k_i == pytest.approx(0.5)
|
||||
assert controller.k_f == pytest.approx(0.8)
|
||||
|
||||
radar_interface = RadarInterface(car_params)
|
||||
assert radar_interface.radar_acc_tssp
|
||||
assert radar_interface.rcp is not None
|
||||
assert radar_interface.pt_cp is not None
|
||||
|
||||
def test_camry_ice_keeps_legacy_longitudinal_tune(self):
|
||||
fingerprint = {bus: ({0x2FF: 8} if bus == 0 else {}) for bus in range(8)}
|
||||
car_params = CarInterface.get_params(
|
||||
CAR.TOYOTA_CAMRY,
|
||||
fingerprint,
|
||||
[],
|
||||
alpha_long=True,
|
||||
is_release=False,
|
||||
docs=False,
|
||||
starpilot_toggles=SimpleNamespace(),
|
||||
)
|
||||
|
||||
assert not car_params.flags & ToyotaFlags.HYBRID.value
|
||||
assert car_params.longitudinalActuatorDelay == pytest.approx(0.15)
|
||||
assert car_params.vEgoStopping == pytest.approx(0.5)
|
||||
assert car_params.stoppingDecelRate == pytest.approx(0.8)
|
||||
|
||||
controller = get_long_tune(car_params, SimpleNamespace(ACCEL_MIN=-3.5, ACCEL_MAX=2.0))
|
||||
controller.speed = 0.0
|
||||
assert controller.k_i == pytest.approx(3.6)
|
||||
assert controller.k_f == pytest.approx(1.0)
|
||||
|
||||
def test_camry_continental_radar_converts_absolute_target_speed(self):
|
||||
radar_interface = RadarInterface.__new__(RadarInterface)
|
||||
radar_interface.CP = SimpleNamespace(wheelSpeedFactor=1.0)
|
||||
|
||||
@@ -10,6 +10,7 @@ from collections import defaultdict, deque
|
||||
from pathlib import Path
|
||||
|
||||
from openpilot.common.basedir import BASEDIR
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
|
||||
MAPD_DIR = Path(BASEDIR) / "starpilot/navigation"
|
||||
@@ -19,6 +20,8 @@ RESTART_DELAY_S = 0.25
|
||||
MISSING_TILE_BACKOFF_S = 30.0
|
||||
FAILURE_WINDOW_S = 3.0
|
||||
FAILURE_THRESHOLD = 3
|
||||
MISSING_COVERAGE_EXIT_CODE = 3
|
||||
ROAD_STATE_POLL_S = 1.0
|
||||
|
||||
|
||||
def extract_bounds_filename(line: str) -> str | None:
|
||||
@@ -75,25 +78,19 @@ class CorruptTileMonitor:
|
||||
def quarantine_offline_tile(filename: str) -> Path | None:
|
||||
tile_path = Path(filename)
|
||||
try:
|
||||
relative_path = tile_path.relative_to(OFFLINE_ROOT)
|
||||
tile_path.relative_to(OFFLINE_ROOT)
|
||||
except ValueError:
|
||||
cloudlog.warning(f"mapd_wrapper refusing to quarantine unexpected path: {filename}")
|
||||
return None
|
||||
|
||||
quarantine_path = tile_path if tile_path.is_file() else None
|
||||
if quarantine_path is None and len(relative_path.parts) >= 2:
|
||||
archive_path = OFFLINE_ROOT / relative_path.parts[0] / f"{relative_path.parts[1]}.tar.gz"
|
||||
if archive_path.is_file():
|
||||
quarantine_path = archive_path
|
||||
|
||||
if quarantine_path is None:
|
||||
if not tile_path.is_file():
|
||||
return None
|
||||
|
||||
quarantined = quarantine_path.with_name(f"{quarantine_path.name}.corrupt.{int(time.time())}")
|
||||
quarantined = tile_path.with_name(f"{tile_path.name}.corrupt.{int(time.time())}")
|
||||
try:
|
||||
quarantine_path.rename(quarantined)
|
||||
tile_path.rename(quarantined)
|
||||
except OSError:
|
||||
cloudlog.exception(f"mapd_wrapper failed to quarantine offline data: {quarantine_path}")
|
||||
cloudlog.exception(f"mapd_wrapper failed to quarantine offline data: {tile_path}")
|
||||
return None
|
||||
return quarantined
|
||||
|
||||
@@ -145,6 +142,15 @@ def run_mapd_once() -> int:
|
||||
for line in proc.stdout:
|
||||
print(line, end="")
|
||||
bad_tile = monitor.observe(line)
|
||||
|
||||
# mapd reports an unmarshal failure even when no offline tile is installed.
|
||||
# Stop its resulting hot loop until the next onroad process cycle.
|
||||
missing_tile = monitor.current_filename
|
||||
if is_offline_read_error(line) and missing_tile is not None and not Path(missing_tile).is_file():
|
||||
cloudlog.info(f"mapd_wrapper has no offline tile for {missing_tile}; stopping mapd until the next drive")
|
||||
terminate_child(proc)
|
||||
return MISSING_COVERAGE_EXIT_CODE
|
||||
|
||||
if bad_tile is None:
|
||||
continue
|
||||
|
||||
@@ -170,7 +176,14 @@ def run_mapd_once() -> int:
|
||||
return proc.wait()
|
||||
|
||||
|
||||
def wait_for_road_state_change(params: Params) -> None:
|
||||
initial_onroad = params.get_bool("IsOnroad")
|
||||
while params.get_bool("IsOnroad") == initial_onroad:
|
||||
time.sleep(ROAD_STATE_POLL_S)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
params = Params()
|
||||
while True:
|
||||
exit_code = run_mapd_once()
|
||||
if exit_code == 1:
|
||||
@@ -179,6 +192,9 @@ def main() -> None:
|
||||
if exit_code == 2:
|
||||
time.sleep(MISSING_TILE_BACKOFF_S)
|
||||
continue
|
||||
if exit_code == MISSING_COVERAGE_EXIT_CODE:
|
||||
wait_for_road_state_change(params)
|
||||
continue
|
||||
raise SystemExit(exit_code)
|
||||
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ import subprocess
|
||||
|
||||
from pathlib import Path
|
||||
|
||||
from openpilot.starpilot.navigation.mapd_wrapper import CorruptTileMonitor, quarantine_offline_tile, terminate_child
|
||||
from openpilot.starpilot.navigation.mapd_wrapper import CorruptTileMonitor, quarantine_offline_tile, run_mapd_once, terminate_child, wait_for_road_state_change
|
||||
|
||||
|
||||
def _loading_line(filename: str) -> str:
|
||||
@@ -43,21 +43,60 @@ def test_quarantine_offline_tile_renames_file(tmp_path, monkeypatch):
|
||||
assert Path(quarantined).name.startswith(f"{tile.name}.corrupt.")
|
||||
|
||||
|
||||
def test_quarantine_offline_tile_renames_backing_archive(tmp_path, monkeypatch):
|
||||
def test_quarantine_offline_tile_ignores_missing_file(tmp_path, monkeypatch):
|
||||
offline_root = tmp_path / "offline"
|
||||
archive = offline_root / "34/-88.tar.gz"
|
||||
archive.parent.mkdir(parents=True)
|
||||
archive.write_text("bad archive")
|
||||
virtual_tile = offline_root / "34/-88/34.750000_-87.750000_35.000000_-87.500000"
|
||||
missing_tile = offline_root / "34/-88/34.750000_-87.750000_35.000000_-87.500000"
|
||||
|
||||
monkeypatch.setitem(quarantine_offline_tile.__globals__, "OFFLINE_ROOT", offline_root)
|
||||
|
||||
quarantined = quarantine_offline_tile(virtual_tile.as_posix())
|
||||
assert quarantine_offline_tile(missing_tile.as_posix()) is None
|
||||
|
||||
assert quarantined is not None
|
||||
assert not archive.exists()
|
||||
assert Path(quarantined).exists()
|
||||
assert Path(quarantined).name.startswith(f"{archive.name}.corrupt.")
|
||||
|
||||
def test_run_mapd_once_stops_for_missing_offline_coverage(tmp_path, monkeypatch):
|
||||
missing_tile = tmp_path / "offline/36/-98/37.500000_-98.000000_37.750000_-97.750000"
|
||||
output = []
|
||||
for _ in range(4):
|
||||
output.extend((_loading_line(missing_tile.as_posix()), _error_line()))
|
||||
|
||||
class CompletedProcess:
|
||||
pid = 123
|
||||
|
||||
def __init__(self):
|
||||
self.stdout = iter(f"{line}\n" for line in output)
|
||||
self.terminated = False
|
||||
|
||||
def poll(self):
|
||||
return 0 if self.terminated else None
|
||||
|
||||
def terminate(self):
|
||||
self.terminated = True
|
||||
|
||||
def wait(self, timeout=None):
|
||||
return 0
|
||||
|
||||
proc = CompletedProcess()
|
||||
monkeypatch.setitem(run_mapd_once.__globals__, "OFFLINE_ROOT", tmp_path / "offline")
|
||||
monkeypatch.setattr(subprocess, "Popen", lambda *args, **kwargs: proc)
|
||||
monkeypatch.setattr("signal.signal", lambda *args: None)
|
||||
|
||||
assert run_mapd_once() == 3
|
||||
assert proc.terminated
|
||||
|
||||
|
||||
def test_missing_coverage_waits_for_road_state_change(monkeypatch):
|
||||
class Params:
|
||||
states = iter((True, True, False))
|
||||
|
||||
def get_bool(self, key):
|
||||
assert key == "IsOnroad"
|
||||
return next(self.states)
|
||||
|
||||
sleeps = []
|
||||
monkeypatch.setattr("time.sleep", sleeps.append)
|
||||
|
||||
wait_for_road_state_change(Params())
|
||||
|
||||
assert sleeps == [1.0]
|
||||
|
||||
|
||||
def test_terminate_child_tolerates_wedged_process():
|
||||
|
||||
@@ -10,6 +10,15 @@ LONG_PITCH_KEY = "LongPitch"
|
||||
STEER_KP_KEY = "SteerKP"
|
||||
STEER_KP_STOCK_KEY = "SteerKPStock"
|
||||
USE_OLD_UI_KEY = "UseOldUI"
|
||||
VISION_SPEED_LIMIT_DETECTION_KEY = "VisionSpeedLimitDetection"
|
||||
DEVELOPER_METRIC_DISPLAY_KEYS = (
|
||||
"FPSCounter",
|
||||
"ShowCPU",
|
||||
"ShowGPU",
|
||||
"NumericalTemp",
|
||||
"ShowMemoryUsage",
|
||||
"SidebarMetrics",
|
||||
)
|
||||
|
||||
DEFAULT_STEER_KP = 0.6
|
||||
LEGACY_STEER_KP = 0.7
|
||||
@@ -20,6 +29,8 @@ BRANCH_DEFAULTS_MIGRATION_MARKER = ".starpilot_branch_defaults_migrations_v1"
|
||||
ACCELERATION_PROFILE_MIGRATION_MARKER = ".starpilot_acceleration_profile_default_v1"
|
||||
USE_OLD_UI_MIGRATION_MARKER = ".starpilot_use_old_ui_migration_v2"
|
||||
LATERAL_METHOD_REBRAND_MIGRATION_MARKER = ".starpilot_lateral_method_rebrand_v1"
|
||||
VISION_SPEED_LIMIT_DETECTION_MIGRATION_MARKER = ".starpilot_vision_speed_limit_detection_v1"
|
||||
DEVELOPER_METRIC_DISPLAY_MIGRATION_MARKER = ".starpilot_developer_metric_display_off_v1"
|
||||
MARKER_DIRNAME = ".starpilot_param_migrations"
|
||||
|
||||
LATERAL_METHOD_PARAM_SUFFIXES = (
|
||||
@@ -99,6 +110,14 @@ def _lateral_method_rebrand_marker_path(params: ParamsLike) -> Path:
|
||||
return _marker_dir_path(params) / LATERAL_METHOD_REBRAND_MIGRATION_MARKER
|
||||
|
||||
|
||||
def _vision_speed_limit_detection_marker_path(params: ParamsLike) -> Path:
|
||||
return _marker_dir_path(params) / VISION_SPEED_LIMIT_DETECTION_MIGRATION_MARKER
|
||||
|
||||
|
||||
def _developer_metric_display_marker_path(params: ParamsLike) -> Path:
|
||||
return _marker_dir_path(params) / DEVELOPER_METRIC_DISPLAY_MIGRATION_MARKER
|
||||
|
||||
|
||||
def _marker_dir_path(params: ParamsLike) -> Path:
|
||||
params_path = Path(params.get_param_path())
|
||||
# Params.clear_all() removes unknown files inside the params directory, so
|
||||
@@ -208,11 +227,36 @@ def _apply_lateral_method_rebrand_migration(params: ParamsLike, marker: Path) ->
|
||||
marker.touch()
|
||||
|
||||
|
||||
def _apply_vision_speed_limit_detection_migration(params: ParamsLike, marker: Path) -> None:
|
||||
if marker.exists():
|
||||
return
|
||||
|
||||
marker.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
params.put_bool(VISION_SPEED_LIMIT_DETECTION_KEY, True)
|
||||
|
||||
marker.touch()
|
||||
|
||||
|
||||
def _apply_developer_metric_display_migration(params: ParamsLike, marker: Path) -> None:
|
||||
if marker.exists():
|
||||
return
|
||||
|
||||
marker.parent.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for key in DEVELOPER_METRIC_DISPLAY_KEYS:
|
||||
params.put_bool(key, False)
|
||||
|
||||
marker.touch()
|
||||
|
||||
|
||||
def apply_launch_param_migrations(params: ParamsLike, marker_path: Path | None = None,
|
||||
branch_defaults_marker_path: Path | None = None,
|
||||
acceleration_profile_marker_path: Path | None = None,
|
||||
use_old_ui_marker_path: Path | None = None,
|
||||
lateral_method_rebrand_marker_path: Path | None = None) -> None:
|
||||
lateral_method_rebrand_marker_path: Path | None = None,
|
||||
vision_speed_limit_detection_marker_path: Path | None = None,
|
||||
developer_metric_display_marker_path: Path | None = None) -> None:
|
||||
_apply_legacy_launch_param_migrations(params, marker_path or _default_marker_path(params))
|
||||
# Keep branch-default rollout on its own marker so older installs that already
|
||||
# have the legacy marker still receive this one-time param reset.
|
||||
@@ -224,6 +268,12 @@ def apply_launch_param_migrations(params: ParamsLike, marker_path: Path | None =
|
||||
_apply_lateral_method_rebrand_migration(
|
||||
params, lateral_method_rebrand_marker_path or _lateral_method_rebrand_marker_path(params)
|
||||
)
|
||||
_apply_vision_speed_limit_detection_migration(
|
||||
params, vision_speed_limit_detection_marker_path or _vision_speed_limit_detection_marker_path(params)
|
||||
)
|
||||
_apply_developer_metric_display_migration(
|
||||
params, developer_metric_display_marker_path or _developer_metric_display_marker_path(params)
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
|
||||
@@ -3,12 +3,15 @@ from pathlib import Path
|
||||
from openpilot.system.manager.launch_param_migrations import (
|
||||
ACCELERATION_PROFILE_MIGRATION_MARKER,
|
||||
BRANCH_DEFAULTS_MIGRATION_MARKER,
|
||||
DEVELOPER_METRIC_DISPLAY_KEYS,
|
||||
DEVELOPER_METRIC_DISPLAY_MIGRATION_MARKER,
|
||||
DEFAULT_STEER_KP,
|
||||
LAUNCH_PARAM_MIGRATION_MARKER,
|
||||
LATERAL_METHOD_REBRAND_MIGRATION_MARKER,
|
||||
MARKER_DIRNAME,
|
||||
STANDARD_ACCELERATION_PROFILE,
|
||||
USE_OLD_UI_MIGRATION_MARKER,
|
||||
VISION_SPEED_LIMIT_DETECTION_MIGRATION_MARKER,
|
||||
apply_launch_param_migrations,
|
||||
)
|
||||
|
||||
@@ -258,3 +261,51 @@ def test_apply_launch_param_migrations_preserves_active_lateral_method_trial(tmp
|
||||
assert params.get(f"FLM{suffix}") == value
|
||||
assert not Path(params.get_param_path(f"{legacy_prefix}{suffix}")).exists()
|
||||
assert marker_path(tmp_path, LATERAL_METHOD_REBRAND_MIGRATION_MARKER).is_file()
|
||||
|
||||
|
||||
def test_apply_launch_param_migrations_enables_vision_speed_limit_detection_once(tmp_path):
|
||||
params = FileBackedFakeParams(tmp_path / "params")
|
||||
params.put_bool("VisionSpeedLimitDetection", False)
|
||||
params.put("SLCPriority1", "Dashboard")
|
||||
params.put("SLCPriority2", "Map Data")
|
||||
|
||||
apply_launch_param_migrations(params)
|
||||
|
||||
assert params.get_bool("VisionSpeedLimitDetection")
|
||||
assert params.get("SLCPriority1") == "Dashboard"
|
||||
assert params.get("SLCPriority2") == "Map Data"
|
||||
assert marker_path(tmp_path, VISION_SPEED_LIMIT_DETECTION_MIGRATION_MARKER).is_file()
|
||||
|
||||
|
||||
def test_apply_launch_param_migrations_does_not_reenable_vision_speed_limit_detection_after_marker(tmp_path):
|
||||
params = FileBackedFakeParams(tmp_path / "params")
|
||||
params.put_bool("VisionSpeedLimitDetection", False)
|
||||
marker_path(tmp_path, VISION_SPEED_LIMIT_DETECTION_MIGRATION_MARKER).touch()
|
||||
|
||||
apply_launch_param_migrations(params)
|
||||
|
||||
assert not params.get_bool("VisionSpeedLimitDetection")
|
||||
|
||||
|
||||
def test_apply_launch_param_migrations_disables_developer_metric_display_once(tmp_path):
|
||||
params = FileBackedFakeParams(tmp_path / "params")
|
||||
for key in DEVELOPER_METRIC_DISPLAY_KEYS:
|
||||
params.put_bool(key, True)
|
||||
|
||||
apply_launch_param_migrations(params)
|
||||
|
||||
for key in DEVELOPER_METRIC_DISPLAY_KEYS:
|
||||
assert not params.get_bool(key)
|
||||
assert marker_path(tmp_path, DEVELOPER_METRIC_DISPLAY_MIGRATION_MARKER).is_file()
|
||||
|
||||
|
||||
def test_apply_launch_param_migrations_preserves_developer_metric_display_after_marker(tmp_path):
|
||||
params = FileBackedFakeParams(tmp_path / "params")
|
||||
for key in DEVELOPER_METRIC_DISPLAY_KEYS:
|
||||
params.put_bool(key, True)
|
||||
marker_path(tmp_path, DEVELOPER_METRIC_DISPLAY_MIGRATION_MARKER).touch()
|
||||
|
||||
apply_launch_param_migrations(params)
|
||||
|
||||
for key in DEVELOPER_METRIC_DISPLAY_KEYS:
|
||||
assert params.get_bool(key)
|
||||
|
||||
Reference in New Issue
Block a user