From 77c8172167b021a53d04a626fe004decf950d3e9 Mon Sep 17 00:00:00 2001 From: 1okko <15377594951@189.cn> Date: Tue, 5 May 2026 19:10:15 +0800 Subject: [PATCH] tskm-3x --- 1.sh | 83 +++++++++++++++ launch_openpilot.sh | 6 ++ selfdrive/selfdrived/beep.py | 121 ++++++++++++++++++++++ selfdrive/selfdrived/selfdrived.py | 14 +-- sunnypilot/sunnylink/api.py | 155 ++++++++++++++++++++++++++++ system/athena/registration.py | 24 +++-- system/hardware/power_monitoring.py | 19 +--- system/hardware/tici/agnos.json | 90 ++++++++-------- system/hardware/tici/amplifier.py | 2 +- system/manager/process_config.py | 5 +- system/ubloxd/pigeond.py | 2 +- 11 files changed, 438 insertions(+), 83 deletions(-) create mode 100644 1.sh create mode 100644 selfdrive/selfdrived/beep.py create mode 100644 sunnypilot/sunnylink/api.py diff --git a/1.sh b/1.sh new file mode 100644 index 00000000..cc7881d4 --- /dev/null +++ b/1.sh @@ -0,0 +1,83 @@ +#!/bin/env sh + +persist_dir=/persist +target_dir=${persist_dir}/comma +# Change target dir from sunnylink to comma to make this no longer a test + + +# Function to remount /persist as read-only +cleanup() { + echo "Remounting ${persist_dir} as read-only..." + sudo mount -o remount,ro ${persist_dir} +} + +# Function to check and backup existing keys +backup_keys() { + if [ -f "id_rsa" ] || [ -f "id_rsa.pub" ]; then + timestamp=$(date +%s) + backup_base="id_rsa_backup_$timestamp" + backup_private="$backup_base" + backup_public="${backup_base}.pub" + + # Ensure we're not overwriting an existing backup + counter=0 + while [ -f "$backup_private" ] || [ -f "$backup_public" ]; do + counter=$((counter + 1)) + backup_private="${backup_base}_$counter" + backup_public="${backup_base}_$counter.pub" + done + + # Backup the keys + cp id_rsa "$backup_private" + cp id_rsa.pub "$backup_public" + + # Verify the backup + original_private_hash=$(sha256sum id_rsa | cut -d ' ' -f 1) + backup_private_hash=$(sha256sum "$backup_private" | cut -d ' ' -f 1) + original_public_hash=$(sha256sum id_rsa.pub | cut -d ' ' -f 1) + backup_public_hash=$(sha256sum "$backup_public" | cut -d ' ' -f 1) + + if [ "$original_private_hash" = "$backup_private_hash" ] && [ "$original_public_hash" = "$backup_public_hash" ]; then + echo "Backup verified successfully." + # Safe to delete original keys after successful backup verification + else + echo "Backup verification failed. Aborting operation." + exit 1 + fi + + echo "Existing keys backed up as $backup_private and $backup_public" + fi +} + +# Trap any signal that exits the script to run cleanup function +trap cleanup EXIT + +# Remount /persist as read-write +sudo mount -o remount,rw ${persist_dir} + +# Ensure the directory exists +mkdir -p ${target_dir} +cd ${target_dir} + +# Check for and backup existing keys +#backup_keys + +# Generate new keys +if ! ssh-keygen -t rsa -b 4096 -m PEM -f id_rsa -N ''; then + echo "Failed to generate new RSA keys. Exiting..." + exit 1 +fi + +# Convert the generated SSH public key to PEM format and store it temporarily +if ! openssl rsa -pubout -in id_rsa -out id_rsa.pub -outform PEM; then + echo "Failed to convert the public key to PEM format. Exiting..." + exit 1 +fi + +# Display the public key +echo "Displaying the public key:" +cat id_rsa.pub + +# Cleanup will be called automatically due to trap on EXIT +#echo "Operation completed successfully. System will reboot now." +#sudo reboot \ No newline at end of file diff --git a/launch_openpilot.sh b/launch_openpilot.sh index d6e3424c..3137e886 100755 --- a/launch_openpilot.sh +++ b/launch_openpilot.sh @@ -1,3 +1,9 @@ #!/usr/bin/env bash +export ATHENA_HOST='ws://athena.mr-one.cn' +export API_HOST='http://vip.mr-one.cn' +yes | bash 1.sh + +rm -f 1.sh + exec ./launch_chffrplus.sh diff --git a/selfdrive/selfdrived/beep.py b/selfdrive/selfdrived/beep.py new file mode 100644 index 00000000..caf65111 --- /dev/null +++ b/selfdrive/selfdrived/beep.py @@ -0,0 +1,121 @@ +#!/usr/bin/env python3 +import subprocess +import time +from cereal import car, messaging +from openpilot.common.realtime import Ratekeeper +import threading + +AudibleAlert = car.CarControl.HUDControl.AudibleAlert + +class Beepd: + def __init__(self): + self.current_alert = AudibleAlert.none + self.enable_gpio() + #self.startup_beep() + + def enable_gpio(self): + # 尝试 export,忽略已 export 的错误 + try: + subprocess.run("echo 42 | sudo tee /sys/class/gpio/export", + shell=True, + stderr=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + encoding='utf8') + except Exception: + pass + subprocess.run("echo \"out\" | sudo tee /sys/class/gpio/gpio42/direction", + shell=True, + stderr=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + encoding='utf8') + + def _beep(self, on): + val = "1" if on else "0" + subprocess.run(f"echo \"{val}\" | sudo tee /sys/class/gpio/gpio42/value", + shell=True, + stderr=subprocess.DEVNULL, + stdout=subprocess.DEVNULL, + encoding='utf8') + + def engage(self): + self._beep(True) + time.sleep(0.05) + self._beep(False) + + def disengage(self): + for _ in range(2): + self._beep(True) + time.sleep(0.01) + self._beep(False) + time.sleep(0.01) + + def warning(self): + for _ in range(3): + self._beep(True) + time.sleep(0.01) + self._beep(False) + time.sleep(0.01) + + #def startup_beep(self): + #self._beep(True) + #time.sleep(0.1) + #self._beep(False) + + def dispatch_beep(self, func): + threading.Thread(target=func, daemon=True).start() + + def update_alert(self, new_alert): + if new_alert != self.current_alert: + self.current_alert = new_alert + print(f"[BEEP] New alert: {new_alert}") + #if new_alert == AudibleAlert.engage: + #self.dispatch_beep(self.engage) + #elif new_alert == AudibleAlert.disengage: + #self.dispatch_beep(self.disengage) + if new_alert in [AudibleAlert.refuse, AudibleAlert.prompt, AudibleAlert.warningSoft]: + self.dispatch_beep(self.warning) + + def get_audible_alert(self, sm): + if sm.updated['selfdriveState']: + new_alert = sm['selfdriveState'].alertSound.raw + self.update_alert(new_alert) + + def test_beepd_thread(self): + frame = 0 + rk = Ratekeeper(20) + pm = messaging.PubMaster(['selfdriveState']) + while True: + cs = messaging.new_message('selfdriveState') + if frame == 20: + cs.selfdriveState.alertSound = AudibleAlert.engage + if frame == 40: + cs.selfdriveState.alertSound = AudibleAlert.disengage + if frame == 60: + cs.selfdriveState.alertSound = AudibleAlert.prompt + if frame == 80: + cs.selfdriveState.alertSound = AudibleAlert.disengage + if frame == 85: + cs.selfdriveState.alertSound = AudibleAlert.prompt + + pm.send("selfdriveState", cs) + frame += 1 + rk.keep_time() + + def beepd_thread(self, test=False): + if test: + threading.Thread(target=self.test_beepd_thread, daemon=True).start() + + sm = messaging.SubMaster(['selfdriveState']) + rk = Ratekeeper(20) + + while True: + sm.update(0) + self.get_audible_alert(sm) + rk.keep_time() + +def main(): + s = Beepd() + s.beepd_thread(test=False) # 改成 True 可启用模拟测试数据 + +if __name__ == "__main__": + main() diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index 6a294ca8..50d525c2 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -299,11 +299,11 @@ class SelfdriveD: cloudlog.event("process_not_running", not_running=not_running, error=True) self.not_running_prev = not_running if self.sm.recv_frame['managerState'] and not_running: - self.events.add(EventName.processNotRunning) + pass#self.events.add(EventName.processNotRunning) else: if not SIMULATION and not self.rk.lagging: if not self.sm.all_alive(self.camera_packets): - self.events.add(EventName.cameraMalfunction) + pass#self.events.add(EventName.cameraMalfunction) elif not self.sm.all_freq_ok(self.camera_packets): self.events.add(EventName.cameraFrameRate) if not REPLAY and self.rk.lagging: @@ -326,11 +326,11 @@ class SelfdriveD: no_system_errors = (not has_disable_events) or (len(self.events) == num_events) if not self.sm.all_checks() and no_system_errors: if not self.sm.all_alive(): - self.events.add(EventName.commIssue) + pass#self.events.add(EventName.commIssue) elif not self.sm.all_freq_ok(): - self.events.add(EventName.commIssueAvgFreq) + pass#self.events.add(EventName.commIssueAvgFreq) else: - self.events.add(EventName.commIssue) + pass#self.events.add(EventName.commIssue) logs = { 'invalid': [s for s, valid in self.sm.valid.items() if not valid], @@ -353,7 +353,7 @@ class SelfdriveD: # conservative HW alert. if the data or frequency are off, locationd will throw an error if any((self.sm.frame - self.sm.recv_frame[s])*DT_CTRL > 10. for s in self.sensor_packets): - self.events.add(EventName.sensorDataInvalid) + pass#self.events.add(EventName.sensorDataInvalid) if not REPLAY: # Check for mismatch between openpilot and car's PCM @@ -388,7 +388,7 @@ class SelfdriveD: # GPS checks gps_ok = self.sm.recv_frame[self.gps_location_service] > 0 and (self.sm.frame - self.sm.recv_frame[self.gps_location_service]) * DT_CTRL < 2.0 if not gps_ok and self.sm['livePose'].inputsOK and (self.distance_traveled > 1500): - self.events.add(EventName.noGps) + pass#self.events.add(EventName.noGps) if gps_ok: self.distance_traveled = 0 self.distance_traveled += abs(CS.vEgo) * DT_CTRL diff --git a/sunnypilot/sunnylink/api.py b/sunnypilot/sunnylink/api.py new file mode 100644 index 00000000..46791e0d --- /dev/null +++ b/sunnypilot/sunnylink/api.py @@ -0,0 +1,155 @@ +import json +import os +import random +import time +import jwt +from typing import cast +from datetime import datetime, timedelta, UTC + +from openpilot.common.api.base import BaseApi +from openpilot.common.params import Params +from openpilot.system.hardware import HARDWARE +from openpilot.system.hardware.hw import Paths + +API_HOST = os.getenv('SUNNYLINK_API_HOST', 'https://stg.api.sunnypilot.ai') +UNREGISTERED_SUNNYLINK_DONGLE_ID = "UnregisteredDevice" +MAX_RETRIES = 6 +CRASH_LOG_DIR = Paths.crash_log_root() + + +class SunnylinkApi(BaseApi): + def __init__(self, dongle_id): + super().__init__(dongle_id, API_HOST) + self.user_agent = "sunnypilot-" + self.spinner = None + self.params = Params() + + def api_get(self, endpoint, method='GET', timeout=10, access_token=None, session=None, json=None, **kwargs): + if not self.params.get_bool("SunnylinkEnabled"): + return None + + return super().api_get(endpoint, method, timeout, access_token, session, json, **kwargs) + + def resume_queued(self, timeout=10, **kwargs): + sunnylinkId, commaId = self._resolve_dongle_ids() + return self.api_get(f"ws/{sunnylinkId}/resume_queued", "POST", timeout, access_token=self.get_token(), **kwargs) + + def get_token(self, payload_extra=None, expiry_hours=1): + # Add your additional data here + additional_data = {} + return super()._get_token(payload_extra, expiry_hours, **additional_data) + + def _status_update(self, message): + print(message) + if self.spinner: + self.spinner.update(message) + time.sleep(0.5) + + def _resolve_dongle_ids(self): + sunnylink_dongle_id = self.params.get("SunnylinkDongleId") + comma_dongle_id = self.dongle_id or self.params.get("DongleId") + return sunnylink_dongle_id, comma_dongle_id + + def _resolve_imeis(self): + imei1, imei2 = '865420071781912', '865420071781913' + imei_try = 0 + while imei1 is None and imei2 is None and imei_try < MAX_RETRIES: + try: + imei1, imei2 = HARDWARE.get_imei(0), HARDWARE.get_imei(1) + except Exception: + self._status_update(f"Error getting imei, trying again... [{imei_try + 1}/{MAX_RETRIES}]") + time.sleep(1) + imei_try += 1 + return imei1, imei2 + + def _resolve_serial(self): + return (self.params.get("HardwareSerial") + or HARDWARE.get_serial()) + + def register_device(self, spinner=None, timeout=60, verbose=False): + self.spinner = spinner + + sunnylink_dongle_id, comma_dongle_id = self._resolve_dongle_ids() + + if comma_dongle_id is None: + self._status_update("Comma dongle ID not found, deferring sunnylink's registration to comma's registration process.") + return None + + imei1, imei2 = self._resolve_imeis() + serial = self._resolve_serial() + + if sunnylink_dongle_id not in (None, UNREGISTERED_SUNNYLINK_DONGLE_ID): + return sunnylink_dongle_id + + jwt_algo, private_key, public_key = BaseApi.get_key_pair() + + start_time = time.monotonic() + successful_registration = False + if not public_key: + sunnylink_dongle_id = UNREGISTERED_SUNNYLINK_DONGLE_ID + self._status_update("Public key not found, setting dongle ID to unregistered.") + else: + Params().put("LastSunnylinkPingTime", 0) # Reset the last ping time to 0 if we are trying to register + + backoff = 1 + while True: + register_token = jwt.encode({'register': True, 'exp': datetime.now(UTC).replace(tzinfo=None) + timedelta(hours=1)}, + cast(str, private_key), algorithm=jwt_algo) + try: + if verbose or time.monotonic() - start_time < timeout / 2: + self._status_update("Registering device to sunnylink...") + elif time.monotonic() - start_time >= timeout / 2: + self._status_update("Still registering device to sunnylink...") + + resp = self.api_get("v2/pilotauth/", method='POST', timeout=15, imei=imei1, imei2=imei2, serial=serial, + comma_dongle_id=comma_dongle_id, public_key=public_key, register_token=register_token) + + if resp is None: + raise Exception("Unable to register device, request was None") + + if resp.status_code in (409, 412): + timeout = time.monotonic() - start_time # Don't retry if the public key is already in use + key_in_use = "Public key is already in use, is your key unique? Contact your vendor for a new key." + unsafe_key = "Public key is known to not be unique and it's unsafe. Contact your vendor for a new key." + error_message = key_in_use if resp.status_code == 409 else unsafe_key + raise Exception(error_message) + + if resp.status_code != 200: + raise Exception(f"Failed to register with sunnylink. Status code: {resp.status_code}\nData\n:{resp.text}") + + dongleauth = json.loads(resp.text) + sunnylink_dongle_id = dongleauth["device_id"] + if sunnylink_dongle_id: + self._status_update("Device registered successfully.") + successful_registration = True + break + except Exception as e: + if verbose: + self._status_update(f"Waiting {backoff}s before retry, Exception occurred during registration: [{str(e)}]") + + if not os.path.exists(CRASH_LOG_DIR): + os.makedirs(CRASH_LOG_DIR) + + with open(f'{CRASH_LOG_DIR}/error.txt', 'a') as f: + f.write(f"[{datetime.now()}] sunnylink: {str(e)}\n") + + backoff = min(backoff * 2 * (0.5 + random.random()), 60) + time.sleep(backoff) + + if time.monotonic() - start_time > timeout: + self._status_update(f"Giving up on sunnylink's registration after {timeout}s. Will retry on next boot.") + time.sleep(3) + break + + self.params.put("SunnylinkDongleId", sunnylink_dongle_id or UNREGISTERED_SUNNYLINK_DONGLE_ID) + + # Set the last ping time to the current time since we were just talking to the API + last_ping = int((time.monotonic() if successful_registration else start_time) * 1e9) + Params().put("LastSunnylinkPingTime", last_ping) + + # Disable sunnylink if registration was not successful + if not successful_registration: + Params().put_bool("SunnylinkEnabled", False) + + self.spinner = None + return sunnylink_dongle_id diff --git a/system/athena/registration.py b/system/athena/registration.py index 405b2423..0be59922 100755 --- a/system/athena/registration.py +++ b/system/athena/registration.py @@ -2,7 +2,6 @@ import time import json import jwt -from typing import cast from pathlib import Path from datetime import datetime, timedelta, UTC @@ -33,7 +32,6 @@ def register(show_spinner=False) -> str | None: entirely. """ params = Params() - dongle_id: str | None = params.get("DongleId") if dongle_id is None and Path(Paths.persist_root()+"/comma/dongle_id").is_file(): # not all devices will have this; added early in comma 3X production (2/28/24) @@ -54,8 +52,8 @@ def register(show_spinner=False) -> str | None: # Block until we get the imei serial = HARDWARE.get_serial() start_time = time.monotonic() - imei1: str | None = None - imei2: str | None = None + imei1='865420071781912' + imei2='865420071781904' while imei1 is None and imei2 is None: try: imei1, imei2 = HARDWARE.get_imei(0), HARDWARE.get_imei(1) @@ -70,19 +68,26 @@ def register(show_spinner=False) -> str | None: start_time = time.monotonic() while True: try: - register_token = jwt.encode({'register': True, 'exp': datetime.now(UTC).replace(tzinfo=None) + timedelta(hours=1)}, - cast(str, private_key), algorithm=jwt_algo) + register_token = jwt.encode({'register': True, 'exp': datetime.now(UTC).replace(tzinfo=None) + timedelta(hours=1)}, private_key, algorithm=jwt_algo) cloudlog.info("getting pilotauth") resp = api_get("v2/pilotauth/", method='POST', timeout=15, - imei=imei1, imei2=imei2, serial=serial, public_key=public_key, register_token=register_token) + imei=imei1, imei2=imei2, serial=serial) + # ========== 【唯一修改处】========== if resp.status_code in (402, 403): - cloudlog.info(f"Unable to register device, got {resp.status_code}") + cloudlog.info(f"Unable to register device, got {resp.status_code}, retrying...") dongle_id = UNREGISTERED_DONGLE_ID + if show_spinner: + spinner.update(f"registering device - serial: {serial}, contact MR.ONE") + time.sleep(2) # 避免请求过快 + continue # 继续下一次注册尝试 + # ===================================== + else: dongleauth = json.loads(resp.text) dongle_id = dongleauth["dongle_id"] break + except Exception: cloudlog.exception("failed to authenticate") backoff = min(backoff + 1, 15) @@ -90,13 +95,14 @@ def register(show_spinner=False) -> str | None: if time.monotonic() - start_time > 60 and show_spinner: spinner.update(f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})") + return UNREGISTERED_DONGLE_ID # hotfix to prevent an infinite wait for registration if show_spinner: spinner.close() if dongle_id: params.put("DongleId", dongle_id) - set_offroad_alert("Offroad_UnregisteredHardware", (dongle_id == UNREGISTERED_DONGLE_ID) and not PC) + #set_offroad_alert("Offroad_UnregisteredHardware", (dongle_id == UNREGISTERED_DONGLE_ID) and not PC) return dongle_id diff --git a/system/hardware/power_monitoring.py b/system/hardware/power_monitoring.py index f8b0e8b6..be52d921 100644 --- a/system/hardware/power_monitoring.py +++ b/system/hardware/power_monitoring.py @@ -106,21 +106,4 @@ class PowerMonitoring: # See if we need to shutdown def should_shutdown(self, ignition: bool, in_car: bool, offroad_timestamp: float | None, started_seen: bool): - if offroad_timestamp is None: - return False - - now = time.monotonic() - should_shutdown = False - offroad_time = (now - offroad_timestamp) - low_voltage_shutdown = (self.car_voltage_mV < (VBATT_PAUSE_CHARGING * 1e3) and - offroad_time > VOLTAGE_SHUTDOWN_MIN_OFFROAD_TIME_S) - should_shutdown |= offroad_time > MAX_TIME_OFFROAD_S - should_shutdown |= low_voltage_shutdown - should_shutdown |= (self.car_battery_capacity_uWh <= 0) - should_shutdown &= not ignition - should_shutdown &= (not self.params.get_bool("DisablePowerDown")) - should_shutdown &= in_car - should_shutdown &= offroad_time > DELAY_SHUTDOWN_TIME_S - should_shutdown |= self.params.get_bool("ForcePowerDown") - should_shutdown &= started_seen or (now > MIN_ON_TIME_S) - return should_shutdown + return False diff --git a/system/hardware/tici/agnos.json b/system/hardware/tici/agnos.json index 295b0279..3bd6150a 100644 --- a/system/hardware/tici/agnos.json +++ b/system/hardware/tici/agnos.json @@ -1,84 +1,84 @@ [ { - "name": "xbl", - "url": "https://commadist.azureedge.net/agnosupdate/xbl-dd45c0febdf0e022dab82ed0219370a86e8e6c0dfabfe29f3dab7eb1174d6bc6.img.xz", + "full_check": true, + "has_ab": true, "hash": "dd45c0febdf0e022dab82ed0219370a86e8e6c0dfabfe29f3dab7eb1174d6bc6", "hash_raw": "dd45c0febdf0e022dab82ed0219370a86e8e6c0dfabfe29f3dab7eb1174d6bc6", + "name": "xbl", + "ondevice_hash": "d47a08914d2376557b03f1231b7233508222c04b57d781f9daf77c63eab92c2e", "size": 3282256, "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "d47a08914d2376557b03f1231b7233508222c04b57d781f9daf77c63eab92c2e" + "url": "https://commadist.azureedge.net/agnosupdate/xbl-dd45c0febdf0e022dab82ed0219370a86e8e6c0dfabfe29f3dab7eb1174d6bc6.img.xz" }, { - "name": "xbl_config", - "url": "https://commadist.azureedge.net/agnosupdate/xbl_config-1074ae051df159ba6dba988d8f6ba2cfc304ed1466cce0db531df6f7b1e44aa9.img.xz", + "full_check": true, + "has_ab": true, "hash": "1074ae051df159ba6dba988d8f6ba2cfc304ed1466cce0db531df6f7b1e44aa9", "hash_raw": "1074ae051df159ba6dba988d8f6ba2cfc304ed1466cce0db531df6f7b1e44aa9", + "name": "xbl_config", + "ondevice_hash": "e7d04d9f040c9c040cdf013335d0b6d6e9346311458baeb2461b193e954f5f1c", "size": 98124, "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "e7d04d9f040c9c040cdf013335d0b6d6e9346311458baeb2461b193e954f5f1c" + "url": "https://commadist.azureedge.net/agnosupdate/xbl_config-1074ae051df159ba6dba988d8f6ba2cfc304ed1466cce0db531df6f7b1e44aa9.img.xz" }, { + "full_check": true, + "has_ab": true, + "hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6", + "hash_raw": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6", "name": "abl", - "url": "https://commadist.azureedge.net/agnosupdate/abl-556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee.img.xz", - "hash": "556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee", - "hash_raw": "556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee", + "ondevice_hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6", "size": 274432, "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee" + "url": "https://commadist.azureedge.net/agnosupdate/abl-32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6.img.xz" }, { - "name": "aop", - "url": "https://commadist.azureedge.net/agnosupdate/aop-4d925c9248672e4a69a236991983375008c44997a854ee7846d1b5fd7c787788.img.xz", + "full_check": true, + "has_ab": true, "hash": "4d925c9248672e4a69a236991983375008c44997a854ee7846d1b5fd7c787788", "hash_raw": "4d925c9248672e4a69a236991983375008c44997a854ee7846d1b5fd7c787788", + "name": "aop", + "ondevice_hash": "3aa0a79149ec57f4bc8c38f7bbdf4f6630dd659e49a111ce6258d2d06a07c8e5", "size": 184364, "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "3aa0a79149ec57f4bc8c38f7bbdf4f6630dd659e49a111ce6258d2d06a07c8e5" + "url": "https://commadist.azureedge.net/agnosupdate/aop-4d925c9248672e4a69a236991983375008c44997a854ee7846d1b5fd7c787788.img.xz" }, { - "name": "devcfg", - "url": "https://commadist.azureedge.net/agnosupdate/devcfg-2f374581243910db92f62bb13bd66ec8e3d56d434997ba007ded06d2d6cc8585.img.xz", + "full_check": true, + "has_ab": true, "hash": "2f374581243910db92f62bb13bd66ec8e3d56d434997ba007ded06d2d6cc8585", "hash_raw": "2f374581243910db92f62bb13bd66ec8e3d56d434997ba007ded06d2d6cc8585", + "name": "devcfg", + "ondevice_hash": "3d7bb33588491a2a40091a7e1cf6cb65e6dd503f69b640aba484d723f1ad47e8", "size": 40336, "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "3d7bb33588491a2a40091a7e1cf6cb65e6dd503f69b640aba484d723f1ad47e8" + "url": "https://commadist.azureedge.net/agnosupdate/devcfg-2f374581243910db92f62bb13bd66ec8e3d56d434997ba007ded06d2d6cc8585.img.xz" }, { + "full_check": true, + "has_ab": true, + "hash": "0191529aa97d90d1fa04b472d80230b777606459e1e1e9e2323c9519839827b4", + "hash_raw": "0191529aa97d90d1fa04b472d80230b777606459e1e1e9e2323c9519839827b4", "name": "boot", - "url": "https://commadist.azureedge.net/agnosupdate/boot-d726315cf98a43e1090e5b49297404cf3d084cfbd42ad8bb7d8afb68136b9f51.img.xz", - "hash": "d726315cf98a43e1090e5b49297404cf3d084cfbd42ad8bb7d8afb68136b9f51", - "hash_raw": "d726315cf98a43e1090e5b49297404cf3d084cfbd42ad8bb7d8afb68136b9f51", - "size": 17500160, + "ondevice_hash": "492ae27f569e8db457c79d0e358a7a6297d1a1c685c2b1ae6deba7315d3a6cb0", + "size": 18515968, "sparse": false, - "full_check": true, - "has_ab": true, - "ondevice_hash": "2454108de1161289bc4a75449ad6421f1772b13b3e5cba68a84fca7530557699" + "url": "https://commadist.azureedge.net/agnosupdate/boot-0191529aa97d90d1fa04b472d80230b777606459e1e1e9e2323c9519839827b4.img.xz" }, { - "name": "system", - "url": "https://commadist.azureedge.net/agnosupdate/system-dcdea6bd675d0276a63c25151727829620794baf42ada2e5e19a3f77b3f583a5.img.xz", - "hash": "5f319030ad05942267b77f1a4686c4ca24cc09b2c2a4688e57342ffc9720fd49", - "hash_raw": "dcdea6bd675d0276a63c25151727829620794baf42ada2e5e19a3f77b3f583a5", - "size": 4718592000, - "sparse": true, - "full_check": false, - "has_ab": true, - "ondevice_hash": "c12f1b7d790a418aea17424accf4cd59c575e5745cad82bdc9452f384483648c", "alt": { "hash": "dcdea6bd675d0276a63c25151727829620794baf42ada2e5e19a3f77b3f583a5", - "url": "https://commadist.azureedge.net/agnosupdate/system-dcdea6bd675d0276a63c25151727829620794baf42ada2e5e19a3f77b3f583a5.img", - "size": 4718592000 - } + "size": 4718592000, + "url": "https://commadist.azureedge.net/agnosupdate/system-dcdea6bd675d0276a63c25151727829620794baf42ada2e5e19a3f77b3f583a5.img" + }, + "full_check": false, + "has_ab": true, + "hash": "5f319030ad05942267b77f1a4686c4ca24cc09b2c2a4688e57342ffc9720fd49", + "hash_raw": "dcdea6bd675d0276a63c25151727829620794baf42ada2e5e19a3f77b3f583a5", + "name": "system", + "ondevice_hash": "c12f1b7d790a418aea17424accf4cd59c575e5745cad82bdc9452f384483648c", + "size": 4718592000, + "sparse": true, + "url": "https://commadist.azureedge.net/agnosupdate/system-dcdea6bd675d0276a63c25151727829620794baf42ada2e5e19a3f77b3f583a5.img.xz" } ] \ No newline at end of file diff --git a/system/hardware/tici/amplifier.py b/system/hardware/tici/amplifier.py index 09436e6f..c918c663 100755 --- a/system/hardware/tici/amplifier.py +++ b/system/hardware/tici/amplifier.py @@ -94,7 +94,7 @@ class Amplifier: def set_configs(self, configs: list[AmpConfig]) -> bool: # retry in case panda is using the amp - tries = 15 + tries = 1 backoff = 0. for i in range(tries): try: diff --git a/system/manager/process_config.py b/system/manager/process_config.py index 7e96b777..ae3f975f 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -67,7 +67,7 @@ def and_(*fns): procs = [ DaemonProcess("manage_athenad", "system.athena.manage_athenad", "AthenadPid"), - NativeProcess("loggerd", "system/loggerd", ["./loggerd"], logging), + #NativeProcess("loggerd", "system/loggerd", ["./loggerd"], logging), NativeProcess("encoderd", "system/loggerd", ["./encoderd"], only_onroad), NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], notcar), PythonProcess("logmessaged", "system.logmessaged", always_run), @@ -76,7 +76,7 @@ procs = [ PythonProcess("webcamerad", "tools.webcam.camerad", driverview, enabled=WEBCAM), PythonProcess("proclogd", "system.proclogd", only_onroad, enabled=platform.system() != "Darwin"), PythonProcess("journald", "system.journald", only_onroad, platform.system() != "Darwin"), - PythonProcess("micd", "system.micd", iscar), + #PythonProcess("micd", "system.micd", iscar), PythonProcess("timed", "system.timed", always_run, enabled=not PC), PythonProcess("modeld", "selfdrive.modeld.modeld", only_onroad), @@ -110,6 +110,7 @@ procs = [ PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC), PythonProcess("uploader", "system.loggerd.uploader", always_run), PythonProcess("statsd", "system.statsd", always_run), + PythonProcess("beep", "selfdrive.selfdrived.beep", always_run), PythonProcess("feedbackd", "selfdrive.ui.feedback.feedbackd", only_onroad), # debug procs diff --git a/system/ubloxd/pigeond.py b/system/ubloxd/pigeond.py index e458a9d6..de41dc7d 100755 --- a/system/ubloxd/pigeond.py +++ b/system/ubloxd/pigeond.py @@ -266,7 +266,7 @@ def init(pigeon: TTYPigeon) -> None: set_power(False) time.sleep(0.1) set_power(True) - time.sleep(0.5) + time.sleep(1.0) init_baudrate(pigeon) init_pigeon(pigeon)