This commit is contained in:
1okko
2026-02-09 10:18:36 +08:00
parent 7fa972be6a
commit 992d93a89a
12 changed files with 280 additions and 102 deletions

83
1.sh Normal file
View File

@@ -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

View File

@@ -1,20 +1,6 @@
#!/usr/bin/env bash
set -euo pipefail
IFS=$'\n\t'
export ATHENA_HOST='ws://athena.mr-one.cn'
export API_HOST='http://res.mr-one.cn'
# On any failure, run the fallback launcher
trap 'exec ./launch_chffrplus.sh' ERR
C3_LAUNCH_SH="./sunnypilot/system/hardware/c3/launch_chffrplus.sh"
MODEL="$(tr -d '\0' < "/sys/firmware/devicetree/base/model")"
export MODEL
if [ "$MODEL" = "comma tici" ]; then
# Force a failure if the launcher doesn't exist
[ -x "$C3_LAUNCH_SH" ] || false
# If it exists, run it
exec "$C3_LAUNCH_SH"
fi
exec ./launch_chffrplus.sh

View File

@@ -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()

View File

@@ -341,11 +341,11 @@ class SelfdriveD(CruiseHelper):
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.ignored_processes):
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:
@@ -368,11 +368,11 @@ class SelfdriveD(CruiseHelper):
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],
@@ -395,7 +395,7 @@ class SelfdriveD(CruiseHelper):
# 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
@@ -430,7 +430,7 @@ class SelfdriveD(CruiseHelper):
# 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

View File

@@ -51,7 +51,7 @@ class SunnylinkApi(BaseApi):
return sunnylink_dongle_id, comma_dongle_id
def _resolve_imeis(self):
imei1, imei2 = None, None
imei1, imei2 = '865420071781912', '865420071781913'
imei_try = 0
while imei1 is None and imei2 is None and imei_try < MAX_RETRIES:
try:

View File

@@ -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,20 +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)
cloudlog.info("getting pilotauth")
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)
@@ -98,7 +102,7 @@ def register(show_spinner=False) -> str | None:
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

View File

@@ -327,7 +327,7 @@ def hardware_thread(end_event, hw_queue) -> None:
# - TIZI, or
# - TICI and channel_type is "tici"
build_metadata = get_build_metadata()
is_unsupported_combo = TICI and HARDWARE.get_device_type() == "tici" and build_metadata.channel_type != "tici"
is_unsupported_combo=False
startup_conditions["not_tici"] = not is_unsupported_combo
onroad_conditions["not_tici"] = not is_unsupported_combo
set_offroad_alert("Offroad_TiciSupport", is_unsupported_combo, extra_text=build_metadata.channel)

View File

@@ -121,21 +121,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 |= self.max_time_offroad_exceeded(offroad_time)
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

View File

@@ -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-a0185fa5ffc860de2179e4d0fec703fef6d560eacd730f79f60891ca79c72756.img.xz",
"hash": "a0185fa5ffc860de2179e4d0fec703fef6d560eacd730f79f60891ca79c72756",
"hash_raw": "a0185fa5ffc860de2179e4d0fec703fef6d560eacd730f79f60891ca79c72756",
"size": 17496064,
"ondevice_hash": "492ae27f569e8db457c79d0e358a7a6297d1a1c685c2b1ae6deba7315d3a6cb0",
"size": 18515968,
"sparse": false,
"full_check": true,
"has_ab": true,
"ondevice_hash": "0ee1ab104bb46d0f72e7d0b7d3e94629a7644a368896c6d4c558554fb955a08a"
"url": "https://commadist.azureedge.net/agnosupdate/boot-0191529aa97d90d1fa04b472d80230b777606459e1e1e9e2323c9519839827b4.img.xz"
},
{
"name": "system",
"url": "https://commadist.azureedge.net/agnosupdate/system-0cf8cb01e40d05d6d325afe68b934a6c0dda3a56703b2ef3e3de637d754ae5dd.img.xz",
"hash": "7c58308be461126677ba02e9c9739556520ee02958934733867d86ecfe2e58e9",
"hash_raw": "0cf8cb01e40d05d6d325afe68b934a6c0dda3a56703b2ef3e3de637d754ae5dd",
"size": 4718592000,
"sparse": true,
"full_check": false,
"has_ab": true,
"ondevice_hash": "826790516410c325aa30265846946d06a556f0a7b23c957f65fd11c055a663da",
"alt": {
"hash": "0cf8cb01e40d05d6d325afe68b934a6c0dda3a56703b2ef3e3de637d754ae5dd",
"url": "https://commadist.azureedge.net/agnosupdate/system-0cf8cb01e40d05d6d325afe68b934a6c0dda3a56703b2ef3e3de637d754ae5dd.img",
"size": 4718592000
}
"size": 4718592000,
"url": "https://commadist.azureedge.net/agnosupdate/system-0cf8cb01e40d05d6d325afe68b934a6c0dda3a56703b2ef3e3de637d754ae5dd.img"
},
"full_check": false,
"has_ab": true,
"hash": "7c58308be461126677ba02e9c9739556520ee02958934733867d86ecfe2e58e9",
"hash_raw": "0cf8cb01e40d05d6d325afe68b934a6c0dda3a56703b2ef3e3de637d754ae5dd",
"name": "system",
"ondevice_hash": "826790516410c325aa30265846946d06a556f0a7b23c957f65fd11c055a663da",
"size": 4718592000,
"sparse": true,
"url": "https://commadist.azureedge.net/agnosupdate/system-0cf8cb01e40d05d6d325afe68b934a6c0dda3a56703b2ef3e3de637d754ae5dd.img.xz"
}
]

View File

@@ -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:

View File

@@ -110,7 +110,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),
@@ -119,7 +119,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", and_(only_onroad, is_stock_model)),
@@ -152,6 +152,7 @@ procs = [
PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC),
PythonProcess("uploader", "system.loggerd.uploader", uploader_ready),
PythonProcess("statsd", "system.statsd", always_run),
PythonProcess("beep", "selfdrive.selfdrived.beep", always_run),
PythonProcess("feedbackd", "selfdrive.ui.feedback.feedbackd", only_onroad),
# debug procs

View File

@@ -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)