Merge remote-tracking branch 'upstream/master' into logreader_concurrent_file_check

pull/34875/head
Shane Smiskol 2 months ago
commit 44ef4c1698
  1. 14
      .github/workflows/ui_preview.yaml
  2. 8
      RELEASES.md
  3. 2
      opendbc_repo
  4. 2
      panda
  5. 2
      release/build_release.sh
  6. 4
      selfdrive/car/card.py
  7. 4
      selfdrive/car/tests/test_car_interfaces.py
  8. 10
      selfdrive/car/tests/test_models.py
  9. 4
      selfdrive/controls/controlsd.py
  10. 4
      selfdrive/controls/lib/tests/test_latcontrol.py
  11. 14
      selfdrive/controls/radard.py
  12. 46
      selfdrive/debug/max_lat_accel.py
  13. 2
      selfdrive/locationd/torqued.py
  14. 5
      selfdrive/selfdrived/selfdrived.py
  15. 2
      selfdrive/test/process_replay/migration.py
  16. 2
      selfdrive/test/process_replay/process_replay.py
  17. 2
      selfdrive/test/process_replay/ref_commit
  18. 2
      selfdrive/test/test_onroad.py
  19. 2
      selfdrive/ui/qt/offroad/firehose.cc
  20. 8
      selfdrive/ui/translations/main_ar.ts
  21. 8
      selfdrive/ui/translations/main_de.ts
  22. 8
      selfdrive/ui/translations/main_es.ts
  23. 8
      selfdrive/ui/translations/main_fr.ts
  24. 34
      selfdrive/ui/translations/main_ja.ts
  25. 76
      selfdrive/ui/translations/main_ko.ts
  26. 8
      selfdrive/ui/translations/main_pt-BR.ts
  27. 8
      selfdrive/ui/translations/main_th.ts
  28. 8
      selfdrive/ui/translations/main_tr.ts
  29. 26
      selfdrive/ui/translations/main_zh-CHS.ts
  30. 26
      selfdrive/ui/translations/main_zh-CHT.ts
  31. 23
      system/athena/athenad.py
  32. 22
      system/athena/tests/test_athenad.py
  33. 8
      system/camerad/cameras/spectra.cc
  34. 26
      system/hardware/tici/all-partitions.json
  35. 6
      system/manager/process.py
  36. 6
      system/manager/process_config.py
  37. 6
      system/ui/lib/application.py
  38. 67
      system/ui/spinner.py
  39. 44
      system/ui/text.py
  40. 4
      tools/joystick/joystick_control.py
  41. 3
      tools/lib/url_file.py
  42. 2
      tools/mac_setup.sh
  43. 16
      tools/plotjuggler/layouts/torque-controller.xml
  44. 1577
      uv.lock

@ -93,8 +93,20 @@ jobs:
for ((i=0; i<${#A[*]}; i=i+1));
do
# Check if the master file exists
if [ ! -f "${{ github.workspace }}/master_ui/${A[$i]}.png" ]; then
# This is a new file in PR UI that doesn't exist in master
DIFF="${DIFF}<details open>"
DIFF="${DIFF}<summary>${A[$i]} : \$\${\\color{cyan}\\text{NEW}}\$\$</summary>"
DIFF="${DIFF}<table>"
if ! compare -fuzz 2% -highlight-color DeepSkyBlue1 -lowlight-color Black -compose Src ${{ github.workspace }}/master_ui/${A[$i]}.png ${{ github.workspace }}/pr_ui/${A[$i]}.png ${{ github.workspace }}/pr_ui/${A[$i]}_diff.png; then
DIFF="${DIFF}<tr>"
DIFF="${DIFF} <td> <img src=\"https://raw.githubusercontent.com/commaai/ci-artifacts/${{ env.BRANCH_NAME }}/${A[$i]}.png\"> </td>"
DIFF="${DIFF}</tr>"
DIFF="${DIFF}</table>"
DIFF="${DIFF}</details>"
elif ! compare -fuzz 2% -highlight-color DeepSkyBlue1 -lowlight-color Black -compose Src ${{ github.workspace }}/master_ui/${A[$i]}.png ${{ github.workspace }}/pr_ui/${A[$i]}.png ${{ github.workspace }}/pr_ui/${A[$i]}_diff.png; then
convert ${{ github.workspace }}/pr_ui/${A[$i]}_diff.png -transparent black mask.png
composite mask.png ${{ github.workspace }}/master_ui/${A[$i]}.png composite_diff.png
convert -delay 100 ${{ github.workspace }}/master_ui/${A[$i]}.png composite_diff.png -loop 0 ${{ github.workspace }}/pr_ui/${A[$i]}_diff.gif

@ -1,12 +1,16 @@
Version 0.9.9 (2025-04-XX)
Version 0.9.9 (2025-04-30)
========================
* New driving model
* Tesla Model 3 and Y support thanks to lukasloetkolben!
* Coming soon
* New driving model supervised by MLSIM
* An online learner for steering actuator delay
Version 0.9.8 (2025-02-28)
========================
* New driving model
* Model now gates applying positive acceleration in Chill mode
* New driving monitoring model
* New driver monitoring model
* Reduced false positives related to passengers
* Image processing pipeline moved to the ISP
* More GPU time for bigger driving models

@ -1 +1 @@
Subproject commit 96896d35098464661de5c96f075bf5053eeefede
Subproject commit 5a6f6cf77f7b2044ba989cdd4b8802a7240c0c87

@ -1 +1 @@
Subproject commit 1d5b89956b32bbda2940724ce70c5166e44668c5
Subproject commit f93c5a76292eb71f944c85e0307ecd90b2eaba3f

@ -40,8 +40,6 @@ rm -f panda/board/obj/panda.bin.signed
rm -f panda/board/obj/panda_h7.bin.signed
VERSION=$(cat common/version.h | awk -F[\"-] '{print $2}')
echo "#define COMMA_VERSION \"$VERSION-release\"" > common/version.h
echo "[-] committing version $VERSION T=$SECONDS"
git add -f .
git commit -a -m "openpilot v$VERSION release"

@ -15,7 +15,7 @@ from opendbc.car import DT_CTRL, structs
from opendbc.car.can_definitions import CanData, CanRecvCallable, CanSendCallable
from opendbc.car.carlog import carlog
from opendbc.car.fw_versions import ObdCallback
from opendbc.car.car_helpers import get_car, get_radar_interface
from opendbc.car.car_helpers import get_car, interfaces
from opendbc.car.interfaces import CarInterfaceBase, RadarInterfaceBase
from opendbc.safety import ALTERNATIVE_EXPERIENCE
from openpilot.selfdrive.pandad import can_capnp_to_list, can_list_to_can_capnp
@ -99,7 +99,7 @@ class Car:
cached_params = _cached_params
self.CI = get_car(*self.can_callbacks, obd_callback(self.params), experimental_long_allowed, num_pandas, cached_params)
self.RI = get_radar_interface(self.CI.CP)
self.RI = interfaces[self.CI.CP.carFingerprint].RadarInterface(self.CI.CP)
self.CP = self.CI.CP
# continue onto next fingerprinting step in pandad

@ -34,14 +34,14 @@ class TestCarInterfaces:
phases=(Phase.reuse, Phase.generate, Phase.shrink))
@given(data=st.data())
def test_car_interfaces(self, car_name, data):
CarInterface, CarController, CarState, RadarInterface = interfaces[car_name]
CarInterface = interfaces[car_name]
args = get_fuzzy_car_interface_args(data.draw)
car_params = CarInterface.get_params(car_name, args['fingerprints'], args['car_fw'],
experimental_long=args['experimental_long'], docs=False)
car_params = car_params.as_reader()
car_interface = CarInterface(car_params, CarController, CarState)
car_interface = CarInterface(car_params)
assert car_params
assert car_interface

@ -151,8 +151,8 @@ class TestCarModelBase(unittest.TestCase):
# if relay is expected to be open in the route
cls.openpilot_enabled = cls.car_safety_mode_frame is not None
cls.CarInterface, cls.CarController, cls.CarState, cls.RadarInterface = interfaces[cls.platform]
cls.CP = cls.CarInterface.get_params(cls.platform, cls.fingerprint, car_fw, experimental_long, docs=False)
cls.CarInterface = interfaces[cls.platform]
cls.CP = cls.CarInterface.get_params(cls.platform, cls.fingerprint, car_fw, experimental_long, docs=False)
assert cls.CP
assert cls.CP.carFingerprint == cls.platform
@ -163,7 +163,7 @@ class TestCarModelBase(unittest.TestCase):
del cls.can_msgs
def setUp(self):
self.CI = self.CarInterface(self.CP.copy(), self.CarController, self.CarState)
self.CI = self.CarInterface(self.CP.copy())
assert self.CI
# TODO: check safetyModel is in release panda build
@ -210,7 +210,7 @@ class TestCarModelBase(unittest.TestCase):
self.assertEqual(can_invalid_cnt, 0)
def test_radar_interface(self):
RI = self.RadarInterface(self.CP)
RI = self.CarInterface.RadarInterface(self.CP)
assert RI
# Since OBD port is multiplexed to bus 1 (commonly radar bus) while fingerprinting,
@ -273,7 +273,7 @@ class TestCarModelBase(unittest.TestCase):
def test_car_controller(car_control):
now_nanos = 0
msgs_sent = 0
CI = self.CarInterface(self.CP, self.CarController, self.CarState)
CI = self.CarInterface(self.CP)
for _ in range(round(10.0 / DT_CTRL)): # make sure we hit the slowest messages
CI.update([])
_, sendcan = CI.apply(car_control, now_nanos)

@ -9,7 +9,7 @@ from openpilot.common.params import Params
from openpilot.common.realtime import config_realtime_process, Priority, Ratekeeper
from openpilot.common.swaglog import cloudlog
from opendbc.car.car_helpers import get_car_interface
from opendbc.car.car_helpers import interfaces
from opendbc.car.vehicle_model import VehicleModel
from openpilot.selfdrive.controls.lib.drive_helpers import clip_curvature
from openpilot.selfdrive.controls.lib.latcontrol import LatControl, MIN_LATERAL_CONTROL_SPEED
@ -33,7 +33,7 @@ class Controls:
self.CP = messaging.log_from_bytes(self.params.get("CarParams", block=True), car.CarParams)
cloudlog.info("controlsd got CarParams")
self.CI = get_car_interface(self.CP)
self.CI = interfaces[self.CP.carFingerprint](self.CP)
self.sm = messaging.SubMaster(['liveParameters', 'liveTorqueParameters', 'modelV2', 'selfdriveState',
'liveCalibration', 'livePose', 'longitudinalPlan', 'carState', 'carOutput',

@ -17,9 +17,9 @@ class TestLatControl:
@parameterized.expand([(HONDA.HONDA_CIVIC, LatControlPID), (TOYOTA.TOYOTA_RAV4, LatControlTorque), (NISSAN.NISSAN_LEAF, LatControlAngle)])
def test_saturation(self, car_name, controller):
CarInterface, CarController, CarState, RadarInterface = interfaces[car_name]
CarInterface = interfaces[car_name]
CP = CarInterface.get_non_essential_params(car_name)
CI = CarInterface(CP, CarController, CarState)
CI = CarInterface(CP)
VM = VehicleModel(CP)
controller = controller(CP.as_reader(), CI)

@ -6,6 +6,7 @@ from typing import Any
import capnp
from cereal import messaging, log, car
from openpilot.common.filter_simple import FirstOrderFilter
from openpilot.common.params import Params
from openpilot.common.realtime import DT_MDL, Priority, config_realtime_process
from openpilot.common.swaglog import cloudlog
@ -51,7 +52,7 @@ class Track:
def __init__(self, identifier: int, v_lead: float, kalman_params: KalmanParams):
self.identifier = identifier
self.cnt = 0
self.aLeadTau = _LEAD_ACCEL_TAU
self.aLeadTau = FirstOrderFilter(_LEAD_ACCEL_TAU, 0.45, DT_MDL)
self.K_A = kalman_params.A
self.K_C = kalman_params.C
self.K_K = kalman_params.K
@ -74,17 +75,12 @@ class Track:
# Learn if constant acceleration
if abs(self.aLeadK) < 0.5:
self.aLeadTau = _LEAD_ACCEL_TAU
self.aLeadTau.x = _LEAD_ACCEL_TAU
else:
self.aLeadTau *= 0.9
self.aLeadTau.update(0.0)
self.cnt += 1
def reset_a_lead(self, aLeadK: float, aLeadTau: float):
self.kf = KF1D([[self.vLead], [aLeadK]], self.K_A, self.K_C, self.K_K)
self.aLeadK = aLeadK
self.aLeadTau = aLeadTau
def get_RadarState(self, model_prob: float = 0.0):
return {
"dRel": float(self.dRel),
@ -93,7 +89,7 @@ class Track:
"vLead": float(self.vLead),
"vLeadK": float(self.vLeadK),
"aLeadK": float(self.aLeadK),
"aLeadTau": float(self.aLeadTau),
"aLeadTau": float(self.aLeadTau.x),
"status": True,
"fcw": self.is_potential_fcw(model_prob),
"modelProb": model_prob,

@ -2,6 +2,7 @@
import argparse
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm
from typing import NamedTuple
from openpilot.tools.lib.logreader import LogReader
from openpilot.selfdrive.locationd.models.pose_kf import EARTH_G
@ -20,14 +21,15 @@ class Event(NamedTuple):
timestamp: float # relative to start of route (s)
def find_events(lr: LogReader, qlog: bool = False) -> list[Event]:
def find_events(lr: LogReader, extrapolate: bool = False, qlog: bool = False) -> list[Event]:
min_lat_active = RLOG_MIN_LAT_ACTIVE // QLOG_DECIMATION if qlog else RLOG_MIN_LAT_ACTIVE
min_steering_unpressed = RLOG_MIN_STEERING_UNPRESSED // QLOG_DECIMATION if qlog else RLOG_MIN_STEERING_UNPRESSED
min_requesting_max = RLOG_MIN_REQUESTING_MAX // QLOG_DECIMATION if qlog else RLOG_MIN_REQUESTING_MAX
events = []
# if we test with driver torque safety, max torque can be slightly noisy
steer_threshold = 0.7 if extrapolate else 0.95
start_ts = 0
events = []
# state tracking
steering_unpressed = 0 # frames
@ -38,7 +40,9 @@ def find_events(lr: LogReader, qlog: bool = False) -> list[Event]:
curvature = 0
v_ego = 0
roll = 0
out_torque = 0
start_ts = 0
for msg in lr:
if msg.which() == 'carControl':
if start_ts == 0:
@ -47,8 +51,8 @@ def find_events(lr: LogReader, qlog: bool = False) -> list[Event]:
lat_active = lat_active + 1 if msg.carControl.latActive else 0
elif msg.which() == 'carOutput':
# if we test with driver torque safety, max torque can be slightly noisy
requesting_max = requesting_max + 1 if abs(msg.carOutput.actuatorsOutput.torque) > 0.95 else 0
out_torque = msg.carOutput.actuatorsOutput.torque
requesting_max = requesting_max + 1 if abs(out_torque) > steer_threshold else 0
elif msg.which() == 'carState':
steering_unpressed = steering_unpressed + 1 if not msg.carState.steeringPressed else 0
@ -64,7 +68,8 @@ def find_events(lr: LogReader, qlog: bool = False) -> list[Event]:
# TODO: record max lat accel at the end of the event, need to use the past lat accel as overriding can happen before we detect it
requesting_max = 0
current_lateral_accel = curvature * v_ego ** 2 - roll * EARTH_G
factor = 1 / abs(out_torque)
current_lateral_accel = (curvature * v_ego ** 2 * factor) - roll * EARTH_G
events.append(Event(current_lateral_accel, v_ego, roll, round((msg.logMonoTime - start_ts) * 1e-9, 2)))
print(events[-1])
@ -75,29 +80,38 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Find max lateral acceleration events",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("route")
parser.add_argument("route", nargs='+')
parser.add_argument("-e", "--extrapolate", action="store_true", help="Extrapolates max lateral acceleration events linearly. " +
"This option can be far less accurate.")
args = parser.parse_args()
lr = LogReader(args.route, sort_by_time=True)
qlog = args.route.endswith('/q')
if qlog:
print('WARNING: Treating route as qlog!')
events = []
for route in tqdm(args.route):
try:
lr = LogReader(route, sort_by_time=True)
except Exception:
print(f'Skipping {route}')
continue
qlog = route.endswith('/q')
if qlog:
print('WARNING: Treating route as qlog!')
print('Finding events...')
events = find_events(lr, qlog=qlog)
print('Finding events...')
events += find_events(lr, extrapolate=args.extrapolate, qlog=qlog)
print()
print(f'Found {len(events)} events')
perc_left_accel = -np.percentile([-ev.lateral_accel for ev in events if ev.lateral_accel < 0], 90)
perc_right_accel = np.percentile([ev.lateral_accel for ev in events if ev.lateral_accel > 0], 90)
perc_left_accel = -np.percentile([-ev.lateral_accel for ev in events if ev.lateral_accel < 0] or [0], 90)
perc_right_accel = np.percentile([ev.lateral_accel for ev in events if ev.lateral_accel > 0] or [0], 90)
CP = lr.first('carParams')
plt.ion()
plt.clf()
plt.suptitle(f'{CP.carFingerprint} - Max lateral acceleration events')
plt.title(args.route)
plt.title(', '.join(args.route))
plt.scatter([ev.speed for ev in events], [ev.lateral_accel for ev in events], label='max lateral accel events')
plt.plot([0, 35], [3, 3], c='r', label='ISO 11270 - 3 m/s^2')

@ -32,7 +32,7 @@ MIN_BUCKET_POINTS = np.array([100, 300, 500, 500, 500, 500, 300, 100])
MIN_ENGAGE_BUFFER = 2 # secs
VERSION = 1 # bump this to invalidate old parameter caches
ALLOWED_CARS = ['toyota', 'hyundai']
ALLOWED_CARS = ['toyota', 'hyundai', 'rivian']
def slope2rot(slope):

@ -270,11 +270,12 @@ class SelfdriveD:
if not REPLAY and self.rk.lagging:
self.events.add(EventName.selfdrivedLagging)
if not self.sm.valid['radarState']:
if self.sm['radarState'].radarErrors.radarUnavailableTemporary:
if self.sm['radarState'].radarErrors.canError:
self.events.add(EventName.canError)
elif self.sm['radarState'].radarErrors.radarUnavailableTemporary:
self.events.add(EventName.radarTempUnavailable)
else:
self.events.add(EventName.radarFault)
self.events.add(EventName.radarFault)
if not self.sm.valid['pandaStates']:
self.events.add(EventName.usbError)
if CS.canTimeout:

@ -276,7 +276,7 @@ def migrate_pandaStates(msgs):
"KIA_EV6": HyundaiSafetyFlags.EV_GAS | HyundaiSafetyFlags.CANFD_LKA_STEERING,
}
# TODO: get new Ford route
safety_param_migration |= {car: FordSafetyFlags.LONG_CONTROL for car in (set(FORD) - FORD.with_flags(FordFlags.CANFD))}
safety_param_migration |= dict.fromkeys((set(FORD) - FORD.with_flags(FordFlags.CANFD)), FordSafetyFlags.LONG_CONTROL)
# Migrate safety param base on carParams
CP = next((m.carParams for _, m in msgs if m.which() == 'carParams'), None)

@ -342,7 +342,7 @@ def card_fingerprint_callback(rc, pm, msgs, fingerprint):
def get_car_params_callback(rc, pm, msgs, fingerprint):
params = Params()
if fingerprint:
CarInterface, _, _, _ = interfaces[fingerprint]
CarInterface = interfaces[fingerprint]
CP = CarInterface.get_non_essential_params(fingerprint)
else:
can = DummySocket()

@ -1 +1 @@
e9d57157494480637a8ffb52257d2b660a48be67
359b08b1a914d61697e10bbcac22d96dc90699fa

@ -187,7 +187,7 @@ class TestOnroad:
def test_manager_starting_time(self):
st = self.ts['managerState']['t'][0]
assert (st - self.manager_st) < 10, f"manager.py took {st - self.manager_st}s to publish the first 'managerState' msg"
assert (st - self.manager_st) < 12.5, f"manager.py took {st - self.manager_st}s to publish the first 'managerState' msg"
def test_cloudlog_size(self):
msgs = self.msgs['logMessage']

@ -106,7 +106,7 @@ void FirehosePanel::refresh() {
toggle_label->setText(tr("ACTIVE"));
toggle_label->setStyleSheet("font-size: 60px; font-weight: bold; color: #2ecc71;");
} else {
toggle_label->setText(tr("<span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network"));
toggle_label->setText(tr("<span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to an unmetered network"));
toggle_label->setStyleSheet("font-size: 60px;");
}
}

@ -327,10 +327,6 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
<source>ACTIVE</source>
<translation>نشط</translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to unmetered network</source>
<translation>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;غير نشط&lt;/span&gt;: اتصل بشبكة غير محسوبة</translation>
</message>
<message>
<source>For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.&lt;br&gt;&lt;br&gt;Firehose Mode can also work while you&apos;re driving if connected to a hotspot or unlimited SIM card.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Frequently Asked Questions&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter how or where I drive?&lt;/i&gt; Nope, just drive as you normally would.&lt;br&gt;&lt;br&gt;&lt;i&gt;Do all of my segments get pulled in Firehose Mode?&lt;/i&gt; No, we selectively pull a subset of your segments.&lt;br&gt;&lt;br&gt;&lt;i&gt;What&apos;s a good USB-C adapter?&lt;/i&gt; Any fast phone or laptop charger should be fine.&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter which software I run?&lt;/i&gt; Yes, only upstream openpilot (and particular forks) are able to be used for training.</source>
<translation>للحصول على أقصى فعالية، أحضر جهازك إلى الداخل واتصل بمحول USB-C جيد وشبكة Wi-Fi أسبوعياً.&lt;br&gt;&lt;br&gt;يمكن أن يعمل وضع خرطوم الحريق أيضاً أثناء القيادة إذا كنت متصلاً بنقطة اتصال أو ببطاقة SIM غير محدودة.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;الأسئلة المتكررة&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;هل يهم كيف أو أين أقود؟&lt;/i&gt; لا، فقط قد كما تفعل عادة.&lt;br&gt;&lt;br&gt;&lt;i&gt;هل يتم سحب كل مقاطع رحلاتي في وضع خرطوم الحريق؟&lt;/i&gt; لا، نقوم بسحب مجموعة مختارة من مقاطع رحلاتك.&lt;br&gt;&lt;br&gt;&lt;i&gt;ما هو محول USB-C الجيد؟&lt;/i&gt; أي شاحن سريع للهاتف أو اللابتوب يجب أن يكون مناسباً.&lt;br&gt;&lt;br&gt;&lt;i&gt;هل يهم أي برنامج أستخدم؟&lt;/i&gt; نعم، فقط النسخة الأصلية من openpilot (وأفرع معينة) يمكن استخدامها للتدريب.</translation>
@ -346,6 +342,10 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
<numerusform>حتى الآن، يوجد &lt;/b&gt;%n مقطع&lt;b&gt;%n من قيادتك في مجموعة بيانات التدريب.</numerusform>
</translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to an unmetered network</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>HudRenderer</name>

@ -325,10 +325,6 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
<source>ACTIVE</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to unmetered network</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.&lt;br&gt;&lt;br&gt;Firehose Mode can also work while you&apos;re driving if connected to a hotspot or unlimited SIM card.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Frequently Asked Questions&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter how or where I drive?&lt;/i&gt; Nope, just drive as you normally would.&lt;br&gt;&lt;br&gt;&lt;i&gt;Do all of my segments get pulled in Firehose Mode?&lt;/i&gt; No, we selectively pull a subset of your segments.&lt;br&gt;&lt;br&gt;&lt;i&gt;What&apos;s a good USB-C adapter?&lt;/i&gt; Any fast phone or laptop charger should be fine.&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter which software I run?&lt;/i&gt; Yes, only upstream openpilot (and particular forks) are able to be used for training.</source>
<translation type="unfinished"></translation>
@ -340,6 +336,10 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
<numerusform></numerusform>
</translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to an unmetered network</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>HudRenderer</name>

@ -325,10 +325,6 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
<source>ACTIVE</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to unmetered network</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.&lt;br&gt;&lt;br&gt;Firehose Mode can also work while you&apos;re driving if connected to a hotspot or unlimited SIM card.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Frequently Asked Questions&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter how or where I drive?&lt;/i&gt; Nope, just drive as you normally would.&lt;br&gt;&lt;br&gt;&lt;i&gt;Do all of my segments get pulled in Firehose Mode?&lt;/i&gt; No, we selectively pull a subset of your segments.&lt;br&gt;&lt;br&gt;&lt;i&gt;What&apos;s a good USB-C adapter?&lt;/i&gt; Any fast phone or laptop charger should be fine.&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter which software I run?&lt;/i&gt; Yes, only upstream openpilot (and particular forks) are able to be used for training.</source>
<translation type="unfinished"></translation>
@ -340,6 +336,10 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
<numerusform></numerusform>
</translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to an unmetered network</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>HudRenderer</name>

@ -325,10 +325,6 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
<source>ACTIVE</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to unmetered network</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.&lt;br&gt;&lt;br&gt;Firehose Mode can also work while you&apos;re driving if connected to a hotspot or unlimited SIM card.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Frequently Asked Questions&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter how or where I drive?&lt;/i&gt; Nope, just drive as you normally would.&lt;br&gt;&lt;br&gt;&lt;i&gt;Do all of my segments get pulled in Firehose Mode?&lt;/i&gt; No, we selectively pull a subset of your segments.&lt;br&gt;&lt;br&gt;&lt;i&gt;What&apos;s a good USB-C adapter?&lt;/i&gt; Any fast phone or laptop charger should be fine.&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter which software I run?&lt;/i&gt; Yes, only upstream openpilot (and particular forks) are able to be used for training.</source>
<translation type="unfinished"></translation>
@ -340,6 +336,10 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
<numerusform></numerusform>
</translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to an unmetered network</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>HudRenderer</name>

@ -315,30 +315,32 @@
<source>openpilot learns to drive by watching humans, like you, drive.
Firehose Mode allows you to maximize your training data uploads to improve openpilot&apos;s driving models. More data means bigger models, which means better Experimental Mode.</source>
<translation type="unfinished"></translation>
<translation>openpilotは人間であるあなたの運転から学びAI学習します
Firehoseモードを有効にするとopenpilotの運転モデルを向上させることができますExperimentalモードの精度を向上させます</translation>
</message>
<message>
<source>Firehose Mode: ACTIVE</source>
<translation type="unfinished"></translation>
<translation>Firehoseモード: 作動中</translation>
</message>
<message>
<source>ACTIVE</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to unmetered network</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.&lt;br&gt;&lt;br&gt;Firehose Mode can also work while you&apos;re driving if connected to a hotspot or unlimited SIM card.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Frequently Asked Questions&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter how or where I drive?&lt;/i&gt; Nope, just drive as you normally would.&lt;br&gt;&lt;br&gt;&lt;i&gt;Do all of my segments get pulled in Firehose Mode?&lt;/i&gt; No, we selectively pull a subset of your segments.&lt;br&gt;&lt;br&gt;&lt;i&gt;What&apos;s a good USB-C adapter?&lt;/i&gt; Any fast phone or laptop charger should be fine.&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter which software I run?&lt;/i&gt; Yes, only upstream openpilot (and particular forks) are able to be used for training.</source>
<translation type="unfinished"></translation>
<translation>USB-C充電器とWi-Fiに毎週接続してください&lt;br&gt;&lt;br&gt;Firehoseモードは公衆無線LANや大容量契約のSIMカードに接続していれば&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;(FAQ)&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;運転のやり方や走る場所は重要ですか?&lt;/i&gt; &lt;br&gt;&lt;br&gt;&lt;i&gt;Firehoseモードでは全てのデータがアップロードされますか&lt;/i&gt; いいえ、アップロードするデータを選ぶことができます。&lt;br&gt;&lt;br&gt;&lt;i&gt;大容量のUSB-C充電器とは何ですか?&lt;/i&gt; 使&lt;br&gt;&lt;br&gt;&lt;i&gt;使&lt;/i&gt;openpilot()使</translation>
</message>
<message numerus="yes">
<source>&lt;b&gt;%n segment(s)&lt;/b&gt; of your driving is in the training dataset so far.</source>
<translation type="unfinished">
<numerusform></numerusform>
<translation>
<numerusform>&lt;b&gt;%nセグメント&lt;/b&gt;</numerusform>
</translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to an unmetered network</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>HudRenderer</name>
@ -945,7 +947,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>Warning: This grants SSH access to all public keys in your GitHub settings. Never enter a GitHub username other than your own. A comma employee will NEVER ask you to add their GitHub username.</source>
<translation>警告: これはGitHub SSH GitHub commaのスタッフが GitHub </translation>
<translation>警告: これはGitHubの設定にあるすべての公開鍵への SSH GitHubユーザー名を入力しないでくださいcommaのスタッフがGitHubのユーザー名を追加するようお願いすることはありません</translation>
</message>
<message>
<source>ADD</source>
@ -953,7 +955,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>Enter your GitHub username</source>
<translation>GitHub </translation>
<translation>GitHubのユーザー名を入力してください</translation>
</message>
<message>
<source>LOADING</source>
@ -995,18 +997,18 @@ This may take up to a minute.</source>
</message>
<message>
<source>Welcome to openpilot</source>
<translation type="unfinished"></translation>
<translation>openpilotへようこそ</translation>
</message>
<message>
<source>You must accept the Terms and Conditions to use openpilot. Read the latest terms at &lt;span style=&apos;color: #465BEA;&apos;&gt;https://comma.ai/terms&lt;/span&gt; before continuing.</source>
<translation type="unfinished"></translation>
<translation>openpilotを使用するには利用規約に同意する必要があります: &lt;span style=&apos;color: #465BEA;&apos;&gt;https://comma.ai/terms&lt;/span&gt;</translation>
</message>
</context>
<context>
<name>TogglesPanel</name>
<message>
<source>Enable openpilot</source>
<translation>openpilot </translation>
<translation>openpilotを有効化</translation>
</message>
<message>
<source>Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off.</source>
@ -1014,7 +1016,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>Enable Lane Departure Warnings</source>
<translation></translation>
<translation></translation>
</message>
<message>
<source>Receive alerts to steer back into the lane when your vehicle drifts over a detected lane line without a turn signal activated while driving over 31 mph (50 km/h).</source>

@ -102,7 +102,7 @@
<name>DeclinePage</name>
<message>
<source>You must accept the Terms and Conditions in order to use openpilot.</source>
<translation>openpilot .</translation>
<translation> .</translation>
</message>
<message>
<source>Back</source>
@ -121,19 +121,19 @@
</message>
<message>
<source>Longitudinal Maneuver Mode</source>
<translation> </translation>
<translation> </translation>
</message>
<message>
<source>openpilot Longitudinal Control (Alpha)</source>
<translation>openpilot ()</translation>
<translation> ()</translation>
</message>
<message>
<source>WARNING: openpilot longitudinal control is in alpha for this car and will disable Automatic Emergency Braking (AEB).</source>
<translation>경고: openpilot (AEB) .</translation>
<translation>경고: 오픈파일럿 (AEB) .</translation>
</message>
<message>
<source>On this car, openpilot defaults to the car&apos;s built-in ACC instead of openpilot&apos;s longitudinal control. Enable this to switch to openpilot longitudinal control. Enabling Experimental mode is recommended when enabling openpilot longitudinal control alpha.</source>
<translation> openpilot은 openpilot ACC로 . openpilot . openpilot .</translation>
<translation> ACC로 . . .</translation>
</message>
<message>
<source>Enable ADB</source>
@ -192,7 +192,7 @@
</message>
<message>
<source>Review the rules, features, and limitations of openpilot</source>
<translation>openpilot , </translation>
<translation> , </translation>
</message>
<message>
<source>Are you sure you want to review the training guide?</source>
@ -228,7 +228,7 @@
</message>
<message>
<source>openpilot requires the device to be mounted within 4° left or right and within 5° up or 9° down. openpilot is continuously calibrating, resetting is rarely required.</source>
<translation>openpilot 4°, 5°, 9° . openpilot .</translation>
<translation> 4°, 5°, 9° . .</translation>
</message>
<message>
<source> Your device is pointed %1° %2 and %3° %4.</source>
@ -317,7 +317,7 @@
Firehose Mode allows you to maximize your training data uploads to improve openpilot&apos;s driving models. More data means bigger models, which means better Experimental Mode.</source>
<translation> .
. , .</translation>
. , .</translation>
</message>
<message>
<source>Firehose Mode: ACTIVE</source>
@ -325,22 +325,22 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
</message>
<message>
<source>ACTIVE</source>
<translation></translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to unmetered network</source>
<translation>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;&lt;/span&gt;: </translation>
<translation> </translation>
</message>
<message>
<source>For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.&lt;br&gt;&lt;br&gt;Firehose Mode can also work while you&apos;re driving if connected to a hotspot or unlimited SIM card.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Frequently Asked Questions&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter how or where I drive?&lt;/i&gt; Nope, just drive as you normally would.&lt;br&gt;&lt;br&gt;&lt;i&gt;Do all of my segments get pulled in Firehose Mode?&lt;/i&gt; No, we selectively pull a subset of your segments.&lt;br&gt;&lt;br&gt;&lt;i&gt;What&apos;s a good USB-C adapter?&lt;/i&gt; Any fast phone or laptop charger should be fine.&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter which software I run?&lt;/i&gt; Yes, only upstream openpilot (and particular forks) are able to be used for training.</source>
<translation> USB-C Wi-Fi에 .&lt;br&gt;&lt;br&gt; SIM .&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt; &lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;운전 방법이나 장소가 중요한가요?&lt;/i&gt; , .&lt;br&gt;&lt;br&gt;&lt;i&gt; ?.&lt;br&gt;&lt;br&gt;&lt;i&gt; , .&lt;br&gt;&lt;br&gt;&lt;i&gt; USB-C ?&lt;/i&gt; 휴대폰이나 노트북 고속 충전기가 있으면 됩니다.&lt;br&gt;&lt;br&gt;&lt;i&gt;어떤 소프트웨어를 실행하는지가 중요한가요?&lt;/i&gt; , openpilot .</translation>
<translation> USB-C Wi-Fi에 .&lt;br&gt;&lt;br&gt; .&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt; &lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;운전 방법이나 장소가 중요한가요?&lt;/i&gt; , .&lt;br&gt;&lt;br&gt;&lt;i&gt; ?&lt;br&gt;&lt;br&gt;&lt;i&gt; , .&lt;br&gt;&lt;br&gt;&lt;i&gt; USB-C ?&lt;/i&gt; 휴대폰이나 노트북충전이 가능한 고속 충전기이면 괜찮습니다.&lt;br&gt;&lt;br&gt;&lt;i&gt;어떤 소프트웨어를 실행하는지가 중요한가요?&lt;/i&gt; , .</translation>
</message>
<message numerus="yes">
<source>&lt;b&gt;%n segment(s)&lt;/b&gt; of your driving is in the training dataset so far.</source>
<translation type="unfinished">
<numerusform></numerusform>
<translation>
<numerusform>&lt;b&gt;%n &lt;/b&gt; .</numerusform>
</translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to an unmetered network</source>
<translation>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt; &lt;/span&gt;: </translation>
</message>
</context>
<context>
<name>HudRenderer</name>
@ -411,11 +411,11 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
<name>OffroadAlert</name>
<message>
<source>Immediately connect to the internet to check for updates. If you do not connect to the internet, openpilot won&apos;t engage in %1</source>
<translation> . %1 openpilot .</translation>
<translation> . %1 .</translation>
</message>
<message>
<source>Connect to internet to check for updates. openpilot won&apos;t automatically start until it connects to internet to check for updates.</source>
<translation> . openpilot은 .</translation>
<translation> . .</translation>
</message>
<message>
<source>Unable to download updates
@ -445,15 +445,15 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
</message>
<message>
<source>openpilot was unable to identify your car. Your car is either unsupported or its ECUs are not recognized. Please submit a pull request to add the firmware versions to the proper vehicle. Need help? Join discord.comma.ai.</source>
<translation>openpilot . ECU가 . PR을 . discord.comma.ai에 .</translation>
<translation> . ECU가 . PR을 . discord.comma.ai에 .</translation>
</message>
<message>
<source>openpilot detected a change in the device&apos;s mounting position. Ensure the device is fully seated in the mount and the mount is firmly secured to the windshield.</source>
<translation>openpilot . . </translation>
<translation> . . </translation>
</message>
<message>
<source>Device temperature too high. System cooling down before starting. Current internal component temperature: %1</source>
<translation> . . : %1</translation>
<translation> . . : %1</translation>
</message>
</context>
<context>
@ -536,7 +536,7 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
</message>
<message>
<source>Become a comma prime member at connect.comma.ai</source>
<translation>connect.comma.ai에 comma prime </translation>
<translation>connect.comma.ai에 comma prime </translation>
</message>
<message>
<source>PRIME FEATURES:</source>
@ -552,7 +552,7 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
</message>
<message>
<source>1 year of drive storage</source>
<translation>1 </translation>
<translation>1 </translation>
</message>
<message>
<source>Remote snapshots</source>
@ -582,7 +582,7 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
</message>
<message>
<source>openpilot</source>
<translation>openpilot</translation>
<translation></translation>
</message>
<message numerus="yes">
<source>%n minute(s) ago</source>
@ -767,7 +767,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>openpilot</source>
<translation>openpilot</translation>
<translation></translation>
</message>
<message>
<source>Custom Software</source>
@ -997,7 +997,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>Welcome to openpilot</source>
<translation> .</translation>
<translation> .</translation>
</message>
<message>
<source>You must accept the Terms and Conditions to use openpilot. Read the latest terms at &lt;span style=&apos;color: #465BEA;&apos;&gt;https://comma.ai/terms&lt;/span&gt; before continuing.</source>
@ -1008,11 +1008,11 @@ This may take up to a minute.</source>
<name>TogglesPanel</name>
<message>
<source>Enable openpilot</source>
<translation>openpilot </translation>
<translation> </translation>
</message>
<message>
<source>Use the openpilot system for adaptive cruise control and lane keep driver assistance. Your attention is required at all times to use this feature. Changing this setting takes effect when the car is powered off.</source>
<translation> openpilot . . .</translation>
<translation> . . .</translation>
</message>
<message>
<source>Enable Lane Departure Warnings</source>
@ -1044,7 +1044,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>When enabled, pressing the accelerator pedal will disengage openpilot.</source>
<translation> openpilot .</translation>
<translation> .</translation>
</message>
<message>
<source>Experimental Mode</source>
@ -1052,11 +1052,11 @@ This may take up to a minute.</source>
</message>
<message>
<source>openpilot defaults to driving in &lt;b&gt;chill mode&lt;/b&gt;. Experimental mode enables &lt;b&gt;alpha-level features&lt;/b&gt; that aren&apos;t ready for chill mode. Experimental features are listed below:</source>
<translation>openpilot &lt;b&gt; &lt;/b&gt; . &lt;b&gt; &lt;/b&gt; . :</translation>
<translation> &lt;b&gt; &lt;/b&gt; . &lt;b&gt; &lt;/b&gt; . :</translation>
</message>
<message>
<source>Let the driving model control the gas and brakes. openpilot will drive as it thinks a human would, including stopping for red lights and stop signs. Since the driving model decides the speed to drive, the set speed will only act as an upper bound. This is an alpha quality feature; mistakes should be expected.</source>
<translation>openpilot의 . openpilot은 . . .</translation>
<translation> . . .</translation>
</message>
<message>
<source>New Driving Visualization</source>
@ -1064,11 +1064,11 @@ This may take up to a minute.</source>
</message>
<message>
<source>Experimental mode is currently unavailable on this car since the car&apos;s stock ACC is used for longitudinal control.</source>
<translation> ACC로 .</translation>
<translation> ACC가 , .</translation>
</message>
<message>
<source>openpilot longitudinal control may come in a future update.</source>
<translation>openpilot .</translation>
<translation> .</translation>
</message>
<message>
<source>Aggressive</source>
@ -1088,11 +1088,11 @@ This may take up to a minute.</source>
</message>
<message>
<source>An alpha version of openpilot longitudinal control can be tested, along with Experimental mode, on non-release branches.</source>
<translation>openpilot .</translation>
<translation> .</translation>
</message>
<message>
<source>Enable the openpilot longitudinal control (alpha) toggle to allow Experimental mode.</source>
<translation> openpilot E2E () .</translation>
<translation> E2E () .</translation>
</message>
<message>
<source>End-to-End Longitudinal Control</source>
@ -1100,7 +1100,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>Standard is recommended. In aggressive mode, openpilot will follow lead cars closer and be more aggressive with the gas and brake. In relaxed mode openpilot will stay further away from lead cars. On supported cars, you can cycle through these personalities with your steering wheel distance button.</source>
<translation> . openpilot . openpilot . .</translation>
<translation> . . . .</translation>
</message>
<message>
<source>The driving visualization will transition to the road-facing wide-angle camera at low speeds to better show some turns. The Experimental mode logo will also be shown in the top right corner.</source>
@ -1112,7 +1112,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>Enable driver monitoring even when openpilot is not engaged.</source>
<translation>openpilot .</translation>
<translation> .</translation>
</message>
</context>
<context>
@ -1158,7 +1158,7 @@ This may take up to a minute.</source>
</message>
<message>
<source>Maximize your training data uploads to improve openpilot&apos;s driving models.</source>
<translation> .</translation>
<translation> .</translation>
</message>
<message>
<source>&lt;span style=&apos;font-family: &quot;Noto Color Emoji&quot;;&apos;&gt;🔥&lt;/span&gt; Firehose Mode &lt;span style=&apos;font-family: Noto Color Emoji;&apos;&gt;🔥&lt;/span&gt;</source>

@ -327,10 +327,6 @@ O Modo Firehose permite maximizar o envio de dados de treinamento para melhorar
<source>ACTIVE</source>
<translation>ATIVO</translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to unmetered network</source>
<translation>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INATIVO&lt;/span&gt;: conecte-se a uma rede sem restrição &lt;br&gt; de dados</translation>
</message>
<message>
<source>For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.&lt;br&gt;&lt;br&gt;Firehose Mode can also work while you&apos;re driving if connected to a hotspot or unlimited SIM card.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Frequently Asked Questions&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter how or where I drive?&lt;/i&gt; Nope, just drive as you normally would.&lt;br&gt;&lt;br&gt;&lt;i&gt;Do all of my segments get pulled in Firehose Mode?&lt;/i&gt; No, we selectively pull a subset of your segments.&lt;br&gt;&lt;br&gt;&lt;i&gt;What&apos;s a good USB-C adapter?&lt;/i&gt; Any fast phone or laptop charger should be fine.&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter which software I run?&lt;/i&gt; Yes, only upstream openpilot (and particular forks) are able to be used for training.</source>
<translation>Para maior eficácia, leve seu dispositivo para dentro de casa e conecte-o a um bom adaptador USB-C e Wi-Fi semanalmente.&lt;br&gt;&lt;br&gt;O Modo Firehose também pode funcionar enquanto você dirige, se estiver conectado a um hotspot ou a um chip SIM com dados ilimitados.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Perguntas Frequentes&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Importa como ou onde eu dirijo?&lt;/i&gt; Não, basta dirigir normalmente.&lt;br&gt;&lt;br&gt;&lt;i&gt;Todos os meus segmentos são enviados no Modo Firehose?&lt;/i&gt; Não, selecionamos apenas um subconjunto dos seus segmentos.&lt;br&gt;&lt;br&gt;&lt;i&gt;Qual é um bom adaptador USB-C?&lt;/i&gt; Qualquer carregador rápido de telefone ou laptop deve ser suficiente.&lt;br&gt;&lt;br&gt;&lt;i&gt;Importa qual software eu uso?&lt;/i&gt; Sim, apenas o openpilot oficial (e alguns forks específicos) podem ser usados para treinamento.</translation>
@ -342,6 +338,10 @@ O Modo Firehose permite maximizar o envio de dados de treinamento para melhorar
<numerusform>&lt;b&gt;%n segmentos&lt;/b&gt; da sua direção estão no conjunto de dados de treinamento até agora.</numerusform>
</translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to an unmetered network</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>HudRenderer</name>

@ -325,10 +325,6 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
<source>ACTIVE</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to unmetered network</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.&lt;br&gt;&lt;br&gt;Firehose Mode can also work while you&apos;re driving if connected to a hotspot or unlimited SIM card.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Frequently Asked Questions&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter how or where I drive?&lt;/i&gt; Nope, just drive as you normally would.&lt;br&gt;&lt;br&gt;&lt;i&gt;Do all of my segments get pulled in Firehose Mode?&lt;/i&gt; No, we selectively pull a subset of your segments.&lt;br&gt;&lt;br&gt;&lt;i&gt;What&apos;s a good USB-C adapter?&lt;/i&gt; Any fast phone or laptop charger should be fine.&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter which software I run?&lt;/i&gt; Yes, only upstream openpilot (and particular forks) are able to be used for training.</source>
<translation type="unfinished"></translation>
@ -339,6 +335,10 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
<numerusform></numerusform>
</translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to an unmetered network</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>HudRenderer</name>

@ -325,10 +325,6 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
<source>ACTIVE</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to unmetered network</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.&lt;br&gt;&lt;br&gt;Firehose Mode can also work while you&apos;re driving if connected to a hotspot or unlimited SIM card.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Frequently Asked Questions&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter how or where I drive?&lt;/i&gt; Nope, just drive as you normally would.&lt;br&gt;&lt;br&gt;&lt;i&gt;Do all of my segments get pulled in Firehose Mode?&lt;/i&gt; No, we selectively pull a subset of your segments.&lt;br&gt;&lt;br&gt;&lt;i&gt;What&apos;s a good USB-C adapter?&lt;/i&gt; Any fast phone or laptop charger should be fine.&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter which software I run?&lt;/i&gt; Yes, only upstream openpilot (and particular forks) are able to be used for training.</source>
<translation type="unfinished"></translation>
@ -339,6 +335,10 @@ Firehose Mode allows you to maximize your training data uploads to improve openp
<numerusform></numerusform>
</translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to an unmetered network</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>HudRenderer</name>

@ -315,30 +315,32 @@
<source>openpilot learns to drive by watching humans, like you, drive.
Firehose Mode allows you to maximize your training data uploads to improve openpilot&apos;s driving models. More data means bigger models, which means better Experimental Mode.</source>
<translation type="unfinished"></translation>
<translation>openpilot
openpilot </translation>
</message>
<message>
<source>Firehose Mode: ACTIVE</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>ACTIVE</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to unmetered network</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.&lt;br&gt;&lt;br&gt;Firehose Mode can also work while you&apos;re driving if connected to a hotspot or unlimited SIM card.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Frequently Asked Questions&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter how or where I drive?&lt;/i&gt; Nope, just drive as you normally would.&lt;br&gt;&lt;br&gt;&lt;i&gt;Do all of my segments get pulled in Firehose Mode?&lt;/i&gt; No, we selectively pull a subset of your segments.&lt;br&gt;&lt;br&gt;&lt;i&gt;What&apos;s a good USB-C adapter?&lt;/i&gt; Any fast phone or laptop charger should be fine.&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter which software I run?&lt;/i&gt; Yes, only upstream openpilot (and particular forks) are able to be used for training.</source>
<translation type="unfinished"></translation>
<translation> USB-C Wi-Fi&lt;br&gt;&lt;br&gt;Firehose 使 SIM &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;我开车的方式或地点有影响吗?&lt;/i&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Firehose &lt;/i&gt;不会,我们会选择性地上传部分片段。&lt;br&gt;&lt;br&gt;&lt;i&gt;什么是好的 USB-C 充电器?&lt;/i&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;使&lt;/i&gt; openpilot</translation>
</message>
<message numerus="yes">
<source>&lt;b&gt;%n segment(s)&lt;/b&gt; of your driving is in the training dataset so far.</source>
<translation type="unfinished">
<numerusform></numerusform>
<translation>
<numerusform>&lt;b&gt; %n &lt;/b&gt; </numerusform>
</translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to an unmetered network</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>HudRenderer</name>
@ -995,11 +997,11 @@ This may take up to a minute.</source>
</message>
<message>
<source>Welcome to openpilot</source>
<translation type="unfinished"></translation>
<translation>使 openpilot</translation>
</message>
<message>
<source>You must accept the Terms and Conditions to use openpilot. Read the latest terms at &lt;span style=&apos;color: #465BEA;&apos;&gt;https://comma.ai/terms&lt;/span&gt; before continuing.</source>
<translation type="unfinished"></translation>
<translation>使 openpilot&lt;span style=&apos;color: #465BEA;&apos;&gt;https://comma.ai/terms&lt;/span&gt;。</translation>
</message>
</context>
<context>

@ -315,30 +315,32 @@
<source>openpilot learns to drive by watching humans, like you, drive.
Firehose Mode allows you to maximize your training data uploads to improve openpilot&apos;s driving models. More data means bigger models, which means better Experimental Mode.</source>
<translation type="unfinished"></translation>
<translation>openpilot
openpilot </translation>
</message>
<message>
<source>Firehose Mode: ACTIVE</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>ACTIVE</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to unmetered network</source>
<translation type="unfinished"></translation>
<translation></translation>
</message>
<message>
<source>For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.&lt;br&gt;&lt;br&gt;Firehose Mode can also work while you&apos;re driving if connected to a hotspot or unlimited SIM card.&lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;Frequently Asked Questions&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter how or where I drive?&lt;/i&gt; Nope, just drive as you normally would.&lt;br&gt;&lt;br&gt;&lt;i&gt;Do all of my segments get pulled in Firehose Mode?&lt;/i&gt; No, we selectively pull a subset of your segments.&lt;br&gt;&lt;br&gt;&lt;i&gt;What&apos;s a good USB-C adapter?&lt;/i&gt; Any fast phone or laptop charger should be fine.&lt;br&gt;&lt;br&gt;&lt;i&gt;Does it matter which software I run?&lt;/i&gt; Yes, only upstream openpilot (and particular forks) are able to be used for training.</source>
<translation type="unfinished"></translation>
<translation> USB-C Wi-Fi&lt;br&gt;&lt;br&gt;使 SIM &lt;br&gt;&lt;br&gt;&lt;br&gt;&lt;b&gt;&lt;/b&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;我開車的方式或地點有影響嗎?&lt;/i&gt; &lt;br&gt;&lt;br&gt;&lt;i&gt;&lt;/i&gt;不會,我們會選擇性地上傳部分片段。&lt;br&gt;&lt;br&gt;&lt;i&gt;什麼是好的 USB-C 充電器?&lt;/i&gt;&lt;br&gt;&lt;br&gt;&lt;i&gt;使&lt;/i&gt; openpilot</translation>
</message>
<message numerus="yes">
<source>&lt;b&gt;%n segment(s)&lt;/b&gt; of your driving is in the training dataset so far.</source>
<translation type="unfinished">
<numerusform></numerusform>
<translation>
<numerusform>&lt;b&gt; %n &lt;/b&gt; </numerusform>
</translation>
</message>
<message>
<source>&lt;span stylesheet=&apos;font-size: 60px; font-weight: bold; color: #e74c3c;&apos;&gt;INACTIVE&lt;/span&gt;: connect to an unmetered network</source>
<translation type="unfinished"></translation>
</message>
</context>
<context>
<name>HudRenderer</name>
@ -995,11 +997,11 @@ This may take up to a minute.</source>
</message>
<message>
<source>Welcome to openpilot</source>
<translation type="unfinished"></translation>
<translation>使 openpilot</translation>
</message>
<message>
<source>You must accept the Terms and Conditions to use openpilot. Read the latest terms at &lt;span style=&apos;color: #465BEA;&apos;&gt;https://comma.ai/terms&lt;/span&gt; before continuing.</source>
<translation type="unfinished"></translation>
<translation>使 openpilot&lt;span style=&apos;color: #465BEA;&apos;&gt;https://comma.ai/terms&lt;/span&gt;。</translation>
</message>
</context>
<context>

@ -16,7 +16,7 @@ import threading
import time
from dataclasses import asdict, dataclass, replace
from datetime import datetime
from functools import partial
from functools import partial, total_ordering
from queue import Queue
from typing import cast
from collections.abc import Callable
@ -53,6 +53,7 @@ MAX_RETRY_COUNT = 30 # Try for at most 5 minutes if upload fails immediately
MAX_AGE = 31 * 24 * 3600 # seconds
WS_FRAME_SIZE = 4096
DEVICE_STATE_UPDATE_INTERVAL = 1.0 # in seconds
DEFAULT_UPLOAD_PRIORITY = 99 # higher number = lower priority
NetworkType = log.DeviceState.NetworkType
@ -68,13 +69,15 @@ class UploadFile:
url: str
headers: dict[str, str]
allow_cellular: bool
priority: int = DEFAULT_UPLOAD_PRIORITY
@classmethod
def from_dict(cls, d: dict) -> UploadFile:
return cls(d.get("fn", ""), d.get("url", ""), d.get("headers", {}), d.get("allow_cellular", False))
return cls(d.get("fn", ""), d.get("url", ""), d.get("headers", {}), d.get("allow_cellular", False), d.get("priority", DEFAULT_UPLOAD_PRIORITY))
@dataclass
@total_ordering
class UploadItem:
path: str
url: str
@ -85,17 +88,28 @@ class UploadItem:
current: bool = False
progress: float = 0
allow_cellular: bool = False
priority: int = DEFAULT_UPLOAD_PRIORITY
@classmethod
def from_dict(cls, d: dict) -> UploadItem:
return cls(d["path"], d["url"], d["headers"], d["created_at"], d["id"], d["retry_count"], d["current"],
d["progress"], d["allow_cellular"])
d["progress"], d["allow_cellular"], d["priority"])
def __lt__(self, other):
if not isinstance(other, UploadItem):
return NotImplemented
return self.priority < other.priority
def __eq__(self, other):
if not isinstance(other, UploadItem):
return NotImplemented
return self.priority == other.priority
dispatcher["echo"] = lambda s: s
recv_queue: Queue[str] = queue.Queue()
send_queue: Queue[str] = queue.Queue()
upload_queue: Queue[UploadItem] = queue.Queue()
upload_queue: Queue[UploadItem] = queue.PriorityQueue()
low_priority_send_queue: Queue[str] = queue.Queue()
log_recv_queue: Queue[str] = queue.Queue()
cancelled_uploads: set[str] = set()
@ -398,6 +412,7 @@ def uploadFilesToUrls(files_data: list[UploadFileDict]) -> UploadFilesToUrlRespo
created_at=int(time.time() * 1000),
id=None,
allow_cellular=file.allow_cellular,
priority=file.priority,
)
upload_id = hashlib.sha1(str(item).encode()).hexdigest()
item = replace(item, id=upload_id)

@ -76,7 +76,7 @@ class TestAthenadMethods:
self.params.put(k, v)
self.params.put_bool("GsmMetered", True)
athenad.upload_queue = queue.Queue()
athenad.upload_queue = queue.PriorityQueue()
athenad.cur_upload_items.clear()
athenad.cancelled_uploads.clear()
@ -321,6 +321,26 @@ class TestAthenadMethods:
assert len(items) == 1
assert items[0]['current']
def test_list_upload_queue_priority(self):
priorities = (25, 50, 99, 75, 0)
for i in priorities:
fn = f'qlog_{i}.zst'
fp = self._create_file(fn)
item = athenad.UploadItem(
path=fp,
url=f"http://localhost:44444/{fn}",
headers={},
created_at=int(time.time()*1000),
id='',
allow_cellular=True,
priority=i
)
athenad.upload_queue.put_nowait(item)
for i in sorted(priorities):
assert athenad.upload_queue.get_nowait().priority == i
def test_list_upload_queue(self):
item = athenad.UploadItem(path="qlog.zst", url="http://localhost:44444/qlog.zst", headers={},
created_at=int(time.time()*1000), id='id', allow_cellular=True)

@ -19,7 +19,6 @@
#include "system/camerad/cameras/ife.h"
#include "system/camerad/cameras/spectra.h"
#include "system/camerad/cameras/bps_blobs.h"
#include "third_party/linux/include/msm_media_info.h"
// ************** low level camera helpers ****************
@ -266,7 +265,7 @@ int SpectraCamera::clear_req_queue() {
req_mgr_flush_request.link_hdl = link_handle;
req_mgr_flush_request.flush_type = CAM_REQ_MGR_FLUSH_TYPE_ALL;
int ret = do_cam_control(m->video0_fd, CAM_REQ_MGR_FLUSH_REQ, &req_mgr_flush_request, sizeof(req_mgr_flush_request));
LOGD("flushed all req: %d", ret);
LOGD("flushed all req: %d", ret); // returns a "time until timeout" on clearing the workq
for (int i = 0; i < MAX_IFE_BUFS; ++i) {
destroySyncObjectAt(i);
@ -1418,11 +1417,13 @@ bool SpectraCamera::waitForFrameReady(uint64_t request_id) {
}
auto waitForSync = [&](uint32_t sync_obj, int timeout_ms, const char *sync_type) {
double st = millis_since_boot();
struct cam_sync_wait sync_wait = {};
sync_wait.sync_obj = sync_obj;
sync_wait.timeout_ms = stress_test(sync_type) ? 1 : timeout_ms;
bool ret = do_sync_control(m->cam_sync_fd, CAM_SYNC_WAIT, &sync_wait, sizeof(sync_wait)) == 0;
if (!ret) LOGE("camera %d %s failed", cc.camera_num, sync_type);
double et = millis_since_boot();
if (!ret) LOGE("camera %d %s failed after %.2fms", cc.camera_num, sync_type, et-st);
return ret;
};
@ -1434,6 +1435,7 @@ bool SpectraCamera::waitForFrameReady(uint64_t request_id) {
// BPS is typically 7ms
success = waitForSync(sync_objs_bps[buf_idx], 50, "BPS sync");
}
return success;
}

@ -366,35 +366,35 @@
},
{
"name": "userdata_90",
"url": "https://commadist.azureedge.net/agnosupdate/userdata_90-17f46ba0d0eec10cf14804c84d9bcf4f6fa864074f1b90ff2fb4873399d64b1a.img.xz",
"hash": "1442ae218daff960783bc493a32dd489fa787e4025c64fa3132f48b1e627647f",
"hash_raw": "17f46ba0d0eec10cf14804c84d9bcf4f6fa864074f1b90ff2fb4873399d64b1a",
"url": "https://commadist.azureedge.net/agnosupdate/userdata_90-0cbfcaba867b8c637a297492fe008aac82cea89a479077585faaa62c8bdc4bcf.img.xz",
"hash": "4a48581a9e2e416ae3b695d1fca7a056eeb8b12e7819fee16a3419ba56662ca1",
"hash_raw": "0cbfcaba867b8c637a297492fe008aac82cea89a479077585faaa62c8bdc4bcf",
"size": 96636764160,
"sparse": true,
"full_check": true,
"has_ab": false,
"ondevice_hash": "a64fea9c3a7bec11b850a55d50ceb30a032742c90aadf0ce35cdbef9349bebba"
"ondevice_hash": "51b690c08c7876d5f6f81c36cdfc64bd7e2326986329923b4eb391dbeb45ced1"
},
{
"name": "userdata_89",
"url": "https://commadist.azureedge.net/agnosupdate/userdata_89-69b2404839f87b1de5c05766550ca0217d5ed566c9f2ea41c46b5a301540a3ac.img.xz",
"hash": "332e6cf5c221690a01ebfd0582420e039c7796a8fb2d499e44a8b657dffe4af2",
"hash_raw": "69b2404839f87b1de5c05766550ca0217d5ed566c9f2ea41c46b5a301540a3ac",
"url": "https://commadist.azureedge.net/agnosupdate/userdata_89-5043e8058de94159e4b36590403120e76bdabe75542743bb41e251158aa14f7c.img.xz",
"hash": "7eca201ce9e6440b389a469eeffe635df50c81c18a7b6af9b73dfe462af7c174",
"hash_raw": "5043e8058de94159e4b36590403120e76bdabe75542743bb41e251158aa14f7c",
"size": 95563022336,
"sparse": true,
"full_check": true,
"has_ab": false,
"ondevice_hash": "c560c76007fd8997e01e516ab16ff445048945a13bf830bb2a4c7f6e9d2fe5f6"
"ondevice_hash": "2c25fb92c7c7085783b3ea1f96d3919acefafe3b4897529ced30540fdb7dc772"
},
{
"name": "userdata_30",
"url": "https://commadist.azureedge.net/agnosupdate/userdata_30-ffc34d8753520e684448185db801c05bb81e23c54a499cc40a2e38b7009cdf36.img.xz",
"hash": "8bfb1fdec9c8f96c97bcce1efbc7d502447bdb3b481cc408b24b5feef66839fd",
"hash_raw": "ffc34d8753520e684448185db801c05bb81e23c54a499cc40a2e38b7009cdf36",
"url": "https://commadist.azureedge.net/agnosupdate/userdata_30-cf9c15c127fb4e776843e7fce36e545b8c8848991186a7ff2cd0d5c2fffe2a1d.img.xz",
"hash": "c0866a0a8e4eedb9f0f1a4d853ace9c83038c955f88e8bfffbaf441dc103c1a6",
"hash_raw": "cf9c15c127fb4e776843e7fce36e545b8c8848991186a7ff2cd0d5c2fffe2a1d",
"size": 32212254720,
"sparse": true,
"full_check": true,
"has_ab": false,
"ondevice_hash": "8f840157d73fa4469aa650d668e046c9750304af84248ab83453cbd285918859"
"ondevice_hash": "78086497dd01efd87b491fe16a9abd382f14ec7366c8eb7acfe0ec0c5d192df6"
}
]
]

@ -221,8 +221,12 @@ class PythonProcess(ManagerProcess):
if self.proc is not None:
return
# TODO: this is just a workaround for this tinygrad check:
# https://github.com/tinygrad/tinygrad/blob/ac9c96dae1656dc220ee4acc39cef4dd449aa850/tinygrad/device.py#L26
name = self.name if "modeld" not in self.name else "MainProcess"
cloudlog.info(f"starting python {self.module}")
self.proc = Process(name=self.name, target=self.launcher, args=(self.module, self.name))
self.proc = Process(name=name, target=self.launcher, args=(self.module, self.name))
self.proc.start()
self.watchdog_seen = False
self.shutting_down = False

@ -75,10 +75,8 @@ procs = [
PythonProcess("micd", "system.micd", iscar),
PythonProcess("timed", "system.timed", always_run, enabled=not PC),
# TODO: Make python process once TG allows opening QCOM from child pro
# https://github.com/tinygrad/tinygrad/blob/ac9c96dae1656dc220ee4acc39cef4dd449aa850/tinygrad/device.py#L26
NativeProcess("modeld", "selfdrive/modeld", ["./modeld.py"], only_onroad),
NativeProcess("dmonitoringmodeld", "selfdrive/modeld", ["./dmonitoringmodeld.py"], driverview, enabled=(WEBCAM or not PC)),
PythonProcess("modeld", "selfdrive.modeld.modeld", only_onroad),
PythonProcess("dmonitoringmodeld", "selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(WEBCAM or not PC)),
NativeProcess("sensord", "system/sensord", ["./sensord"], only_onroad, enabled=not PC),
NativeProcess("ui", "selfdrive/ui", ["./ui"], always_run, watchdog_max_dt=(5 if not PC else None)),

@ -64,11 +64,16 @@ class GuiApplication:
return texture
def close(self):
if not rl.is_window_ready():
return
for texture in self._textures:
rl.unload_texture(texture)
self._textures = []
for font in self._fonts.values():
rl.unload_font(font)
self._fonts = []
rl.close_window()
@ -120,7 +125,6 @@ class GuiApplication:
rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.TEXT_SIZE, DEFAULT_TEXT_SIZE)
rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.BACKGROUND_COLOR, rl.color_to_int(rl.BLACK))
rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiControlProperty.TEXT_COLOR_NORMAL, rl.color_to_int(DEFAULT_TEXT_COLOR))
rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiDefaultProperty.BACKGROUND_COLOR, rl.color_to_int(rl.Color(30, 30, 30, 255)))
rl.gui_set_style(rl.GuiControl.DEFAULT, rl.GuiControlProperty.BASE_COLOR_NORMAL, rl.color_to_int(rl.Color(50, 50, 50, 255)))
def _monitor_fps(self):

@ -1,8 +1,7 @@
#!/usr/bin/env python3
import pyray as rl
import os
import select
import sys
import threading
from openpilot.common.basedir import BASEDIR
from openpilot.system.ui.lib.application import gui_app
@ -20,57 +19,57 @@ def clamp(value, min_value, max_value):
return max(min(value, max_value), min_value)
def check_input_non_blocking():
if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
return sys.stdin.readline().strip()
return ""
class Spinner:
def __init__(self):
self._comma_texture = gui_app.load_texture_from_image(os.path.join(BASEDIR, "selfdrive/assets/img_spinner_comma.png"), TEXTURE_SIZE, TEXTURE_SIZE)
self._spinner_texture = gui_app.load_texture_from_image(os.path.join(BASEDIR, "selfdrive/assets/img_spinner_track.png"), TEXTURE_SIZE, TEXTURE_SIZE)
self._rotation = 0.0
self._text: str = ""
self._lock = threading.Lock()
def set_text(self, text: str) -> None:
with self._lock:
self._text = text
def main():
gui_app.init_window("Spinner")
# Load textures
comma_texture = gui_app.load_texture_from_image(os.path.join(BASEDIR, "selfdrive/assets/img_spinner_comma.png"), TEXTURE_SIZE, TEXTURE_SIZE)
spinner_texture = gui_app.load_texture_from_image(os.path.join(BASEDIR, "selfdrive/assets/img_spinner_track.png"), TEXTURE_SIZE, TEXTURE_SIZE)
def render(self):
center = rl.Vector2(gui_app.width / 2.0, gui_app.height / 2.0)
spinner_origin = rl.Vector2(TEXTURE_SIZE / 2.0, TEXTURE_SIZE / 2.0)
comma_position = rl.Vector2(center.x - TEXTURE_SIZE / 2.0, center.y - TEXTURE_SIZE / 2.0)
# Initial values
rotation = 0.0
user_input = ""
center = rl.Vector2(gui_app.width / 2.0, gui_app.height / 2.0)
spinner_origin = rl.Vector2(TEXTURE_SIZE / 2.0, TEXTURE_SIZE / 2.0)
comma_position = rl.Vector2(center.x - TEXTURE_SIZE / 2.0, center.y - TEXTURE_SIZE / 2.0)
for _ in gui_app.render():
fps = rl.get_fps()
if fps > 0:
degrees_per_frame = 360.0 / (ROTATION_TIME_SECONDS * fps)
rotation = (rotation + degrees_per_frame) % 360.0
self._rotation = (self._rotation + degrees_per_frame) % 360.0
# Draw rotating spinner and static comma logo
rl.draw_texture_pro(spinner_texture, rl.Rectangle(0, 0, TEXTURE_SIZE, TEXTURE_SIZE),
rl.draw_texture_pro(self._spinner_texture, rl.Rectangle(0, 0, TEXTURE_SIZE, TEXTURE_SIZE),
rl.Rectangle(center.x, center.y, TEXTURE_SIZE, TEXTURE_SIZE),
spinner_origin, rotation, rl.WHITE)
rl.draw_texture_v(comma_texture, comma_position, rl.WHITE)
# Read user input
if input_str := check_input_non_blocking():
user_input = input_str
spinner_origin, self._rotation, rl.WHITE)
rl.draw_texture_v(self._comma_texture, comma_position, rl.WHITE)
# Display progress bar or text based on user input
if user_input:
text = None
with self._lock:
text = self._text
if text:
y_pos = rl.get_screen_height() - MARGIN - PROGRESS_BAR_HEIGHT
if user_input.isdigit():
progress = clamp(int(user_input), 0, 100)
if text.isdigit():
progress = clamp(int(text), 0, 100)
bar = rl.Rectangle(center.x - PROGRESS_BAR_WIDTH / 2.0, y_pos, PROGRESS_BAR_WIDTH, PROGRESS_BAR_HEIGHT)
rl.draw_rectangle_rounded(bar, 0.5, 10, rl.GRAY)
bar.width *= progress / 100.0
rl.draw_rectangle_rounded(bar, 0.5, 10, rl.WHITE)
else:
text_size = rl.measure_text_ex(gui_app.font(), user_input, FONT_SIZE, 1.0)
rl.draw_text_ex(gui_app.font(), user_input,
text_size = rl.measure_text_ex(gui_app.font(), text, FONT_SIZE, 1.0)
rl.draw_text_ex(gui_app.font(), text,
rl.Vector2(center.x - text_size.x / 2, y_pos), FONT_SIZE, 1.0, rl.WHITE)
if __name__ == "__main__":
main()
gui_app.init_window("Spinner")
spinner = Spinner()
spinner.set_text("Spinner text")
for _ in gui_app.render():
spinner.render()

@ -1,7 +1,5 @@
#!/usr/bin/env python3
import sys
import pyray as rl
from openpilot.system.hardware import HARDWARE
from openpilot.system.ui.lib.button import gui_button, ButtonStyle
from openpilot.system.ui.lib.scroll_panel import GuiScrollPanel
@ -33,32 +31,36 @@ def wrap_text(text, font_size, max_width):
return lines
class TextWindow:
def __init__(self, text: str):
self._textarea_rect = rl.Rectangle(MARGIN, MARGIN, gui_app.width - MARGIN * 2, gui_app.height - MARGIN * 2)
self._wrapped_lines = wrap_text(text, FONT_SIZE, self._textarea_rect.width - 20)
self._content_rect = rl.Rectangle(0, 0, self._textarea_rect.width - 20, len(self._wrapped_lines) * LINE_HEIGHT)
self._scroll_panel = GuiScrollPanel(show_vertical_scroll_bar=True)
def main():
gui_app.init_window("Text")
text_content = sys.argv[1] if len(sys.argv) > 1 else DEMO_TEXT
textarea_rect = rl.Rectangle(MARGIN, MARGIN, gui_app.width - MARGIN * 2, gui_app.height - MARGIN * 2)
wrapped_lines = wrap_text(text_content, FONT_SIZE, textarea_rect.width - 20)
content_rect = rl.Rectangle(0, 0, textarea_rect.width - 20, len(wrapped_lines) * LINE_HEIGHT)
scroll_panel = GuiScrollPanel(show_vertical_scroll_bar=True)
for _ in gui_app.render():
scroll = scroll_panel.handle_scroll(textarea_rect, content_rect)
rl.begin_scissor_mode(int(textarea_rect.x), int(textarea_rect.y), int(textarea_rect.width), int(textarea_rect.height))
for i, line in enumerate(wrapped_lines):
position = rl.Vector2(textarea_rect.x + scroll.x, textarea_rect.y + scroll.y + i * LINE_HEIGHT)
if position.y + LINE_HEIGHT < textarea_rect.y or position.y > textarea_rect.y + textarea_rect.height:
def render(self):
scroll = self._scroll_panel.handle_scroll(self._textarea_rect, self._content_rect)
rl.begin_scissor_mode(int(self._textarea_rect.x), int(self._textarea_rect.y), int(self._textarea_rect.width), int(self._textarea_rect.height))
for i, line in enumerate(self._wrapped_lines):
position = rl.Vector2(self._textarea_rect.x + scroll.x, self._textarea_rect.y + scroll.y + i * LINE_HEIGHT)
if position.y + LINE_HEIGHT < self._textarea_rect.y or position.y > self._textarea_rect.y + self._textarea_rect.height:
continue
rl.draw_text_ex(gui_app.font(), line.strip(), position, FONT_SIZE, 0, rl.WHITE)
rl.end_scissor_mode()
button_bounds = rl.Rectangle(gui_app.width - MARGIN - BUTTON_SIZE.x, gui_app.height - MARGIN - BUTTON_SIZE.y, BUTTON_SIZE.x, BUTTON_SIZE.y)
if gui_button(button_bounds, "Reboot", button_style=ButtonStyle.TRANSPARENT):
ret = gui_button(button_bounds, "Reboot", button_style=ButtonStyle.TRANSPARENT)
if ret:
HARDWARE.reboot()
return ret
def show_text_in_window(text: str):
gui_app.init_window("Text")
text_window = TextWindow(text)
for _ in gui_app.render():
text_window.render()
if __name__ == "__main__":
main()
show_text_in_window(DEMO_TEXT)

@ -28,7 +28,7 @@ class Keyboard:
key = self.kb.getch().lower()
self.cancel = False
if key == 'r':
self.axes_values = {ax: 0. for ax in self.axes_values}
self.axes_values = dict.fromkeys(self.axes_values, 0.)
elif key == 'c':
self.cancel = True
elif key in self.axes_map:
@ -65,7 +65,7 @@ class Joystick:
try:
joystick_event = get_gamepad()[0]
except (OSError, UnpluggedError):
self.axes_values = {ax: 0. for ax in self.axes_values}
self.axes_values = dict.fromkeys(self.axes_values, 0.)
return False
event = (joystick_event.code, joystick_event.state)

@ -16,8 +16,7 @@ CHUNK_SIZE = 1000 * K
logging.getLogger("urllib3").setLevel(logging.WARNING)
def hash_256(link: str) -> str:
hsh = str(sha256((link.split("?")[0]).encode('utf-8')).hexdigest())
return hsh
return sha256((link.split("?")[0]).encode('utf-8')).hexdigest()
class URLFileException(Exception):

@ -28,6 +28,8 @@ if [[ $(command -v brew) == "" ]]; then
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> $RC_FILE
eval "$(/opt/homebrew/bin/brew shellenv)"
fi
else
brew up
fi
brew bundle --file=- <<-EOS

@ -150,44 +150,44 @@
<plot flip_x="false" style="Lines" flip_y="false" mode="TimeSeries">
<range top="3.586831" right="269.943117" left="0.134774" bottom="-2.354077"/>
<limitY/>
<curve color="#d62728" name="/controlsState/lateralControlState/torqueState/desiredLateralAccel"/>
<curve color="#1f77b4" name="/controlsState/lateralControlState/torqueState/actualLateralAccel"/>
<curve color="#ff7f0e" name="/controlsState/lateralControlState/torqueState/desiredLateralAccel"/>
<curve color="#1ac938" name="/controlsState/lateralControlState/torqueState/actualLateralAccel"/>
</plot>
</DockArea>
<DockArea name="desired vs actual lateral acceleration (desired shifted by +0.1s)">
<plot flip_x="false" style="Lines" flip_y="false" mode="TimeSeries">
<range top="3.586831" right="269.943117" left="0.134774" bottom="-2.354077"/>
<limitY/>
<curve color="#1ac938" name="/controlsState/lateralControlState/torqueState/desiredLateralAccel">
<curve color="#ff7f0e" name="/controlsState/lateralControlState/torqueState/desiredLateralAccel">
<transform alias="/controlsState/lateralControlState/torqueState/desiredLateralAccel[Scale/Offset]" name="Scale/Offset">
<options value_scale="1.0" time_offset="0.1" value_offset="0"/>
</transform>
</curve>
<curve color="#ff7f0e" name="/controlsState/lateralControlState/torqueState/actualLateralAccel"/>
<curve color="#1ac938" name="/controlsState/lateralControlState/torqueState/actualLateralAccel"/>
</plot>
</DockArea>
<DockArea name="desired vs actual lateral acceleration (desired shifted by +0.2s)">
<plot flip_x="false" style="Lines" flip_y="false" mode="TimeSeries">
<range top="3.586831" right="269.943117" left="0.134774" bottom="-2.354077"/>
<limitY/>
<curve color="#1ac938" name="/controlsState/lateralControlState/torqueState/desiredLateralAccel">
<curve color="#ff7f0e" name="/controlsState/lateralControlState/torqueState/desiredLateralAccel">
<transform alias="/controlsState/lateralControlState/torqueState/desiredLateralAccel[Scale/Offset]" name="Scale/Offset">
<options value_scale="1.0" time_offset="0.2" value_offset="0"/>
</transform>
</curve>
<curve color="#ff7f0e" name="/controlsState/lateralControlState/torqueState/actualLateralAccel"/>
<curve color="#1ac938" name="/controlsState/lateralControlState/torqueState/actualLateralAccel"/>
</plot>
</DockArea>
<DockArea name="desired vs actual lateral acceleration (desired shifted by +0.3s)">
<plot flip_x="false" style="Lines" flip_y="false" mode="TimeSeries">
<range top="3.586831" right="269.943117" left="0.134774" bottom="-2.354077"/>
<limitY/>
<curve color="#1ac938" name="/controlsState/lateralControlState/torqueState/desiredLateralAccel">
<curve color="#ff7f0e" name="/controlsState/lateralControlState/torqueState/desiredLateralAccel">
<transform alias="/controlsState/lateralControlState/torqueState/desiredLateralAccel[Scale/Offset]" name="Scale/Offset">
<options value_scale="1.0" time_offset="0.3" value_offset="0"/>
</transform>
</curve>
<curve color="#ff7f0e" name="/controlsState/lateralControlState/torqueState/actualLateralAccel"/>
<curve color="#1ac938" name="/controlsState/lateralControlState/torqueState/actualLateralAccel"/>
</plot>
</DockArea>
</DockSplitter>

1577
uv.lock

File diff suppressed because it is too large Load Diff
Loading…
Cancel
Save