diff --git a/cereal/README.md b/cereal/README.md index ad940facdc..45e859c09c 100644 --- a/cereal/README.md +++ b/cereal/README.md @@ -29,6 +29,50 @@ then means breaking backwards-compatibility with all old logs of your fork. So w [custom.capnp](custom.capnp) that we will leave empty in mainline cereal/openpilot. **If you only modify those, you can ensure your fork will remain backwards-compatible with all versions of mainline openpilot and your fork.** +An example of compatible changes: +```diff +diff --git a/cereal/custom.capnp b/cereal/custom.capnp +index 3348e859e..3365c7b98 100644 +--- a/cereal/custom.capnp ++++ b/cereal/custom.capnp +@@ -10,7 +10,11 @@ $Cxx.namespace("cereal"); + # DO rename the structs + # DON'T change the identifier (e.g. @0x81c2f05a394cf4af) + +-struct CustomReserved0 @0x81c2f05a394cf4af { ++struct SteeringInfo @0x81c2f05a394cf4af { ++ active @0 :Bool; ++ steeringAngleDeg @1 :Float32; ++ steeringRateDeg @2 :Float32; ++ steeringAccelDeg @3 :Float32; + } + + struct CustomReserved1 @0xaedffd8f31e7b55d { +diff --git a/cereal/log.capnp b/cereal/log.capnp +index 1209f3fd9..b189f58b6 100644 +--- a/cereal/log.capnp ++++ b/cereal/log.capnp +@@ -2558,14 +2558,14 @@ struct Event { + + # DO change the name of the field + # DON'T change anything after the "@" +- customReservedRawData0 @124 :Data; ++ rawCanData @124 :Data; + customReservedRawData1 @125 :Data; + customReservedRawData2 @126 :Data; + + # DO change the name of the field and struct + # DON'T change the ID (e.g. @107) + # DON'T change which struct it points to +- customReserved0 @107 :Custom.CustomReserved0; ++ steeringInfo @107 :Custom.SteeringInfo; + customReserved1 @108 :Custom.CustomReserved1; + customReserved2 @109 :Custom.CustomReserved2; + customReserved3 @110 :Custom.CustomReserved3; +``` + +--- + Example --- ```python diff --git a/cereal/custom.capnp b/cereal/custom.capnp index 3ddeed75f6..1d825270fb 100644 --- a/cereal/custom.capnp +++ b/cereal/custom.capnp @@ -7,7 +7,9 @@ $Cxx.namespace("cereal"); # These structs are guaranteed to remain reserved and empty in mainline # cereal, so use these if you want custom events in your fork. -# you can rename the struct, but don't change the identifier +# DO rename the structs +# DON'T change the identifier (e.g. @0x81c2f05a394cf4af) + struct SelfdriveStateSP @0x81c2f05a394cf4af { mads @0 :ModularAssistiveDrivingSystem; @@ -64,7 +66,7 @@ struct ModelManagerSP @0xaedffd8f31e7b55d { progress @1 :Float32; eta @2 :UInt32; } - + enum Runner { snpe @0; tinygrad @1; @@ -105,3 +107,33 @@ struct CustomReserved8 @0xf416ec09499d9d19 { struct CustomReserved9 @0xa1680744031fdb2d { } + +struct CustomReserved10 @0xcb9fd56c7057593a { +} + +struct CustomReserved11 @0xc2243c65e0340384 { +} + +struct CustomReserved12 @0x9ccdc8676701b412 { +} + +struct CustomReserved13 @0xcd96dafb67a082d0 { +} + +struct CustomReserved14 @0xb057204d7deadf3f { +} + +struct CustomReserved15 @0xbd443b539493bc68 { +} + +struct CustomReserved16 @0xfc6241ed8877b611 { +} + +struct CustomReserved17 @0xa30662f84033036c { +} + +struct CustomReserved18 @0xc86a3d38d13eb3ef { +} + +struct CustomReserved19 @0xa4f1eb3323f5f582 { +} diff --git a/cereal/log.capnp b/cereal/log.capnp index 0f838b7f73..9705875c42 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -2628,11 +2628,17 @@ struct Event { livestreamWideRoadEncodeData @121 :EncodeData; livestreamDriverEncodeData @122 :EncodeData; + # *********** Custom: reserved for forks *********** + + # DO change the name of the field + # DON'T change anything after the "@" customReservedRawData0 @124 :Data; customReservedRawData1 @125 :Data; customReservedRawData2 @126 :Data; - # *********** Custom: reserved for forks *********** + # DO change the name of the field and struct + # DON'T change the ID (e.g. @107) + # DON'T change which struct it points to selfdriveStateSP @107 :Custom.SelfdriveStateSP; modelManagerSP @108 :Custom.ModelManagerSP; customReserved2 @109 :Custom.CustomReserved2; @@ -2643,6 +2649,16 @@ struct Event { customReserved7 @114 :Custom.CustomReserved7; customReserved8 @115 :Custom.CustomReserved8; customReserved9 @116 :Custom.CustomReserved9; + customReserved10 @136 :Custom.CustomReserved10; + customReserved11 @137 :Custom.CustomReserved11; + customReserved12 @138 :Custom.CustomReserved12; + customReserved13 @139 :Custom.CustomReserved13; + customReserved14 @140 :Custom.CustomReserved14; + customReserved15 @141 :Custom.CustomReserved15; + customReserved16 @142 :Custom.CustomReserved16; + customReserved17 @143 :Custom.CustomReserved17; + customReserved18 @144 :Custom.CustomReserved18; + customReserved19 @145 :Custom.CustomReserved19; # *********** legacy + deprecated *********** model @9 :Legacy.ModelData; # TODO: rename modelV2 and mark this as deprecated diff --git a/common/util.cc b/common/util.cc index f4c69eb269..096df85634 100644 --- a/common/util.cc +++ b/common/util.cc @@ -294,4 +294,17 @@ std::string check_output(const std::string& command) { return result; } +bool system_time_valid() { + // Default to August 26, 2024 + tm min_tm = {.tm_year = 2024 - 1900, .tm_mon = 7, .tm_mday = 26}; + time_t min_date = mktime(&min_tm); + + struct stat st; + if (stat("/lib/systemd/systemd", &st) == 0) { + min_date = std::max(min_date, st.st_mtime + 86400); // Add 1 day (86400 seconds) + } + + return time(nullptr) > min_date; +} + } // namespace util diff --git a/common/util.h b/common/util.h index d4106b5002..4fb4b13fae 100644 --- a/common/util.h +++ b/common/util.h @@ -96,6 +96,8 @@ bool create_directories(const std::string &dir, mode_t mode); std::string check_output(const std::string& command); +bool system_time_valid(); + inline void sleep_for(const int milliseconds) { if (milliseconds > 0) { std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds)); diff --git a/selfdrive/car/car_specific.py b/selfdrive/car/car_specific.py index cd2d66228c..144f9f073b 100644 --- a/selfdrive/car/car_specific.py +++ b/selfdrive/car/car_specific.py @@ -191,7 +191,7 @@ class CarSpecificEvents: events.add(EventName.speedTooHigh) if CS.cruiseState.nonAdaptive: events.add(EventName.wrongCruiseMode) - if CS.brakeHoldActive and self.CP.openpilotLongitudinalControl and self.CP.carName != 'toyota': + if CS.brakeHoldActive and self.CP.openpilotLongitudinalControl: events.add(EventName.brakeHold) if CS.parkingBrake: events.add(EventName.parkBrake) diff --git a/selfdrive/car/card.py b/selfdrive/car/card.py index 5cb3b6f598..4432d1f0b5 100755 --- a/selfdrive/car/card.py +++ b/selfdrive/car/card.py @@ -133,6 +133,15 @@ class Car: self.CP.safetyConfigs = [safety_config] if self.CP.secOcRequired and not self.params.get_bool("IsReleaseBranch"): + # Copy user key if available + try: + with open("/cache/params/SecOCKey") as f: + user_key = f.readline().strip() + if len(user_key) == 32: + self.params.put("SecOCKey", user_key) + except Exception: + pass + secoc_key = self.params.get("SecOCKey", encoding='utf8') if secoc_key is not None: saved_secoc_key = bytes.fromhex(secoc_key.strip()) diff --git a/selfdrive/selfdrived/events.py b/selfdrive/selfdrived/events.py index 481a33079b..aab9bc433b 100755 --- a/selfdrive/selfdrived/events.py +++ b/selfdrive/selfdrived/events.py @@ -652,8 +652,11 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = { }, EventName.brakeHold: { - ET.USER_DISABLE: EngagementAlert(AudibleAlert.disengage), - ET.NO_ENTRY: NoEntryAlert("Brake Hold Active"), + ET.WARNING: Alert( + "Press Resume to Exit Brake Hold", + "", + AlertStatus.userPrompt, AlertSize.small, + Priority.LOW, VisualAlert.none, AudibleAlert.none, .2), }, EventName.parkBrake: { diff --git a/selfdrive/ui/qt/widgets/prime.cc b/selfdrive/ui/qt/widgets/prime.cc index 85ccfa64be..a69580ea50 100644 --- a/selfdrive/ui/qt/widgets/prime.cc +++ b/selfdrive/ui/qt/widgets/prime.cc @@ -116,6 +116,14 @@ PairingPopup::PairingPopup(QWidget *parent) : DialogBase(parent) { hlayout->addWidget(qr, 1); } +int PairingPopup::exec() { + if (!util::system_time_valid()) { + ConfirmationDialog::alert(tr("Please connect to Wi-Fi to complete initial pairing"), parentWidget()); + return QDialog::Rejected; + } + return DialogBase::exec(); +} + PrimeUserWidget::PrimeUserWidget(QWidget *parent) : QFrame(parent) { setObjectName("primeWidget"); diff --git a/selfdrive/ui/qt/widgets/prime.h b/selfdrive/ui/qt/widgets/prime.h index 7c27b6f7d9..53d743398d 100644 --- a/selfdrive/ui/qt/widgets/prime.h +++ b/selfdrive/ui/qt/widgets/prime.h @@ -33,6 +33,7 @@ class PairingPopup : public DialogBase { public: explicit PairingPopup(QWidget* parent); + int exec() override; }; diff --git a/selfdrive/ui/translations/main_ar.ts b/selfdrive/ui/translations/main_ar.ts index 482893fae5..46747257af 100644 --- a/selfdrive/ui/translations/main_ar.ts +++ b/selfdrive/ui/translations/main_ar.ts @@ -584,6 +584,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Bookmark connect.comma.ai to your home screen to use it like an app اجعل لـconnect.comma.ai إشارة مرجعية على شاشتك الرئيسية من أجل استخدامه مثل أي تطبيق + + Please connect to Wi-Fi to complete initial pairing + + ParamControl diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index 3129b79f0d..dfd810f95e 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -579,6 +579,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Bookmark connect.comma.ai to your home screen to use it like an app Füge connect.comma.ai als Lesezeichen auf deinem Homescreen hinzu um es wie eine App zu verwenden + + Please connect to Wi-Fi to complete initial pairing + + ParamControl diff --git a/selfdrive/ui/translations/main_es.ts b/selfdrive/ui/translations/main_es.ts index dd58f9ddb5..18b299869b 100644 --- a/selfdrive/ui/translations/main_es.ts +++ b/selfdrive/ui/translations/main_es.ts @@ -580,6 +580,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Bookmark connect.comma.ai to your home screen to use it like an app Añada connect.comma.ai a su pantalla de inicio para usarlo como una aplicación + + Please connect to Wi-Fi to complete initial pairing + + ParamControl diff --git a/selfdrive/ui/translations/main_fr.ts b/selfdrive/ui/translations/main_fr.ts index dac8c0373b..b4379bda70 100644 --- a/selfdrive/ui/translations/main_fr.ts +++ b/selfdrive/ui/translations/main_fr.ts @@ -580,6 +580,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Bookmark connect.comma.ai to your home screen to use it like an app Ajoutez connect.comma.ai à votre écran d'accueil pour l'utiliser comme une application + + Please connect to Wi-Fi to complete initial pairing + + ParamControl diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 28a4db8a8f..782fde3d2a 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -578,6 +578,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Bookmark connect.comma.ai to your home screen to use it like an app 「connect.comma.ai」をホーム画面に追加して、アプリのように使うことができます。 + + Please connect to Wi-Fi to complete initial pairing + + ParamControl diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index af62de8bd5..768981205d 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -579,6 +579,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Bookmark connect.comma.ai to your home screen to use it like an app connect.comma.ai를 앱처럼 사용하려면 홈 화면에 바로가기를 만드세요 + + Please connect to Wi-Fi to complete initial pairing + + ParamControl diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index 004f03affe..748cece4b3 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -580,6 +580,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Bookmark connect.comma.ai to your home screen to use it like an app Salve connect.comma.ai como sua página inicial para utilizar como um app + + Please connect to Wi-Fi to complete initial pairing + + ParamControl diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts index 1c28c0ebd1..4e10fd94c0 100644 --- a/selfdrive/ui/translations/main_th.ts +++ b/selfdrive/ui/translations/main_th.ts @@ -579,6 +579,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Bookmark connect.comma.ai to your home screen to use it like an app จดจำ connect.comma.ai โดยการเพิ่มไปยังหน้าจอโฮม เพื่อใช้งานเหมือนเป็นแอปพลิเคชัน + + Please connect to Wi-Fi to complete initial pairing + + ParamControl diff --git a/selfdrive/ui/translations/main_tr.ts b/selfdrive/ui/translations/main_tr.ts index 81bc70e154..1e1f4b0939 100644 --- a/selfdrive/ui/translations/main_tr.ts +++ b/selfdrive/ui/translations/main_tr.ts @@ -578,6 +578,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Bookmark connect.comma.ai to your home screen to use it like an app Uygulama gibi kullanmak için connect.comma.ai sitesini yer işaretlerine ekleyin. + + Please connect to Wi-Fi to complete initial pairing + + ParamControl diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index 81de7f76b8..e3be287ab5 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -579,6 +579,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Bookmark connect.comma.ai to your home screen to use it like an app 将 connect.comma.ai 收藏到您的主屏幕,以便像应用程序一样使用它 + + Please connect to Wi-Fi to complete initial pairing + + ParamControl diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 0f8a40ed29..088d80366e 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -579,6 +579,10 @@ Pause Steering: ALC will be paused after the brake pedal is manually pressed.Bookmark connect.comma.ai to your home screen to use it like an app 將 connect.comma.ai 加入您的主螢幕,以便像手機 App 一樣使用它 + + Please connect to Wi-Fi to complete initial pairing + + ParamControl diff --git a/system/manager/build.py b/system/manager/build.py index 956336a604..d4961850ca 100755 --- a/system/manager/build.py +++ b/system/manager/build.py @@ -14,7 +14,7 @@ from openpilot.system.version import get_build_metadata MAX_CACHE_SIZE = 4e9 if "CI" in os.environ else 2e9 CACHE_DIR = Path("/data/scons_cache" if AGNOS else "/tmp/scons_cache") -TOTAL_SCONS_NODES = 2820 +TOTAL_SCONS_NODES = 3130 MAX_BUILD_PROGRESS = 100 def build(spinner: Spinner, dirty: bool = False, minimal: bool = False) -> None: diff --git a/tools/joystick/joystick_control.py b/tools/joystick/joystick_control.py index 60131ba370..74d034d505 100755 --- a/tools/joystick/joystick_control.py +++ b/tools/joystick/joystick_control.py @@ -34,7 +34,7 @@ class Keyboard: elif key in self.axes_map: axis = self.axes_map[key] incr = self.axis_increment if key in ['w', 'a'] else -self.axis_increment - self.axes_values[axis] = np.clip(self.axes_values[axis] + incr, -1, 1) + self.axes_values[axis] = float(np.clip(self.axes_values[axis] + incr, -1, 1)) else: return False return True @@ -83,7 +83,7 @@ class Joystick: self.max_axis_value[event[0]] = max(event[1], self.max_axis_value[event[0]]) self.min_axis_value[event[0]] = min(event[1], self.min_axis_value[event[0]]) - norm = -np.interp(event[1], [self.min_axis_value[event[0]], self.max_axis_value[event[0]]], [-1., 1.]) + norm = -float(np.interp(event[1], [self.min_axis_value[event[0]], self.max_axis_value[event[0]]], [-1., 1.])) norm = norm if abs(norm) > 0.03 else 0. # center can be noisy, deadzone of 3% self.axes_values[event[0]] = EXPO * norm ** 3 + (1 - EXPO) * norm # less action near center for fine control else: diff --git a/tools/joystick/joystickd.py b/tools/joystick/joystickd.py index 21d10b36d4..d52e80af86 100755 --- a/tools/joystick/joystickd.py +++ b/tools/joystick/joystickd.py @@ -9,6 +9,7 @@ from openpilot.common.params import Params from openpilot.common.swaglog import cloudlog from openpilot.selfdrive.controls.lib.vehicle_model import VehicleModel +LongCtrlState = car.CarControl.Actuators.LongControlState MAX_LAT_ACCEL = 2.5 @@ -45,13 +46,14 @@ def joystickd_thread(): joystick_axes = [0.0, 0.0] if CC.longActive: - actuators.accel = 4.0 * np.clip(joystick_axes[0], -1, 1) + actuators.accel = 4.0 * float(np.clip(joystick_axes[0], -1, 1)) + actuators.longControlState = LongCtrlState.pid if sm['carState'].vEgo > CP.vEgoStopping else LongCtrlState.stopping if CC.latActive: max_curvature = MAX_LAT_ACCEL / max(sm['carState'].vEgo ** 2, 5) max_angle = math.degrees(VM.get_steer_from_curvature(max_curvature, sm['carState'].vEgo, sm['liveParameters'].roll)) - actuators.steer = np.clip(joystick_axes[1], -1, 1) + actuators.steer = float(np.clip(joystick_axes[1], -1, 1)) actuators.steeringAngleDeg, actuators.curvature = actuators.steer * max_angle, actuators.steer * -max_curvature pm.send('carControl', cc_msg)