diff --git a/.github/workflows/selfdrive_tests.yaml b/.github/workflows/selfdrive_tests.yaml index ea591cbf4..b042ae043 100644 --- a/.github/workflows/selfdrive_tests.yaml +++ b/.github/workflows/selfdrive_tests.yaml @@ -86,6 +86,23 @@ jobs: docker_hub_pat: ${{ secrets.DOCKER_HUB_PAT }} - uses: ./.github/workflows/compile-openpilot timeout-minutes: ${{ ((steps.restore-scons-cache.outputs.cache-hit == 'true') && 15 || 30) }} # allow more time when we missed the scons cache + + build_mac: + name: build macos + runs-on: macos-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - run: git lfs pull + - name: Install dependencies + run: ./tools/mac_setup.sh + env: + SKIP_PROMPT: 1 + # package install has DeprecationWarnings + PYTHONWARNINGS: default + - name: Test openpilot environment + run: poetry run scons -h static_analysis: name: static analysis diff --git a/.gitignore b/.gitignore index f067893c7..ac61591bf 100644 --- a/.gitignore +++ b/.gitignore @@ -43,6 +43,7 @@ persist selfdrive/pandad/pandad cereal/services.h cereal/gen +cereal/messaging/bridge selfdrive/logcatd/logcatd selfdrive/mapd/default_speeds_by_region.json system/proclogd/proclogd diff --git a/cereal/messaging/.gitignore b/cereal/messaging/.gitignore deleted file mode 100644 index dbbe8e22a..000000000 --- a/cereal/messaging/.gitignore +++ /dev/null @@ -1,10 +0,0 @@ -demo -bridge -test_runner -*.o -*.os -*.d -*.a -*.so -messaging_pyx.cpp -build/ diff --git a/cereal/messaging/messaging.h b/cereal/messaging/messaging.h index f3850130e..fb9c261f2 100644 --- a/cereal/messaging/messaging.h +++ b/cereal/messaging/messaging.h @@ -5,20 +5,13 @@ #include #include #include -#include #include #include "cereal/gen/cpp/log.capnp.h" +#include "common/timing.h" #include "msgq/ipc.h" -#ifdef __APPLE__ -#define CLOCK_BOOTTIME CLOCK_MONOTONIC -#endif - -#define MSG_MULTIPLE_PUBLISHERS 100 - - class SubMaster { public: SubMaster(const std::vector &service_list, const std::vector &poll = {}, @@ -53,10 +46,7 @@ public: cereal::Event::Builder initEvent(bool valid = true) { cereal::Event::Builder event = initRoot(); - struct timespec t; - clock_gettime(CLOCK_BOOTTIME, &t); - uint64_t current_time = t.tv_sec * 1000000000ULL + t.tv_nsec; - event.setLogMonoTime(current_time); + event.setLogMonoTime(nanos_since_boot()); event.setValid(valid); return event; } diff --git a/cereal/messaging/socketmaster.cc b/cereal/messaging/socketmaster.cc index cd697b1f5..38b984241 100644 --- a/cereal/messaging/socketmaster.cc +++ b/cereal/messaging/socketmaster.cc @@ -1,4 +1,3 @@ -#include #include #include #include @@ -7,15 +6,8 @@ #include "cereal/services.h" #include "cereal/messaging/messaging.h" - const bool SIMULATION = (getenv("SIMULATION") != nullptr) && (std::string(getenv("SIMULATION")) == "1"); -static inline uint64_t nanos_since_boot() { - struct timespec t; - clock_gettime(CLOCK_BOOTTIME, &t); - return t.tv_sec * 1000000000ULL + t.tv_nsec; -} - static inline bool inList(const std::vector &list, const char *value) { for (auto &v : list) { if (strcmp(value, v) == 0) return true; diff --git a/panda b/panda index a68768639..ce9642dbb 160000 --- a/panda +++ b/panda @@ -1 +1 @@ -Subproject commit a687686391602d77d2dd34d4ca1dc7c3504885c7 +Subproject commit ce9642dbb69beebf4a847ef6be8ccb4056103c3a diff --git a/selfdrive/car/gm/interface.py b/selfdrive/car/gm/interface.py index 5ea2b1989..d08805048 100755 --- a/selfdrive/car/gm/interface.py +++ b/selfdrive/car/gm/interface.py @@ -53,7 +53,12 @@ class CarInterface(CarInterfaceBase): friction = get_friction(lateral_accel_error, lateral_accel_deadzone, FRICTION_THRESHOLD, torque_params, friction_compensation) def sig(val): - return 1 / (1 + exp(-val)) - 0.5 + # https://timvieira.github.io/blog/post/2014/02/11/exp-normalize-trick + if val >= 0: + return 1 / (1 + exp(-val)) - 0.5 + else: + z = exp(val) + return z / (1 + z) - 0.5 # The "lat_accel vs torque" relationship is assumed to be the sum of "sigmoid + linear" curves # An important thing to consider is that the slope at 0 should be > 0 (ideally >1) diff --git a/selfdrive/car/hyundai/fingerprints.py b/selfdrive/car/hyundai/fingerprints.py index 8db0849cb..e33f3e415 100644 --- a/selfdrive/car/hyundai/fingerprints.py +++ b/selfdrive/car/hyundai/fingerprints.py @@ -1001,6 +1001,7 @@ FW_VERSIONS = { b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.03 99211-GI010 220401', b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.05 99211-GI010 220614', b'\xf1\x00NE1 MFC AT USA LHD 1.00 1.06 99211-GI010 230110', + b'\xf1\x00NE1 MFC AT EUR LHD 1.00 1.01 99211-GI100 240110', ], }, CAR.HYUNDAI_IONIQ_6: { diff --git a/selfdrive/controls/lib/longitudinal_planner.py b/selfdrive/controls/lib/longitudinal_planner.py index 649119d77..174e63062 100755 --- a/selfdrive/controls/lib/longitudinal_planner.py +++ b/selfdrive/controls/lib/longitudinal_planner.py @@ -195,15 +195,11 @@ class LongitudinalPlanner: plan_send.valid = sm.all_checks(service_list=['carState', 'controlsState']) - longitudinalPlan = plan_send.longitudinalPlan longitudinalPlan.modelMonoTime = sm.logMonoTime['modelV2'] longitudinalPlan.processingDelay = (plan_send.logMonoTime / 1e9) - sm.logMonoTime['modelV2'] longitudinalPlan.solverExecutionTime = self.mpc.solve_time - longitudinalPlan.allowBrake = True - longitudinalPlan.allowThrottle = True - longitudinalPlan.speeds = self.v_desired_trajectory.tolist() longitudinalPlan.accels = self.a_desired_trajectory.tolist() longitudinalPlan.jerks = self.j_desired_trajectory.tolist() diff --git a/selfdrive/ui/SConscript b/selfdrive/ui/SConscript index 400612de0..58cef3608 100644 --- a/selfdrive/ui/SConscript +++ b/selfdrive/ui/SConscript @@ -120,10 +120,6 @@ if GetOption('extras') and arch != "Darwin": if "internal" in name: d['INTERNAL'] = "1" - import requests - r = requests.get("https://github.com/commaci2.keys") - r.raise_for_status() - d['SSH_KEYS'] = f'\\"{r.text.strip()}\\"' obj = senv.Object(f"installer/installers/installer_{name}.o", ["installer/installer.cc"], CPPDEFINES=d) f = senv.Program(f"installer/installers/installer_{name}", [obj, cont], LIBS=qt_libs) # keep installers small diff --git a/selfdrive/ui/installer/installer.cc b/selfdrive/ui/installer/installer.cc index d43ed37ae..17f6ba19a 100644 --- a/selfdrive/ui/installer/installer.cc +++ b/selfdrive/ui/installer/installer.cc @@ -180,10 +180,12 @@ void Installer::cloneFinished(int exitCode, QProcess::ExitStatus exitStatus) { #ifdef INTERNAL run("mkdir -p /data/params/d/"); + // https://github.com/commaci2.keys + const std::string ssh_keys = "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIMX2kU8eBZyEWmbq0tjMPxksWWVuIV/5l64GabcYbdpI"; std::map params = { {"SshEnabled", "1"}, {"RecordFrontLock", "1"}, - {"GithubSshKeys", SSH_KEYS}, + {"GithubSshKeys", ssh_keys}, }; for (const auto& [key, value] : params) { std::ofstream param; diff --git a/tools/lib/logreader.py b/tools/lib/logreader.py index 98c10941b..f6932c029 100755 --- a/tools/lib/logreader.py +++ b/tools/lib/logreader.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 import bz2 -from functools import partial +from functools import cache, partial import multiprocessing import capnp import enum @@ -87,18 +87,21 @@ Source = Callable[[SegmentRange, ReadMode], LogPaths] InternalUnavailableException = Exception("Internal source not available") + +@cache def default_valid_file(fn: LogPath) -> bool: return fn is not None and file_exists(fn) def auto_strategy(rlog_paths: LogPaths, qlog_paths: LogPaths, interactive: bool, valid_file: ValidFileCallable) -> LogPaths: # auto select logs based on availability - if any(rlog is None or not valid_file(rlog) for rlog in rlog_paths) and all(qlog is not None and valid_file(qlog) for qlog in qlog_paths): + missing_rlogs = [rlog is None or not valid_file(rlog) for rlog in rlog_paths].count(True) + if missing_rlogs != 0: if interactive: - if input("Some rlogs were not found, would you like to fallback to qlogs for those segments? (y/n) ").lower() != "y": + if input(f"{missing_rlogs} rlogs were not found, would you like to fallback to qlogs for those segments? (y/n) ").lower() != "y": return rlog_paths else: - cloudlog.warning("Some rlogs were not found, falling back to qlogs for those segments...") + cloudlog.warning(f"{missing_rlogs} rlogs were not found, falling back to qlogs for those segments...") return [rlog if valid_file(rlog) else (qlog if valid_file(qlog) else None) for (rlog, qlog) in zip(rlog_paths, qlog_paths, strict=True)]