diff --git a/.github/labeler.yaml b/.github/labeler.yaml index 94bc9074cd..4c4d371d43 100644 --- a/.github/labeler.yaml +++ b/.github/labeler.yaml @@ -1,42 +1,61 @@ CI / testing: - - all: ['.github/**'] - - all: ['**/test_*'] + - all: + - changed-files: ['.github/**'] + - all: + - changed-files: ['**/test_*'] car: - - all: ['selfdrive/car/**'] + - all: + - changed-files: ['selfdrive/car/**'] body: - - all: ['selfdrive/car/body/*'] + - all: + - changed-files: ['selfdrive/car/body/*'] chrysler: - - all: ['selfdrive/car/chrysler/*'] + - all: + - changed-files: ['selfdrive/car/chrysler/*'] ford: - - all: ['selfdrive/car/ford/*'] + - all: + - changed-files: ['selfdrive/car/ford/*'] gm: - - all: ['selfdrive/car/gm/*'] + - all: + - changed-files: ['selfdrive/car/gm/*'] honda: - - all: ['selfdrive/car/honda/*'] + - all: + - changed-files: ['selfdrive/car/honda/*'] hyundai: - - all: ['selfdrive/car/hyundai/*'] + - all: + - changed-files: ['selfdrive/car/hyundai/*'] mazda: - - all: ['selfdrive/car/mazda/*'] + - all: + - changed-files: ['selfdrive/car/mazda/*'] nissan: - - all: ['selfdrive/car/nissan/*'] + - all: + - changed-files: ['selfdrive/car/nissan/*'] subaru: - - all: ['selfdrive/car/subaru/*'] + - all: + - changed-files: ['selfdrive/car/subaru/*'] tesla: - - all: ['selfdrive/car/tesla/*'] + - all: + - changed-files: ['selfdrive/car/tesla/*'] toyota: - - all: ['selfdrive/car/toyota/*'] + - all: + - changed-files: ['selfdrive/car/toyota/*'] volkswagen: - - all: ['selfdrive/car/volkswagen/*'] + - all: + - changed-files: ['selfdrive/car/volkswagen/*'] simulation: - - all: ['tools/sim/**'] + - all: + - changed-files: ['tools/sim/**'] ui: - - all: ['selfdrive/ui/**'] + - all: + - changed-files: ['selfdrive/ui/**'] tools: - - all: ['tools/**'] + - all: + - changed-files: ['tools/**'] multilanguage: - - all: ['selfdrive/ui/translations/**'] + - all: + - changed-files: ['selfdrive/ui/translations/**'] diff --git a/.github/workflows/labeler.yaml b/.github/workflows/labeler.yaml index 7c91b1591c..20f7260ef7 100644 --- a/.github/workflows/labeler.yaml +++ b/.github/workflows/labeler.yaml @@ -12,7 +12,7 @@ jobs: - uses: actions/checkout@v3 with: submodules: false - - uses: actions/labeler@v4 + - uses: actions/labeler@v5.0.0-alpha.1 with: dot: true configuration-path: .github/labeler.yaml \ No newline at end of file diff --git a/.github/workflows/setup-with-retry/action.yaml b/.github/workflows/setup-with-retry/action.yaml index 846d8bbaf0..e4c97af3ce 100644 --- a/.github/workflows/setup-with-retry/action.yaml +++ b/.github/workflows/setup-with-retry/action.yaml @@ -9,9 +9,10 @@ inputs: description: 'Prefix for caching key' required: false default: 'scons_x86_64' - -env: - SLEEP_TIME: 30 # Time to sleep between retries + sleep_time: + description: 'Time to sleep between retries' + required: false + default: 30 runs: using: "composite" @@ -25,7 +26,7 @@ runs: is_retried: true - if: steps.setup1.outcome == 'failure' shell: bash - run: sleep ${{ env.SLEEP_TIME }} + run: sleep ${{ inputs.sleep_time }} - id: setup2 if: steps.setup1.outcome == 'failure' uses: ./.github/workflows/setup @@ -36,7 +37,7 @@ runs: is_retried: true - if: steps.setup2.outcome == 'failure' shell: bash - run: sleep ${{ env.SLEEP_TIME }} + run: sleep ${{ inputs.sleep_time }} - id: setup3 if: steps.setup2.outcome == 'failure' uses: ./.github/workflows/setup diff --git a/cereal b/cereal index 7de568b659..4b334f6f10 160000 --- a/cereal +++ b/cereal @@ -1 +1 @@ -Subproject commit 7de568b65922b1b7a5cb9a9a391e3e03394500f7 +Subproject commit 4b334f6f10877e4a666b23983de2d27934ebf3b1 diff --git a/opendbc b/opendbc index 5ebf73ebed..8d2f614ce3 160000 --- a/opendbc +++ b/opendbc @@ -1 +1 @@ -Subproject commit 5ebf73ebed8d1693aadffe97bd2dd012da3b3c1c +Subproject commit 8d2f614ce3f323c65de802b2d5f29143de9c427b diff --git a/selfdrive/car/hyundai/carstate.py b/selfdrive/car/hyundai/carstate.py index b4ff0e9e6e..8090bbcd8f 100644 --- a/selfdrive/car/hyundai/carstate.py +++ b/selfdrive/car/hyundai/carstate.py @@ -105,10 +105,12 @@ class CarState(CarStateBase): ret.cruiseState.available = cp.vl["TCS13"]["ACCEnable"] == 0 ret.cruiseState.enabled = cp.vl["TCS13"]["ACC_REQ"] == 1 ret.cruiseState.standstill = False + ret.cruiseState.nonAdaptive = False else: ret.cruiseState.available = cp_cruise.vl["SCC11"]["MainMode_ACC"] == 1 ret.cruiseState.enabled = cp_cruise.vl["SCC12"]["ACCMode"] != 0 ret.cruiseState.standstill = cp_cruise.vl["SCC11"]["SCCInfoDisplay"] == 4. + ret.cruiseState.nonAdaptive = cp_cruise.vl["SCC11"]["SCCInfoDisplay"] == 2. # Shows 'Cruise Control' on dash ret.cruiseState.speed = cp_cruise.vl["SCC11"]["VSetDis"] * speed_conv # TODO: Find brake pressure @@ -226,6 +228,13 @@ class CarState(CarStateBase): ret.cruiseState.speed = cp_cruise_info.vl["SCC_CONTROL"]["VSetDis"] * speed_factor self.cruise_info = copy.copy(cp_cruise_info.vl["SCC_CONTROL"]) + # Manual Speed Limit Assist is a feature that replaces non-adaptive cruise control on EV CAN FD platforms. + # It limits the vehicle speed, overridable by pressing the accelerator past a certain point. + # The car will brake, but does not respect positive acceleration commands in this mode + # TODO: find this message on ICE & HYBRID cars + cruise control signals (if exists) + if self.CP.carFingerprint in EV_CAR: + ret.cruiseState.nonAdaptive = cp.vl["MANUAL_SPEED_LIMIT_ASSIST"]["MSLA_ENABLED"] == 1 + self.prev_cruise_buttons = self.cruise_buttons[-1] self.cruise_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"]) self.main_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["ADAPTIVE_CRUISE_MAIN_BTN"]) @@ -320,6 +329,11 @@ class CarState(CarStateBase): ("DOORS_SEATBELTS", 4), ] + if CP.carFingerprint in EV_CAR: + messages += [ + ("MANUAL_SPEED_LIMIT_ASSIST", 10), + ] + if not (CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS): messages += [ ("CRUISE_BUTTONS", 50) diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 6cfeabefd4..1dc9dd39f7 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -374,19 +374,19 @@ class Controls: else: self.logged_comm_issue = None - if not self.sm['liveParameters'].valid and not TESTING_CLOSET and (not SIMULATION or REPLAY): - self.events.add(EventName.vehicleModelInvalid) if not self.sm['lateralPlan'].mpcSolutionValid: self.events.add(EventName.plannerError) - if not (self.sm['liveParameters'].sensorValid or self.sm['liveLocationKalman'].sensorsOK) and not NOSENSOR: - if self.sm.frame > 5 / DT_CTRL: # Give locationd some time to receive all the inputs - self.events.add(EventName.sensorDataInvalid) - if not self.sm['liveLocationKalman'].inputsOK and not NOSENSOR: - self.events.add(EventName.localizerMalfunction) if not self.sm['liveLocationKalman'].posenetOK: self.events.add(EventName.posenetInvalid) if not self.sm['liveLocationKalman'].deviceStable: self.events.add(EventName.deviceFalling) + if not (self.sm['liveParameters'].sensorValid or self.sm['liveLocationKalman'].sensorsOK): + if self.sm.frame > 5 / DT_CTRL: # Give locationd some time to receive sensor inputs + self.events.add(EventName.sensorDataInvalid) + if not self.sm['liveLocationKalman'].inputsOK: + self.events.add(EventName.locationdTemporaryError) + if not self.sm['liveParameters'].valid and not TESTING_CLOSET and (not SIMULATION or REPLAY): + self.events.add(EventName.paramsdTemporaryError) if not REPLAY: # Check for mismatch between openpilot and car's PCM diff --git a/selfdrive/controls/lib/events.py b/selfdrive/controls/lib/events.py index 6f41224475..81e55e6bbc 100755 --- a/selfdrive/controls/lib/events.py +++ b/selfdrive/controls/lib/events.py @@ -424,19 +424,6 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { # ********** events only containing alerts that display while engaged ********** - # openpilot tries to learn certain parameters about your car by observing - # how the car behaves to steering inputs from both human and openpilot driving. - # This includes: - # - steer ratio: gear ratio of the steering rack. Steering angle divided by tire angle - # - tire stiffness: how much grip your tires have - # - angle offset: most steering angle sensors are offset and measure a non zero angle when driving straight - # This alert is thrown when any of these values exceed a sanity check. This can be caused by - # bad alignment or bad sensor data. If this happens consistently consider creating an issue on GitHub - EventName.vehicleModelInvalid: { - ET.NO_ENTRY: NoEntryAlert("Vehicle Parameter Identification Failed"), - ET.SOFT_DISABLE: soft_disable_alert("Vehicle Parameter Identification Failed"), - }, - EventName.steerTempUnavailableSilent: { ET.WARNING: Alert( "Steering Temporarily Unavailable", @@ -576,9 +563,34 @@ EVENTS: Dict[int, Dict[str, Union[Alert, AlertCallbackType]]] = { ET.PERMANENT: NormalPermanentAlert("GPS Malfunction", "Likely Hardware Issue"), }, - EventName.localizerMalfunction: { - ET.NO_ENTRY: NoEntryAlert("Localizer Malfunction"), - ET.SOFT_DISABLE: soft_disable_alert("Localizer Malfunction"), + EventName.locationdTemporaryError: { + ET.NO_ENTRY: NoEntryAlert("locationd Temporary Error"), + ET.SOFT_DISABLE: soft_disable_alert("locationd Temporary Error"), + }, + + EventName.locationdPermanentError: { + ET.NO_ENTRY: NoEntryAlert("locationd Permanent Error"), + ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("locationd Permanent Error"), + ET.PERMANENT: NormalPermanentAlert("locationd Permanent Error"), + }, + + # openpilot tries to learn certain parameters about your car by observing + # how the car behaves to steering inputs from both human and openpilot driving. + # This includes: + # - steer ratio: gear ratio of the steering rack. Steering angle divided by tire angle + # - tire stiffness: how much grip your tires have + # - angle offset: most steering angle sensors are offset and measure a non zero angle when driving straight + # This alert is thrown when any of these values exceed a sanity check. This can be caused by + # bad alignment or bad sensor data. If this happens consistently consider creating an issue on GitHub + EventName.paramsdTemporaryError: { + ET.NO_ENTRY: NoEntryAlert("paramsd Temporary Error"), + ET.SOFT_DISABLE: soft_disable_alert("paramsd Temporary Error"), + }, + + EventName.paramsdPermanentError: { + ET.NO_ENTRY: NoEntryAlert("paramsd Permanent Error"), + ET.IMMEDIATE_DISABLE: ImmediateDisableAlert("paramsd Permanent Error"), + ET.PERMANENT: NormalPermanentAlert("paramsd Permanent Error"), }, # ********** events that affect controls state transitions ********** diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 19a8a56e55..c6a2d58fec 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -98c21236f831ca3cff63939cb760b213460e84de \ No newline at end of file +b421ff389ce720b70a36dd2b3510af54eb484b5f \ No newline at end of file diff --git a/tools/cabana/chart/chart.cc b/tools/cabana/chart/chart.cc index 709a052d72..3ee47ae0c6 100644 --- a/tools/cabana/chart/chart.cc +++ b/tools/cabana/chart/chart.cc @@ -474,7 +474,7 @@ void ChartView::mouseReleaseEvent(QMouseEvent *event) { auto rubber = findChild(); if (event->button() == Qt::LeftButton && rubber && rubber->isVisible()) { rubber->hide(); - QRectF rect = rubber->geometry().normalized(); + auto rect = rubber->geometry().normalized(); double min = chart()->mapToValue(rect.topLeft()).x(); double max = chart()->mapToValue(rect.bottomRight()).x(); @@ -698,7 +698,10 @@ void ChartView::drawForeground(QPainter *painter, const QRectF &rect) { } } - // paint zoom range + drawRubberBandTimeRange(painter); +} + +void ChartView::drawRubberBandTimeRange(QPainter *painter) { auto rubber = findChild(); if (rubber && rubber->isVisible() && rubber->width() > 1) { painter->setPen(Qt::white); diff --git a/tools/cabana/chart/chart.h b/tools/cabana/chart/chart.h index 2740d81b66..71cf7058ab 100644 --- a/tools/cabana/chart/chart.h +++ b/tools/cabana/chart/chart.h @@ -84,6 +84,7 @@ private: void drawBackground(QPainter *painter, const QRectF &rect) override; void drawDropIndicator(bool draw) { if (std::exchange(can_drop, draw) != can_drop) viewport()->update(); } void drawTimeline(QPainter *painter); + void drawRubberBandTimeRange(QPainter *painter); std::tuple getNiceAxisNumbers(qreal min, qreal max, int tick_count); qreal niceNumber(qreal x, bool ceiling); QXYSeries *createSeries(SeriesType type, QColor color); diff --git a/tools/cabana/chart/chartswidget.cc b/tools/cabana/chart/chartswidget.cc index e852e6d206..d4ad9d48ad 100644 --- a/tools/cabana/chart/chartswidget.cc +++ b/tools/cabana/chart/chartswidget.cc @@ -219,7 +219,7 @@ void ChartsWidget::updateToolBar() { undo_zoom_action->setVisible(is_zoomed); redo_zoom_action->setVisible(is_zoomed); reset_zoom_action->setVisible(is_zoomed); - reset_zoom_btn->setText(is_zoomed ? tr("%1-%2").arg(zoomed_range.first, 0, 'f', 1).arg(zoomed_range.second, 0, 'f', 1) : ""); + reset_zoom_btn->setText(is_zoomed ? tr("%1-%2").arg(zoomed_range.first, 0, 'f', 2).arg(zoomed_range.second, 0, 'f', 2) : ""); remove_all_btn->setEnabled(!charts.isEmpty()); dock_btn->setIcon(docking ? "arrow-up-right-square" : "arrow-down-left-square"); dock_btn->setToolTip(docking ? tr("Undock charts") : tr("Dock charts")); diff --git a/tools/cabana/chart/chartswidget.h b/tools/cabana/chart/chartswidget.h index 88ba4226c0..3541f8d96e 100644 --- a/tools/cabana/chart/chartswidget.h +++ b/tools/cabana/chart/chartswidget.h @@ -120,7 +120,7 @@ class ZoomCommand : public QUndoCommand { public: ZoomCommand(ChartsWidget *charts, std::pair range) : charts(charts), range(range), QUndoCommand() { prev_range = charts->is_zoomed ? charts->zoomed_range : charts->display_range; - setText(QObject::tr("Zoom to %1-%2").arg(range.first, 0, 'f', 1).arg(range.second, 0, 'f', 1)); + setText(QObject::tr("Zoom to %1-%2").arg(range.first, 0, 'f', 2).arg(range.second, 0, 'f', 2)); } void undo() override { charts->setZoom(prev_range.first, prev_range.second); } void redo() override { charts->setZoom(range.first, range.second); } diff --git a/tools/mac_setup.sh b/tools/mac_setup.sh index 712923626b..0c9627ca4e 100755 --- a/tools/mac_setup.sh +++ b/tools/mac_setup.sh @@ -74,6 +74,27 @@ export PYCURL_SSL_LIBRARY=openssl $DIR/install_python_dependencies.sh echo "[ ] installed python dependencies t=$SECONDS" +# brew does not link qt5 by default +# check if qt5 can be linked, if not, prompt the user to link it +QT_BIN_LOCATION="$(command -v lupdate || :)" +if [ -n "$QT_BIN_LOCATION" ]; then + # if qt6 is linked, prompt the user to unlink it and link the right version + QT_BIN_VERSION="$(lupdate -version | awk '{print $NF}')" + if [[ ! "$QT_BIN_VERSION" =~ 5\.[0-9]+\.[0-9]+ ]]; then + echo + echo "lupdate/lrelease available at PATH is $QT_BIN_VERSION" + if [[ "$QT_BIN_LOCATION" == "$(brew --prefix)/"* ]]; then + echo "Run the following command to link qt5:" + echo "brew unlink qt@6 && brew link qt@5" + else + echo "Remove conflicting qt entries from PATH and run the following command to link qt5:" + echo "brew link qt@5" + fi + fi +else + brew link qt@5 +fi + echo echo "---- OPENPILOT SETUP DONE ----" echo "Open a new shell or configure your active shell env by running:"