Skip to content

Commit

Permalink
January 26th, 2025 Patch
Browse files Browse the repository at this point in the history
  • Loading branch information
FrogAi committed Jan 27, 2025
1 parent 56c5694 commit 2e0e3a2
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 107 deletions.
6 changes: 3 additions & 3 deletions selfdrive/car/car_helpers.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import os
import threading
import time
from collections.abc import Callable

Expand Down Expand Up @@ -205,9 +204,10 @@ def get_car(logcan, sendcan, disable_openpilot_long, experimental_long_allowed,

if frogpilot_toggles.block_user:
candidate = "MOCK"
threading.Thread(target=sentry.capture_fingerprint, args=(candidate, params, True,)).start()
sentry.capture_fingerprint(candidate, params, blocked_user=True)
elif candidate != "MOCK" and not params.get_bool("FingerprintLogged"):
threading.Thread(target=sentry.capture_fingerprint, args=(candidate, params,)).start()
sentry.capture_fingerprint(candidate, params)
params.put_bool("FingerprintLogged", True)

CarInterface, _, _ = interfaces[candidate]
CP = CarInterface.get_params(candidate, fingerprints, car_fw, disable_openpilot_long, experimental_long_allowed, params, docs=False)
Expand Down
6 changes: 0 additions & 6 deletions selfdrive/car/toyota/carcontroller.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,6 @@ def __init__(self, dbc_name, CP, VM):
self.secoc_prev_reset_counter = 0

# FrogPilot variables
self.stock_integral_gain = self.long_pid._k_i
self.stock_max_accel = self.params.ACCEL_MAX

self.doors_locked = False
Expand All @@ -99,11 +98,6 @@ def __init__(self, dbc_name, CP, VM):
self.previous_set_speed = 0

def update(self, CC, CS, now_nanos, frogpilot_toggles):
if frogpilot_toggles.frogsgomoo_tweak:
self.long_pid._k_i = [frogpilot_toggles.kiBP, frogpilot_toggles.kiV]
else:
self.long_pid._k_i = self.stock_integral_gain

if frogpilot_toggles.sport_plus:
self.params.ACCEL_MAX = min(frogpilot_toggles.max_desired_acceleration, get_max_allowed_accel(CS.out.vEgo))
self.long_pid.pos_limit = self.params.ACCEL_MAX
Expand Down
1 change: 0 additions & 1 deletion selfdrive/controls/lib/latcontrol_pid.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ def update(self, active, CS, VM, params, steer_limited, desired_curvature, llk,
# offset does not contribute to resistive torque
steer_feedforward = self.get_steer_feedforward(angle_steers_des_no_offset, CS.vEgo)

self.pid._k_p = frogpilot_toggles.steer_kp
output_steer = self.pid.update(error, override=CS.steeringPressed,
feedforward=steer_feedforward, speed=CS.vEgo)
pid_log.active = True
Expand Down
8 changes: 2 additions & 6 deletions selfdrive/frogpilot/frogpilot_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
import threading
import time

import openpilot.system.sentry as sentry

from openpilot.common.basedir import BASEDIR
from openpilot.common.params_pyx import ParamKeyType
from openpilot.common.time import system_time_valid
Expand Down Expand Up @@ -177,19 +175,17 @@ def frogpilot_boot_functions(build_metadata, params_storage):
FrogPilotVariables().update(holiday_theme="stock", started=False)
ThemeManager().update_active_theme(time_validated=system_time_valid(), frogpilot_toggles=get_frogpilot_toggles(), boot_run=True)

def logging_and_backup_runner():
def backup_thread():
while not system_time_valid():
print("Waiting for system time to become valid...")
time.sleep(1)

sentry.capture_user(build_metadata.channel)

subprocess.run(["pkill", "-SIGUSR1", "-f", "system.updated.updated"], check=False)

backup_frogpilot(build_metadata)
backup_toggles(params_storage)

threading.Thread(target=logging_and_backup_runner, daemon=True).start()
threading.Thread(target=backup_thread, daemon=True).start()

def setup_frogpilot(build_metadata):
run_cmd(["sudo", "mount", "-o", "remount,rw", "/persist"], "Successfully remounted /persist as read-write", "Failed to remount /persist")
Expand Down
4 changes: 2 additions & 2 deletions selfdrive/frogpilot/frogpilot_process.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#!/usr/bin/env python3
import datetime
import threading
import time

import openpilot.system.sentry as sentry
Expand Down Expand Up @@ -120,7 +119,8 @@ def frogpilot_thread():
if frogpilot_toggles.lock_doors_timer != 0:
run_thread_with_lock("lock_doors", lock_doors, (frogpilot_toggles.lock_doors_timer, sm))
elif started and not started_previously:
threading.Thread(target=sentry.capture_model, args=(frogpilot_toggles,)).start()
sentry.capture_model(frogpilot_toggles)
sentry.capture_user(frogpilot_variables.short_branch)

radarless_model = frogpilot_toggles.radarless_model

Expand Down
10 changes: 5 additions & 5 deletions selfdrive/frogpilot/frogpilot_variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,11 +339,11 @@ def __init__(self):
self.frogpilot_toggles = get_frogpilot_toggles(block=False)
self.tuning_levels = {key: lvl for key, _, lvl in frogpilot_default_params + misc_tuning_levels}

short_branch = get_build_metadata().channel
self.development_branch = short_branch == "FrogPilot-Development"
self.release_branch = short_branch == "FrogPilot"
self.staging_branch = short_branch == "FrogPilot-Staging"
self.testing_branch = short_branch == "FrogPilot-Testing"
self.short_branch = get_build_metadata().channel
self.development_branch = self.short_branch == "FrogPilot-Development"
self.release_branch = self.short_branch == "FrogPilot"
self.staging_branch = self.short_branch == "FrogPilot-Staging"
self.testing_branch = self.short_branch == "FrogPilot-Testing"

self.frogpilot_toggles.frogs_go_moo = Path("/persist/frogsgomoo.py").is_file()
self.frogpilot_toggles.block_user = self.development_branch and not self.frogpilot_toggles.frogs_go_moo
Expand Down
27 changes: 18 additions & 9 deletions selfdrive/frogpilot/navigation/mapd.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from pathlib import Path

from openpilot.selfdrive.frogpilot.frogpilot_utilities import is_url_pingable, run_cmd
from openpilot.selfdrive.frogpilot.frogpilot_utilities import is_url_pingable
from openpilot.selfdrive.frogpilot.frogpilot_variables import MAPD_PATH, MAPS_PATH

VERSION = "v1"
Expand All @@ -24,8 +24,22 @@

VERSION_PATH = Path("/data/media/0/osm/mapd_version")

def fix_permissions():
try:
current_permissions = stat.S_IMODE(os.lstat(MAPD_PATH).st_mode)
desired_permissions = current_permissions | stat.S_IEXEC

if current_permissions != desired_permissions:
print(f"{MAPD_PATH} has the wrong permissions. Attempting to fix...")
os.chmod(MAPD_PATH, desired_permissions)
sentry.capture_exception(Exception(f"Successfully fixed permissions for {MAPD_PATH}"))
except OSError as error:
sentry.capture_exception(Exception(f"Failed to fix permissions for {MAPD_PATH}: {error}"))

def download():
run_cmd(["sudo", "mount", "-o", "remount,rw", str(MAPD_PATH)], f"Successfully remounted {MAPD_PATH} as read-write", f"Failed to remount {MAPD_PATH}")
if not os.access(MAPD_PATH, os.W_OK):
print(f"{MAPD_PATH} is not writable. Attempting to fix permissions...")
fix_permissions()

while not (is_url_pingable("https://github.com") or is_url_pingable("https://gitlab.com")):
time.sleep(60)
Expand All @@ -45,8 +59,7 @@ def download():
with open(MAPD_PATH, 'wb') as output:
shutil.copyfileobj(response, output)
os.fsync(output.fileno())
current_permissions = stat.S_IMODE(os.lstat(MAPD_PATH).st_mode)
os.chmod(MAPD_PATH, current_permissions | stat.S_IEXEC)
fix_permissions()
with open(VERSION_PATH, 'w') as version_file:
version_file.write(latest_version)
os.fsync(version_file.fileno())
Expand Down Expand Up @@ -84,12 +97,8 @@ def mapd_thread():
download()
continue
else:
current_permissions = stat.S_IMODE(os.lstat(MAPD_PATH).st_mode)
desired_permissions = current_permissions | stat.S_IEXEC
fix_permissions()

if current_permissions != desired_permissions:
print(f"{MAPD_PATH} has the wrong permissions. Attempting to fix...")
os.chmod(MAPD_PATH, desired_permissions)
if not os.path.exists(VERSION_PATH):
download()
continue
Expand Down
175 changes: 100 additions & 75 deletions system/sentry.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""Install exception handler for process crash."""
import os
import sentry_sdk
import threading
import time
import traceback
from datetime import datetime
Expand All @@ -25,96 +26,121 @@ class SentryProject(Enum):


def report_tombstone(fn: str, message: str, contents: str) -> None:
cloudlog.error({'tombstone': message})
def report_tombstone_thread():
cloudlog.error({'tombstone': message})

with sentry_sdk.configure_scope() as scope:
scope.set_extra("tombstone_fn", fn)
scope.set_extra("tombstone", contents)
sentry_sdk.capture_message(message=message)
sentry_sdk.flush()
with sentry_sdk.configure_scope() as scope:
scope.set_extra("tombstone_fn", fn)
scope.set_extra("tombstone", contents)
sentry_sdk.capture_message(message=message)
sentry_sdk.flush()

threading.Thread(target=report_tombstone_thread, daemon=True).start()

def capture_exception(*args, **kwargs) -> None:
exc_text = traceback.format_exc()

errors_to_ignore = [
"already exists. To overwrite it, set 'overwrite' to True",
"setup_quectel failed after retry",
]

if any(error in exc_text for error in errors_to_ignore):
return

save_exception(exc_text)
cloudlog.error("crash", exc_info=kwargs.get('exc_info', 1))

try:
sentry_sdk.capture_exception(*args, **kwargs)
sentry_sdk.flush() # https://github.com/getsentry/sentry-python/issues/291
except Exception:
cloudlog.exception("sentry exception")


def capture_fingerprint(candidate, params, blocked=False):
while not system_time_valid():
time.sleep(1)

params_tracking = Params("/persist/tracking")

param_types = {
"FrogPilot Controls": ParamKeyType.FROGPILOT_CONTROLS,
"FrogPilot Vehicles": ParamKeyType.FROGPILOT_VEHICLES,
"FrogPilot Visuals": ParamKeyType.FROGPILOT_VISUALS,
"FrogPilot Other": ParamKeyType.FROGPILOT_OTHER,
"FrogPilot Tracking": ParamKeyType.FROGPILOT_TRACKING,
}

matched_params = {label: {} for label in param_types}
for key in params.all_keys():
for label, key_type in param_types.items():
if params.get_key_type(key) & key_type:
if key_type == ParamKeyType.FROGPILOT_TRACKING:
value = params_tracking.get_int(key)
else:
if isinstance(params.get(key), bytes):
value = params.get(key, encoding='utf-8')
def capture_exception(*args, **kwargs) -> None:
def capture_exception_thread():
exc_text = traceback.format_exc()

errors_to_ignore = [
"already exists. To overwrite it, set 'overwrite' to True",
"setup_quectel failed after retry",
]

if any(error in exc_text for error in errors_to_ignore):
return

save_exception(exc_text)
cloudlog.error("crash", exc_info=kwargs.get('exc_info', 1))

try:
while not system_time_valid():
time.sleep(1)

sentry_sdk.capture_exception(*args, **kwargs)
sentry_sdk.flush() # https://github.com/getsentry/sentry-python/issues/291
except Exception:
cloudlog.exception("sentry exception")

threading.Thread(target=capture_exception_thread, daemon=True).start()


def capture_fingerprint(candidate, params, blocked_user=False):
def capture_fingerprint_thread():
while not system_time_valid():
time.sleep(1)

if blocked_user:
with sentry_sdk.push_scope() as scope:
sentry_sdk.capture_message("Blocked user from using the development branch", level='warning')
sentry_sdk.flush()
return

params_tracking = Params("/persist/tracking")

param_types = {
"FrogPilot Controls": ParamKeyType.FROGPILOT_CONTROLS,
"FrogPilot Vehicles": ParamKeyType.FROGPILOT_VEHICLES,
"FrogPilot Visuals": ParamKeyType.FROGPILOT_VISUALS,
"FrogPilot Other": ParamKeyType.FROGPILOT_OTHER,
"FrogPilot Tracking": ParamKeyType.FROGPILOT_TRACKING,
}

matched_params = {label: {} for label in param_types}
for key in params.all_keys():
for label, key_type in param_types.items():
if params.get_key_type(key) & key_type:
if key_type == ParamKeyType.FROGPILOT_TRACKING:
value = params_tracking.get_int(key)
else:
value = params.get(key) or "0"
if isinstance(params.get(key), bytes):
value = params.get(key, encoding='utf-8')
else:
value = params.get(key) or "0"

if isinstance(value, str) and "." in value:
value = value.rstrip("0").rstrip(".")
matched_params[label][key.decode('utf-8')] = value
if isinstance(value, str) and "." in value:
value = value.rstrip("0").rstrip(".")
matched_params[label][key.decode('utf-8')] = value

for label, key_values in matched_params.items():
if label == "FrogPilot Tracking":
matched_params[label] = {key: f"{value:,}" for key, value in key_values.items()}
else:
matched_params[label] = {key: f"{value:}" for key, value in key_values.items()}

with sentry_sdk.push_scope() as scope:
for label, key_values in matched_params.items():
scope.set_context(label, key_values)
if label == "FrogPilot Tracking":
matched_params[label] = {key: f"{value:,}" for key, value in key_values.items()}
else:
matched_params[label] = {key: f"{value:}" for key, value in key_values.items()}

scope.fingerprint = [params.get("DongleId", encoding='utf-8'), candidate]
with sentry_sdk.push_scope() as scope:
for label, key_values in matched_params.items():
scope.set_context(label, key_values)

if blocked:
sentry_sdk.capture_message("Blocked user from using the development branch", level='warning')
else:
scope.fingerprint = [params.get("DongleId", encoding='utf-8'), candidate]
sentry_sdk.capture_message(f"Fingerprinted {candidate}", level='info')
sentry_sdk.flush()

params.put_bool("FingerprintLogged", True)
sentry_sdk.flush()
threading.Thread(target=capture_fingerprint_thread, daemon=True).start()


def capture_model(frogpilot_toggles):
while not system_time_valid():
time.sleep(1)
def capture_model_thread():
while not system_time_valid():
time.sleep(1)

sentry_sdk.capture_message(f"User using: {frogpilot_toggles.model_name}", level='info')
with sentry_sdk.push_scope() as scope:
sentry_sdk.capture_message(f"User using: {frogpilot_toggles.model_name}", level='info')
sentry_sdk.flush()

threading.Thread(target=capture_model_thread, daemon=True).start()


def capture_user(channel):
sentry_sdk.capture_message(f"Logged user on: {channel}", level='info')
def capture_user_thread():
while not system_time_valid():
time.sleep(1)

with sentry_sdk.push_scope() as scope:
sentry_sdk.capture_message(f"Logged user on: {channel}", level='info')
sentry_sdk.flush()

threading.Thread(target=capture_user_thread, daemon=True).start()


def set_tag(key: str, value: str) -> None:
Expand Down Expand Up @@ -146,10 +172,6 @@ def init(project: SentryProject) -> bool:
if not FrogPilot or PC:
return False

params = Params()
installed = params.get("InstallDate", encoding='utf-8')
updated = params.get("Updated", encoding='utf-8')

short_branch = build_metadata.channel

if short_branch == "FrogPilot-Development":
Expand All @@ -161,7 +183,10 @@ def init(project: SentryProject) -> bool:
else:
env = short_branch

params = Params()
dongle_id = params.get("DongleId", encoding='utf-8')
installed = params.get("InstallDate", encoding='utf-8')
updated = params.get("Updated", encoding='utf-8')

integrations = []
if project == SentryProject.SELFDRIVE:
Expand Down

0 comments on commit 2e0e3a2

Please sign in to comment.