From 2da496e8625ff71c1cd056d5ddf9455dbfb1a51a Mon Sep 17 00:00:00 2001 From: FrogAi <91348155+FrogAi@users.noreply.github.com> Date: Tue, 3 Sep 2024 21:35:44 -0700 Subject: [PATCH] September 4th, 2024 Patch --- cereal/custom.capnp | 51 +++-- selfdrive/car/toyota/carstate.py | 13 +- selfdrive/car/toyota/interface.py | 2 +- selfdrive/controls/controlsd.py | 17 +- .../frogpilot/controls/frogpilot_planner.py | 24 +-- .../lib/conditional_experimental_mode.py | 11 +- .../ui/qt/offroad/control_settings.cc | 32 +-- .../ui/qt/offroad/visual_settings.cc | 62 +++--- .../ui/qt/widgets/frogpilot_controls.cc | 48 ++--- .../ui/qt/widgets/frogpilot_controls.h | 190 ++++-------------- selfdrive/ui/qt/network/networking.cc | 21 +- selfdrive/ui/qt/network/networking.h | 2 +- selfdrive/ui/qt/offroad/settings.cc | 18 +- selfdrive/ui/qt/onroad/annotated_camera.cc | 34 +--- selfdrive/ui/qt/onroad/annotated_camera.h | 4 +- selfdrive/ui/ui.cc | 4 +- system/manager/manager.py | 6 +- 17 files changed, 196 insertions(+), 343 deletions(-) diff --git a/cereal/custom.capnp b/cereal/custom.capnp index 8375709c5..5202fa156 100644 --- a/cereal/custom.capnp +++ b/cereal/custom.capnp @@ -50,32 +50,31 @@ struct FrogPilotPlan @0x80ae746ee2596b11 { accelerationJerk @0 :Float32; accelerationJerkStock @1 :Float32; adjustedCruise @2 :Float32; - alwaysOnLateralActive @3 :Bool; - dangerJerk @4 :Float32; - desiredFollowDistance @5 :Float32; - experimentalMode @6 :Bool; - forcingStop @7 :Bool; - frogpilotEvents @8: List(Car.CarEvent); - lateralCheck @9 :Bool; - laneWidthLeft @10 :Float32; - laneWidthRight @11 :Float32; - maxAcceleration @12 :Float32; - minAcceleration @13 :Float32; - redLight @14 :Bool; - safeObstacleDistance @15 :Int32; - safeObstacleDistanceStock @16 :Int32; - slcOverridden @17 :Bool; - slcOverriddenSpeed @18 :Float32; - slcSpeedLimit @19 :Float32; - slcSpeedLimitOffset @20 :Float32; - speedJerk @21 :Float32; - speedJerkStock @22 :Float32; - speedLimitChanged @23 :Bool; - stoppedEquivalenceFactor @24 :Int32; - tFollow @25 :Float32; - unconfirmedSlcSpeedLimit @26 :Float32; - vCruise @27 :Float32; - vtscControllingCurve @28 :Bool; + dangerJerk @3 :Float32; + desiredFollowDistance @4 :Float32; + experimentalMode @5 :Bool; + forcingStop @6 :Bool; + frogpilotEvents @7: List(Car.CarEvent); + lateralCheck @8 :Bool; + laneWidthLeft @9 :Float32; + laneWidthRight @10 :Float32; + maxAcceleration @11 :Float32; + minAcceleration @12 :Float32; + redLight @13 :Bool; + safeObstacleDistance @14 :Int32; + safeObstacleDistanceStock @15 :Int32; + slcOverridden @16 :Bool; + slcOverriddenSpeed @17 :Float32; + slcSpeedLimit @18 :Float32; + slcSpeedLimitOffset @19 :Float32; + speedJerk @20 :Float32; + speedJerkStock @21 :Float32; + speedLimitChanged @22 :Bool; + stoppedEquivalenceFactor @23 :Int32; + tFollow @24 :Float32; + unconfirmedSlcSpeedLimit @25 :Float32; + vCruise @26 :Float32; + vtscControllingCurve @27 :Bool; } struct CustomReserved5 @0xa5cd762cd951a455 { diff --git a/selfdrive/car/toyota/carstate.py b/selfdrive/car/toyota/carstate.py index 98dea943f..080ed7058 100644 --- a/selfdrive/car/toyota/carstate.py +++ b/selfdrive/car/toyota/carstate.py @@ -76,7 +76,7 @@ class CarState(CarStateBase): self.zss_angle_offset = 0 self.zss_threshold_count = 0 - def update(self, cp, cp_cam, frogpilot_toggles): + def update(self, cp, cp_cam, CC, frogpilot_toggles): ret = car.CarState.new_message() fp_ret = custom.FrogPilotCarState.new_message() @@ -229,15 +229,14 @@ class CarState(CarStateBase): self.pcm_neutral_force = cp.vl["PCM_CRUISE"]["NEUTRAL_FORCE"] # ZSS Support - Credit goes to the DragonPilot team! - if self.CP.flags & ToyotaFlags.ZSS and self.zss_threshold_count < ZSS_THRESHOLD_COUNT: + if self.CP.flags & ToyotaFlags.ZSS and self.zss_threshold_count <= ZSS_THRESHOLD_COUNT: zorro_steer = cp.vl["SECONDARY_STEER_ANGLE"]["ZORRO_STEER"] - # Only compute ZSS offset when cruise is active - cruise_active = ret.cruiseState.available - if cruise_active and not self.zss_cruise_active_last: - self.zss_compute = True # Cruise was just activated, so allow offset to be recomputed + # Only compute ZSS offset when control is active + if CC.latActive and not self.zss_cruise_active_last: self.zss_threshold_count = 0 - self.zss_cruise_active_last = cruise_active + self.zss_compute = True # Control was just activated, so allow offset to be recomputed + self.zss_cruise_active_last = CC.latActive # Compute ZSS offset if self.zss_compute: diff --git a/selfdrive/car/toyota/interface.py b/selfdrive/car/toyota/interface.py index c00a7e9e4..c682e6dc3 100644 --- a/selfdrive/car/toyota/interface.py +++ b/selfdrive/car/toyota/interface.py @@ -175,7 +175,7 @@ class CarInterface(CarInterfaceBase): # returns a car.CarState def _update(self, c, frogpilot_toggles): - ret, fp_ret = self.CS.update(self.cp, self.cp_cam, frogpilot_toggles) + ret, fp_ret = self.CS.update(self.cp, self.cp_cam, c, frogpilot_toggles) if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR) or (self.CP.flags & ToyotaFlags.SMART_DSU and not self.CP.flags & ToyotaFlags.RADAR_CAN_FILTER): ret.buttonEvents = [ diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index e7ff0fcf0..f71254f87 100644 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -53,6 +53,7 @@ EventName = car.CarEvent.EventName ButtonType = car.CarState.ButtonEvent.Type FrogPilotButtonType = custom.FrogPilotCarState.ButtonEvent.Type SafetyModel = car.CarParams.SafetyModel +GearShifter = car.CarState.GearShifter IGNORED_SAFETY_MODES = (SafetyModel.silent, SafetyModel.noOutput) CSID_MAP = {"1": EventName.roadCameraError, "2": EventName.wideRoadCameraError, "0": EventName.driverCameraError} @@ -555,8 +556,8 @@ class Controls: # Check if openpilot is engaged and actuators are enabled self.enabled = self.state in ENABLED_STATES - self.active = self.state in ACTIVE_STATES or self.always_on_lateral_active - if self.active: + self.active = self.state in ACTIVE_STATES + if self.active or self.always_on_lateral_active: self.current_alert_types.append(ET.WARNING) def state_control(self, CS): @@ -583,7 +584,7 @@ class Controls: # Check which actuators can be enabled standstill = CS.vEgo <= max(self.CP.minSteerSpeed, MIN_LATERAL_CONTROL_SPEED) or CS.standstill - CC.latActive = self.active and not CS.steerFaultTemporary and not CS.steerFaultPermanent and \ + CC.latActive = (self.active or self.always_on_lateral_active) and not CS.steerFaultTemporary and not CS.steerFaultPermanent and \ (not standstill or self.joystick_mode) and self.sm['frogpilotPlan'].lateralCheck CC.longActive = self.enabled and not self.events.contains(ET.OVERRIDE_LONGITUDINAL) and self.CP.openpilotLongitudinalControl @@ -710,7 +711,13 @@ class Controls: return CC, lac_log, FPCC def update_frogpilot_variables(self, CS): - self.always_on_lateral_active = self.sm['frogpilotPlan'].alwaysOnLateralActive and self.sm.all_checks(['frogpilotPlan']) + self.always_on_lateral_active |= self.frogpilot_toggles.always_on_lateral_main or CS.cruiseState.enabled + self.always_on_lateral_active &= self.frogpilot_toggles.always_on_lateral and CS.cruiseState.available + self.always_on_lateral_active &= CS.gearShifter not in (GearShifter.neutral, GearShifter.park, GearShifter.reverse, GearShifter.unknown) + self.always_on_lateral_active &= self.sm['frogpilotPlan'].lateralCheck + self.always_on_lateral_active &= not (self.frogpilot_toggles.always_on_lateral_lkas and self.sm['frogpilotCarState'].alwaysOnLateralDisabled) + self.always_on_lateral_active &= not (CS.brakePressed and CS.vEgo < self.frogpilot_toggles.always_on_lateral_pause_speed) or CS.standstill + if self.frogpilot_toggles.conditional_experimental_mode: self.experimental_mode = self.sm['frogpilotPlan'].experimentalMode @@ -728,7 +735,7 @@ class Controls: self.resume_previously_pressed = self.resume_pressed FPCC = custom.FrogPilotCarControl.new_message() - FPCC.alwaysOnLateralActive = self.always_on_lateral_active + FPCC.alwaysOnLateralActive = bool(self.always_on_lateral_active) FPCC.fcwEventTriggered = self.fcw_event_triggered FPCC.noEntryEventTriggered = self.no_entry_alert_triggered FPCC.resumePressed = self.resume_previously_pressed diff --git a/selfdrive/frogpilot/controls/frogpilot_planner.py b/selfdrive/frogpilot/controls/frogpilot_planner.py index 69dcd6519..b7666dea7 100644 --- a/selfdrive/frogpilot/controls/frogpilot_planner.py +++ b/selfdrive/frogpilot/controls/frogpilot_planner.py @@ -30,7 +30,8 @@ class FrogPilotPlanner: self.frogpilot_vcruise = FrogPilotVCruise(self) self.lead_one = Lead() - self.always_on_lateral_active = False + self.tracking_lead_mac = WeightedMovingAverageCalculator(window_size=5) + self.lateral_check = False self.lead_departing = False self.model_stopped = False @@ -43,8 +44,6 @@ class FrogPilotPlanner: self.tracking_lead_distance = 0 self.v_cruise = 0 - self.tracking_lead_mac = WeightedMovingAverageCalculator(window_size=4) - def update(self, carState, controlsState, frogpilotCarControl, frogpilotCarState, frogpilotNavigation, modelData, radarState, frogpilot_toggles): if frogpilot_toggles.radarless_model: model_leads = list(modelData.leadsV3) @@ -69,15 +68,8 @@ class FrogPilotPlanner: if frogpilot_toggles.openpilot_longitudinal: self.frogpilot_acceleration.update(controlsState, frogpilotCarState, v_cruise, v_ego, frogpilot_toggles) - self.always_on_lateral_active |= frogpilot_toggles.always_on_lateral_main or carState.cruiseState.enabled - self.always_on_lateral_active &= frogpilot_toggles.always_on_lateral and carState.cruiseState.available - self.always_on_lateral_active &= driving_gear - self.always_on_lateral_active &= self.lateral_check - self.always_on_lateral_active &= not (frogpilot_toggles.always_on_lateral_lkas and frogpilotCarState.alwaysOnLateralDisabled) - self.always_on_lateral_active &= not (carState.brakePressed and v_ego < frogpilot_toggles.always_on_lateral_pause_speed) or carState.standstill - run_cem = frogpilot_toggles.conditional_experimental_mode or frogpilot_toggles.force_stops or frogpilot_toggles.green_light_alert or frogpilot_toggles.show_stopping_point - if run_cem and (controlsState.enabled or self.always_on_lateral_active) and driving_gear: + if run_cem and (controlsState.enabled or frogpilotCarControl.alwaysOnLateralActive) and driving_gear: self.cem.update(carState, frogpilotNavigation, modelData, v_ego, v_lead, frogpilot_toggles) else: self.cem.stop_light_detected = False @@ -119,7 +111,8 @@ class FrogPilotPlanner: else: self.taking_curve_quickly = False - self.tracking_lead = self.set_lead_status(lead_distance, stopping_distance, v_ego) + self.tracking_lead = self.set_lead_status(carState, lead_distance, stopping_distance, v_ego) + if frogpilot_toggles.openpilot_longitudinal: self.v_cruise = self.frogpilot_vcruise.update(carState, controlsState, frogpilotCarControl, frogpilotCarState, frogpilotNavigation, modelData, v_cruise, v_ego, frogpilot_toggles) else: @@ -129,8 +122,9 @@ class FrogPilotPlanner: if self.frogpilot_events.frame == 1: # Force update to check the current state of "Always On Lateral" and holiday theme update_frogpilot_toggles() - def set_lead_status(self, lead_distance, stopping_distance, v_ego): - following_lead = self.lead_one.status and 1 < lead_distance < self.model_length + stopping_distance + def set_lead_status(self, carState, lead_distance, stopping_distance, v_ego): + following_lead = self.lead_one.status + following_lead &= 1 < lead_distance < self.model_length + stopping_distance or carState.standstill and self.tracking_lead following_lead &= v_ego > CRUISING_SPEED or self.tracking_lead self.tracking_lead_mac.add_data(following_lead) @@ -151,8 +145,6 @@ class FrogPilotPlanner: frogpilotPlan.adjustedCruise = float(min(self.frogpilot_vcruise.mtsc_target, self.frogpilot_vcruise.vtsc_target) * (CV.MS_TO_KPH if frogpilot_toggles.is_metric else CV.MS_TO_MPH)) frogpilotPlan.vtscControllingCurve = bool(self.frogpilot_vcruise.mtsc_target > self.frogpilot_vcruise.vtsc_target) - frogpilotPlan.alwaysOnLateralActive = self.always_on_lateral_active - frogpilotPlan.desiredFollowDistance = self.frogpilot_following.safe_obstacle_distance - self.frogpilot_following.stopped_equivalence_factor frogpilotPlan.safeObstacleDistance = self.frogpilot_following.safe_obstacle_distance frogpilotPlan.safeObstacleDistanceStock = self.frogpilot_following.safe_obstacle_distance_stock diff --git a/selfdrive/frogpilot/controls/lib/conditional_experimental_mode.py b/selfdrive/frogpilot/controls/lib/conditional_experimental_mode.py index a15dad77f..6a766c5c3 100644 --- a/selfdrive/frogpilot/controls/lib/conditional_experimental_mode.py +++ b/selfdrive/frogpilot/controls/lib/conditional_experimental_mode.py @@ -1,3 +1,5 @@ +from openpilot.common.params import Params + from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_functions import WeightedMovingAverageCalculator from openpilot.selfdrive.frogpilot.controls.lib.frogpilot_variables import CITY_SPEED_LIMIT, THRESHOLD @@ -5,10 +7,9 @@ class ConditionalExperimentalMode: def __init__(self, FrogPilotPlanner): self.frogpilot_planner = FrogPilotPlanner - self.params_memory = self.frogpilot_planner.params_memory + self.params_memory = Params("/dev/shm/params") self.curvature_wmac = WeightedMovingAverageCalculator(window_size=5) - self.slow_lead_wmac = WeightedMovingAverageCalculator(window_size=3) self.stop_light_wmac = WeightedMovingAverageCalculator(window_size=5) self.curve_detected = False @@ -61,6 +62,8 @@ class ConditionalExperimentalMode: self.status_value = 17 return True + return False + def update_conditions(self, tracking_lead, v_ego, v_lead, frogpilot_toggles): self.curve_detection(tracking_lead, v_ego, frogpilot_toggles) self.slow_lead(tracking_lead, v_lead, frogpilot_toggles) @@ -82,10 +85,8 @@ class ConditionalExperimentalMode: slower_lead = self.frogpilot_planner.frogpilot_following.slower_lead and frogpilot_toggles.conditional_slower_lead stopped_lead = frogpilot_toggles.conditional_stopped_lead and v_lead < 1 - self.slow_lead_wmac.add_data(slower_lead or stopped_lead) - self.slow_lead_detected = self.slow_lead_wmac.get_weighted_average() >= THRESHOLD + self.slow_lead_detected = slower_lead or stopped_lead else: - self.slow_lead_wmac.reset_data() self.slow_lead_detected = False def stop_sign_and_light(self, tracking_lead, v_ego, frogpilot_toggles): diff --git a/selfdrive/frogpilot/ui/qt/offroad/control_settings.cc b/selfdrive/frogpilot/ui/qt/offroad/control_settings.cc index 27d5ddb98..9698a26fb 100644 --- a/selfdrive/frogpilot/ui/qt/offroad/control_settings.cc +++ b/selfdrive/frogpilot/ui/qt/offroad/control_settings.cc @@ -208,7 +208,11 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil std::vector navigationToggleNames{tr("Intersections"), tr("Turns"), tr("With Lead")}; controlToggle = new FrogPilotParamToggleControl(param, title, desc, icon, navigationToggles, navigationToggleNames); } else if (param == "CEModelStopTime") { - controlToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 10, std::map(), this, false, tr(" seconds")); + std::map modelStopTimeLabels; + for (int i = 0; i <= 10; i++) { + modelStopTimeLabels[i] = (i == 0) ? tr("Off") : QString::number(i) + " seconds"; + } + controlToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 10, modelStopTimeLabels, this, false); } else if (param == "DeviceManagement") { FrogPilotParamManageControl *deviceManagementToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); @@ -268,8 +272,7 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil }); controlToggle = reinterpret_cast(personalitiesInfoBtn); } else if (param == "ResetTrafficPersonality" || param == "ResetAggressivePersonality" || param == "ResetStandardPersonality" || param == "ResetRelaxedPersonality") { - std::vector personalityOptions{tr("Reset")}; - FrogPilotButtonsControl *profileBtn = new FrogPilotButtonsControl(title, desc, icon, personalityOptions); + FrogPilotButtonsControl *profileBtn = new FrogPilotButtonsControl(title, {tr("Reset")}, desc); controlToggle = profileBtn; } else if (param == "TrafficPersonalityProfile") { FrogPilotParamManageControl *trafficPersonalityToggle = new FrogPilotParamManageControl(param, title, desc, icon, this); @@ -326,8 +329,7 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil } } else if (param == "OnroadDistanceButtonButtons") { - std::vector CustomDistanceIconsOptions{tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")}; - manageDistanceIconsBtn = new FrogPilotButtonsControl(title, desc, icon, CustomDistanceIconsOptions); + manageDistanceIconsBtn = new FrogPilotButtonsControl(title, {tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")}, desc); std::function formatIconName = [](QString name) -> QString { QChar separator = name.contains('_') ? '_' : '-'; @@ -406,7 +408,7 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil themeDeleting = false; } } else if (id == 1) { - if (manageDistanceIconsBtn->getButton(id)->text() == tr("CANCEL")) { + if (iconsDownloading) { paramsMemory.putBool("CancelThemeDownload", true); cancellingDownload = true; @@ -523,11 +525,11 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil controlToggle = longitudinalTuneToggle; } else if (param == "AccelerationProfile") { std::vector profileOptions{tr("Standard"), tr("Eco"), tr("Sport"), tr("Sport+")}; - FrogPilotButtonParamControl *profileSelection = new FrogPilotButtonParamControl(param, title, desc, icon, profileOptions); + ButtonParamControl *profileSelection = new ButtonParamControl(param, title, desc, icon, profileOptions); controlToggle = profileSelection; } else if (param == "DecelerationProfile") { std::vector profileOptions{tr("Standard"), tr("Eco"), tr("Sport")}; - FrogPilotButtonParamControl *profileSelection = new FrogPilotButtonParamControl(param, title, desc, icon, profileOptions); + ButtonParamControl *profileSelection = new ButtonParamControl(param, title, desc, icon, profileOptions); controlToggle = profileSelection; } else if (param == "StoppingDistance") { controlToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 10, std::map(), this, false, tr(" feet")); @@ -582,7 +584,7 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil }); controlToggle = modelRandomizerToggle; } else if (param == "ManageBlacklistedModels") { - FrogPilotButtonsControl *blacklistBtn = new FrogPilotButtonsControl(title, desc, icon, {tr("ADD"), tr("REMOVE")}); + FrogPilotButtonsControl *blacklistBtn = new FrogPilotButtonsControl(title, {tr("ADD"), tr("REMOVE")}, desc); QObject::connect(blacklistBtn, &FrogPilotButtonsControl::buttonClicked, [=](int id) { QStringList blacklistedModels = QString::fromStdString(params.get("BlacklistedModels")).split(",", QString::SkipEmptyParts); QMap labelToModelMap; @@ -841,7 +843,7 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil selectModelBtn->setValue(QString::fromStdString(params.get("ModelName"))); controlToggle = reinterpret_cast(selectModelBtn); } else if (param == "ResetCalibrations") { - FrogPilotButtonsControl *resetCalibrationsBtn = new FrogPilotButtonsControl(title, desc, icon, {tr("RESET ALL"), tr("RESET ONE")}); + FrogPilotButtonsControl *resetCalibrationsBtn = new FrogPilotButtonsControl(title, {tr("RESET ALL"), tr("RESET ONE")}, desc); QObject::connect(resetCalibrationsBtn, &FrogPilotButtonsControl::showDescriptionEvent, this, &FrogPilotControlsPanel::updateCalibrationDescription); QObject::connect(resetCalibrationsBtn, &FrogPilotButtonsControl::buttonClicked, [=](int id) { if (id == 0) { @@ -1013,11 +1015,11 @@ FrogPilotControlsPanel::FrogPilotControlsPanel(SettingsWindow *parent) : FrogPil controlToggle = new FrogPilotParamToggleControl(param, title, desc, icon, slcOffsetToggles, slcOffsetToggleNames); } else if (param == "SLCFallback") { std::vector fallbackOptions{tr("Set Speed"), tr("Experimental Mode"), tr("Previous Limit")}; - FrogPilotButtonParamControl *fallbackSelection = new FrogPilotButtonParamControl(param, title, desc, icon, fallbackOptions); + ButtonParamControl *fallbackSelection = new ButtonParamControl(param, title, desc, icon, fallbackOptions); controlToggle = fallbackSelection; } else if (param == "SLCOverride") { std::vector overrideOptions{tr("None"), tr("Manual Set Speed"), tr("Set Speed")}; - FrogPilotButtonParamControl *overrideSelection = new FrogPilotButtonParamControl(param, title, desc, icon, overrideOptions); + ButtonParamControl *overrideSelection = new ButtonParamControl(param, title, desc, icon, overrideOptions); controlToggle = overrideSelection; } else if (param == "SLCPriority") { ButtonControl *slcPriorityButton = new ButtonControl(title, tr("SELECT"), desc); @@ -1305,9 +1307,9 @@ void FrogPilotControlsPanel::updateState(const UIState &s) { } manageDistanceIconsBtn->setText(1, iconsDownloading ? tr("CANCEL") : tr("DOWNLOAD")); - manageDistanceIconsBtn->setButtonEnabled(0, !themeDeleting && !themeDownloading); - manageDistanceIconsBtn->setButtonEnabled(1, s.scene.online && (!themeDownloading || iconsDownloading) && !cancellingDownload && !themeDeleting && !iconsDownloaded); - manageDistanceIconsBtn->setButtonEnabled(2, !themeDeleting && !themeDownloading); + manageDistanceIconsBtn->setEnabledButtons(0, !themeDeleting && !themeDownloading); + manageDistanceIconsBtn->setEnabledButtons(1, s.scene.online && (!themeDownloading || iconsDownloading) && !cancellingDownload && !themeDeleting && !iconsDownloaded); + manageDistanceIconsBtn->setEnabledButtons(2, !themeDeleting && !themeDownloading); } else if (modelManagementOpen) { downloadAllModelsBtn->setText(modelDownloading && allModelsDownloading ? tr("CANCEL") : tr("DOWNLOAD")); downloadModelBtn->setText(modelDownloading && !allModelsDownloading ? tr("CANCEL") : tr("DOWNLOAD")); diff --git a/selfdrive/frogpilot/ui/qt/offroad/visual_settings.cc b/selfdrive/frogpilot/ui/qt/offroad/visual_settings.cc index dc75b0000..9be577e61 100644 --- a/selfdrive/frogpilot/ui/qt/offroad/visual_settings.cc +++ b/selfdrive/frogpilot/ui/qt/offroad/visual_settings.cc @@ -119,8 +119,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot }); visualToggle = personalizeOpenpilotToggle; } else if (param == "CustomColors") { - std::vector customColorsOptions{tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")}; - manageCustomColorsBtn = new FrogPilotButtonsControl(title, desc, icon, customColorsOptions); + manageCustomColorsBtn = new FrogPilotButtonsControl(title, {tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")}, desc); std::function formatColorName = [](QString name) -> QString { QChar separator = name.contains('_') ? '_' : '-'; @@ -201,7 +200,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot themeDeleting = false; } } else if (id == 1) { - if (manageCustomColorsBtn->getButton(id)->text() == tr("CANCEL")) { + if (colorDownloading) { paramsMemory.putBool("CancelThemeDownload", true); cancellingDownload = true; @@ -250,8 +249,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot manageCustomColorsBtn->setValue(currentColor); visualToggle = reinterpret_cast(manageCustomColorsBtn); } else if (param == "CustomIcons") { - std::vector customIconsOptions{tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")}; - manageCustomIconsBtn = new FrogPilotButtonsControl(title, desc, icon, customIconsOptions); + manageCustomIconsBtn = new FrogPilotButtonsControl(title, {tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")}, desc); std::function formatIconName = [](QString name) -> QString { QChar separator = name.contains('_') ? '_' : '-'; @@ -331,7 +329,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot themeDeleting = false; } } else if (id == 1) { - if (manageCustomIconsBtn->getButton(id)->text() == tr("CANCEL")) { + if (iconDownloading) { paramsMemory.putBool("CancelThemeDownload", true); cancellingDownload = true; @@ -380,8 +378,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot manageCustomIconsBtn->setValue(currentIcon); visualToggle = reinterpret_cast(manageCustomIconsBtn); } else if (param == "CustomSignals") { - std::vector customSignalsOptions{tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")}; - manageCustomSignalsBtn = new FrogPilotButtonsControl(title, desc, icon, customSignalsOptions); + manageCustomSignalsBtn = new FrogPilotButtonsControl(title, {tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")}, desc); std::function formatSignalName = [](QString name) -> QString { QChar separator = name.contains('_') ? '_' : '-'; @@ -461,7 +458,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot themeDeleting = false; } } else if (id == 1) { - if (manageCustomSignalsBtn->getButton(id)->text() == tr("CANCEL")) { + if (signalDownloading) { paramsMemory.putBool("CancelThemeDownload", true); cancellingDownload = true; @@ -510,8 +507,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot manageCustomSignalsBtn->setValue(currentSignal); visualToggle = reinterpret_cast(manageCustomSignalsBtn); } else if (param == "CustomSounds") { - std::vector customSoundsOptions{tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")}; - manageCustomSoundsBtn = new FrogPilotButtonsControl(title, desc, icon, customSoundsOptions); + manageCustomSoundsBtn = new FrogPilotButtonsControl(title, {tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")}, desc); std::function formatSoundName = [](QString name) -> QString { QChar separator = name.contains('_') ? '_' : '-'; @@ -591,7 +587,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot themeDeleting = false; } } else if (id == 1) { - if (manageCustomSoundsBtn->getButton(id)->text() == tr("CANCEL")) { + if (soundDownloading) { paramsMemory.putBool("CancelThemeDownload", true); cancellingDownload = true; @@ -640,8 +636,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot manageCustomSoundsBtn->setValue(currentSound); visualToggle = reinterpret_cast(manageCustomSoundsBtn); } else if (param == "WheelIcon") { - std::vector wheelIconOptions{tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")}; - manageWheelIconsBtn = new FrogPilotButtonsControl(title, desc, icon, wheelIconOptions); + manageWheelIconsBtn = new FrogPilotButtonsControl(title, {tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")}, desc); std::function formatWheelName = [](QString name) -> QString { QChar separator = name.contains('_') ? '_' : '-'; @@ -721,15 +716,15 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot themeDeleting = false; } } else if (id == 1) { - if (manageWheelIconsBtn->getButton(id)->text() == tr("CANCEL")) { + if (wheelDownloading) { paramsMemory.putBool("CancelThemeDownload", true); cancellingDownload = true; QTimer::singleShot(2000, [=]() { paramsMemory.putBool("CancelThemeDownload", false); cancellingDownload = false; - themeDownloading = false; wheelDownloading = false; + themeDownloading = false; }); } else { QStringList downloadableWheels = QString::fromStdString(params.get("DownloadableWheels")).split(","); @@ -773,8 +768,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot downloadStatusLabel = new LabelControl(title, "Idle"); visualToggle = reinterpret_cast(downloadStatusLabel); } else if (param == "StartupAlert") { - std::vector startupAlertOptions{tr("STOCK"), tr("FROGPILOT"), tr("CUSTOM"), tr("CLEAR")}; - FrogPilotButtonsControl *startupAlertButton = new FrogPilotButtonsControl(title, desc, icon, startupAlertOptions); + FrogPilotButtonsControl *startupAlertButton = new FrogPilotButtonsControl(title, {tr("STOCK"), tr("FROGPILOT"), tr("CUSTOM"), tr("CLEAR")}, desc); QObject::connect(startupAlertButton, &FrogPilotButtonsControl::buttonClicked, [=](int id) { int maxLengthTop = 35; int maxLengthBottom = 45; @@ -947,7 +941,7 @@ FrogPilotVisualsPanel::FrogPilotVisualsPanel(SettingsWindow *parent) : FrogPilot visualToggle = qolToggle; } else if (param == "CameraView") { std::vector cameraOptions{tr("Auto"), tr("Driver"), tr("Standard"), tr("Wide")}; - FrogPilotButtonParamControl *preferredCamera = new FrogPilotButtonParamControl(param, title, desc, icon, cameraOptions); + ButtonParamControl *preferredCamera = new ButtonParamControl(param, title, desc, icon, cameraOptions); visualToggle = preferredCamera; } else if (param == "BigMap") { std::vector mapToggles{"FullMap"}; @@ -1102,29 +1096,29 @@ void FrogPilotVisualsPanel::updateState(const UIState &s) { } manageCustomColorsBtn->setText(1, colorDownloading ? tr("CANCEL") : tr("DOWNLOAD")); - manageCustomColorsBtn->setButtonEnabled(0, !themeDeleting && !themeDownloading); - manageCustomColorsBtn->setButtonEnabled(1, s.scene.online && (!themeDownloading || colorDownloading) && !cancellingDownload && !themeDeleting && !colorsDownloaded); - manageCustomColorsBtn->setButtonEnabled(2, !themeDeleting && !themeDownloading); + manageCustomColorsBtn->setEnabledButtons(0, !themeDeleting && !themeDownloading); + manageCustomColorsBtn->setEnabledButtons(1, s.scene.online && (!themeDownloading || colorDownloading) && !cancellingDownload && !themeDeleting && !colorsDownloaded); + manageCustomColorsBtn->setEnabledButtons(2, !themeDeleting && !themeDownloading); manageCustomIconsBtn->setText(1, iconDownloading ? tr("CANCEL") : tr("DOWNLOAD")); - manageCustomIconsBtn->setButtonEnabled(0, !themeDeleting && !themeDownloading); - manageCustomIconsBtn->setButtonEnabled(1, s.scene.online && (!themeDownloading || iconDownloading) && !cancellingDownload && !themeDeleting && !iconsDownloaded); - manageCustomIconsBtn->setButtonEnabled(2, !themeDeleting && !themeDownloading); + manageCustomIconsBtn->setEnabledButtons(0, !themeDeleting && !themeDownloading); + manageCustomIconsBtn->setEnabledButtons(1, s.scene.online && (!themeDownloading || iconDownloading) && !cancellingDownload && !themeDeleting && !iconsDownloaded); + manageCustomIconsBtn->setEnabledButtons(2, !themeDeleting && !themeDownloading); manageCustomSignalsBtn->setText(1, signalDownloading ? tr("CANCEL") : tr("DOWNLOAD")); - manageCustomSignalsBtn->setButtonEnabled(0, !themeDeleting && !themeDownloading); - manageCustomSignalsBtn->setButtonEnabled(1, s.scene.online && (!themeDownloading || signalDownloading) && !cancellingDownload && !themeDeleting && !signalsDownloaded); - manageCustomSignalsBtn->setButtonEnabled(2, !themeDeleting && !themeDownloading); + manageCustomSignalsBtn->setEnabledButtons(0, !themeDeleting && !themeDownloading); + manageCustomSignalsBtn->setEnabledButtons(1, s.scene.online && (!themeDownloading || signalDownloading) && !cancellingDownload && !themeDeleting && !signalsDownloaded); + manageCustomSignalsBtn->setEnabledButtons(2, !themeDeleting && !themeDownloading); manageCustomSoundsBtn->setText(1, soundDownloading ? tr("CANCEL") : tr("DOWNLOAD")); - manageCustomSoundsBtn->setButtonEnabled(0, !themeDeleting && !themeDownloading); - manageCustomSoundsBtn->setButtonEnabled(1, s.scene.online && (!themeDownloading || soundDownloading) && !cancellingDownload && !themeDeleting && !soundsDownloaded); - manageCustomSoundsBtn->setButtonEnabled(2, !themeDeleting && !themeDownloading); + manageCustomSoundsBtn->setEnabledButtons(0, !themeDeleting && !themeDownloading); + manageCustomSoundsBtn->setEnabledButtons(1, s.scene.online && (!themeDownloading || soundDownloading) && !cancellingDownload && !themeDeleting && !soundsDownloaded); + manageCustomSoundsBtn->setEnabledButtons(2, !themeDeleting && !themeDownloading); manageWheelIconsBtn->setText(1, wheelDownloading ? tr("CANCEL") : tr("DOWNLOAD")); - manageWheelIconsBtn->setButtonEnabled(0, !themeDeleting && !themeDownloading); - manageWheelIconsBtn->setButtonEnabled(1, s.scene.online && (!themeDownloading || wheelDownloading) && !cancellingDownload && !themeDeleting && !wheelsDownloaded); - manageWheelIconsBtn->setButtonEnabled(2, !themeDeleting && !themeDownloading); + manageWheelIconsBtn->setEnabledButtons(0, !themeDeleting && !themeDownloading); + manageWheelIconsBtn->setEnabledButtons(1, s.scene.online && (!themeDownloading || wheelDownloading) && !cancellingDownload && !themeDeleting && !wheelsDownloaded); + manageWheelIconsBtn->setEnabledButtons(2, !themeDeleting && !themeDownloading); } started = s.scene.started; diff --git a/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.cc b/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.cc index 5cc6a7b0d..1114b9e95 100644 --- a/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.cc +++ b/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.cc @@ -3,13 +3,14 @@ Params paramsMemory{"/dev/shm/params"}; std::atomic callCounter(0); - void updateFrogPilotToggles() { int currentCall = ++callCounter; + std::thread([currentCall]() { paramsMemory.putBool("FrogPilotTogglesUpdated", true); util::sleep_for(1000); - if (currentCall == callCounter) { + + if (currentCall == callCounter.load()) { paramsMemory.putBool("FrogPilotTogglesUpdated", false); } }).detach(); @@ -21,53 +22,28 @@ QColor loadThemeColors(const QString &colorKey) { QJsonParseError parseError; QJsonDocument doc = QJsonDocument::fromJson(file.readAll(), &parseError); - file.close(); - if (parseError.error != QJsonParseError::NoError || !doc.isObject()) return QColor(); QJsonObject colorObj = doc.object().value(colorKey).toObject(); - int red = colorObj["red"].toInt(); - int green = colorObj["green"].toInt(); - int blue = colorObj["blue"].toInt(); - int alpha = colorObj["alpha"].toInt(); - - return QColor(red, green, blue, alpha); + return QColor( + colorObj["red"].toInt(), + colorObj["green"].toInt(), + colorObj["blue"].toInt(), + colorObj["alpha"].toInt() + ); } bool FrogPilotConfirmationDialog::toggle(const QString &prompt_text, const QString &confirm_text, QWidget *parent) { - ConfirmationDialog d = ConfirmationDialog(prompt_text, confirm_text, tr("Reboot Later"), false, parent); + ConfirmationDialog d(prompt_text, confirm_text, tr("Reboot Later"), false, parent); return d.exec(); } bool FrogPilotConfirmationDialog::toggleAlert(const QString &prompt_text, const QString &button_text, QWidget *parent) { - ConfirmationDialog d = ConfirmationDialog(prompt_text, button_text, "", false, parent); + ConfirmationDialog d(prompt_text, button_text, "", false, parent); return d.exec(); } bool FrogPilotConfirmationDialog::yesorno(const QString &prompt_text, QWidget *parent) { - ConfirmationDialog d = ConfirmationDialog(prompt_text, tr("Yes"), tr("No"), false, parent); + ConfirmationDialog d(prompt_text, tr("Yes"), tr("No"), false, parent); return d.exec(); } - -FrogPilotButtonIconControl::FrogPilotButtonIconControl(const QString &title, const QString &text, const QString &desc, const QString &icon, QWidget *parent) : AbstractControl(title, desc, icon, parent) { - btn.setText(text); - btn.setStyleSheet(R"( - QPushButton { - padding: 0; - border-radius: 50px; - font-size: 35px; - font-weight: 500; - color: #E4E4E4; - background-color: #393939; - } - QPushButton:pressed { - background-color: #4a4a4a; - } - QPushButton:disabled { - color: #33E4E4E4; - } - )"); - btn.setFixedSize(250, 100); - QObject::connect(&btn, &QPushButton::clicked, this, &FrogPilotButtonIconControl::clicked); - hlayout->addWidget(&btn); -} diff --git a/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.h b/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.h index 87fb8db13..7141aafff 100644 --- a/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.h +++ b/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.h @@ -26,13 +26,16 @@ public: class FrogPilotListWidget : public QWidget { Q_OBJECT + public: - explicit FrogPilotListWidget(QWidget *parent = nullptr) : QWidget(parent), outer_layout(this) { + explicit FrogPilotListWidget(QWidget *parent = nullptr) : QWidget(parent), outer_layout(this), inner_layout() { outer_layout.setMargin(0); outer_layout.setSpacing(0); outer_layout.addLayout(&inner_layout); + inner_layout.setMargin(0); inner_layout.setSpacing(25); // default spacing is 25 + outer_layout.addStretch(); } inline void addItem(QWidget *w) { @@ -47,93 +50,53 @@ public: inline void setSpacing(int spacing) { inner_layout.setSpacing(spacing); - adjustStretch(); - } - -private: - void adjustStretch() { - if (inner_layout.stretch(inner_layout.count() - 1) > 0) { - inner_layout.setStretch(inner_layout.count() - 1, 0); - } - if (inner_layout.count() > 3) { - outer_layout.addStretch(); - } } +protected: void paintEvent(QPaintEvent *event) override { QPainter p(this); p.setPen(Qt::gray); - int visibleWidgetCount = 0; std::vector visibleRects; - for (int i = 0; i < inner_layout.count(); ++i) { QWidget *widget = inner_layout.itemAt(i)->widget(); if (widget && widget->isVisible()) { - visibleWidgetCount++; - visibleRects.push_back(inner_layout.itemAt(i)->geometry()); + visibleRects.push_back(widget->geometry()); } } - for (int i = 0; i < visibleWidgetCount - 1; ++i) { - int bottom = visibleRects[i].bottom() + inner_layout.spacing() / 2; + int lineOffset = inner_layout.spacing() / 2; + for (size_t i = 0; i + 1 < visibleRects.size(); ++i) { + int bottom = visibleRects[i].bottom() + lineOffset; p.drawLine(visibleRects[i].left() + 40, bottom, visibleRects[i].right() - 40, bottom); } } +private: + void adjustStretch() { + if (inner_layout.count() > 3) { + outer_layout.addStretch(); + } + } + QVBoxLayout outer_layout; QVBoxLayout inner_layout; }; -class FrogPilotButtonControl : public AbstractControl { +class FrogPilotButtonsControl : public AbstractControl { Q_OBJECT public: - FrogPilotButtonControl(const QString &title, const QString &text, const QString &desc = "", QWidget *parent = nullptr); - inline void setText(const QString &text) { btn.setText(text); } - inline QString text() const { return btn.text(); } + FrogPilotButtonsControl(const QString &title, const std::vector &button_labels, const QString &desc, bool checkable = false, QWidget *parent = nullptr) + : AbstractControl(title, desc, "") { -signals: - void clicked(); - -public slots: - void setEnabled(bool enabled) { btn.setEnabled(enabled); } - -private: - QPushButton btn; -}; - -class FrogPilotButtonIconControl : public AbstractControl { - Q_OBJECT - -public: - FrogPilotButtonIconControl(const QString &title, const QString &text, const QString &desc = "", const QString &icon = "", QWidget *parent = nullptr); - inline void setText(const QString &text) { btn.setText(text); } - inline QString text() const { return btn.text(); } - -signals: - void clicked(); - -public slots: - void setEnabled(bool enabled) { btn.setEnabled(enabled); } - -private: - QPushButton btn; -}; - -class FrogPilotButtonParamControl : public ParamControl { - Q_OBJECT -public: - FrogPilotButtonParamControl(const QString ¶m, const QString &title, const QString &desc, const QString &icon, - const std::vector &button_texts, const int minimum_button_width = 225) - : ParamControl(param, title, desc, icon) { const QString style = R"( QPushButton { border-radius: 50px; font-size: 40px; font-weight: 500; - height:100px; - padding: 0 25 0 25; + height: 100px; + padding: 0 25px; color: #E4E4E4; background-color: #393939; } @@ -148,95 +111,18 @@ public: } )"; - key = param.toStdString(); - int value = atoi(params.get(key).c_str()); - button_group = new QButtonGroup(this); button_group->setExclusive(true); - for (size_t i = 0; i < button_texts.size(); i++) { - QPushButton *button = new QPushButton(button_texts[i], this); - button->setCheckable(true); - button->setChecked(i == value); + + for (int i = 0; i < button_labels.size(); ++i) { + QPushButton *button = new QPushButton(button_labels[i], this); + button->setCheckable(checkable); button->setStyleSheet(style); - button->setMinimumWidth(minimum_button_width); + button->setMinimumWidth(255); hlayout->addWidget(button); button_group->addButton(button, i); - } - QObject::connect(button_group, QOverload::of(&QButtonGroup::buttonToggled), [=](int id, bool checked) { - if (checked) { - params.put(key, std::to_string(id)); - refresh(); - emit buttonClicked(id); - } - }); - - toggle.hide(); - } - - void setEnabled(bool enable) { - for (auto btn : button_group->buttons()) { - btn->setEnabled(enable); - } - } - -signals: - void buttonClicked(int id); - -private: - std::string key; - Params params; - QButtonGroup *button_group; -}; - -class FrogPilotButtonsControl : public ParamControl { - Q_OBJECT -public: - FrogPilotButtonsControl(const QString &title, const QString &desc, const QString &icon, - const std::vector &button_texts, const bool checkable = false, const int minimum_button_width = 225) - : ParamControl("", title, desc, icon) { - const QString style = R"( - QPushButton { - border-radius: 50px; - font-size: 40px; - font-weight: 500; - height: 100px; - padding: 0 25px 0 25px; - color: #E4E4E4; - background-color: #393939; - } - QPushButton:checked { - background-color: #33Ab4C; - } - QPushButton:pressed { - background-color: #33Ab4C; - } - QPushButton:disabled { - color: #33E4E4E4; - } - )"; - - button_group = new QButtonGroup(this); - - for (size_t i = 0; i < button_texts.size(); i++) { - QPushButton *button = new QPushButton(button_texts[i], this); - button->setStyleSheet(style); - button->setCheckable(checkable); - button->setMinimumWidth(minimum_button_width); - hlayout->addWidget(button); - button_group->addButton(button, static_cast(i)); - - connect(button, &QPushButton::clicked, this, [this, i]() { - emit buttonClicked(static_cast(i)); - }); - } - - toggle.hide(); - } - - void updateButtonStyles(int id) { - for (auto button : button_group->buttons()) { - button->setChecked(button_group->id(button) == id); + connect(button, &QPushButton::clicked, this, [this, i]() { emit buttonClicked(i); }); } } @@ -246,27 +132,31 @@ public: } } - void setButtonEnabled(int id, bool enable) { - if (QPushButton *button = qobject_cast(button_group->button(id))) { + void setCheckedButton(int id) { + if (auto button = button_group->button(id)) { + button->setChecked(true); + } + } + + void setEnabledButtons(int id, bool enable) { + QPushButton *button = qobject_cast(button_group->button(id)); + if (button) { button->setEnabled(enable); } } void setText(int id, const QString &text) { - if (QPushButton *button = qobject_cast(button_group->button(id))) { + QPushButton *button = qobject_cast(button_group->button(id)); + if (button) { button->setText(text); } } - QPushButton *getButton(int id) const { - return qobject_cast(button_group->button(id)); - } +private: + QButtonGroup *button_group; signals: void buttonClicked(int id); - -private: - QButtonGroup *button_group; }; class FrogPilotButtonsParamControl : public ParamControl { diff --git a/selfdrive/ui/qt/network/networking.cc b/selfdrive/ui/qt/network/networking.cc index e2b3c2b66..7da71a53b 100644 --- a/selfdrive/ui/qt/network/networking.cc +++ b/selfdrive/ui/qt/network/networking.cc @@ -126,12 +126,21 @@ AdvancedNetworking::AdvancedNetworking(QWidget* parent, WifiManager* wifi): QWid ListWidget *list = new ListWidget(this); // Enable tethering layout - std::vector tetheringSelection{tr("Off"), tr("Only Onroad"), tr("Always")}; - tetheringToggle = new FrogPilotButtonParamControl("TetheringEnabled", "Enable Tethering", "", "", tetheringSelection); + std::vector tetheringSelection{tr("Off"), tr("Always"), tr("Only Onroad"), tr("Until Reboot")}; + tetheringToggle = new ButtonParamControl("TetheringEnabled", tr("Enable Tethering"), + tr("Allow tethering with your data SIM and keep it active either while driving or continuously."), + "", tetheringSelection); + if (params.getInt("TetheringEnabled") == 3) { + params.remove("TetheringEnabled"); + tetheringToggle->setCheckedButton(0); + } + QButtonGroup *buttonGroup = tetheringToggle->findChild(); + if (buttonGroup) { + QObject::connect(buttonGroup, QOverload::of(&QButtonGroup::buttonClicked), [this](int id) { + toggleTethering(id); + }); + } list->addItem(tetheringToggle); - QObject::connect(tetheringToggle, &FrogPilotButtonParamControl::buttonClicked, [this](int id) { - toggleTethering(id); - }); // Change tethering password ButtonControl *editPasswordButton = new ButtonControl(tr("Tethering Password"), tr("EDIT")); @@ -224,7 +233,7 @@ void AdvancedNetworking::refresh() { } void AdvancedNetworking::toggleTethering(int id) { - wifi->setTetheringEnabled(id == 2); + wifi->setTetheringEnabled(id == 1 || id == 3); tetheringToggle->setEnabled(false); updateFrogPilotToggles(); } diff --git a/selfdrive/ui/qt/network/networking.h b/selfdrive/ui/qt/network/networking.h index 3fcc307c0..75d259926 100644 --- a/selfdrive/ui/qt/network/networking.h +++ b/selfdrive/ui/qt/network/networking.h @@ -65,7 +65,7 @@ public: private: LabelControl* ipLabel; - FrogPilotButtonParamControl* tetheringToggle; + ButtonParamControl* tetheringToggle; ToggleControl* roamingToggle; ButtonControl* editApnButton; ButtonControl* hiddenNetworkButton; diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 69430a753..f944352a7 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -316,8 +316,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { addItem(deleteDrivingDataBtn); // Screen recordings - std::vector recordingsOptions{tr("DELETE"), tr("RENAME")}; - FrogPilotButtonsControl *screenRecordingsBtn = new FrogPilotButtonsControl(tr("Screen Recordings"), tr("Delete or rename your screen recordings."), "", recordingsOptions); + FrogPilotButtonsControl *screenRecordingsBtn = new FrogPilotButtonsControl(tr("Screen Recordings"), {tr("DELETE"), tr("RENAME")}, tr("Delete or rename your screen recordings.")); connect(screenRecordingsBtn, &FrogPilotButtonsControl::buttonClicked, [=](int id) { QDir recordingsDir("/data/media/0/videos"); QStringList recordingsNames = recordingsDir.entryList(QDir::Files | QDir::NoDotAndDotDot); @@ -372,8 +371,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { addItem(screenRecordingsBtn); // Backup FrogPilot - std::vector frogpilotBackupOptions{tr("BACKUP"), tr("DELETE"), tr("RESTORE")}; - FrogPilotButtonsControl *frogpilotBackupBtn = new FrogPilotButtonsControl(tr("FrogPilot Backups"), tr("Backup, delete, or restore your FrogPilot backups."), "", frogpilotBackupOptions); + FrogPilotButtonsControl *frogpilotBackupBtn = new FrogPilotButtonsControl(tr("FrogPilot Backups"), {tr("BACKUP"), tr("DELETE"), tr("RESTORE")}, tr("Backup, delete, or restore your FrogPilot backups.")); connect(frogpilotBackupBtn, &FrogPilotButtonsControl::buttonClicked, [=](int id) { QDir backupDir("/data/backups"); QStringList backupNames = backupDir.entryList(QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::Name); @@ -529,8 +527,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { addItem(frogpilotBackupBtn); // Backup toggles - std::vector toggleBackupOptions{tr("BACKUP"), tr("DELETE"), tr("RESTORE")}; - FrogPilotButtonsControl *toggleBackupBtn = new FrogPilotButtonsControl(tr("Toggle Backups"), tr("Backup, delete, or restore your toggle backups."), "", toggleBackupOptions); + FrogPilotButtonsControl *toggleBackupBtn = new FrogPilotButtonsControl(tr("Toggle Backups"), {tr("BACKUP"), tr("DELETE"), tr("RESTORE")}, tr("Backup, delete, or restore your toggle backups.")); connect(toggleBackupBtn, &FrogPilotButtonsControl::buttonClicked, [=](int id) { QDir backupDir("/data/toggle_backups"); QStringList backupNames = backupDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot); @@ -674,8 +671,7 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { addItem(resetTogglesBtn); // Force offroad/onroad - std::vector forceStartedOptions{tr("OFFROAD"), tr("ONROAD"), tr("OFF")}; - forceStartedBtn = new FrogPilotButtonsControl(tr("Force Started State"), tr("Force openpilot either offroad or onroad."), "", forceStartedOptions, true); + forceStartedBtn = new FrogPilotButtonsControl(tr("Force Started State"), {tr("OFFROAD"), tr("ONROAD"), tr("OFF")}, tr("Force openpilot either offroad or onroad."), true); connect(forceStartedBtn, &FrogPilotButtonsControl::buttonClicked, [=](int id) { if (id == 0) { paramsMemory.putBool("ForceOffroad", true); @@ -687,9 +683,9 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { paramsMemory.putBool("ForceOffroad", false); paramsMemory.putBool("ForceOnroad", false); } - forceStartedBtn->updateButtonStyles(id); + forceStartedBtn->setCheckedButton(id); }); - forceStartedBtn->updateButtonStyles(2); + forceStartedBtn->setCheckedButton(2); addItem(forceStartedBtn); // power buttons @@ -859,7 +855,7 @@ SettingsWindow::SettingsWindow(QWidget *parent) : QFrame(parent) { {tr("Network"), new Networking(this)}, {tr("Toggles"), toggles}, {tr("Software"), new SoftwarePanel(this)}, - {tr("Controls"), frogpilotControls}, + {tr("Driving"), frogpilotControls}, {tr("Navigation"), new FrogPilotNavigationPanel(this)}, {tr("Vehicles"), new FrogPilotVehiclesPanel(this)}, {tr("Visuals"), frogpilotVisuals}, diff --git a/selfdrive/ui/qt/onroad/annotated_camera.cc b/selfdrive/ui/qt/onroad/annotated_camera.cc index daa3f202b..387386263 100644 --- a/selfdrive/ui/qt/onroad/annotated_camera.cc +++ b/selfdrive/ui/qt/onroad/annotated_camera.cc @@ -901,40 +901,26 @@ void AnnotatedCameraWidget::updateSignals() { const QString signalFolderPath = "../frogpilot/assets/active_theme/signals/"; QDir directory(signalFolderPath); + const QTransform flipTransform = QTransform().scale(-1, 1); QFileInfoList fileList = directory.entryInfoList({"turn_signal_*.png"}, QDir::Files); - - const QTransform flipTransform = QTransform().scale(-1, 1); - std::vector flippedImages; + QFileInfoList nonPngFileList = directory.entryInfoList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name); + nonPngFileList.erase(std::remove_if(nonPngFileList.begin(), nonPngFileList.end(), [](const QFileInfo &fileInfo) {return fileInfo.suffix() == "png";}), nonPngFileList.end()); for (const QFileInfo &fileInfo : fileList) { QPixmap pixmap(fileInfo.absoluteFilePath()); - - if (fileInfo.fileName().contains("blindspot")) { - blindspotImages.push_back(pixmap); - blindspotImages.push_back(pixmap.transformed(flipTransform)); - } else { - regularImages.push_back(pixmap); - flippedImages.push_back(pixmap.transformed(flipTransform)); - } + QVector *targetList = fileInfo.fileName().contains("blindspot") ? &blindspotImages : ®ularImages; + targetList->push_back(pixmap); } - regularImages.insert(regularImages.end(), flippedImages.begin(), flippedImages.end()); - - QFileInfoList nonPngFileList = directory.entryInfoList(QDir::Files | QDir::NoDotAndDotDot, QDir::Name); - - for (QFileInfoList::iterator it = nonPngFileList.begin(); it != nonPngFileList.end(); ) { - if ((*it).suffix() == "png") { - it = nonPngFileList.erase(it); - } else { - it++; - } + for (const QFileInfo &fileInfo : fileList) { + QPixmap pixmap(fileInfo.absoluteFilePath()); + QVector *targetList = fileInfo.fileName().contains("blindspot") ? &blindspotImages : ®ularImages; + targetList->push_back(pixmap.transformed(flipTransform)); } if (!nonPngFileList.isEmpty()) { - const QFileInfo &fileInfo = nonPngFileList.first(); - const QStringList parts = fileInfo.fileName().split('_'); - + QStringList parts = nonPngFileList.first().fileName().split('_'); if (parts.size() == 2) { signalStyle = parts[0]; signalAnimationLength = parts[1].toInt(); diff --git a/selfdrive/ui/qt/onroad/annotated_camera.h b/selfdrive/ui/qt/onroad/annotated_camera.h index 1f86892dd..85c3f179f 100644 --- a/selfdrive/ui/qt/onroad/annotated_camera.h +++ b/selfdrive/ui/qt/onroad/annotated_camera.h @@ -180,8 +180,8 @@ private: QTimer *animationTimer; - std::vector regularImages; - std::vector blindspotImages; + QVector regularImages; + QVector blindspotImages; inline QColor blueColor(int alpha = 255) { return QColor(0, 150, 255, alpha); } inline QColor greenColor(int alpha = 242) { return QColor(23, 134, 68, alpha); } diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index 6b0a9befb..f501eae7f 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -451,7 +451,7 @@ void ui_update_frogpilot_params(UIState *s, Params ¶ms) { scene.use_vienna_slc_sign = scene.speed_limit_controller && params.getBool("UseVienna"); scene.tethering_config = params.getInt("TetheringEnabled"); - if (scene.tethering_config == 2) { + if (scene.tethering_config == 1) { WifiManager(s).setTetheringEnabled(true); } } @@ -488,7 +488,7 @@ void UIState::updateStatus() { started_prev = scene.started; scene.world_objects_visible = false; emit offroadTransition(!scene.started); - if (scene.tethering_config == 1) { + if (scene.tethering_config == 2) { wifi->setTetheringEnabled(scene.started); } } diff --git a/system/manager/manager.py b/system/manager/manager.py index cfddaa2f4..55dbe0f12 100755 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -11,7 +11,9 @@ import cereal.messaging as messaging import openpilot.system.sentry as sentry from openpilot.common.params import Params, ParamKeyType from openpilot.common.text_window import TextWindow +from openpilot.selfdrive.controls.lib.desire_helper import LANE_CHANGE_SPEED_MIN from openpilot.system.hardware import HARDWARE, PC +from openpilot.system.hardware.power_monitoring import VBATT_PAUSE_CHARGING from openpilot.system.manager.helpers import unblock_stdout, write_onroad_params, save_bootlog from openpilot.system.manager.process import ensure_running from openpilot.system.manager.process_config import managed_processes @@ -201,7 +203,7 @@ def manager_init() -> None: ("LosAngelesLiveTorqueParameters", ""), ("LosAngelesScore", "0"), ("LoudBlindspotAlert", "0"), - ("LowVoltageShutdown", "11.8"), + ("LowVoltageShutdown", "VBATT_PAUSE_CHARGING"), ("MapAcceleration", "0"), ("MapDeceleration", "0"), ("MapGears", "0"), @@ -209,7 +211,7 @@ def manager_init() -> None: ("MapboxSecretKey", ""), ("MapsSelected", ""), ("MapStyle", "10"), - ("MinimumLaneChangeSpeed", "20"), + ("MinimumLaneChangeSpeed", "LANE_CHANGE_SPEED_MIN"), ("Model", DEFAULT_MODEL), ("ModelManagement", "0"), ("ModelName", DEFAULT_MODEL_NAME),