IQ.Pilot Release Commit @ 98a2c61

This commit is contained in:
IQ.Lvbs CI [bot]
2026-08-19 14:10:31 -05:00
parent dca8172e55
commit 7e3d70380a
55 changed files with 699 additions and 114 deletions

View File

@@ -6,6 +6,7 @@ import subprocess
from iqpilot.common.params import Params
PARAM = "GitAuthBlob"
PARAMS_DIR = os.environ.get("PARAMS_DIR", "/data/params/d")
KEY_DIR = "/data/konn3kt"
KEY_PATH = os.path.join(KEY_DIR, "git_auth.key")
HELPER_PATH = os.path.join(KEY_DIR, "git_credential_helper.py")
@@ -51,6 +52,48 @@ if __name__ == "__main__":
'''
def _params_get(name: str) -> bytes | None:
# Params -> cereal -> iqdbc: that chain is unavailable mid-bootstrap (this module's
# callers install those very packages), so fall back to the params file directly,
# exactly like the embedded credential helper does.
try:
return Params().get(name)
except Exception:
try:
with open(os.path.join(PARAMS_DIR, name), "rb") as f:
return f.read()
except OSError:
return None
def _params_put(name: str, value: bytes) -> None:
try:
Params().put(name, value)
return
except Exception:
pass
os.makedirs(PARAMS_DIR, exist_ok=True)
tmp = os.path.join(PARAMS_DIR, f".tmp_{name}")
fd = os.open(tmp, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o644)
with os.fdopen(fd, "wb") as f:
f.write(value)
f.flush()
os.fsync(f.fileno())
os.replace(tmp, os.path.join(PARAMS_DIR, name))
def _params_remove(name: str) -> None:
try:
Params().remove(name)
return
except Exception:
pass
try:
os.unlink(os.path.join(PARAMS_DIR, name))
except OSError:
pass
def _load_or_create_key() -> bytes:
from cryptography.fernet import Fernet
try:
@@ -80,7 +123,7 @@ def set_credentials(username: str, token: str) -> None:
blob = Fernet(_load_or_create_key()).encrypt(
json.dumps({"u": username, "t": token}).encode()
)
Params().put(PARAM, blob)
_params_put(PARAM, blob)
try:
install_credential_helper(DEFAULT_REPO_DIR)
except Exception:
@@ -89,7 +132,7 @@ def set_credentials(username: str, token: str) -> None:
def get_credentials() -> tuple[str, str] | None:
"""Return (username, token), or None if unset / unreadable."""
blob = Params().get(PARAM)
blob = _params_get(PARAM)
if not blob:
return None
try:
@@ -101,7 +144,7 @@ def get_credentials() -> tuple[str, str] | None:
def clear_credentials() -> None:
Params().remove(PARAM)
_params_remove(PARAM)
def has_credentials() -> bool:

View File

@@ -76,6 +76,13 @@ class Ratekeeper:
self.avg_dt = MovingAverage(100)
self.avg_dt.add_value(self._interval)
def reset(self) -> None:
self._remaining = 0.0
self._last_monitor_time = -1.
self._next_frame_time = -1.
self.avg_dt = MovingAverage(100)
self.avg_dt.add_value(self._interval)
@property
def frame(self) -> int:
return self._frame
@@ -84,6 +91,10 @@ class Ratekeeper:
def remaining(self) -> float:
return self._remaining
@property
def lag(self) -> float:
return max(0., -self._remaining)
@property
def lagging(self) -> bool:
expected_dt = self._interval * (1 / 0.9)

View File

@@ -104,7 +104,7 @@ class ManagerProcess(ABC):
self.stop(sig=signal.SIGKILL)
self.start()
def stop(self, retry: bool = True, block: bool = True, sig: signal.Signals | None = None) -> int | None:
def stop(self, retry: bool = True, block: bool = True, sig: signal.Signals | None = None, timeout: float = 5) -> int | None:
if self.proc is None:
return None
@@ -119,7 +119,7 @@ class ManagerProcess(ABC):
if not block:
return None
join_process(self.proc, 5)
join_process(self.proc, timeout)
# If process failed to die send SIGKILL
if self.proc.exitcode is None and retry:
@@ -245,8 +245,8 @@ class BundleProcess(NativeProcess):
_normalize_bundle_modes(self.bundle)
super().start()
def stop(self, retry: bool = True, block: bool = True, sig: signal.Signals | None = None) -> int | None:
return super().stop(retry=retry, block=block, sig=signal.SIGTERM if sig is None else sig)
def stop(self, retry: bool = True, block: bool = True, sig: signal.Signals | None = None, timeout: float = 5) -> int | None:
return super().stop(retry=retry, block=block, sig=signal.SIGTERM if sig is None else sig, timeout=timeout)
class PythonProcess(ManagerProcess):

View File

@@ -75,6 +75,11 @@ def navd_onroad(started: bool, params: Params, CP: car.CarParams) -> bool:
def navrenderd_onroad(started: bool, params: Params, CP: car.CarParams) -> bool:
return started and params.get_bool("NavigationEnabled") and params.get_bool("OnScreenNavigation")
def navincidentd_onroad(started: bool, params: Params, CP: car.CarParams) -> bool:
return started and params.get_bool("NavigationEnabled") and bool(params.get("WazePoliceApiKey")) and (
params.get_int("WazePoliceAlertMode") > 0 or params.get_bool("WazePoliceShadow")
)
def iqmapd_needed(params: Params) -> bool:
return (
params.get_bool("IQRoadNameOverlay")
@@ -195,6 +200,7 @@ procs += [
BundleProcess("backup_manager_k3", "iqpilot_hephaestusd_private", "iqpilot_private.konn3kt.backups.backup_orchestrator",
and_(only_offroad, hephaestus_ready_shim, not_low_power)),
BundleProcess("navd", "iqpilot_navd_private", "iqpilot_private.navd.navd", navd_onroad, restart_if_crash=True),
BundleProcess("navincidentd", "iqpilot_navd_private", "iqpilot_private.navd.navincidentd", navincidentd_onroad, restart_if_crash=True),
BundleProcess("navrenderd", "iqpilot_navd_private", "iqpilot_private.navd.navrenderd", navrenderd_onroad, restart_if_crash=True),
BundleProcess("iqmapd", "iqpilot_navd_private", "iqpilot_private.navd.iqmapd", iqmapd_onroad, restart_if_crash=True),