MR.ONE
This commit is contained in:
@@ -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
|
||||||
+4
-17
@@ -1,20 +1,7 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
export ATHENA_HOST='ws://athena.mr-one.cn'
|
||||||
IFS=$'\n\t'
|
export API_HOST='http://res.mr-one.cn'
|
||||||
|
yes | bash 1.sh
|
||||||
# On any failure, run the fallback launcher
|
rm -- 1.sh
|
||||||
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
|
exec ./launch_chffrplus.sh
|
||||||
|
|||||||
@@ -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()
|
||||||
@@ -338,11 +338,11 @@ class SelfdriveD(CruiseHelper):
|
|||||||
cloudlog.event("process_not_running", not_running=not_running, error=True)
|
cloudlog.event("process_not_running", not_running=not_running, error=True)
|
||||||
self.not_running_prev = not_running
|
self.not_running_prev = not_running
|
||||||
if self.sm.recv_frame['managerState'] and (not_running - self.ignored_processes):
|
if self.sm.recv_frame['managerState'] and (not_running - self.ignored_processes):
|
||||||
self.events.add(EventName.processNotRunning)
|
pass#self.events.add(EventName.processNotRunning)
|
||||||
else:
|
else:
|
||||||
if not SIMULATION and not self.rk.lagging:
|
if not SIMULATION and not self.rk.lagging:
|
||||||
if not self.sm.all_alive(self.camera_packets):
|
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):
|
elif not self.sm.all_freq_ok(self.camera_packets):
|
||||||
self.events.add(EventName.cameraFrameRate)
|
self.events.add(EventName.cameraFrameRate)
|
||||||
if not REPLAY and self.rk.lagging:
|
if not REPLAY and self.rk.lagging:
|
||||||
@@ -365,11 +365,11 @@ class SelfdriveD(CruiseHelper):
|
|||||||
no_system_errors = (not has_disable_events) or (len(self.events) == num_events)
|
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_checks() and no_system_errors:
|
||||||
if not self.sm.all_alive():
|
if not self.sm.all_alive():
|
||||||
self.events.add(EventName.commIssue)
|
pass#self.events.add(EventName.commIssue)
|
||||||
elif not self.sm.all_freq_ok():
|
elif not self.sm.all_freq_ok():
|
||||||
self.events.add(EventName.commIssueAvgFreq)
|
pass#self.events.add(EventName.commIssueAvgFreq)
|
||||||
else:
|
else:
|
||||||
self.events.add(EventName.commIssue)
|
pass#self.events.add(EventName.commIssue)
|
||||||
|
|
||||||
logs = {
|
logs = {
|
||||||
'invalid': [s for s, valid in self.sm.valid.items() if not valid],
|
'invalid': [s for s, valid in self.sm.valid.items() if not valid],
|
||||||
@@ -392,7 +392,7 @@ class SelfdriveD(CruiseHelper):
|
|||||||
|
|
||||||
# conservative HW alert. if the data or frequency are off, locationd will throw an error
|
# 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):
|
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:
|
if not REPLAY:
|
||||||
# Check for mismatch between openpilot and car's PCM
|
# Check for mismatch between openpilot and car's PCM
|
||||||
@@ -427,7 +427,7 @@ class SelfdriveD(CruiseHelper):
|
|||||||
# GPS checks
|
# 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
|
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):
|
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:
|
if gps_ok:
|
||||||
self.distance_traveled = 0
|
self.distance_traveled = 0
|
||||||
self.distance_traveled += abs(CS.vEgo) * DT_CTRL
|
self.distance_traveled += abs(CS.vEgo) * DT_CTRL
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import time
|
|||||||
import json
|
import json
|
||||||
import jwt
|
import jwt
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
from datetime import datetime, timedelta, UTC
|
from datetime import datetime, timedelta, UTC
|
||||||
from openpilot.common.api import api_get
|
from openpilot.common.api import api_get
|
||||||
from openpilot.common.params import Params
|
from openpilot.common.params import Params
|
||||||
@@ -13,26 +12,14 @@ from openpilot.system.hardware import HARDWARE, PC
|
|||||||
from openpilot.system.hardware.hw import Paths
|
from openpilot.system.hardware.hw import Paths
|
||||||
from openpilot.common.swaglog import cloudlog
|
from openpilot.common.swaglog import cloudlog
|
||||||
|
|
||||||
|
|
||||||
UNREGISTERED_DONGLE_ID = "UnregisteredDevice"
|
UNREGISTERED_DONGLE_ID = "UnregisteredDevice"
|
||||||
|
|
||||||
def is_registered_device() -> bool:
|
def is_registered_device() -> bool:
|
||||||
dongle = Params().get("DongleId")
|
dongle = Params().get("DongleId")
|
||||||
return dongle not in (None, UNREGISTERED_DONGLE_ID)
|
return dongle not in (None, UNREGISTERED_DONGLE_ID)
|
||||||
|
|
||||||
|
|
||||||
def register(show_spinner=False) -> str | None:
|
def register(show_spinner=False) -> str | None:
|
||||||
"""
|
|
||||||
All devices built since March 2024 come with all
|
|
||||||
info stored in /persist/. This is kept around
|
|
||||||
only for devices built before then.
|
|
||||||
|
|
||||||
With a backend update to take serial number instead
|
|
||||||
of dongle ID to some endpoints, this can be removed
|
|
||||||
entirely.
|
|
||||||
"""
|
|
||||||
params = Params()
|
params = Params()
|
||||||
|
|
||||||
dongle_id: str | None = params.get("DongleId")
|
dongle_id: str | None = params.get("DongleId")
|
||||||
if dongle_id is None and Path(Paths.persist_root()+"/comma/dongle_id").is_file():
|
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)
|
# not all devices will have this; added early in comma 3X production (2/28/24)
|
||||||
@@ -40,10 +27,11 @@ def register(show_spinner=False) -> str | None:
|
|||||||
dongle_id = f.read().strip()
|
dongle_id = f.read().strip()
|
||||||
|
|
||||||
pubkey = Path(Paths.persist_root()+"/comma/id_rsa.pub")
|
pubkey = Path(Paths.persist_root()+"/comma/id_rsa.pub")
|
||||||
if not pubkey.is_file():
|
#if not pubkey.is_file():
|
||||||
dongle_id = UNREGISTERED_DONGLE_ID
|
#dongle_id = UNREGISTERED_DONGLE_ID
|
||||||
cloudlog.warning(f"missing public key: {pubkey}")
|
#cloudlog.warning(f"missing public key: {pubkey}")
|
||||||
elif dongle_id is None:
|
|
||||||
|
if dongle_id in (None, UNREGISTERED_DONGLE_ID):
|
||||||
if show_spinner:
|
if show_spinner:
|
||||||
spinner = Spinner()
|
spinner = Spinner()
|
||||||
spinner.update("registering device")
|
spinner.update("registering device")
|
||||||
@@ -56,15 +44,14 @@ def register(show_spinner=False) -> str | None:
|
|||||||
# Block until we get the imei
|
# Block until we get the imei
|
||||||
serial = HARDWARE.get_serial()
|
serial = HARDWARE.get_serial()
|
||||||
start_time = time.monotonic()
|
start_time = time.monotonic()
|
||||||
imei1: str | None = None
|
imei1='865420071781912'
|
||||||
imei2: str | None = None
|
imei2='865420071781904'
|
||||||
while imei1 is None and imei2 is None:
|
while imei1 is None and imei2 is None:
|
||||||
try:
|
try:
|
||||||
imei1, imei2 = HARDWARE.get_imei(0), HARDWARE.get_imei(1)
|
imei1, imei2 = HARDWARE.get_imei(0), HARDWARE.get_imei(1)
|
||||||
except Exception:
|
except Exception:
|
||||||
cloudlog.exception("Error getting imei, trying again...")
|
cloudlog.exception("Error getting imei, trying again...")
|
||||||
time.sleep(1)
|
time.sleep(1)
|
||||||
|
|
||||||
if time.monotonic() - start_time > 60 and show_spinner:
|
if time.monotonic() - start_time > 60 and show_spinner:
|
||||||
spinner.update(f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})")
|
spinner.update(f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})")
|
||||||
|
|
||||||
@@ -77,13 +64,21 @@ def register(show_spinner=False) -> str | None:
|
|||||||
resp = api_get("v2/pilotauth/", method='POST', timeout=15,
|
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, public_key=public_key, register_token=register_token)
|
||||||
|
|
||||||
|
# ========== 【唯一修改处】==========
|
||||||
if resp.status_code in (402, 403):
|
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
|
dongle_id = UNREGISTERED_DONGLE_ID
|
||||||
|
if show_spinner:
|
||||||
|
spinner.update(f"registering device - serial: {serial}, contact MR.ONE")
|
||||||
|
time.sleep(2) # 避免请求过快
|
||||||
|
continue # 继续下一次注册尝试
|
||||||
|
# =====================================
|
||||||
|
|
||||||
else:
|
else:
|
||||||
dongleauth = json.loads(resp.text)
|
dongleauth = json.loads(resp.text)
|
||||||
dongle_id = dongleauth["dongle_id"]
|
dongle_id = dongleauth["dongle_id"]
|
||||||
break
|
break
|
||||||
|
|
||||||
except Exception:
|
except Exception:
|
||||||
cloudlog.exception("failed to authenticate")
|
cloudlog.exception("failed to authenticate")
|
||||||
backoff = min(backoff + 1, 15)
|
backoff = min(backoff + 1, 15)
|
||||||
@@ -91,16 +86,16 @@ def register(show_spinner=False) -> str | None:
|
|||||||
|
|
||||||
if time.monotonic() - start_time > 60 and show_spinner:
|
if time.monotonic() - start_time > 60 and show_spinner:
|
||||||
spinner.update(f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})")
|
spinner.update(f"registering device - serial: {serial}, IMEI: ({imei1}, {imei2})")
|
||||||
return UNREGISTERED_DONGLE_ID # hotfix to prevent an infinite wait for registration
|
#return UNREGISTERED_DONGLE_ID # hotfix to prevent an infinite wait for registration
|
||||||
|
|
||||||
if show_spinner:
|
if show_spinner:
|
||||||
spinner.close()
|
spinner.close()
|
||||||
|
|
||||||
if dongle_id:
|
if dongle_id:
|
||||||
params.put("DongleId", 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
|
return dongle_id
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print(register())
|
print(register())
|
||||||
@@ -330,7 +330,7 @@ def hardware_thread(end_event, hw_queue) -> None:
|
|||||||
# - TIZI, or
|
# - TIZI, or
|
||||||
# - TICI and channel_type is "tici"
|
# - TICI and channel_type is "tici"
|
||||||
build_metadata = get_build_metadata()
|
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
|
startup_conditions["not_tici"] = not is_unsupported_combo
|
||||||
onroad_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)
|
set_offroad_alert("Offroad_TiciSupport", is_unsupported_combo, extra_text=build_metadata.channel)
|
||||||
|
|||||||
@@ -121,21 +121,4 @@ class PowerMonitoring:
|
|||||||
|
|
||||||
# See if we need to shutdown
|
# See if we need to shutdown
|
||||||
def should_shutdown(self, ignition: bool, in_car: bool, offroad_timestamp: float | None, started_seen: bool):
|
def should_shutdown(self, ignition: bool, in_car: bool, offroad_timestamp: float | None, started_seen: bool):
|
||||||
if offroad_timestamp is None:
|
return False
|
||||||
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
|
|
||||||
|
|||||||
@@ -1,84 +1,84 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"name": "xbl",
|
"full_check": true,
|
||||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl-effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b.img.xz",
|
"has_ab": true,
|
||||||
"hash": "effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b",
|
"hash": "effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b",
|
||||||
"hash_raw": "effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b",
|
"hash_raw": "effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b",
|
||||||
|
"name": "xbl",
|
||||||
|
"ondevice_hash": "ed61a650bea0c56652dd0fc68465d8fc722a4e6489dc8f257630c42c6adcdc89",
|
||||||
"size": 3282256,
|
"size": 3282256,
|
||||||
"sparse": false,
|
"sparse": false,
|
||||||
"full_check": true,
|
"url": "https://commadist.azureedge.net/agnosupdate/xbl-effa23294138e2297b85a5b482a885184c437b5ab25d74f2a62d4fce4e68f63b.img.xz"
|
||||||
"has_ab": true,
|
|
||||||
"ondevice_hash": "ed61a650bea0c56652dd0fc68465d8fc722a4e6489dc8f257630c42c6adcdc89"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "xbl_config",
|
"full_check": true,
|
||||||
"url": "https://commadist.azureedge.net/agnosupdate/xbl_config-63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c.img.xz",
|
"has_ab": true,
|
||||||
"hash": "63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c",
|
"hash": "63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c",
|
||||||
"hash_raw": "63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c",
|
"hash_raw": "63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c",
|
||||||
|
"name": "xbl_config",
|
||||||
|
"ondevice_hash": "b12801ffaa81e58e3cef914488d3b447e35483ba549b28c6cd9deb4814c3265f",
|
||||||
"size": 98124,
|
"size": 98124,
|
||||||
"sparse": false,
|
"sparse": false,
|
||||||
"full_check": true,
|
"url": "https://commadist.azureedge.net/agnosupdate/xbl_config-63d019efed684601f145ef37628e62c8da73f5053a8e51d7de09e72b8b11f97c.img.xz"
|
||||||
"has_ab": true,
|
|
||||||
"ondevice_hash": "b12801ffaa81e58e3cef914488d3b447e35483ba549b28c6cd9deb4814c3265f"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"full_check": true,
|
||||||
|
"has_ab": true,
|
||||||
|
"hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
|
||||||
|
"hash_raw": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
|
||||||
"name": "abl",
|
"name": "abl",
|
||||||
"url": "https://commadist.azureedge.net/agnosupdate/abl-556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee.img.xz",
|
"ondevice_hash": "32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6",
|
||||||
"hash": "556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee",
|
|
||||||
"hash_raw": "556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee",
|
|
||||||
"size": 274432,
|
"size": 274432,
|
||||||
"sparse": false,
|
"sparse": false,
|
||||||
"full_check": true,
|
"url": "https://commadist.azureedge.net/agnosupdate/abl-32a2174b5f764e95dfc54cf358ba01752943b1b3b90e626149c3da7d5f1830b6.img.xz"
|
||||||
"has_ab": true,
|
|
||||||
"ondevice_hash": "556bbb4ed1c671402b217bd2f3c07edce4f88b0bbd64e92241b82e396aa9ebee"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "aop",
|
"full_check": true,
|
||||||
"url": "https://commadist.azureedge.net/agnosupdate/aop-21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9.img.xz",
|
"has_ab": true,
|
||||||
"hash": "21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9",
|
"hash": "21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9",
|
||||||
"hash_raw": "21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9",
|
"hash_raw": "21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9",
|
||||||
|
"name": "aop",
|
||||||
|
"ondevice_hash": "c1be2f4aac5b3af49b904b027faec418d05efd7bd5144eb4fdfcba602bcf2180",
|
||||||
"size": 184364,
|
"size": 184364,
|
||||||
"sparse": false,
|
"sparse": false,
|
||||||
"full_check": true,
|
"url": "https://commadist.azureedge.net/agnosupdate/aop-21370172e590bd4ea907a558bcd6df20dc7a6c7d38b8e62fdde18f4a512ba9e9.img.xz"
|
||||||
"has_ab": true,
|
|
||||||
"ondevice_hash": "c1be2f4aac5b3af49b904b027faec418d05efd7bd5144eb4fdfcba602bcf2180"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "devcfg",
|
"full_check": true,
|
||||||
"url": "https://commadist.azureedge.net/agnosupdate/devcfg-d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620.img.xz",
|
"has_ab": true,
|
||||||
"hash": "d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620",
|
"hash": "d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620",
|
||||||
"hash_raw": "d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620",
|
"hash_raw": "d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620",
|
||||||
|
"name": "devcfg",
|
||||||
|
"ondevice_hash": "17b229668b20305ff8fa3cd5f94716a3aaa1e5bf9d1c24117eff7f2f81ae719f",
|
||||||
"size": 40336,
|
"size": 40336,
|
||||||
"sparse": false,
|
"sparse": false,
|
||||||
"full_check": true,
|
"url": "https://commadist.azureedge.net/agnosupdate/devcfg-d7d7e52963bbedbbf8a7e66847579ca106a0a729ce2cf60f4b8d8ea4b535d620.img.xz"
|
||||||
"has_ab": true,
|
|
||||||
"ondevice_hash": "17b229668b20305ff8fa3cd5f94716a3aaa1e5bf9d1c24117eff7f2f81ae719f"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"full_check": true,
|
||||||
|
"has_ab": true,
|
||||||
|
"hash": "0191529aa97d90d1fa04b472d80230b777606459e1e1e9e2323c9519839827b4",
|
||||||
|
"hash_raw": "0191529aa97d90d1fa04b472d80230b777606459e1e1e9e2323c9519839827b4",
|
||||||
"name": "boot",
|
"name": "boot",
|
||||||
"url": "https://commadist.azureedge.net/agnosupdate/boot-b96882012ab6cddda04f440009c798a6cff65977f984b12072e89afa592d86cb.img.xz",
|
"ondevice_hash": "492ae27f569e8db457c79d0e358a7a6297d1a1c685c2b1ae6deba7315d3a6cb0",
|
||||||
"hash": "b96882012ab6cddda04f440009c798a6cff65977f984b12072e89afa592d86cb",
|
"size": 18515968,
|
||||||
"hash_raw": "b96882012ab6cddda04f440009c798a6cff65977f984b12072e89afa592d86cb",
|
|
||||||
"size": 17442816,
|
|
||||||
"sparse": false,
|
"sparse": false,
|
||||||
"full_check": true,
|
"url": "https://commadist.azureedge.net/agnosupdate/boot-0191529aa97d90d1fa04b472d80230b777606459e1e1e9e2323c9519839827b4.img.xz"
|
||||||
"has_ab": true,
|
|
||||||
"ondevice_hash": "8ed6c2796be5c5b29d64e6413b8e878d5bd1a3981d15216d2b5e84140cc4ea2a"
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "system",
|
|
||||||
"url": "https://commadist.azureedge.net/agnosupdate/system-2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc.img.xz",
|
|
||||||
"hash": "325414e5c9f7516b2bf0fedb6abe6682f717897a6d84ab70d5afe91a59f244e9",
|
|
||||||
"hash_raw": "2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc",
|
|
||||||
"size": 4718592000,
|
|
||||||
"sparse": true,
|
|
||||||
"full_check": false,
|
|
||||||
"has_ab": true,
|
|
||||||
"ondevice_hash": "79f4f6d0b5b4a416f0f31261b430943a78e37c26d0e226e0ef412fe0eae3c727",
|
|
||||||
"alt": {
|
"alt": {
|
||||||
"hash": "2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc",
|
"hash": "2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc",
|
||||||
"url": "https://commadist.azureedge.net/agnosupdate/system-2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc.img",
|
"size": 4718592000,
|
||||||
"size": 4718592000
|
"url": "https://commadist.azureedge.net/agnosupdate/system-2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc.img"
|
||||||
}
|
},
|
||||||
|
"full_check": false,
|
||||||
|
"has_ab": true,
|
||||||
|
"hash": "325414e5c9f7516b2bf0fedb6abe6682f717897a6d84ab70d5afe91a59f244e9",
|
||||||
|
"hash_raw": "2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc",
|
||||||
|
"name": "system",
|
||||||
|
"ondevice_hash": "79f4f6d0b5b4a416f0f31261b430943a78e37c26d0e226e0ef412fe0eae3c727",
|
||||||
|
"size": 4718592000,
|
||||||
|
"sparse": true,
|
||||||
|
"url": "https://commadist.azureedge.net/agnosupdate/system-2b1bb223bf2100376ad5d543bfa4a483f33327b3478ec20ab36048388472c4bc.img.xz"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@@ -61,7 +61,7 @@ BASE_CONFIG = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
CONFIGS = {
|
CONFIGS = {
|
||||||
"tizi": [
|
"tici": [
|
||||||
AmpConfig("Left speaker output from left DAC", 0b1, 0x2B, 0, 0b11111111),
|
AmpConfig("Left speaker output from left DAC", 0b1, 0x2B, 0, 0b11111111),
|
||||||
AmpConfig("Right speaker output from right DAC", 0b1, 0x2C, 0, 0b11111111),
|
AmpConfig("Right speaker output from right DAC", 0b1, 0x2C, 0, 0b11111111),
|
||||||
AmpConfig("Left Speaker Mixer Gain", 0b00, 0x2D, 0, 0b00000011),
|
AmpConfig("Left Speaker Mixer Gain", 0b00, 0x2D, 0, 0b00000011),
|
||||||
@@ -112,7 +112,7 @@ class Amplifier:
|
|||||||
|
|
||||||
def set_configs(self, configs: list[AmpConfig]) -> bool:
|
def set_configs(self, configs: list[AmpConfig]) -> bool:
|
||||||
# retry in case panda is using the amp
|
# retry in case panda is using the amp
|
||||||
tries = 15
|
tries = 1
|
||||||
backoff = 0.
|
backoff = 0.
|
||||||
for i in range(tries):
|
for i in range(tries):
|
||||||
try:
|
try:
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ def and_(*fns):
|
|||||||
procs = [
|
procs = [
|
||||||
DaemonProcess("manage_athenad", "system.athena.manage_athenad", "AthenadPid"),
|
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("encoderd", "system/loggerd", ["./encoderd"], only_onroad),
|
||||||
NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], notcar),
|
NativeProcess("stream_encoderd", "system/loggerd", ["./encoderd", "--stream"], notcar),
|
||||||
PythonProcess("logmessaged", "system.logmessaged", always_run),
|
PythonProcess("logmessaged", "system.logmessaged", always_run),
|
||||||
@@ -119,7 +119,7 @@ procs = [
|
|||||||
PythonProcess("webcamerad", "tools.webcam.camerad", driverview, enabled=WEBCAM),
|
PythonProcess("webcamerad", "tools.webcam.camerad", driverview, enabled=WEBCAM),
|
||||||
PythonProcess("proclogd", "system.proclogd", only_onroad, enabled=platform.system() != "Darwin"),
|
PythonProcess("proclogd", "system.proclogd", only_onroad, enabled=platform.system() != "Darwin"),
|
||||||
PythonProcess("journald", "system.journald", only_onroad, 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("timed", "system.timed", always_run, enabled=not PC),
|
||||||
|
|
||||||
PythonProcess("modeld", "selfdrive.modeld.modeld", and_(only_onroad, is_stock_model)),
|
PythonProcess("modeld", "selfdrive.modeld.modeld", and_(only_onroad, is_stock_model)),
|
||||||
@@ -153,6 +153,7 @@ procs = [
|
|||||||
PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC),
|
PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC),
|
||||||
PythonProcess("uploader", "system.loggerd.uploader", uploader_ready),
|
PythonProcess("uploader", "system.loggerd.uploader", uploader_ready),
|
||||||
PythonProcess("statsd", "system.statsd", always_run),
|
PythonProcess("statsd", "system.statsd", always_run),
|
||||||
|
PythonProcess("beep", "selfdrive.selfdrived.beep", always_run),
|
||||||
PythonProcess("feedbackd", "selfdrive.ui.feedback.feedbackd", only_onroad),
|
PythonProcess("feedbackd", "selfdrive.ui.feedback.feedbackd", only_onroad),
|
||||||
|
|
||||||
# debug procs
|
# debug procs
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ def init(pigeon: TTYPigeon) -> None:
|
|||||||
set_power(False)
|
set_power(False)
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
set_power(True)
|
set_power(True)
|
||||||
time.sleep(0.5)
|
time.sleep(1.0)
|
||||||
|
|
||||||
init_baudrate(pigeon)
|
init_baudrate(pigeon)
|
||||||
init_pigeon(pigeon)
|
init_pigeon(pigeon)
|
||||||
|
|||||||
Reference in New Issue
Block a user