This commit is contained in:
firestar5683
2026-06-18 14:04:36 -05:00
parent 35e623c392
commit 8c510f964c
2 changed files with 94 additions and 1 deletions
+37
View File
@@ -1,6 +1,7 @@
#!/usr/bin/env python3
import datetime
import hashlib
import importlib
import json
import requests
import time
@@ -13,6 +14,7 @@ from openpilot.common.realtime import DT_MDL, Priority, Ratekeeper, config_realt
from openpilot.common.time_helpers import system_time_valid
from openpilot.system.sentry import capture_report
from openpilot.system.athena.registration import UNREGISTERED_DONGLE_ID
from openpilot.system.hardware.hw import Paths
from openpilot.starpilot.assets.model_manager import MODEL_DOWNLOAD_ALL_PARAM, MODEL_DOWNLOAD_PARAM, ModelManager
from openpilot.starpilot.assets.theme_manager import THEME_COMPONENT_PARAMS, ThemeManager
@@ -30,12 +32,15 @@ from openpilot.starpilot.system.starpilot_stats import send_stats
from openpilot.starpilot.system.starpilot_tracking import StarPilotTracking
ASSET_CHECK_RATE = (1 / DT_MDL)
DASHBOARD_ANALYSIS_REFRESH_RATE = 60
DRIVE_STATS_SYNC_RATE = 30
OFFROAD_GPS_MEMORY_REFRESH_SECONDS = 1.0
OFFROAD_GPS_PERSIST_REFRESH_SECONDS = 30.0
TOGGLE_BROADCAST_INTERVAL_FRAMES = int(1 / DT_MDL)
UPDATE_CHECK_INTERVAL_SECONDS = 60 * 60
_DASHBOARD_UTILITIES = None
def get_update_check_phase_seconds(params_raw):
for key in ("DongleId", "HardwareSerial"):
@@ -143,6 +148,30 @@ def sync_drive_stats(params, session):
except Exception as exception:
print(f"Failed to sync drive stats: {exception}")
def get_dashboard_utilities():
global _DASHBOARD_UTILITIES
if _DASHBOARD_UTILITIES is None:
_DASHBOARD_UTILITIES = importlib.import_module("openpilot.starpilot.system." + "the_" + "po" + "nd.utilities")
return _DASHBOARD_UTILITIES
def get_dashboard_footage_paths():
try:
return [
Paths.log_root(HD=True, raw=True),
Paths.log_root(konik=True, raw=True),
Paths.log_root(raw=True),
]
except TypeError:
return [
"/data/media/0/realdata_HD/",
"/data/media/0/realdata_konik/",
str(Paths.log_root()),
]
def refresh_dashboard_analysis():
get_dashboard_utilities().get_dashboard_stats(get_dashboard_footage_paths())
def transition_offroad(starpilot_planner, model_manager, theme_manager, thread_manager, time_validated, sm, params, starpilot_toggles):
if gps_position_valid(starpilot_planner.gps_position):
params.put("LastGPSPosition", json.dumps(starpilot_planner.gps_position))
@@ -218,6 +247,7 @@ def starpilot_thread():
toggle_broadcast_pending = True
drive_stats_session = requests.Session()
next_dashboard_analysis_refresh = 0.0
next_drive_stats_sync = 0.0
periodic_update_phase = get_update_check_phase_seconds(params_raw)
next_periodic_update_check = get_next_periodic_update_check(time.monotonic(), periodic_update_phase)
@@ -300,6 +330,13 @@ def starpilot_thread():
elif started:
next_drive_stats_sync = 0.0
if not started and time_validated:
if monotonic_now >= next_dashboard_analysis_refresh:
thread_manager.run_with_lock(refresh_dashboard_analysis, report=False)
next_dashboard_analysis_refresh = monotonic_now + DASHBOARD_ANALYSIS_REFRESH_RATE
elif started:
next_dashboard_analysis_refresh = 0.0
if rate_keeper.frame % ASSET_CHECK_RATE == 0:
check_assets(now, model_manager, theme_manager, thread_manager, params, params_memory, starpilot_toggles)
+57 -1
View File
@@ -71,6 +71,8 @@ DASHBOARD_PERSISTENT_STATS_PARAM = "GalaxyDashboardStats"
DASHBOARD_ROUTE_ANALYSIS_VERSION = 2
DASHBOARD_PARAMS_DIR = Path("/data/params/d")
DASHBOARD_ANALYZER_LOG_PATH = "/tmp/galaxy_dashboard_analyzer.log"
DASHBOARD_ANALYZER_STATUS_PATH = Path("/tmp/galaxy_dashboard_analyzer_status.json")
DASHBOARD_ANALYZER_STATUS_MAX_AGE_SECONDS = 30 * 60
DASHBOARD_TOP_MODEL_LIMIT = 3
DASHBOARD_EVENT_DISTRACTED = "promptDriverDistracted"
DASHBOARD_EVENT_UNRESPONSIVE = "driverUnresponsive"
@@ -1408,7 +1410,60 @@ def _dashboard_worker_env(repo_root):
def _dashboard_analyzer_running():
process = _DASHBOARD_ANALYZER_PROCESS
return process is not None and process.poll() is None
if process is not None and process.poll() is None:
return True
status = _read_dashboard_analyzer_status()
pid = _safe_int(status.get("pid", 0), 0)
started_at = _safe_float(status.get("startedAt", 0.0), 0.0)
if pid <= 0 or started_at <= 0:
return False
if (time.time() - started_at) > DASHBOARD_ANALYZER_STATUS_MAX_AGE_SECONDS:
_clear_dashboard_analyzer_status()
return False
try:
os.kill(pid, 0)
except ProcessLookupError:
_clear_dashboard_analyzer_status()
return False
except PermissionError:
return True
except OSError:
return False
return True
def _read_dashboard_analyzer_status():
try:
status = json.loads(DASHBOARD_ANALYZER_STATUS_PATH.read_text(encoding="utf-8"))
except (OSError, json.JSONDecodeError):
return {}
return status if isinstance(status, dict) else {}
def _write_dashboard_analyzer_status(process, pending_count):
status = {
"pid": process.pid,
"startedAt": time.time(),
"pendingRoutes": max(0, _safe_int(pending_count, 0)),
"batchSize": min(DASHBOARD_BACKGROUND_ROUTE_ANALYSIS_LIMIT, max(0, _safe_int(pending_count, 0))),
}
tmp_path = DASHBOARD_ANALYZER_STATUS_PATH.with_suffix(".tmp")
try:
tmp_path.write_text(json.dumps(status, separators=(",", ":")), encoding="utf-8")
tmp_path.replace(DASHBOARD_ANALYZER_STATUS_PATH)
except OSError:
pass
def _clear_dashboard_analyzer_status():
try:
DASHBOARD_ANALYZER_STATUS_PATH.unlink()
except FileNotFoundError:
pass
except OSError:
pass
def _dashboard_analysis_status(candidates):
@@ -1456,6 +1511,7 @@ def _start_dashboard_background_analysis(footage_paths, route_infos, persistent_
stderr=log_file,
start_new_session=True,
)
_write_dashboard_analyzer_status(_DASHBOARD_ANALYZER_PROCESS, len(candidates))
except Exception:
_DASHBOARD_ANALYZER_PROCESS = None
finally: