Crocs Marathon

This commit is contained in:
firestar5683
2026-08-18 21:17:45 -05:00
parent c201bef873
commit 4f0264d07e
13 changed files with 125 additions and 10 deletions
+11 -3
View File
@@ -1,3 +1,5 @@
import subprocess
Import('env', 'common', 'msgq')
cereal_dir = Dir('.')
@@ -5,9 +7,15 @@ gen_dir = Dir('gen')
# Build cereal
schema_files = ['log.capnp', 'car.capnp', 'legacy.capnp', 'custom.capnp']
env.Command([f'gen/cpp/{s}.c++' for s in schema_files] + [f'gen/cpp/{s}.h' for s in schema_files],
schema_files,
f"capnpc --src-prefix={cereal_dir.path} $SOURCES -o c++:{gen_dir.path}/cpp/")
schema_outputs = env.Command([f'gen/cpp/{s}.c++' for s in schema_files] + [f'gen/cpp/{s}.h' for s in schema_files],
schema_files,
f"capnpc --src-prefix={cereal_dir.path} $SOURCES -o c++:{gen_dir.path}/cpp/")
# capnpc embeds an exact compiler-version guard in every generated C++ header.
# Include the tool version in the dependency signature so SCons cannot reuse
# generated headers from a cache populated by another AGNOS/toolchain version.
capnp_compiler_version = subprocess.check_output(['capnpc', '--version'], encoding='utf-8').strip()
env.Depends(schema_outputs, env.Value(capnp_compiler_version))
cereal = env.Library('cereal', [f'gen/cpp/{s}.c++' for s in schema_files])
Binary file not shown.
+3 -2
View File
@@ -70,8 +70,9 @@ class CarInterface(CarInterfaceBase):
late_prius_camera = candidate == CAR.TOYOTA_PRIUS and any(
fw.ecu == Ecu.fwdCamera and bytes(fw.fwVersion).startswith(b'8646F4705') for fw in car_fw
)
if candidate == CAR.LEXUS_IS or late_prius_camera:
has_dsu_bypass = ((0x343 in camera_fingerprint and 0x343 not in fingerprint.get(1, {})) or
if candidate in (CAR.LEXUS_IS, CAR.TOYOTA_CAMRY) or late_prius_camera:
native_acc_fingerprints = (fingerprint.get(0, {}), fingerprint.get(1, {}))
has_dsu_bypass = ((0x343 in camera_fingerprint and not any(0x343 in native_bus for native_bus in native_acc_fingerprints)) or
(0x4CB in camera_fingerprint and 0x4CB not in fingerprint.get(0, {})))
if not use_sdsu and candidate not in TSS2_CAR and has_dsu_bypass:
ret.flags |= ToyotaFlags.DSU_BYPASS.value
@@ -284,6 +284,36 @@ class TestToyotaInterfaces:
assert car_params.safetyConfigs[0].safetyParam & ToyotaSafetyFlags.STOCK_LONGITUDINAL.value
assert car_params.safetyConfigs[0].safetyParam & ToyotaSafetyFlags.ALT_CRUISE.value
def test_camry_ignores_startup_acc_bus_mirror(self):
fingerprint = {bus: {} for bus in range(8)}
fingerprint[0][0x343] = 8
fingerprint[2][0x343] = 8
car_params = CarInterface.get_params(
CAR.TOYOTA_CAMRY,
fingerprint,
[CarParams.CarFw(ecu=Ecu.hybrid, address=0x7D2, fwVersion=b"test")],
alpha_long=False,
is_release=False,
docs=False,
starpilot_toggles=SimpleNamespace(),
)
assert car_params.flags & ToyotaFlags.HYBRID.value
assert not car_params.flags & ToyotaFlags.DSU_BYPASS.value
assert not car_params.openpilotLongitudinalControl
assert car_params.safetyConfigs[0].safetyParam & ToyotaSafetyFlags.STOCK_LONGITUDINAL.value
starpilot_params = CarInterface.get_starpilot_params(
CAR.TOYOTA_CAMRY, fingerprint, [], car_params, SimpleNamespace(),
)
car_state = CarState(car_params, starpilot_params)
can_parsers = car_state.get_can_parsers(car_params)
car_state.update(can_parsers, SimpleNamespace(cluster_offset=1.0))
assert "PRE_COLLISION" in can_parsers[Bus.pt].vl
for message in ("ACC_CONTROL", "PRE_COLLISION"):
assert message not in can_parsers[Bus.cam].vl
@pytest.mark.parametrize(("native_bus", "message"), [(1, 0x343), (0, 0x4CB)])
def test_prius_dsu_bypass_allows_native_bus_message(self, native_bus, message):
fingerprint = {bus: {} for bus in range(8)}
@@ -261,6 +261,21 @@ def test_curve_speed_controller_persists_data_after_leaving_curve():
assert any(key == "CurvatureData" for key, _ in planner.params.writes)
def test_curve_speed_controller_publishes_live_values_to_memory_params():
planner, vcruise = make_vcruise(road_curvature=0.02)
sm = make_sm(standstill=False)
sm["carControl"].longActive = False
planner.driving_in_curve = True
planner.lateral_acceleration = 2.4
vcruise.csc.training_timer = PLANNER_TIME
vcruise.csc.log_data(20.0, sm)
assert any(key == "CalibratedLateralAcceleration" for key, _ in planner.params_memory.writes)
assert any(key == "CalibrationProgress" for key, _ in planner.params_memory.writes)
assert planner.params_memory.values["CalibrationProgress"] > 0.0
def test_curve_speed_controller_ramps_toward_curve_speed_at_bounded_rate():
planner = SimpleNamespace(
params=FakeParams(),
@@ -1022,6 +1022,8 @@ class StarPilotLongitudinalLayout(_SettingsPage):
self._params.put_float("CalibratedLateralAcceleration", 2.00)
self._params.remove("CalibrationProgress")
self._params.remove("CurvatureData")
self._params_memory.put_float("CalibratedLateralAcceleration", 2.00)
self._params_memory.put_float("CalibrationProgress", 0.0)
gui_app.push_widget(ConfirmDialog(tr_noop("Reset Curve Data?"), tr_noop("Confirm"), callback=on_close))
+3
View File
@@ -257,6 +257,9 @@ class Soundd:
@retry(attempts=10, delay=3)
def get_stream(self, sd):
# reload sounddevice to reinitialize portaudio
sd._terminate()
sd._initialize()
return sd.OutputStream(channels=1, samplerate=SAMPLE_RATE, callback=self.callback, blocksize=SAMPLE_BUFFER)
def start_stream(self, sd):
@@ -54,6 +54,7 @@ class CurveSpeedController:
self.required_curvatures = [str(round(road_curvature, ROUNDING_PRECISION)) for road_curvature in np.arange(MIN_CURVATURE, MAX_CURVATURE + STEP, STEP)]
self.update_lateral_acceleration()
self._publish_calibration_progress()
@staticmethod
def _bucket_curvature(road_curvature):
@@ -102,15 +103,27 @@ class CurveSpeedController:
if not self.data_dirty:
return
progress = self._calibration_progress()
self.starpilot_planner.params.put_nonblocking("CalibrationProgress", progress)
self.starpilot_planner.params.put_nonblocking("CurvatureData", self.curvature_data)
self._put_memory_param("CalibrationProgress", progress)
self.data_dirty = False
self.persistence_timer = 0.0
def _calibration_progress(self):
progress = 0.0
for key in self.required_curvatures:
if key in self.curvature_data:
progress += min(self.curvature_data[key]["count"] / CALIBRATION_PROGRESS_THRESHOLD, 1.0)
return (progress / len(self.required_curvatures)) * 100
self.starpilot_planner.params.put_nonblocking("CalibrationProgress", (progress / len(self.required_curvatures)) * 100)
self.starpilot_planner.params.put_nonblocking("CurvatureData", self.curvature_data)
self.data_dirty = False
self.persistence_timer = 0.0
def _publish_calibration_progress(self):
self._put_memory_param("CalibrationProgress", self._calibration_progress())
def _put_memory_param(self, key, value):
params_memory = getattr(self.starpilot_planner, "params_memory", None)
if params_memory is not None:
params_memory.put_nonblocking(key, value)
def flush_data(self):
self._persist_data()
@@ -158,6 +171,7 @@ class CurveSpeedController:
self.data_dirty = True
self.update_lateral_acceleration()
self._publish_calibration_progress()
self.enable_training = True
if self.persistence_timer >= PLANNER_TIME:
@@ -173,6 +187,7 @@ class CurveSpeedController:
self.lateral_acceleration = DEFAULT_LATERAL_ACCELERATION
self.starpilot_planner.params.put_nonblocking("CalibratedLateralAcceleration", self.lateral_acceleration)
self._put_memory_param("CalibratedLateralAcceleration", self.lateral_acceleration)
def update_target(self, v_ego):
lateral_acceleration = self.lateral_acceleration
@@ -42,6 +42,10 @@ sys.modules.setdefault("openpilot.system.loggerd.uploader", loggerd_uploader)
model_manager = ModuleType("openpilot.starpilot.assets.model_manager")
model_manager.canonical_model_key = lambda value: str(value or "").strip().lower().replace(" ", "-")
model_manager.external_gpu_available = lambda: False
model_manager.is_builtin_model_key = lambda key: False
model_manager.model_key_aliases = lambda key: ()
model_manager.model_uses_external_gpu = lambda key: False
sys.modules.setdefault("openpilot.starpilot.assets.model_manager", model_manager)
starpilot_variables = ModuleType("openpilot.starpilot.common.starpilot_variables")
@@ -220,6 +224,7 @@ def _install_server_import_stubs():
)
for name, value in {
"ACTIVE_THEME_PATH": Path("/tmp/dashboard-test-active-theme"),
"BUTTON_FUNCTIONS": {},
"ERROR_LOGS_PATH": "/tmp/dashboard-test-errors",
"EXCLUDED_KEYS": set(),
"LEGACY_STARPILOT_PARAM_RENAMES": {},
@@ -1613,6 +1618,24 @@ def _load_server_module():
return module
def test_clear_generated_build_state_preserves_prebuilts_and_user_data(tmp_path):
server = _load_server_module()
sconsign = tmp_path / ".sconsign.dblite"
generated = tmp_path / "cereal" / "gen" / "cpp" / "log.capnp.h"
prebuilt = tmp_path / "prebuilt"
user_model = tmp_path / "uncompiledmodels" / "custom.onnx"
for path in (sconsign, generated, prebuilt, user_model):
path.parent.mkdir(parents=True, exist_ok=True)
path.write_text("test")
server._clear_generated_build_state(tmp_path)
assert not sconsign.exists()
assert not (tmp_path / "cereal" / "gen").exists()
assert prebuilt.read_text() == "test"
assert user_model.read_text() == "test"
def test_troubleshoot_steer_delay_normalizes_vehicle_delay_for_display():
server = _load_server_module()
+15
View File
@@ -2161,6 +2161,18 @@ def _git_stdout(repo_path, args, timeout=15):
raise RuntimeError(stderr)
return (result.stdout or "").strip()
def _clear_generated_build_state(repo_path):
"""Drop ignored build metadata that is unsafe to carry across revisions."""
root = Path(repo_path)
for path in (root / ".sconsign.dblite", root / "cereal" / "gen"):
try:
if path.is_dir() and not path.is_symlink():
shutil.rmtree(path)
else:
path.unlink(missing_ok=True)
except OSError as exception:
raise RuntimeError(f"Unable to clear stale build state at {path}: {exception}") from exception
def _git_config_get(repo_path, key):
try:
return _git_stdout(repo_path, ["config", "--local", "--get", key], timeout=10)
@@ -2497,6 +2509,7 @@ def _fast_update_worker():
reset = _run_git(repo_path, ["reset", "--hard", "FETCH_HEAD"], timeout=120)
if reset.returncode != 0:
raise RuntimeError((reset.stderr or reset.stdout or "git reset failed").strip())
_clear_generated_build_state(repo_path)
_set_fast_update_progress(3, "Applying fetched commit", 100.0, "Repository reset complete.")
_run_submodule_update_if_needed(repo_path, step=4)
@@ -2549,6 +2562,7 @@ def _branch_switch_worker(target_branch):
reset = _run_git(repo_path, ["reset", "--hard", "FETCH_HEAD"], timeout=120)
if reset.returncode != 0:
raise RuntimeError((reset.stderr or reset.stdout or "git reset failed").strip())
_clear_generated_build_state(repo_path)
_run_git(repo_path, ["branch", "--set-upstream-to", f"origin/{target_branch}", target_branch], timeout=30)
_set_fast_update_progress(3, "Switching branch", 100.0, f"Now on '{target_branch}'.")
@@ -2617,6 +2631,7 @@ def _rollback_worker():
reset = _run_git(repo_path, ["reset", "--hard", target_commit], timeout=120)
if reset.returncode != 0:
raise RuntimeError((reset.stderr or reset.stdout or "git reset failed").strip())
_clear_generated_build_state(repo_path)
_run_git(repo_path, ["branch", "--set-upstream-to", f"origin/{target_branch}", target_branch], timeout=30)
_set_fast_update_progress(3, "Applying rollback target", 100.0, f"Now on {target_branch} @ {short_commit}.")
Binary file not shown.
+3
View File
@@ -97,6 +97,9 @@ class Mic:
@retry(attempts=10, delay=3)
def get_stream(self, sd, device=None):
# reload sounddevice to reinitialize portaudio
sd._terminate()
sd._initialize()
kwargs = {
"channels": 1,
"samplerate": SAMPLE_RATE,
+1 -1
View File
@@ -1,6 +1,6 @@
FROM ghcr.io/commaai/openpilot-base-aarch64:latest
ARG CAPNP_VERSION=1.3.0
ARG CAPNP_VERSION=1.0.2
ENV PYTHONUNBUFFERED=1
ENV UV_LINK_MODE=copy