diff --git a/common/params.cc b/common/params.cc index f3338e143..918603f51 100644 --- a/common/params.cc +++ b/common/params.cc @@ -224,6 +224,7 @@ std::unordered_map keys = { {"AdvancedLateralTune", PERSISTENT}, {"AdvancedLongitudinalTune", PERSISTENT}, {"AggressiveFollow", PERSISTENT}, + {"AggressiveFollowHigh", PERSISTENT}, {"AggressiveJerkAcceleration", PERSISTENT}, {"AggressiveJerkDanger", PERSISTENT}, {"AggressiveJerkDeceleration", PERSISTENT}, @@ -456,6 +457,7 @@ std::unordered_map keys = { {"RandomThemes", PERSISTENT}, {"RefuseVolume", PERSISTENT}, {"RelaxedFollow", PERSISTENT}, + {"RelaxedFollowHigh", PERSISTENT}, {"RelaxedJerkAcceleration", PERSISTENT}, {"RelaxedJerkDanger", PERSISTENT}, {"RelaxedJerkDeceleration", PERSISTENT}, @@ -515,6 +517,7 @@ std::unordered_map keys = { {"SpeedLimitsFiltered", PERSISTENT | DONT_LOG}, {"SpeedLimitSources", PERSISTENT}, {"StandardFollow", PERSISTENT}, + {"StandardFollowHigh", PERSISTENT}, {"StandardJerkAcceleration", PERSISTENT}, {"StandardJerkDanger", PERSISTENT}, {"StandardJerkDeceleration", PERSISTENT}, diff --git a/common/params_pyx.so b/common/params_pyx.so index 0af154791..b2a936679 100755 Binary files a/common/params_pyx.so and b/common/params_pyx.so differ diff --git a/frogpilot/common/frogpilot_variables.py b/frogpilot/common/frogpilot_variables.py index e4dc77c2c..1eed80b49 100644 --- a/frogpilot/common/frogpilot_variables.py +++ b/frogpilot/common/frogpilot_variables.py @@ -129,6 +129,7 @@ frogpilot_default_params: list[tuple[str, str | bytes, int, str]] = [ ("AdvancedLateralTune", "0", 2, "0"), ("AdvancedLongitudinalTune", "0", 3, "0"), ("AggressiveFollow", "1.25", 2, "1.25"), + ("AggressiveFollowHigh", "1.25", 2, "1.25"), ("AggressiveJerkAcceleration", "50", 3, "50"), ("AggressiveJerkDanger", "100", 3, "100"), ("AggressiveJerkDeceleration", "50", 3, "50"), @@ -329,6 +330,7 @@ frogpilot_default_params: list[tuple[str, str | bytes, int, str]] = [ ("RecordFront", "0", 0, "0"), ("RefuseVolume", "101", 2, "101"), ("RelaxedFollow", "1.75", 2, "1.75"), + ("RelaxedFollowHigh", "1.75", 2, "1.75"), ("RelaxedJerkAcceleration", "50", 3, "50"), ("RelaxedJerkDanger", "100", 3, "100"), ("RelaxedJerkDeceleration", "50", 3, "50"), @@ -386,6 +388,7 @@ frogpilot_default_params: list[tuple[str, str | bytes, int, str]] = [ ("StartupMessageBottom", "Human-tested, frog-approved 🐸", 0, "Always keep hands on wheel and eyes on road"), ("StartupMessageTop", "Hop in and buckle up!", 0, "Be ready to take over at any time"), ("StandardFollow", "1.45", 2, "1.45"), + ("StandardFollowHigh", "1.45", 2, "1.45"), ("StandardJerkAcceleration", "50", 3, "50"), ("StandardJerkDanger", "100", 3, "100"), ("StandardJerkDeceleration", "50", 3, "50"), @@ -676,28 +679,31 @@ class FrogPilotVariables: toggle.aggressive_jerk_danger = np.clip(params.get_int("AggressiveJerkDanger") / 100, 0.25, 2) if aggressive_profile and tuning_level >= level["AggressiveJerkDanger"] else default.get_int("AggressiveJerkDanger") / 100 toggle.aggressive_jerk_speed = np.clip(params.get_int("AggressiveJerkSpeed") / 100, 0.25, 2) if aggressive_profile and tuning_level >= level["AggressiveJerkSpeed"] else default.get_int("AggressiveJerkSpeed") / 100 toggle.aggressive_jerk_speed_decrease = np.clip(params.get_int("AggressiveJerkSpeedDecrease") / 100, 0.25, 2) if aggressive_profile and tuning_level >= level["AggressiveJerkSpeedDecrease"] else default.get_int("AggressiveJerkSpeedDecrease") / 100 - toggle.aggressive_follow = np.clip(params.get_float("AggressiveFollow"), 1, MAX_T_FOLLOW) if aggressive_profile and tuning_level >= level["AggressiveFollow"] else default.get_float("AggressiveFollow") + toggle.aggressive_follow = [np.clip(params.get_float("AggressiveFollow"), 1, MAX_T_FOLLOW) if aggressive_profile and tuning_level >= level["AggressiveFollow"] else default.get_float("AggressiveFollow"), + np.clip(params.get_float("AggressiveFollowHigh"), 1, MAX_T_FOLLOW) if aggressive_profile and tuning_level >= level["AggressiveFollowHigh"] else default.get_float("AggressiveFollowHigh")] standard_profile = toggle.custom_personalities and (params.get_bool("StandardPersonalityProfile") if tuning_level >= level["StandardPersonalityProfile"] else default.get_bool("StandardPersonalityProfile")) toggle.standard_jerk_acceleration = np.clip(params.get_int("StandardJerkAcceleration") / 100, 0.25, 2) if standard_profile and tuning_level >= level["StandardJerkAcceleration"] else default.get_int("StandardJerkAcceleration") / 100 toggle.standard_jerk_deceleration = np.clip(params.get_int("StandardJerkDeceleration") / 100, 0.25, 2) if standard_profile and tuning_level >= level["StandardJerkDeceleration"] else default.get_int("StandardJerkDeceleration") / 100 toggle.standard_jerk_danger = np.clip(params.get_int("StandardJerkDanger") / 100, 0.25, 2) if standard_profile and tuning_level >= level["StandardJerkDanger"] else default.get_int("StandardJerkDanger") / 100 toggle.standard_jerk_speed = np.clip(params.get_int("StandardJerkSpeed") / 100, 0.25, 2) if standard_profile and tuning_level >= level["StandardJerkSpeed"] else default.get_int("StandardJerkSpeed") / 100 toggle.standard_jerk_speed_decrease = np.clip(params.get_int("StandardJerkSpeedDecrease") / 100, 0.25, 2) if standard_profile and tuning_level >= level["StandardJerkSpeedDecrease"] else default.get_int("StandardJerkSpeedDecrease") / 100 - toggle.standard_follow = np.clip(params.get_float("StandardFollow"), 1, MAX_T_FOLLOW) if standard_profile and tuning_level >= level["StandardFollow"] else default.get_float("StandardFollow") + toggle.standard_follow = [np.clip(params.get_float("StandardFollow"), 1, MAX_T_FOLLOW) if standard_profile and tuning_level >= level["StandardFollow"] else default.get_float("StandardFollow"), + np.clip(params.get_float("StandardFollowHigh"), 1, MAX_T_FOLLOW) if standard_profile and tuning_level >= level["StandardFollowHigh"] else default.get_float("StandardFollowHigh")] relaxed_profile = toggle.custom_personalities and (params.get_bool("RelaxedPersonalityProfile") if tuning_level >= level["RelaxedPersonalityProfile"] else default.get_bool("RelaxedPersonalityProfile")) toggle.relaxed_jerk_acceleration = np.clip(params.get_int("RelaxedJerkAcceleration") / 100, 0.25, 2) if relaxed_profile and tuning_level >= level["RelaxedJerkAcceleration"] else default.get_int("RelaxedJerkAcceleration") / 100 toggle.relaxed_jerk_deceleration = np.clip(params.get_int("RelaxedJerkDeceleration") / 100, 0.25, 2) if relaxed_profile and tuning_level >= level["RelaxedJerkDeceleration"] else default.get_int("RelaxedJerkDeceleration") / 100 toggle.relaxed_jerk_danger = np.clip(params.get_int("RelaxedJerkDanger") / 100, 0.25, 2) if relaxed_profile and tuning_level >= level["RelaxedJerkDanger"] else default.get_int("RelaxedJerkDanger") / 100 toggle.relaxed_jerk_speed = np.clip(params.get_int("RelaxedJerkSpeed") / 100, 0.25, 2) if relaxed_profile and tuning_level >= level["RelaxedJerkSpeed"] else default.get_int("RelaxedJerkSpeed") / 100 toggle.relaxed_jerk_speed_decrease = np.clip(params.get_int("RelaxedJerkSpeedDecrease") / 100, 0.25, 2) if relaxed_profile and tuning_level >= level["RelaxedJerkSpeedDecrease"] else default.get_int("RelaxedJerkSpeedDecrease") / 100 - toggle.relaxed_follow = np.clip(params.get_float("RelaxedFollow"), 1, MAX_T_FOLLOW) if relaxed_profile and tuning_level >= level["RelaxedFollow"] else default.get_float("RelaxedFollow") + toggle.relaxed_follow = [np.clip(params.get_float("RelaxedFollow"), 1, MAX_T_FOLLOW) if relaxed_profile and tuning_level >= level["RelaxedFollow"] else default.get_float("RelaxedFollow"), + np.clip(params.get_float("RelaxedFollowHigh"), 1, MAX_T_FOLLOW) if relaxed_profile and tuning_level >= level["RelaxedFollowHigh"] else default.get_float("RelaxedFollowHigh")] traffic_profile = toggle.custom_personalities and (params.get_bool("TrafficPersonalityProfile") if tuning_level >= level["TrafficPersonalityProfile"] else default.get_bool("TrafficPersonalityProfile")) toggle.traffic_mode_jerk_acceleration = [np.clip(params.get_int("TrafficJerkAcceleration") / 100, 0.25, 2) if traffic_profile and tuning_level >= level["TrafficJerkAcceleration"] else default.get_int("TrafficJerkAcceleration") / 100, toggle.aggressive_jerk_acceleration] toggle.traffic_mode_jerk_deceleration = [np.clip(params.get_int("TrafficJerkDeceleration") / 100, 0.25, 2) if traffic_profile and tuning_level >= level["TrafficJerkDeceleration"] else default.get_int("TrafficJerkDeceleration") / 100, toggle.aggressive_jerk_deceleration] toggle.traffic_mode_jerk_danger = [np.clip(params.get_int("TrafficJerkDanger") / 100, 0.25, 2) if traffic_profile and tuning_level >= level["TrafficJerkDanger"] else default.get_int("TrafficJerkDanger") / 100, toggle.aggressive_jerk_danger] toggle.traffic_mode_jerk_speed = [np.clip(params.get_int("TrafficJerkSpeed") / 100, 0.25, 2) if traffic_profile and tuning_level >= level["TrafficJerkSpeed"] else default.get_int("TrafficJerkSpeed") / 100, toggle.aggressive_jerk_speed] toggle.traffic_mode_jerk_speed_decrease = [np.clip(params.get_int("TrafficJerkSpeedDecrease") / 100, 0.25, 2) if traffic_profile and tuning_level >= level["TrafficJerkSpeedDecrease"] else default.get_int("TrafficJerkSpeedDecrease") / 100, toggle.aggressive_jerk_speed_decrease] - toggle.traffic_mode_follow = [np.clip(params.get_float("TrafficFollow"), 0.5, MAX_T_FOLLOW) if traffic_profile and tuning_level >= level["TrafficFollow"] else default.get_float("TrafficFollow"), toggle.aggressive_follow] + toggle.traffic_mode_follow = [np.clip(params.get_float("TrafficFollow"), 0.5, MAX_T_FOLLOW) if traffic_profile and tuning_level >= level["TrafficFollow"] else default.get_float("TrafficFollow"), toggle.aggressive_follow[0]] custom_ui = params.get_bool("CustomUI") if tuning_level >= level["CustomUI"] else default.get_bool("CustomUI") toggle.acceleration_path = toggle.openpilot_longitudinal and (custom_ui and (params.get_bool("AccelerationPath") if tuning_level >= level["AccelerationPath"] else default.get_bool("AccelerationPath")) or toggle.debug_mode) diff --git a/frogpilot/controls/lib/frogpilot_following.py b/frogpilot/controls/lib/frogpilot_following.py index 072fcc7ab..9bb9ebb7e 100644 --- a/frogpilot/controls/lib/frogpilot_following.py +++ b/frogpilot/controls/lib/frogpilot_following.py @@ -1,11 +1,13 @@ #!/usr/bin/env python3 import numpy as np +from openpilot.common.conversions import Conversions as CV from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import COMFORT_BRAKE, desired_follow_distance, get_jerk_factor, get_T_FOLLOW from openpilot.frogpilot.common.frogpilot_variables import CITY_SPEED_LIMIT TRAFFIC_MODE_BP = [0., CITY_SPEED_LIMIT] +PERSONALITY_BP = [20. * CV.KPH_TO_MS, 90. * CV.KPH_TO_MS] class FrogPilotFollowing: def __init__(self, FrogPilotPlanner): @@ -48,12 +50,16 @@ class FrogPilotFollowing: frogpilot_toggles.custom_personalities, sm["controlsState"].personality ) - self.t_follow = get_T_FOLLOW( + t_follow_param = get_T_FOLLOW( frogpilot_toggles.aggressive_follow, frogpilot_toggles.standard_follow, frogpilot_toggles.relaxed_follow, frogpilot_toggles.custom_personalities, sm["controlsState"].personality ) + if isinstance(t_follow_param, list): + self.t_follow = float(np.interp(v_ego, PERSONALITY_BP, t_follow_param)) + else: + self.t_follow = float(t_follow_param) else: self.base_acceleration_jerk = 0 self.base_danger_jerk = 0 diff --git a/frogpilot/ui/qt/offroad/longitudinal_settings.cc b/frogpilot/ui/qt/offroad/longitudinal_settings.cc index 66edb1a28..eca9c4464 100644 --- a/frogpilot/ui/qt/offroad/longitudinal_settings.cc +++ b/frogpilot/ui/qt/offroad/longitudinal_settings.cc @@ -1,13 +1,21 @@ #include "frogpilot/ui/qt/offroad/longitudinal_settings.h" -FrogPilotLongitudinalPanel::FrogPilotLongitudinalPanel(FrogPilotSettingsWindow *parent) : FrogPilotListWidget(parent), parent(parent) { - QJsonObject shownDescriptions = QJsonDocument::fromJson(QString::fromStdString(params.get("ShownToggleDescriptions")).toUtf8()).object(); +FrogPilotLongitudinalPanel::FrogPilotLongitudinalPanel( + FrogPilotSettingsWindow *parent) + : FrogPilotListWidget(parent), parent(parent) { + QJsonObject shownDescriptions = + QJsonDocument::fromJson( + QString::fromStdString(params.get("ShownToggleDescriptions")) + .toUtf8()) + .object(); QString className = this->metaObject()->className(); if (!shownDescriptions.value(className).toBool(false)) { forceOpenDescriptions = true; shownDescriptions.insert(className, true); - params.put("ShownToggleDescriptions", QJsonDocument(shownDescriptions).toJson(QJsonDocument::Compact).toStdString()); + params.put("ShownToggleDescriptions", QJsonDocument(shownDescriptions) + .toJson(QJsonDocument::Compact) + .toStdString()); } QStackedLayout *longitudinalLayout = new QStackedLayout(); @@ -19,35 +27,54 @@ FrogPilotLongitudinalPanel::FrogPilotLongitudinalPanel(FrogPilotSettingsWindow * longitudinalLayout->addWidget(longitudinalPanel); - FrogPilotListWidget *advancedLongitudinalTuneList = new FrogPilotListWidget(this); - FrogPilotListWidget *aggressivePersonalityList = new FrogPilotListWidget(this); - FrogPilotListWidget *conditionalExperimentalList = new FrogPilotListWidget(this); + FrogPilotListWidget *advancedLongitudinalTuneList = + new FrogPilotListWidget(this); + FrogPilotListWidget *aggressivePersonalityList = + new FrogPilotListWidget(this); + FrogPilotListWidget *conditionalExperimentalList = + new FrogPilotListWidget(this); FrogPilotListWidget *curveSpeedList = new FrogPilotListWidget(this); - FrogPilotListWidget *customDrivingPersonalityList = new FrogPilotListWidget(this); + FrogPilotListWidget *customDrivingPersonalityList = + new FrogPilotListWidget(this); FrogPilotListWidget *longitudinalTuneList = new FrogPilotListWidget(this); FrogPilotListWidget *qolList = new FrogPilotListWidget(this); FrogPilotListWidget *relaxedPersonalityList = new FrogPilotListWidget(this); FrogPilotListWidget *speedLimitControllerList = new FrogPilotListWidget(this); - FrogPilotListWidget *speedLimitControllerOffsetsList = new FrogPilotListWidget(this); - FrogPilotListWidget *speedLimitControllerQOLList = new FrogPilotListWidget(this); - FrogPilotListWidget *speedLimitControllerVisualList = new FrogPilotListWidget(this); + FrogPilotListWidget *speedLimitControllerOffsetsList = + new FrogPilotListWidget(this); + FrogPilotListWidget *speedLimitControllerQOLList = + new FrogPilotListWidget(this); + FrogPilotListWidget *speedLimitControllerVisualList = + new FrogPilotListWidget(this); FrogPilotListWidget *standardPersonalityList = new FrogPilotListWidget(this); FrogPilotListWidget *trafficPersonalityList = new FrogPilotListWidget(this); - ScrollView *advancedLongitudinalTunePanel = new ScrollView(advancedLongitudinalTuneList, this); - ScrollView *aggressivePersonalityPanel = new ScrollView(aggressivePersonalityList, this); - ScrollView *conditionalExperimentalPanel = new ScrollView(conditionalExperimentalList, this); + ScrollView *advancedLongitudinalTunePanel = + new ScrollView(advancedLongitudinalTuneList, this); + ScrollView *aggressivePersonalityPanel = + new ScrollView(aggressivePersonalityList, this); + ScrollView *conditionalExperimentalPanel = + new ScrollView(conditionalExperimentalList, this); ScrollView *curveSpeedPanel = new ScrollView(curveSpeedList, this); - ScrollView *customDrivingPersonalityPanel = new ScrollView(customDrivingPersonalityList, this); - ScrollView *longitudinalTunePanel = new ScrollView(longitudinalTuneList, this); + ScrollView *customDrivingPersonalityPanel = + new ScrollView(customDrivingPersonalityList, this); + ScrollView *longitudinalTunePanel = + new ScrollView(longitudinalTuneList, this); ScrollView *qolPanel = new ScrollView(qolList, this); - ScrollView *relaxedPersonalityPanel = new ScrollView(relaxedPersonalityList, this); - ScrollView *speedLimitControllerPanel = new ScrollView(speedLimitControllerList, this); - ScrollView *speedLimitControllerOffsetsPanel = new ScrollView(speedLimitControllerOffsetsList, this); - ScrollView *speedLimitControllerQOLPanel = new ScrollView(speedLimitControllerQOLList, this); - ScrollView *speedLimitControllerVisualPanel = new ScrollView(speedLimitControllerVisualList, this); - ScrollView *standardPersonalityPanel = new ScrollView(standardPersonalityList, this); - ScrollView *trafficPersonalityPanel = new ScrollView(trafficPersonalityList, this); + ScrollView *relaxedPersonalityPanel = + new ScrollView(relaxedPersonalityList, this); + ScrollView *speedLimitControllerPanel = + new ScrollView(speedLimitControllerList, this); + ScrollView *speedLimitControllerOffsetsPanel = + new ScrollView(speedLimitControllerOffsetsList, this); + ScrollView *speedLimitControllerQOLPanel = + new ScrollView(speedLimitControllerQOLList, this); + ScrollView *speedLimitControllerVisualPanel = + new ScrollView(speedLimitControllerVisualList, this); + ScrollView *standardPersonalityPanel = + new ScrollView(standardPersonalityList, this); + ScrollView *trafficPersonalityPanel = + new ScrollView(trafficPersonalityList, this); longitudinalLayout->addWidget(advancedLongitudinalTunePanel); longitudinalLayout->addWidget(aggressivePersonalityPanel); @@ -64,194 +91,641 @@ FrogPilotLongitudinalPanel::FrogPilotLongitudinalPanel(FrogPilotSettingsWindow * longitudinalLayout->addWidget(standardPersonalityPanel); longitudinalLayout->addWidget(trafficPersonalityPanel); - const std::vector> longitudinalToggles { - {"AdvancedLongitudinalTune", tr("Advanced Longitudinal Tuning"), tr("Advanced acceleration and braking control changes to fine-tune how openpilot drives."), "../../frogpilot/assets/toggle_icons/icon_advanced_longitudinal_tune.png"}, - {"LongitudinalActuatorDelay", longitudinalActuatorDelay != 0 ? QString(tr("Actuator Delay (Default: %1)")).arg(QString::number(longitudinalActuatorDelay, 'f', 2)) : tr("Actuator Delay"), tr("The time between openpilot's throttle or brake command and the vehicle's response. Increase if the vehicle feels slow to react; decrease if it feels too eager or overshoots."), ""}, - {"StartAccel", startAccel != 0 ? QString(tr("Start Acceleration (Default: %1)")).arg(QString::number(startAccel, 'f', 2)) : tr("Start Acceleration"), tr("Extra acceleration applied when starting from a stop. Increase for quicker takeoffs; decrease for smoother, gentler starts."), ""}, - {"VEgoStarting", vEgoStarting != 0 ? QString(tr("Start Speed (Default: %1)")).arg(QString::number(vEgoStarting, 'f', 2)) : tr("Start Speed"), tr("The speed at which openpilot exits the stopped state. Increase to reduce creeping; decrease to move sooner after stopping."), ""}, - {"StopAccel", stopAccel != 0 ? QString(tr("Stop Acceleration (Default: %1)")).arg(QString::number(stopAccel, 'f', 2)) : tr("Stop Acceleration"), tr("Brake force applied to hold the vehicle at a standstill. Increase to prevent rolling on hills; decrease for smoother, softer stops."), ""}, - {"StoppingDecelRate", stoppingDecelRate != 0 ? QString(tr("Stopping Rate (Default: %1)")).arg(QString::number(stoppingDecelRate, 'f', 2)) : tr("Stopping Rate"), tr("How quickly braking ramps up when stopping. Increase for shorter, firmer stops; decrease for smoother, longer stops."), ""}, - {"VEgoStopping", vEgoStopping != 0 ? QString(tr("Stop Speed (Default: %1)")).arg(QString::number(vEgoStopping, 'f', 2)) : tr("Stop Speed"), tr("The speed at which openpilot considers the vehicle stopped. Increase to brake earlier and stop smoothly; decrease to wait longer but risk overshooting."), ""}, + const std::vector> + longitudinalToggles{ + {"AdvancedLongitudinalTune", tr("Advanced Longitudinal Tuning"), + tr("Advanced acceleration and braking control changes to " + "fine-tune how openpilot drives."), + "../../frogpilot/assets/toggle_icons/" + "icon_advanced_longitudinal_tune.png"}, + {"LongitudinalActuatorDelay", + longitudinalActuatorDelay != 0 + ? QString(tr("Actuator Delay (Default: %1)")) + .arg(QString::number(longitudinalActuatorDelay, 'f', 2)) + : tr("Actuator Delay"), + tr("The time between openpilot's throttle or brake command and " + "the vehicle's response. Increase if the vehicle feels slow " + "to react; decrease if it feels too eager or overshoots."), + ""}, + {"StartAccel", + startAccel != 0 ? QString(tr("Start Acceleration (Default: %1)")) + .arg(QString::number(startAccel, 'f', 2)) + : tr("Start Acceleration"), + tr("Extra acceleration applied when starting from a stop. " + "Increase for quicker takeoffs; decrease for smoother, gentler " + "starts."), + ""}, + {"VEgoStarting", + vEgoStarting != 0 ? QString(tr("Start Speed (Default: %1)")) + .arg(QString::number(vEgoStarting, 'f', 2)) + : tr("Start Speed"), + tr("The speed at which openpilot exits the stopped state. " + "Increase to reduce creeping; decrease to move sooner after " + "stopping."), + ""}, + {"StopAccel", + stopAccel != 0 ? QString(tr("Stop Acceleration (Default: %1)")) + .arg(QString::number(stopAccel, 'f', 2)) + : tr("Stop Acceleration"), + tr("Brake force applied to hold the vehicle at a standstill. " + "Increase to prevent rolling on hills; decrease for smoother, " + "softer stops."), + ""}, + {"StoppingDecelRate", + stoppingDecelRate != 0 + ? QString(tr("Stopping Rate (Default: %1)")) + .arg(QString::number(stoppingDecelRate, 'f', 2)) + : tr("Stopping Rate"), + tr("How quickly braking ramps up when stopping. Increase for " + "shorter, firmer stops; decrease for smoother, longer stops."), + ""}, + {"VEgoStopping", + vEgoStopping != 0 ? QString(tr("Stop Speed (Default: %1)")) + .arg(QString::number(vEgoStopping, 'f', 2)) + : tr("Stop Speed"), + tr("The speed at which openpilot considers the vehicle " + "stopped. Increase to brake earlier and stop smoothly; " + "decrease to wait longer but risk overshooting."), + ""}, - {"ConditionalExperimental", tr("Conditional Experimental Mode"), tr("Automatically switch to \"Experimental Mode\" when set conditions are met. Allows the model to handle challenging situations with smarter decision making."), "../../frogpilot/assets/toggle_icons/icon_conditional.png"}, - {"CESpeed", tr("Below"), tr("Switch to \"Experimental Mode\" when driving below this speed without a lead to help openpilot handle low-speed situations more smoothly."), ""}, - {"CECurves", tr("Curve Detected Ahead"), tr("Switch to \"Experimental Mode\" when a curve is detected to allow the model to set an appropriate speed for the curve."), ""}, - {"CELead", tr("Lead Detected Ahead"), tr("Switch to \"Experimental Mode\" when a slower or stopped vehicle is detected. Can make braking smoother and more reliable on some vehicles."), ""}, - {"CENavigation", tr("Navigation-Based"), tr("Switch to \"Experimental Mode\" when approaching intersections or turns on the active route while using \"Navigate on openpilot\" (NOO) to allow the model to set an appropriate speed for upcoming maneuvers."), ""}, - {"CEModelStopTime", tr("Predicted Stop In"), tr("Switch to \"Experimental Mode\" when openpilot predicts a stop within the set time. This is usually triggered when the model \"sees\" a red light or stop sign ahead.

Disclaimer: openpilot does not explicitly detect traffic lights or stop signs. In \"Experimental Mode\", openpilot makes end-to-end driving decisions from camera input, which means it may stop even when there's no clear reason."), ""}, - {"CESignalSpeed", tr("Turn Signal Below"), tr("Switch to \"Experimental Mode\" when using a turn signal below the set speed to allow the model to choose an appropriate speed for smoother left and right turns."), ""}, - {"ShowCEMStatus", tr("Status Widget"), tr("Show which condition triggered \"Experimental Mode\" on the driving screen."), ""}, + {"ConditionalExperimental", tr("Conditional Experimental Mode"), + tr("Automatically switch to \"Experimental Mode\" when set " + "conditions are met. Allows the model to handle challenging " + "situations with smarter decision making."), + "../../frogpilot/assets/toggle_icons/icon_conditional.png"}, + {"CESpeed", tr("Below"), + tr("Switch to \"Experimental Mode\" when driving below this " + "speed without a lead to help openpilot handle low-speed " + "situations more smoothly."), + ""}, + {"CECurves", tr("Curve Detected Ahead"), + tr("Switch to \"Experimental Mode\" when a curve is detected " + "to allow the model to set an appropriate speed for the curve."), + ""}, + {"CELead", tr("Lead Detected Ahead"), + tr("Switch to \"Experimental Mode\" when a slower or stopped " + "vehicle is detected. Can make braking smoother and more " + "reliable on some vehicles."), + ""}, + {"CENavigation", tr("Navigation-Based"), + tr("Switch to \"Experimental Mode\" when approaching " + "intersections or turns on the active route while using " + "\"Navigate on openpilot\" (NOO) to allow the model to set an " + "appropriate speed for upcoming maneuvers."), + ""}, + {"CEModelStopTime", tr("Predicted Stop In"), + tr("Switch to \"Experimental Mode\" when openpilot predicts a " + "stop within the set time. This is usually triggered when " + "the model \"sees\" a red light or stop sign " + "ahead.

Disclaimer: openpilot does not " + "explicitly detect traffic lights or stop signs. In " + "\"Experimental Mode\", openpilot makes end-to-end driving " + "decisions from camera input, which means it may stop even when " + "there's no clear reason."), + ""}, + {"CESignalSpeed", tr("Turn Signal Below"), + tr("Switch to \"Experimental Mode\" when using a turn signal " + "below the set speed to allow the model to choose an " + "appropriate speed for smoother left and right turns."), + ""}, + {"ShowCEMStatus", tr("Status Widget"), + tr("Show which condition triggered \"Experimental Mode\" on " + "the driving screen."), + ""}, - {"CurveSpeedController", tr("Curve Speed Controller"), tr("Automatically slow down for upcoming curves using data learned from your driving style, adapting to curves as you would."), "../../frogpilot/assets/toggle_icons/icon_speed_map.png"}, - {"CalibratedLateralAcceleration", tr("Calibrated Lateral Acceleration"), tr("The learned lateral acceleration from collected driving data. This sets how fast openpilot will take curves. Higher values allow faster cornering; lower values slow the vehicle for gentler turns."), ""}, - {"CalibrationProgress", tr("Calibration Progress"), tr("How much curve data has been collected. This is a progress meter; it is normal for the value to stay low and rarely reach 100%."), ""}, - {"ResetCurveData", tr("Reset Curve Data"), tr("Reset collected user data for \"Curve Speed Controller\"."), ""}, - {"ShowCSCStatus", tr("Status Widget"), tr("Show the \"Curve Speed Controller\" target speed on the driving screen."), ""}, + {"CurveSpeedController", tr("Curve Speed Controller"), + tr("Automatically slow down for upcoming curves using data " + "learned from your driving style, adapting to curves as you " + "would."), + "../../frogpilot/assets/toggle_icons/icon_speed_map.png"}, + {"CalibratedLateralAcceleration", + tr("Calibrated Lateral Acceleration"), + tr("The learned lateral acceleration from collected driving " + "data. This sets how fast openpilot will take curves. Higher " + "values allow faster cornering; lower values slow the vehicle " + "for gentler turns."), + ""}, + {"CalibrationProgress", tr("Calibration Progress"), + tr("How much curve data has been collected. This is a " + "progress meter; it is normal for the value to stay low and " + "rarely reach 100%."), + ""}, + {"ResetCurveData", tr("Reset Curve Data"), + tr("Reset collected user data for \"Curve Speed " + "Controller\"."), + ""}, + {"ShowCSCStatus", tr("Status Widget"), + tr("Show the \"Curve Speed Controller\" target speed on the " + "driving screen."), + ""}, - {"CustomPersonalities", tr("Driving Personalities"), tr("Customize the \"Driving Personalities\" to better match your driving style."), "../../frogpilot/assets/toggle_icons/icon_personality.png"}, + {"CustomPersonalities", tr("Driving Personalities"), + tr("Customize the \"Driving Personalities\" to better match " + "your driving style."), + "../../frogpilot/assets/toggle_icons/icon_personality.png"}, - {"TrafficPersonalityProfile", tr("Traffic Mode"), tr("Customize the \"Traffic Mode\" personality profile. Designed for stop-and-go driving."), "../../frogpilot/assets/stock_theme/distance_icons/traffic.png"}, - {"TrafficFollow", tr("Following Distance"), tr("The minimum following distance to the lead vehicle in \"Traffic Mode\". openpilot blends between this value and the \"Aggressive\" profile as speed increases. Increase for more space; decrease for tighter gaps."), ""}, - {"TrafficJerkAcceleration", tr("Acceleration Smoothness"), tr("How smoothly openpilot accelerates in \"Traffic Mode\". Increase for gentler starts; decrease for faster but more abrupt takeoffs."), ""}, - {"TrafficJerkDeceleration", tr("Braking Smoothness"), tr("How smoothly openpilot brakes in \"Traffic Mode\". Increase for gentler stops; decrease for quicker but sharper braking."), ""}, - {"TrafficJerkDanger", tr("Safety Gap Bias"), tr("How much extra space openpilot keeps from the vehicle ahead in \"Traffic Mode\". Increase for larger gaps and more cautious following; decrease for tighter gaps and closer following."), ""}, - {"TrafficJerkSpeedDecrease", tr("Slowdown Response"), tr("How smoothly openpilot slows down in \"Traffic Mode\". Increase for more gradual deceleration; decrease for faster but sharper slowdowns."), ""}, - {"TrafficJerkSpeed", tr("Speed-Up Response"), tr("How smoothly openpilot speeds up in \"Traffic Mode\". Increase for more gradual acceleration; decrease for quicker but more jolting acceleration."), ""}, - {"ResetTrafficPersonality", tr("Reset to Defaults"), tr("Reset \"Traffic Mode\" settings to defaults."), ""}, + {"TrafficPersonalityProfile", tr("Traffic Mode"), + tr("Customize the \"Traffic Mode\" personality profile. " + "Designed for stop-and-go driving."), + "../../frogpilot/assets/stock_theme/distance_icons/traffic.png"}, + {"TrafficFollow", tr("Following Distance"), + tr("The minimum following distance to the lead vehicle in " + "\"Traffic Mode\". openpilot blends between this value and " + "the \"Aggressive\" profile as speed increases. Increase for " + "more space; decrease for tighter gaps."), + ""}, + {"TrafficJerkAcceleration", tr("Acceleration Smoothness"), + tr("How smoothly openpilot accelerates in \"Traffic Mode\". " + "Increase for gentler starts; decrease for faster but more " + "abrupt takeoffs."), + ""}, + {"TrafficJerkDeceleration", tr("Braking Smoothness"), + tr("How smoothly openpilot brakes in \"Traffic Mode\". " + "Increase for gentler stops; decrease for quicker but sharper " + "braking."), + ""}, + {"TrafficJerkDanger", tr("Safety Gap Bias"), + tr("How much extra space openpilot keeps from the vehicle ahead " + "in \"Traffic Mode\". Increase for larger gaps and more " + "cautious following; decrease for tighter gaps and closer " + "following."), + ""}, + {"TrafficJerkSpeedDecrease", tr("Slowdown Response"), + tr("How smoothly openpilot slows down in \"Traffic Mode\". " + "Increase for more gradual deceleration; decrease for faster but " + "sharper slowdowns."), + ""}, + {"TrafficJerkSpeed", tr("Speed-Up Response"), + tr("How smoothly openpilot speeds up in \"Traffic Mode\". " + "Increase for more gradual acceleration; decrease for quicker " + "but more jolting acceleration."), + ""}, + {"ResetTrafficPersonality", tr("Reset to Defaults"), + tr("Reset \"Traffic Mode\" settings to defaults."), ""}, - {"AggressivePersonalityProfile", tr("Aggressive"), tr("Customize the \"Aggressive\" personality profile. Designed for assertive driving with tighter gaps."), "../../frogpilot/assets/stock_theme/distance_icons/aggressive.png"}, - {"AggressiveFollow", tr("Following Distance"), tr("How many seconds openpilot follows behind lead vehicles when using the \"Aggressive\" profile. Increase for more space; decrease for tighter gaps.

Default: 1.25 seconds."), ""}, - {"AggressiveJerkAcceleration", tr("Acceleration Smoothness"), tr("How smoothly openpilot accelerates with the \"Aggressive\" profile. Increase for gentler starts; decrease for faster but more abrupt takeoffs."), ""}, - {"AggressiveJerkDeceleration", tr("Braking Smoothness"), tr("How smoothly openpilot brakes with the \"Aggressive\" profile. Increase for gentler stops; decrease for quicker but sharper braking."), ""}, - {"AggressiveJerkDanger", tr("Safety Gap Bias"), tr("How much extra space openpilot keeps from the vehicle ahead with the \"Aggressive\" profile. Increase for larger gaps and more cautious following; decrease for tighter gaps and closer following."), ""}, - {"AggressiveJerkSpeedDecrease", tr("Slowdown Response"), tr("How smoothly openpilot slows down with the \"Aggressive\" profile. Increase for more gradual deceleration; decrease for faster but sharper slowdowns."), ""}, - {"AggressiveJerkSpeed", tr("Speed-Up Response"), tr("How smoothly openpilot speeds up with the \"Aggressive\" profile. Increase for more gradual acceleration; decrease for quicker but more jolting acceleration."), ""}, - {"ResetAggressivePersonality", tr("Reset to Defaults"), tr("Reset the \"Aggressive\" profile to defaults."), ""}, + {"AggressivePersonalityProfile", tr("Aggressive"), + tr("Customize the \"Aggressive\" personality profile. " + "Designed for assertive driving with tighter gaps."), + "../../frogpilot/assets/stock_theme/distance_icons/aggressive.png"}, + {"AggressiveFollow", tr("Following Distance"), + tr("How many seconds openpilot follows behind lead vehicles when " + "using the \"Aggressive\" profile. Increase for more space; " + "decrease for tighter gaps.

Default: 1.25 seconds."), + ""}, + {"AggressiveFollowHigh", tr("High Speed Following Distance"), + tr("How many seconds openpilot follows behind lead vehicles when " + "using the \"Aggressive\" profile at high speeds. Increase " + "for more space; decrease for tighter gaps.

Default: 1.25 " + "seconds."), + ""}, + {"AggressiveJerkAcceleration", tr("Acceleration Smoothness"), + tr("How smoothly openpilot accelerates with the \"Aggressive\" " + "profile. Increase for gentler starts; decrease for faster " + "but more abrupt takeoffs."), + ""}, + {"AggressiveJerkDeceleration", tr("Braking Smoothness"), + tr("How smoothly openpilot brakes with the \"Aggressive\" " + "profile. Increase for gentler stops; decrease for quicker " + "but sharper braking."), + ""}, + {"AggressiveJerkDanger", tr("Safety Gap Bias"), + tr("How much extra space openpilot keeps from the vehicle ahead " + "with the \"Aggressive\" profile. Increase for larger gaps " + "and more cautious following; decrease for tighter gaps and " + "closer following."), + ""}, + {"AggressiveJerkSpeedDecrease", tr("Slowdown Response"), + tr("How smoothly openpilot slows down with the \"Aggressive\" " + "profile. Increase for more gradual deceleration; decrease " + "for faster but sharper slowdowns."), + ""}, + {"AggressiveJerkSpeed", tr("Speed-Up Response"), + tr("How smoothly openpilot speeds up with the \"Aggressive\" " + "profile. Increase for more gradual acceleration; decrease " + "for quicker but more jolting acceleration."), + ""}, + {"ResetAggressivePersonality", tr("Reset to Defaults"), + tr("Reset the \"Aggressive\" profile to defaults."), ""}, - {"StandardPersonalityProfile", tr("Standard"), tr("Customize the \"Standard\" personality profile. Designed for balanced driving with moderate gaps."), "../../frogpilot/assets/stock_theme/distance_icons/standard.png"}, - {"StandardFollow", tr("Following Distance"), tr("How many seconds openpilot follows behind lead vehicles when using the \"Standard\" profile. Increase for more space; decrease for tighter gaps.

Default: 1.45 seconds."), ""}, - {"StandardJerkAcceleration", tr("Acceleration Smoothness"), tr("How smoothly openpilot accelerates with the \"Standard\" profile. Increase for gentler starts; decrease for faster but more abrupt takeoffs."), ""}, - {"StandardJerkDeceleration", tr("Braking Smoothness"), tr("How smoothly openpilot brakes with the \"Standard\" profile. Increase for gentler stops; decrease for quicker but sharper braking."), ""}, - {"StandardJerkDanger", tr("Safety Gap Bias"), tr("How much extra space openpilot keeps from the vehicle ahead with the \"Standard\" profile. Increase for larger gaps and more cautious following; decrease for tighter gaps and closer following."), ""}, - {"StandardJerkSpeedDecrease", tr("Slowdown Response"), tr("How smoothly openpilot slows down with the \"Standard\" profile. Increase for more gradual deceleration; decrease for faster but sharper slowdowns."), ""}, - {"StandardJerkSpeed", tr("Speed-Up Response"), tr("How smoothly openpilot speeds up with the \"Standard\" profile. Increase for more gradual acceleration; decrease for quicker but more jolting acceleration."), ""}, - {"ResetStandardPersonality", tr("Reset to Defaults"), tr("Reset the \"Standard\" profile to defaults."), ""}, + {"StandardPersonalityProfile", tr("Standard"), + tr("Customize the \"Standard\" personality profile. Designed " + "for balanced driving with moderate gaps."), + "../../frogpilot/assets/stock_theme/distance_icons/standard.png"}, + {"StandardFollow", tr("Following Distance"), + tr("How many seconds openpilot follows behind lead vehicles when " + "using the \"Standard\" profile. Increase for more space; " + "decrease for tighter gaps.

Default: 1.45 seconds."), + ""}, + {"StandardFollowHigh", tr("High Speed Following Distance"), + tr("How many seconds openpilot follows behind lead vehicles when " + "using the \"Standard\" profile at high speeds. Increase for " + "more space; decrease for tighter gaps.

Default: 1.45 " + "seconds."), + ""}, + {"StandardJerkAcceleration", tr("Acceleration Smoothness"), + tr("How smoothly openpilot accelerates with the \"Standard\" " + "profile. Increase for gentler starts; decrease for faster " + "but more abrupt takeoffs."), + ""}, + {"StandardJerkDeceleration", tr("Braking Smoothness"), + tr("How smoothly openpilot brakes with the \"Standard\" " + "profile. Increase for gentler stops; decrease for quicker " + "but sharper braking."), + ""}, + {"StandardJerkDanger", tr("Safety Gap Bias"), + tr("How much extra space openpilot keeps from the vehicle ahead " + "with the \"Standard\" profile. Increase for larger gaps and " + "more cautious following; decrease for tighter gaps and closer " + "following."), + ""}, + {"StandardJerkSpeedDecrease", tr("Slowdown Response"), + tr("How smoothly openpilot slows down with the \"Standard\" " + "profile. Increase for more gradual deceleration; decrease " + "for faster but sharper slowdowns."), + ""}, + {"StandardJerkSpeed", tr("Speed-Up Response"), + tr("How smoothly openpilot speeds up with the \"Standard\" " + "profile. Increase for more gradual acceleration; decrease " + "for quicker but more jolting acceleration."), + ""}, + {"ResetStandardPersonality", tr("Reset to Defaults"), + tr("Reset the \"Standard\" profile to defaults."), ""}, - {"RelaxedPersonalityProfile", tr("Relaxed"), tr("Customize the \"Relaxed\" personality profile. Designed for smoother, more comfortable driving with larger gaps."), "../../frogpilot/assets/stock_theme/distance_icons/relaxed.png"}, - {"RelaxedFollow", tr("Following Distance"), tr("How many seconds openpilot follows behind lead vehicles when using the \"Relaxed\" profile. Increase for more space; decrease for tighter gaps.

Default: 1.75 seconds."), ""}, - {"RelaxedJerkAcceleration", tr("Acceleration Smoothness"), tr("How smoothly openpilot accelerates with the \"Relaxed\" profile. Increase for gentler starts; decrease for faster but more abrupt takeoffs."), ""}, - {"RelaxedJerkDeceleration", tr("Braking Smoothness"), tr("How smoothly openpilot brakes with the \"Relaxed\" profile. Increase for gentler stops; decrease for quicker but sharper braking."), ""}, - {"RelaxedJerkDanger", tr("Safety Gap Bias"), tr("How much extra space openpilot keeps from the vehicle ahead with the \"Relaxed\" profile. Increase for larger gaps and more cautious following; decrease for tighter gaps and closer following."), ""}, - {"RelaxedJerkSpeedDecrease", tr("Slowdown Response"), tr("How smoothly openpilot slows down with the \"Relaxed\" profile. Increase for more gradual deceleration; decrease for faster but sharper slowdowns."), ""}, - {"RelaxedJerkSpeed", tr("Speed-Up Response"), tr("How smoothly openpilot speeds up with the \"Relaxed\" profile. Increase for more gradual acceleration; decrease for quicker but more jolting acceleration."), ""}, - {"ResetRelaxedPersonality", tr("Reset to Defaults"), tr("Reset the \"Relaxed\" profile to defaults."), ""}, + {"RelaxedPersonalityProfile", tr("Relaxed"), + tr("Customize the \"Relaxed\" personality profile. Designed " + "for smoother, more comfortable driving with larger gaps."), + "../../frogpilot/assets/stock_theme/distance_icons/relaxed.png"}, + {"RelaxedFollow", tr("Following Distance"), + tr("How many seconds openpilot follows behind lead vehicles when " + "using the \"Relaxed\" profile. Increase for more space; " + "decrease for tighter gaps.

Default: 1.75 seconds."), + ""}, + {"RelaxedFollowHigh", tr("High Speed Following Distance"), + tr("How many seconds openpilot follows behind lead vehicles when " + "using the \"Relaxed\" profile at high speeds. Increase for " + "more space; decrease for tighter gaps.

Default: 1.75 " + "seconds."), + ""}, + {"RelaxedJerkAcceleration", tr("Acceleration Smoothness"), + tr("How smoothly openpilot accelerates with the \"Relaxed\" " + "profile. Increase for gentler starts; decrease for faster " + "but more abrupt takeoffs."), + ""}, + {"RelaxedJerkDeceleration", tr("Braking Smoothness"), + tr("How smoothly openpilot brakes with the \"Relaxed\" " + "profile. Increase for gentler stops; decrease for quicker " + "but sharper braking."), + ""}, + {"RelaxedJerkDanger", tr("Safety Gap Bias"), + tr("How much extra space openpilot keeps from the vehicle ahead " + "with the \"Relaxed\" profile. Increase for larger gaps and " + "more cautious following; decrease for tighter gaps and closer " + "following."), + ""}, + {"RelaxedJerkSpeedDecrease", tr("Slowdown Response"), + tr("How smoothly openpilot slows down with the \"Relaxed\" " + "profile. Increase for more gradual deceleration; decrease " + "for faster but sharper slowdowns."), + ""}, + {"RelaxedJerkSpeed", tr("Speed-Up Response"), + tr("How smoothly openpilot speeds up with the \"Relaxed\" " + "profile. Increase for more gradual acceleration; decrease " + "for quicker but more jolting acceleration."), + ""}, + {"ResetRelaxedPersonality", tr("Reset to Defaults"), + tr("Reset the \"Relaxed\" profile to defaults."), ""}, - {"LongitudinalTune", tr("Longitudinal Tuning"), tr("Acceleration and braking control changes to fine-tune how openpilot drives."), "../../frogpilot/assets/toggle_icons/icon_longitudinal_tune.png"}, - {"AccelerationProfile", tr("Acceleration Profile"), tr("How quickly openpilot speeds up. \"Eco\" is gentle and efficient, \"Sport\" is firmer and more responsive, and \"Sport+\" accelerates at the maximum rate allowed."), ""}, - {"DecelerationProfile", tr("Deceleration Profile"), tr("How firmly openpilot slows down. \"Eco\" favors coasting, \"Sport\" applies stronger braking."), ""}, - {"HumanAcceleration", tr("Human-Like Acceleration"), tr("Acceleration that mimics human behavior by easing the throttle at low speeds and adding extra power when taking off from a stop."), ""}, - {"HumanFollowing", tr("Human-Like Following"), tr("Following behavior that mimics human drivers by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking."), ""}, - {"LeadDetectionThreshold", tr("Lead Detection Sensitivity"), tr("How sensitive openpilot is to detecting vehicles. Higher sensitivity allows quicker detection at longer distances but may react to non-vehicle objects; lower sensitivity is more conservative and reduces false detections."), ""}, - {"MaxDesiredAcceleration", tr("Maximum Acceleration"), tr("Limit the strongest acceleration openpilot can command."), ""}, - {"TacoTune", tr("\"Taco Bell Run\" Turn Speed Hack"), tr("The turn-speed hack from comma's 2022 \"Taco Bell Run\". Designed to slow down for left and right turns."), ""}, + {"LongitudinalTune", tr("Longitudinal Tuning"), + tr("Acceleration and braking control changes to fine-tune " + "how openpilot drives."), + "../../frogpilot/assets/toggle_icons/icon_longitudinal_tune.png"}, + {"AccelerationProfile", tr("Acceleration Profile"), + tr("How quickly openpilot speeds up. \"Eco\" is gentle and " + "efficient, \"Sport\" is firmer and more responsive, and " + "\"Sport+\" accelerates at the maximum rate allowed."), + ""}, + {"DecelerationProfile", tr("Deceleration Profile"), + tr("How firmly openpilot slows down. \"Eco\" favors " + "coasting, \"Sport\" applies stronger braking."), + ""}, + {"HumanAcceleration", tr("Human-Like Acceleration"), + tr("Acceleration that mimics human behavior by easing the " + "throttle at low speeds and adding extra power when taking off " + "from a stop."), + ""}, + {"HumanFollowing", tr("Human-Like Following"), + tr("Following behavior that mimics human drivers by closing " + "gaps behind faster vehicles for quicker takeoffs and " + "dynamically adjusting the desired following distance for " + "gentler, more efficient braking."), + ""}, + {"LeadDetectionThreshold", tr("Lead Detection Sensitivity"), + tr("How sensitive openpilot is to detecting vehicles. Higher " + "sensitivity allows quicker detection at longer distances but " + "may react to non-vehicle objects; lower sensitivity is more " + "conservative and reduces false detections."), + ""}, + {"MaxDesiredAcceleration", tr("Maximum Acceleration"), + tr("Limit the strongest acceleration openpilot can command."), + ""}, + {"TacoTune", tr("\"Taco Bell Run\" Turn Speed Hack"), + tr("The turn-speed hack from comma's 2022 \"Taco Bell Run\". " + "Designed to slow down for left and right turns."), + ""}, - {"QOLLongitudinal", tr("Quality of Life"), tr("Miscellaneous acceleration and braking control changes to fine-tune how openpilot drives."), "../../frogpilot/assets/toggle_icons/icon_quality_of_life.png"}, - {"CustomCruise", tr("Cruise Interval"), tr("How much the set speed increases or decreases for each + or – cruise control button press."), ""}, - {"CustomCruiseLong", tr("Cruise Interval (Hold)"), tr("How much the set speed increases or decreases while holding the + or – cruise control buttons."), ""}, - {"ForceStops", tr("Force Stop at \"Detected\" Stop Lights/Signs"), tr("Force openpilot to stop whenever the driving model \"detects\" a red light or stop sign.

Disclaimer: openpilot does not explicitly detect traffic lights or stop signs. In \"Experimental Mode\", openpilot makes end-to-end driving decisions from camera input, which means it may stop even when there's no clear reason."), ""}, - {"IncreasedStoppedDistance", tr("Increase Stopped Distance by:"), tr("Add extra space when stopped behind vehicles. Increase for more room; decrease for shorter gaps."), ""}, - {"MapGears", tr("Map Accel/Decel to Gears"), tr("Map the Acceleration or Deceleration profiles to the vehicle's \"Eco\" and \"Sport\" gear modes."), ""}, - {"SetSpeedOffset", tr("Offset Set Speed by:"), tr("Increase the set speed by the chosen offset. For example, set +5 if you usually drive 5 over the limit."), ""}, - {"ReverseCruise", tr("Reverse Cruise Increase"), tr("Reverse the cruise control button behavior so a short press increases the set speed by 5 instead of 1."), ""}, + {"QOLLongitudinal", tr("Quality of Life"), + tr("Miscellaneous acceleration and braking control changes " + "to fine-tune how openpilot drives."), + "../../frogpilot/assets/toggle_icons/icon_quality_of_life.png"}, + {"CustomCruise", tr("Cruise Interval"), + tr("How much the set speed increases or decreases for each + " + "or – cruise control button press."), + ""}, + {"CustomCruiseLong", tr("Cruise Interval (Hold)"), + tr("How much the set speed increases or decreases while holding " + "the + or – cruise control buttons."), + ""}, + {"ForceStops", tr("Force Stop at \"Detected\" Stop Lights/Signs"), + tr("Force openpilot to stop whenever the driving model " + "\"detects\" a red light or stop " + "sign.

Disclaimer: openpilot does not " + "explicitly detect traffic lights or stop signs. In " + "\"Experimental Mode\", openpilot makes end-to-end driving " + "decisions from camera input, which means it may stop even when " + "there's no clear reason."), + ""}, + {"IncreasedStoppedDistance", tr("Increase Stopped Distance by:"), + tr("Add extra space when stopped behind vehicles. Increase " + "for more room; decrease for shorter gaps."), + ""}, + {"MapGears", tr("Map Accel/Decel to Gears"), + tr("Map the Acceleration or Deceleration profiles to the " + "vehicle's \"Eco\" and \"Sport\" gear modes."), + ""}, + {"SetSpeedOffset", tr("Offset Set Speed by:"), + tr("Increase the set speed by the chosen offset. For " + "example, set +5 if you usually drive 5 over the limit."), + ""}, + {"ReverseCruise", tr("Reverse Cruise Increase"), + tr("Reverse the cruise control button behavior so a short " + "press increases the set speed by 5 instead of 1."), + ""}, - {"SnowOffsets", tr("Snow"), tr("Driving adjustments for snowy conditions."), ""}, - {"IncreaseFollowingSnow", tr("Increase Following Distance by:"), tr("Add extra space behind lead vehicles in snow. Increase for more space; decrease for tighter gaps."), ""}, - {"IncreasedStoppedDistanceSnow", tr("Increase Stopped Distance by:"), tr("Add extra buffer when stopped behind vehicles in snow. Increase for more room; decrease for shorter gaps."), ""}, - {"ReduceAccelerationSnow", tr("Reduce Acceleration by:"), tr("Lower the maximum acceleration in snow. Increase for softer takeoffs; decrease for quicker but less stable takeoffs."), ""}, - {"ReduceLateralAccelerationSnow", tr("Reduce Speed in Curves by:"), tr("Lower the desired speed while driving through curves in snow. Increase for safer, gentler turns; decrease for more aggressive driving in curves."), ""}, + {"SnowOffsets", tr("Snow"), + tr("Driving adjustments for snowy conditions."), ""}, + {"IncreaseFollowingSnow", tr("Increase Following Distance by:"), + tr("Add extra space behind lead vehicles in snow. Increase " + "for more space; decrease for tighter gaps."), + ""}, + {"IncreasedStoppedDistanceSnow", tr("Increase Stopped Distance by:"), + tr("Add extra buffer when stopped behind vehicles in snow. " + "Increase for more room; decrease for shorter gaps."), + ""}, + {"ReduceAccelerationSnow", tr("Reduce Acceleration by:"), + tr("Lower the maximum acceleration in snow. Increase for " + "softer takeoffs; decrease for quicker but less stable " + "takeoffs."), + ""}, + {"ReduceLateralAccelerationSnow", tr("Reduce Speed in Curves by:"), + tr("Lower the desired speed while driving through curves in " + "snow. Increase for safer, gentler turns; decrease for more " + "aggressive driving in curves."), + ""}, - {"SpeedLimitController", tr("Speed Limit Controller"), tr("Limit openpilot's maximum driving speed to the current speed limit obtained from downloaded maps, Mapbox, Navigate on openpilot, or the dashboard for supported vehicles (Ford, Genesis, Hyundai, Kia, Lexus, Toyota)."), "../assets/offroad/icon_speed_limit.png"}, - {"SLCFallback", tr("Fallback Speed"), tr("The speed used by \"Speed Limit Controller\" when no speed limit is found.

- Set Speed: Use the cruise set speed
- Experimental Mode: Estimate the limit using the driving model
- Previous Limit: Keep using the last confirmed limit"), ""}, - {"SLCOverride", tr("Override Speed"), tr("The speed used by \"Speed Limit Controller\" after you manually drive faster than the posted limit.

- Set with Gas Pedal: Use the highest speed reached while pressing the gas
- Max Set Speed: Use the cruise set speed

Overrides clear when openpilot disengages."), ""}, - {"SLCQOL", tr("Quality of Life"), tr("Miscellaneous \"Speed Limit Controller\" changes to fine-tune how openpilot drives."), ""}, - {"SLCConfirmation", tr("Confirm New Speed Limits"), tr("Ask before changing to a new speed limit. To accept, tap the flashing on-screen widget or press the Cruise Increase button. To deny, press the Cruise Decrease button or ignore the prompt for 30 seconds."), ""}, - {"ForceMPHDashboard", tr("Force MPH from Dashboard"), tr("Always read dashboard speed limit signs in mph. Turn this on if the cluster shows mph but the limit is interpreted as km/h."), ""}, - {"SLCLookaheadHigher", tr("Higher Limit Lookahead Time"), tr("How far ahead openpilot anticipates upcoming higher speed limits from downloaded map data."), ""}, - {"SLCLookaheadLower", tr("Lower Limit Lookahead Time"), tr("How far ahead openpilot anticipates upcoming lower speed limits from downloaded map data."), ""}, - {"SetSpeedLimit", tr("Match Speed Limit on Engage"), tr("When openpilot is first enabled, automatically set the max speed to the current posted limit."), ""}, - {"SLCMapboxFiller", tr("Use Mapbox as Fallback"), tr("Use Mapbox speed-limit data when no other source is available."), ""}, - {"SLCPriority", tr("Speed Limit Source Priority"), tr("The source order for speed limits when more than one is available."), ""}, - {"SLCOffsets", tr("Speed Limit Offsets"), tr("Add an offset to the posted speed limit to better match your driving style."), ""}, - {"Offset1", tr("Speed Offset (0–24 mph)"), tr("How much to offset posted speed-limits between 0 and 24 mph."), ""}, - {"Offset2", tr("Speed Offset (25–34 mph)"), tr("How much to offset posted speed-limits between 25 and 34 mph."), ""}, - {"Offset3", tr("Speed Offset (35–44 mph)"), tr("How much to offset posted speed-limits between 35 and 44 mph."), ""}, - {"Offset4", tr("Speed Offset (45–54 mph)"), tr("How much to offset posted speed-limits between 45 and 54 mph."), ""}, - {"Offset5", tr("Speed Offset (55–64 mph)"), tr("How much to offset posted speed-limits between 55 and 64 mph."), ""}, - {"Offset6", tr("Speed Offset (65–74 mph)"), tr("How much to offset posted speed-limits between 65 and 74 mph."), ""}, - {"Offset7", tr("Speed Offset (75–99 mph)"), tr("How much to offset posted speed-limits between 75 and 99 mph."), ""}, - {"SLCVisuals", tr("Visual Settings"), tr("Visual \"Speed Limit Controller\" changes to fine-tune how the driving screen looks."), ""}, - {"ShowSLCOffset", tr("Show Speed Limit Offset"), tr("Show the current offset from the posted limit on the driving screen."), ""}, - {"SpeedLimitSources", tr("Show Speed Limit Sources"), tr("Display the speed-limit sources and their current values on the driving screen."), ""} - }; + {"SpeedLimitController", tr("Speed Limit Controller"), + tr("Limit openpilot's maximum driving speed to the current speed " + "limit obtained from downloaded maps, Mapbox, Navigate on " + "openpilot, or the dashboard for supported vehicles (Ford, " + "Genesis, Hyundai, Kia, Lexus, Toyota)."), + "../assets/offroad/icon_speed_limit.png"}, + {"SLCFallback", tr("Fallback Speed"), + tr("The speed used by \"Speed Limit Controller\" when no speed " + "limit is found.

- Set Speed: Use the cruise " + "set speed
- Experimental Mode: Estimate the limit " + "using the driving model
- Previous Limit: Keep using " + "the last confirmed limit"), + ""}, + {"SLCOverride", tr("Override Speed"), + tr("The speed used by \"Speed Limit Controller\" after you " + "manually drive faster than the posted limit.

- " + "Set with Gas Pedal: Use the highest speed reached while " + "pressing the gas
- Max Set Speed: Use the cruise set " + "speed

Overrides clear when openpilot disengages."), + ""}, + {"SLCQOL", tr("Quality of Life"), + tr("Miscellaneous \"Speed Limit Controller\" changes to " + "fine-tune how openpilot drives."), + ""}, + {"SLCConfirmation", tr("Confirm New Speed Limits"), + tr("Ask before changing to a new speed limit. To accept, tap " + "the flashing on-screen widget or press the Cruise Increase " + "button. To deny, press the Cruise Decrease button or ignore the " + "prompt for 30 seconds."), + ""}, + {"ForceMPHDashboard", tr("Force MPH from Dashboard"), + tr("Always read dashboard speed limit signs in mph. Turn " + "this on if the cluster shows mph but the limit is interpreted " + "as km/h."), + ""}, + {"SLCLookaheadHigher", tr("Higher Limit Lookahead Time"), + tr("How far ahead openpilot anticipates upcoming higher speed " + "limits from downloaded map data."), + ""}, + {"SLCLookaheadLower", tr("Lower Limit Lookahead Time"), + tr("How far ahead openpilot anticipates upcoming lower speed " + "limits from downloaded map data."), + ""}, + {"SetSpeedLimit", tr("Match Speed Limit on Engage"), + tr("When openpilot is first enabled, automatically set the max " + "speed to the current posted limit."), + ""}, + {"SLCMapboxFiller", tr("Use Mapbox as Fallback"), + tr("Use Mapbox speed-limit data when no other source is " + "available."), + ""}, + {"SLCPriority", tr("Speed Limit Source Priority"), + tr("The source order for speed limits when more than one is " + "available."), + ""}, + {"SLCOffsets", tr("Speed Limit Offsets"), + tr("Add an offset to the posted speed limit to better match " + "your driving style."), + ""}, + {"Offset1", tr("Speed Offset (0–24 mph)"), + tr("How much to offset posted speed-limits between 0 and 24 " + "mph."), + ""}, + {"Offset2", tr("Speed Offset (25–34 mph)"), + tr("How much to offset posted speed-limits between 25 and 34 " + "mph."), + ""}, + {"Offset3", tr("Speed Offset (35–44 mph)"), + tr("How much to offset posted speed-limits between 35 and 44 " + "mph."), + ""}, + {"Offset4", tr("Speed Offset (45–54 mph)"), + tr("How much to offset posted speed-limits between 45 and 54 " + "mph."), + ""}, + {"Offset5", tr("Speed Offset (55–64 mph)"), + tr("How much to offset posted speed-limits between 55 and 64 " + "mph."), + ""}, + {"Offset6", tr("Speed Offset (65–74 mph)"), + tr("How much to offset posted speed-limits between 65 and 74 " + "mph."), + ""}, + {"Offset7", tr("Speed Offset (75–99 mph)"), + tr("How much to offset posted speed-limits between 75 and 99 " + "mph."), + ""}, + {"SLCVisuals", tr("Visual Settings"), + tr("Visual \"Speed Limit Controller\" changes to fine-tune " + "how the driving screen looks."), + ""}, + {"ShowSLCOffset", tr("Show Speed Limit Offset"), + tr("Show the current offset from the posted limit on the " + "driving screen."), + ""}, + {"SpeedLimitSources", tr("Show Speed Limit Sources"), + tr("Display the speed-limit sources and their current values " + "on the driving screen."), + ""}}; for (const auto &[param, title, desc, icon] : longitudinalToggles) { AbstractControl *longitudinalToggle; if (param == "AdvancedLongitudinalTune") { - FrogPilotManageControl *advancedLongitudinalTuneToggle = new FrogPilotManageControl(param, title, desc, icon); - QObject::connect(advancedLongitudinalTuneToggle, &FrogPilotManageControl::manageButtonClicked, [longitudinalLayout, advancedLongitudinalTunePanel]() { - longitudinalLayout->setCurrentWidget(advancedLongitudinalTunePanel); - }); + FrogPilotManageControl *advancedLongitudinalTuneToggle = + new FrogPilotManageControl(param, title, desc, icon); + QObject::connect(advancedLongitudinalTuneToggle, + &FrogPilotManageControl::manageButtonClicked, + [longitudinalLayout, advancedLongitudinalTunePanel]() { + longitudinalLayout->setCurrentWidget( + advancedLongitudinalTunePanel); + }); longitudinalToggle = advancedLongitudinalTuneToggle; } else if (param == "LongitudinalActuatorDelay") { - longitudinalActuatorDelayToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 1, tr(" seconds"), std::map(), 0.01); + longitudinalActuatorDelayToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 0, 1, tr(" seconds"), + std::map(), 0.01); longitudinalToggle = longitudinalActuatorDelayToggle; } else if (param == "StartAccel") { - startAccelToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 4, tr(" m/s²"), std::map(), 0.01, true); + startAccelToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 0, 4, tr(" m/s²"), + std::map(), 0.01, true); longitudinalToggle = startAccelToggle; } else if (param == "VEgoStarting") { - vEgoStartingToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0.01, 1, tr(" m/s²"), std::map(), 0.01); + vEgoStartingToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 0.01, 1, tr(" m/s²"), + std::map(), 0.01); longitudinalToggle = vEgoStartingToggle; } else if (param == "StopAccel") { - stopAccelToggle = new FrogPilotParamValueControl(param, title, desc, icon, -4, 0, tr(" m/s²"), std::map(), 0.01, true); + stopAccelToggle = new FrogPilotParamValueControl( + param, title, desc, icon, -4, 0, tr(" m/s²"), + std::map(), 0.01, true); longitudinalToggle = stopAccelToggle; } else if (param == "StoppingDecelRate") { - stoppingDecelRateToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0.001, 1, tr(" m/s²"), std::map(), 0.001, true); + stoppingDecelRateToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 0.001, 1, tr(" m/s²"), + std::map(), 0.001, true); longitudinalToggle = stoppingDecelRateToggle; } else if (param == "VEgoStopping") { - vEgoStoppingToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0.01, 1, tr(" m/s²"), std::map(), 0.01); + vEgoStoppingToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 0.01, 1, tr(" m/s²"), + std::map(), 0.01); longitudinalToggle = vEgoStoppingToggle; } else if (param == "ConditionalExperimental") { - FrogPilotManageControl *conditionalExperimentalToggle = new FrogPilotManageControl(param, title, desc, icon); - QObject::connect(conditionalExperimentalToggle, &FrogPilotManageControl::manageButtonClicked, [longitudinalLayout, conditionalExperimentalPanel]() { - longitudinalLayout->setCurrentWidget(conditionalExperimentalPanel); - }); + FrogPilotManageControl *conditionalExperimentalToggle = + new FrogPilotManageControl(param, title, desc, icon); + QObject::connect(conditionalExperimentalToggle, + &FrogPilotManageControl::manageButtonClicked, + [longitudinalLayout, conditionalExperimentalPanel]() { + longitudinalLayout->setCurrentWidget( + conditionalExperimentalPanel); + }); longitudinalToggle = conditionalExperimentalToggle; } else if (param == "CESpeed") { - FrogPilotParamValueControl *CESpeed = new FrogPilotParamValueControl(param, title, desc, icon, 0, 99, tr(" mph"), std::map(), 1, true, 175); - FrogPilotParamValueControl *CESpeedLead = new FrogPilotParamValueControl("CESpeedLead", tr("With Lead"), tr("Switch to \"Experimental Mode\" when driving below this speed with a lead to help openpilot handle low-speed situations more smoothly."), icon, 0, 99, tr(" mph"), std::map(), 1, true, 175); - FrogPilotDualParamValueControl *conditionalSpeeds = new FrogPilotDualParamValueControl(CESpeed, CESpeedLead); - longitudinalToggle = reinterpret_cast(conditionalSpeeds); + FrogPilotParamValueControl *CESpeed = new FrogPilotParamValueControl( + param, title, desc, icon, 0, 99, tr(" mph"), + std::map(), 1, true, 175); + FrogPilotParamValueControl *CESpeedLead = new FrogPilotParamValueControl( + "CESpeedLead", tr("With Lead"), + tr("Switch to \"Experimental Mode\" when driving below this speed " + "with a lead to help openpilot handle low-speed situations " + "more smoothly."), + icon, 0, 99, tr(" mph"), std::map(), 1, true, 175); + FrogPilotDualParamValueControl *conditionalSpeeds = + new FrogPilotDualParamValueControl(CESpeed, CESpeedLead); + longitudinalToggle = + reinterpret_cast(conditionalSpeeds); } else if (param == "CECurves") { std::vector curveToggles{"CECurvesLead"}; std::vector curveToggleNames{tr("With Lead")}; - longitudinalToggle = new FrogPilotButtonToggleControl(param, title, desc, icon, curveToggles, curveToggleNames); + longitudinalToggle = new FrogPilotButtonToggleControl( + param, title, desc, icon, curveToggles, curveToggleNames); } else if (param == "CELead") { std::vector leadToggles{"CESlowerLead", "CEStoppedLead"}; - std::vector leadToggleNames{tr("Slower Lead"), tr("Stopped Lead")}; - longitudinalToggle = new FrogPilotButtonToggleControl(param, title, desc, icon, leadToggles, leadToggleNames); + std::vector leadToggleNames{tr("Slower Lead"), + tr("Stopped Lead")}; + longitudinalToggle = new FrogPilotButtonToggleControl( + param, title, desc, icon, leadToggles, leadToggleNames); } else if (param == "CENavigation") { - std::vector navigationToggles{"CENavigationIntersections", "CENavigationTurns", "CENavigationLead"}; - std::vector navigationToggleNames{tr("Intersections"), tr("Turns"), tr("With Lead")}; - longitudinalToggle = new FrogPilotButtonToggleControl(param, title, desc, icon, navigationToggles, navigationToggleNames); + std::vector navigationToggles{ + "CENavigationIntersections", "CENavigationTurns", "CENavigationLead"}; + std::vector navigationToggleNames{tr("Intersections"), + tr("Turns"), tr("With Lead")}; + longitudinalToggle = new FrogPilotButtonToggleControl( + param, title, desc, icon, navigationToggles, navigationToggleNames); } else if (param == "CEModelStopTime") { std::map stopTimeLabels; for (int i = 0; i <= 10; ++i) { - stopTimeLabels[i] = i == 0 ? tr("Off") : i == 1 ? QString::number(i) + tr(" second") : QString::number(i) + tr(" seconds"); + stopTimeLabels[i] = i == 0 ? tr("Off") + : i == 1 ? QString::number(i) + tr(" second") + : QString::number(i) + tr(" seconds"); } - longitudinalToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 9, QString(), stopTimeLabels); + longitudinalToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 0, 9, QString(), stopTimeLabels); } else if (param == "CESignalSpeed") { std::vector ceSignalToggles{"CESignalLaneDetection"}; std::vector ceSignalToggleNames{tr("Not For Detected Lanes")}; - longitudinalToggle = new FrogPilotParamValueButtonControl(param, title, desc, icon, 0, 99, tr(" mph"), std::map(), 1.0, true, ceSignalToggles, ceSignalToggleNames, true); + longitudinalToggle = new FrogPilotParamValueButtonControl( + param, title, desc, icon, 0, 99, tr(" mph"), + std::map(), 1.0, true, ceSignalToggles, + ceSignalToggleNames, true); } else if (param == "CurveSpeedController") { - FrogPilotManageControl *curveControlToggle = new FrogPilotManageControl(param, title, desc, icon); - QObject::connect(curveControlToggle, &FrogPilotManageControl::manageButtonClicked, [longitudinalLayout, curveSpeedPanel]() { - longitudinalLayout->setCurrentWidget(curveSpeedPanel); - }); + FrogPilotManageControl *curveControlToggle = + new FrogPilotManageControl(param, title, desc, icon); + QObject::connect(curveControlToggle, + &FrogPilotManageControl::manageButtonClicked, + [longitudinalLayout, curveSpeedPanel]() { + longitudinalLayout->setCurrentWidget(curveSpeedPanel); + }); longitudinalToggle = curveControlToggle; } else if (param == "CalibrationProgress") { - calibrationProgressLabel = new LabelControl(title, QString::number(params.getFloat("CalibrationProgress"), 'f', 2) + "%", desc); + calibrationProgressLabel = new LabelControl( + title, + QString::number(params.getFloat("CalibrationProgress"), 'f', 2) + "%", + desc); longitudinalToggle = calibrationProgressLabel; } else if (param == "CalibratedLateralAcceleration") { - calibratedLateralAccelerationLabel = new LabelControl(title, QString::number(params.getFloat("CalibratedLateralAcceleration"), 'f', 2) + tr(" m/s²"), desc); + calibratedLateralAccelerationLabel = new LabelControl( + title, + QString::number(params.getFloat("CalibratedLateralAcceleration"), 'f', + 2) + + tr(" m/s²"), + desc); longitudinalToggle = calibratedLateralAccelerationLabel; } else if (param == "ResetCurveData") { - ButtonControl *resetCurveDataButton = new ButtonControl(title, tr("RESET"), desc); + ButtonControl *resetCurveDataButton = + new ButtonControl(title, tr("RESET"), desc); QObject::connect(resetCurveDataButton, &ButtonControl::clicked, [this]() { - if (FrogPilotConfirmationDialog::yesorno(tr("Are you sure you want to completely reset your curvature data?"), this)) { + if (FrogPilotConfirmationDialog::yesorno( + tr("Are you sure you want to completely reset your curvature " + "data?"), + this)) { params.putFloat("CalibratedLateralAcceleration", 2.00); params.remove("CalibrationProgress"); params.remove("CurvatureData"); @@ -260,159 +734,239 @@ FrogPilotLongitudinalPanel::FrogPilotLongitudinalPanel(FrogPilotSettingsWindow * params_cache.remove("CalibrationProgress"); params_cache.remove("CurvatureData"); - calibratedLateralAccelerationLabel->setText(QString::number(2.00, 'f', 2) + tr(" m/s²")); - calibrationProgressLabel->setText(QString::number(0.00, 'f', 2) + "%"); + calibratedLateralAccelerationLabel->setText( + QString::number(2.00, 'f', 2) + tr(" m/s²")); + calibrationProgressLabel->setText(QString::number(0.00, 'f', 2) + + "%"); } }); longitudinalToggle = resetCurveDataButton; } else if (param == "CustomPersonalities") { - FrogPilotManageControl *customPersonalitiesToggle = new FrogPilotManageControl(param, title, desc, icon); - QObject::connect(customPersonalitiesToggle, &FrogPilotManageControl::manageButtonClicked, [longitudinalLayout, customDrivingPersonalityPanel]() { - longitudinalLayout->setCurrentWidget(customDrivingPersonalityPanel); - }); + FrogPilotManageControl *customPersonalitiesToggle = + new FrogPilotManageControl(param, title, desc, icon); + QObject::connect(customPersonalitiesToggle, + &FrogPilotManageControl::manageButtonClicked, + [longitudinalLayout, customDrivingPersonalityPanel]() { + longitudinalLayout->setCurrentWidget( + customDrivingPersonalityPanel); + }); longitudinalToggle = customPersonalitiesToggle; - } else if (param == "ResetTrafficPersonality" || param == "ResetAggressivePersonality" || param == "ResetStandardPersonality" || param == "ResetRelaxedPersonality") { + } else if (param == "ResetTrafficPersonality" || + param == "ResetAggressivePersonality" || + param == "ResetStandardPersonality" || + param == "ResetRelaxedPersonality") { ButtonControl *resetButton = new ButtonControl(title, tr("RESET"), desc); longitudinalToggle = resetButton; } else if (param == "TrafficPersonalityProfile") { - FrogPilotManageControl *trafficPersonalityToggle = new FrogPilotManageControl(param, title, desc, icon); - QObject::connect(trafficPersonalityToggle, &FrogPilotManageControl::manageButtonClicked, [longitudinalLayout, trafficPersonalityPanel, this]() { - openSubSubPanel(); + FrogPilotManageControl *trafficPersonalityToggle = + new FrogPilotManageControl(param, title, desc, icon); + QObject::connect(trafficPersonalityToggle, + &FrogPilotManageControl::manageButtonClicked, + [longitudinalLayout, trafficPersonalityPanel, this]() { + openSubSubPanel(); - longitudinalLayout->setCurrentWidget(trafficPersonalityPanel); + longitudinalLayout->setCurrentWidget( + trafficPersonalityPanel); - customPersonalityOpen = true; - }); + customPersonalityOpen = true; + }); longitudinalToggle = trafficPersonalityToggle; } else if (param == "AggressivePersonalityProfile") { - FrogPilotManageControl *aggressivePersonalityToggle = new FrogPilotManageControl(param, title, desc, icon); - QObject::connect(aggressivePersonalityToggle, &FrogPilotManageControl::manageButtonClicked, [longitudinalLayout, aggressivePersonalityPanel, this]() { - openSubSubPanel(); + FrogPilotManageControl *aggressivePersonalityToggle = + new FrogPilotManageControl(param, title, desc, icon); + QObject::connect( + aggressivePersonalityToggle, + &FrogPilotManageControl::manageButtonClicked, + [longitudinalLayout, aggressivePersonalityPanel, this]() { + openSubSubPanel(); - longitudinalLayout->setCurrentWidget(aggressivePersonalityPanel); + longitudinalLayout->setCurrentWidget(aggressivePersonalityPanel); - customPersonalityOpen = true; - }); + customPersonalityOpen = true; + }); longitudinalToggle = aggressivePersonalityToggle; } else if (param == "StandardPersonalityProfile") { - FrogPilotManageControl *standardPersonalityToggle = new FrogPilotManageControl(param, title, desc, icon); - QObject::connect(standardPersonalityToggle, &FrogPilotManageControl::manageButtonClicked, [longitudinalLayout, standardPersonalityPanel, this]() { - openSubSubPanel(); + FrogPilotManageControl *standardPersonalityToggle = + new FrogPilotManageControl(param, title, desc, icon); + QObject::connect(standardPersonalityToggle, + &FrogPilotManageControl::manageButtonClicked, + [longitudinalLayout, standardPersonalityPanel, this]() { + openSubSubPanel(); - longitudinalLayout->setCurrentWidget(standardPersonalityPanel); + longitudinalLayout->setCurrentWidget( + standardPersonalityPanel); - customPersonalityOpen = true; - }); + customPersonalityOpen = true; + }); longitudinalToggle = standardPersonalityToggle; } else if (param == "RelaxedPersonalityProfile") { - FrogPilotManageControl *relaxedPersonalityToggle = new FrogPilotManageControl(param, title, desc, icon); - QObject::connect(relaxedPersonalityToggle, &FrogPilotManageControl::manageButtonClicked, [longitudinalLayout, relaxedPersonalityPanel, this]() { - openSubSubPanel(); + FrogPilotManageControl *relaxedPersonalityToggle = + new FrogPilotManageControl(param, title, desc, icon); + QObject::connect(relaxedPersonalityToggle, + &FrogPilotManageControl::manageButtonClicked, + [longitudinalLayout, relaxedPersonalityPanel, this]() { + openSubSubPanel(); - longitudinalLayout->setCurrentWidget(relaxedPersonalityPanel); + longitudinalLayout->setCurrentWidget( + relaxedPersonalityPanel); - customPersonalityOpen = true; - }); + customPersonalityOpen = true; + }); longitudinalToggle = relaxedPersonalityToggle; - } else if (aggressivePersonalityKeys.contains(param) || standardPersonalityKeys.contains(param) || relaxedPersonalityKeys.contains(param) || trafficPersonalityKeys.contains(param)) { - if (param == "TrafficFollow" || param == "AggressiveFollow" || param == "StandardFollow" || param == "RelaxedFollow") { + } else if (aggressivePersonalityKeys.contains(param) || + standardPersonalityKeys.contains(param) || + relaxedPersonalityKeys.contains(param) || + trafficPersonalityKeys.contains(param)) { + if (param == "TrafficFollow" || param == "AggressiveFollow" || + param == "StandardFollow" || param == "RelaxedFollow" || + param == "AggressiveFollowHigh" || param == "StandardFollowHigh" || + param == "RelaxedFollowHigh") { std::map followTimeLabels; for (float i = 0; i <= 3; i += 0.01) { - followTimeLabels[i] = std::lround(i / 0.01) == 1 / 0.01 ? QString::number(i, 'f', 2) + tr(" second") : QString::number(i, 'f', 2) + tr(" seconds"); + followTimeLabels[i] = + std::lround(i / 0.01) == 1 / 0.01 + ? QString::number(i, 'f', 2) + tr(" second") + : QString::number(i, 'f', 2) + tr(" seconds"); } if (param == "TrafficFollow") { - longitudinalToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0.5, 3, QString(), followTimeLabels, 0.01, true); + longitudinalToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 0.5, 3, QString(), followTimeLabels, + 0.01, true); } else { - longitudinalToggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 3, QString(), followTimeLabels, 0.01, true); + longitudinalToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 1, 3, QString(), followTimeLabels, 0.01, + true); } } else { - longitudinalToggle = new FrogPilotParamValueControl(param, title, desc, icon, 25, 200, "%"); + longitudinalToggle = new FrogPilotParamValueControl(param, title, desc, + icon, 25, 200, "%"); } } else if (param == "LongitudinalTune") { - FrogPilotManageControl *longitudinalTuneToggle = new FrogPilotManageControl(param, title, desc, icon); - QObject::connect(longitudinalTuneToggle, &FrogPilotManageControl::manageButtonClicked, [longitudinalLayout, longitudinalTunePanel]() { - longitudinalLayout->setCurrentWidget(longitudinalTunePanel); - }); + FrogPilotManageControl *longitudinalTuneToggle = + new FrogPilotManageControl(param, title, desc, icon); + QObject::connect( + longitudinalTuneToggle, &FrogPilotManageControl::manageButtonClicked, + [longitudinalLayout, longitudinalTunePanel]() { + longitudinalLayout->setCurrentWidget(longitudinalTunePanel); + }); longitudinalToggle = longitudinalTuneToggle; } else if (param == "AccelerationProfile") { - std::vector accelerationProfiles{tr("Standard"), tr("Eco"), tr("Sport"), tr("Sport+")}; - ButtonParamControl *accelerationProfileToggle = new ButtonParamControl(param, title, desc, icon, accelerationProfiles); + std::vector accelerationProfiles{tr("Standard"), tr("Eco"), + tr("Sport"), tr("Sport+")}; + ButtonParamControl *accelerationProfileToggle = new ButtonParamControl( + param, title, desc, icon, accelerationProfiles); longitudinalToggle = accelerationProfileToggle; } else if (param == "DecelerationProfile") { - std::vector decelerationProfiles{tr("Standard"), tr("Eco"), tr("Sport")}; - ButtonParamControl *decelerationProfileToggle = new ButtonParamControl(param, title, desc, icon, decelerationProfiles); + std::vector decelerationProfiles{tr("Standard"), tr("Eco"), + tr("Sport")}; + ButtonParamControl *decelerationProfileToggle = new ButtonParamControl( + param, title, desc, icon, decelerationProfiles); longitudinalToggle = decelerationProfileToggle; } else if (param == "LeadDetectionThreshold") { - longitudinalToggle = new FrogPilotParamValueControl(param, title, desc, icon, 25, 50, "%"); + longitudinalToggle = + new FrogPilotParamValueControl(param, title, desc, icon, 25, 50, "%"); } else if (param == "MaxDesiredAcceleration") { - longitudinalToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0.1, 4.0, tr(" m/s²"), std::map(), 0.1); + longitudinalToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 0.1, 4.0, tr(" m/s²"), + std::map(), 0.1); } else if (param == "QOLLongitudinal") { - FrogPilotManageControl *qolLongitudinalToggle = new FrogPilotManageControl(param, title, desc, icon); - QObject::connect(qolLongitudinalToggle, &FrogPilotManageControl::manageButtonClicked, [longitudinalLayout, qolPanel]() { - longitudinalLayout->setCurrentWidget(qolPanel); - }); + FrogPilotManageControl *qolLongitudinalToggle = + new FrogPilotManageControl(param, title, desc, icon); + QObject::connect(qolLongitudinalToggle, + &FrogPilotManageControl::manageButtonClicked, + [longitudinalLayout, qolPanel]() { + longitudinalLayout->setCurrentWidget(qolPanel); + }); longitudinalToggle = qolLongitudinalToggle; } else if (param == "CustomCruise") { - longitudinalToggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 99, tr(" mph")); + longitudinalToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 1, 99, tr(" mph")); } else if (param == "CustomCruiseLong") { - longitudinalToggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 99, tr(" mph")); + longitudinalToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 1, 99, tr(" mph")); } else if (param == "IncreasedStoppedDistance") { - longitudinalToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 10, tr(" feet")); + longitudinalToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 0, 10, tr(" feet")); } else if (param == "MapGears") { - std::vector mapGearsToggles{"MapAcceleration", "MapDeceleration"}; - std::vector mapGearsToggleNames{tr("Acceleration"), tr("Deceleration")}; - longitudinalToggle = new FrogPilotButtonToggleControl(param, title, desc, icon, mapGearsToggles, mapGearsToggleNames); + std::vector mapGearsToggles{"MapAcceleration", + "MapDeceleration"}; + std::vector mapGearsToggleNames{tr("Acceleration"), + tr("Deceleration")}; + longitudinalToggle = new FrogPilotButtonToggleControl( + param, title, desc, icon, mapGearsToggles, mapGearsToggleNames); } else if (param == "SetSpeedOffset") { - longitudinalToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 99, tr(" mph")); + longitudinalToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 0, 99, tr(" mph")); } else if (param == "SpeedLimitController") { - FrogPilotManageControl *speedLimitControllerToggle = new FrogPilotManageControl(param, title, desc, icon); - QObject::connect(speedLimitControllerToggle, &FrogPilotManageControl::manageButtonClicked, [longitudinalLayout, speedLimitControllerPanel]() { - longitudinalLayout->setCurrentWidget(speedLimitControllerPanel); - }); + FrogPilotManageControl *speedLimitControllerToggle = + new FrogPilotManageControl(param, title, desc, icon); + QObject::connect(speedLimitControllerToggle, + &FrogPilotManageControl::manageButtonClicked, + [longitudinalLayout, speedLimitControllerPanel]() { + longitudinalLayout->setCurrentWidget( + speedLimitControllerPanel); + }); longitudinalToggle = speedLimitControllerToggle; } else if (param == "SLCFallback") { - std::vector fallbackOptions{tr("Set Speed"), tr("Experimental Mode"), tr("Previous Limit")}; - ButtonParamControl *fallbackSelection = new ButtonParamControl(param, title, desc, icon, fallbackOptions); + std::vector fallbackOptions{ + tr("Set Speed"), tr("Experimental Mode"), tr("Previous Limit")}; + ButtonParamControl *fallbackSelection = + new ButtonParamControl(param, title, desc, icon, fallbackOptions); longitudinalToggle = fallbackSelection; } else if (param == "SLCOverride") { - std::vector overrideOptions{tr("None"), tr("Set With Gas Pedal"), tr("Max Set Speed")}; - ButtonParamControl *overrideSelection = new ButtonParamControl(param, title, desc, icon, overrideOptions); + std::vector overrideOptions{tr("None"), tr("Set With Gas Pedal"), + tr("Max Set Speed")}; + ButtonParamControl *overrideSelection = + new ButtonParamControl(param, title, desc, icon, overrideOptions); longitudinalToggle = overrideSelection; } else if (param == "SLCPriority") { - ButtonControl *slcPriorityButton = new ButtonControl(title, tr("SELECT"), desc); - QStringList primaryPriorities = {tr("Dashboard"), tr("Map Data"), tr("Navigation"), tr("Highest"), tr("Lowest")}; - QStringList otherPriorities = {tr("None"), tr("Dashboard"), tr("Map Data"), tr("Navigation")}; - QStringList priorityPrompts = {tr("Select your primary priority"), tr("Select your secondary priority"), tr("Select your tertiary priority")}; + ButtonControl *slcPriorityButton = + new ButtonControl(title, tr("SELECT"), desc); + QStringList primaryPriorities = {tr("Dashboard"), tr("Map Data"), + tr("Navigation"), tr("Highest"), + tr("Lowest")}; + QStringList otherPriorities = {tr("None"), tr("Dashboard"), + tr("Map Data"), tr("Navigation")}; + QStringList priorityPrompts = {tr("Select your primary priority"), + tr("Select your secondary priority"), + tr("Select your tertiary priority")}; QObject::connect(slcPriorityButton, &ButtonControl::clicked, [=]() { QStringList selectedPriorities; for (int i = 1; i <= 3; ++i) { - QStringList availablePriorities = i == 1 ? primaryPriorities : otherPriorities; - availablePriorities = availablePriorities.toSet().subtract(selectedPriorities.toSet()).toList(); + QStringList availablePriorities = + i == 1 ? primaryPriorities : otherPriorities; + availablePriorities = availablePriorities.toSet() + .subtract(selectedPriorities.toSet()) + .toList(); if (!hasDashSpeedLimits) { availablePriorities.removeAll(tr("Dashboard")); } - if (availablePriorities.size() == 1 && availablePriorities.contains(tr("None"))) { + if (availablePriorities.size() == 1 && + availablePriorities.contains(tr("None"))) { break; } - QString selection = MultiOptionDialog::getSelection(priorityPrompts[i - 1], availablePriorities, "", this); + QString selection = MultiOptionDialog::getSelection( + priorityPrompts[i - 1], availablePriorities, "", this); if (selection.isEmpty()) { break; } selectedPriorities.append(selection); - params.put(QString("SLCPriority%1").arg(i).toStdString(), selection.toStdString()); + params.put(QString("SLCPriority%1").arg(i).toStdString(), + selection.toStdString()); if (selection == tr("None")) { for (int j = i + 1; j <= 3; ++j) { - params.put(QString("SLCPriority%1").arg(j).toStdString(), tr("None").toStdString()); + params.put(QString("SLCPriority%1").arg(j).toStdString(), + tr("None").toStdString()); } break; } @@ -430,7 +984,8 @@ FrogPilotLongitudinalPanel::FrogPilotLongitudinalPanel(FrogPilotSettingsWindow * QStringList selectedPriorities; for (int i = 1; i <= 3; ++i) { - QString priority = QString::fromStdString(params.get(QString("SLCPriority%1").arg(i).toStdString())); + QString priority = QString::fromStdString( + params.get(QString("SLCPriority%1").arg(i).toStdString())); if (primaryPriorities.contains(priority)) { selectedPriorities.append(priority); } @@ -439,42 +994,59 @@ FrogPilotLongitudinalPanel::FrogPilotLongitudinalPanel(FrogPilotSettingsWindow * longitudinalToggle = slcPriorityButton; } else if (param == "SLCOffsets") { - ButtonControl *manageSLCOffsetsButton = new ButtonControl(title, tr("MANAGE"), desc); - QObject::connect(manageSLCOffsetsButton, &ButtonControl::clicked, [longitudinalLayout, speedLimitControllerOffsetsPanel, this]() { - openSubSubPanel(); + ButtonControl *manageSLCOffsetsButton = + new ButtonControl(title, tr("MANAGE"), desc); + QObject::connect( + manageSLCOffsetsButton, &ButtonControl::clicked, + [longitudinalLayout, speedLimitControllerOffsetsPanel, this]() { + openSubSubPanel(); - longitudinalLayout->setCurrentWidget(speedLimitControllerOffsetsPanel); + longitudinalLayout->setCurrentWidget( + speedLimitControllerOffsetsPanel); - slcOpen = true; - }); + slcOpen = true; + }); longitudinalToggle = manageSLCOffsetsButton; } else if (speedLimitControllerOffsetsKeys.contains(param)) { - longitudinalToggle = new FrogPilotParamValueControl(param, title, desc, icon, -99, 99, tr(" mph")); + longitudinalToggle = new FrogPilotParamValueControl( + param, title, desc, icon, -99, 99, tr(" mph")); } else if (param == "SLCQOL") { - ButtonControl *manageSLCQOLButton = new ButtonControl(title, tr("MANAGE"), desc); - QObject::connect(manageSLCQOLButton, &ButtonControl::clicked, [longitudinalLayout, speedLimitControllerQOLPanel, this]() { - openSubSubPanel(); + ButtonControl *manageSLCQOLButton = + new ButtonControl(title, tr("MANAGE"), desc); + QObject::connect( + manageSLCQOLButton, &ButtonControl::clicked, + [longitudinalLayout, speedLimitControllerQOLPanel, this]() { + openSubSubPanel(); - longitudinalLayout->setCurrentWidget(speedLimitControllerQOLPanel); + longitudinalLayout->setCurrentWidget(speedLimitControllerQOLPanel); - slcOpen = true; - }); + slcOpen = true; + }); longitudinalToggle = manageSLCQOLButton; } else if (param == "SLCConfirmation") { - std::vector confirmationToggles{"SLCConfirmationLower", "SLCConfirmationHigher"}; - std::vector confirmationToggleNames{tr("Lower Limits"), tr("Higher Limits")}; - longitudinalToggle = new FrogPilotButtonToggleControl(param, title, desc, icon, confirmationToggles, confirmationToggleNames); + std::vector confirmationToggles{"SLCConfirmationLower", + "SLCConfirmationHigher"}; + std::vector confirmationToggleNames{tr("Lower Limits"), + tr("Higher Limits")}; + longitudinalToggle = new FrogPilotButtonToggleControl( + param, title, desc, icon, confirmationToggles, + confirmationToggleNames); } else if (param == "SLCLookaheadHigher" || param == "SLCLookaheadLower") { - longitudinalToggle = new FrogPilotParamValueControl(param, title, desc, icon, 0, 30, tr(" seconds")); + longitudinalToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 0, 30, tr(" seconds")); } else if (param == "SLCVisuals") { - ButtonControl *manageSLCVisualsButton = new ButtonControl(title, tr("MANAGE"), desc); - QObject::connect(manageSLCVisualsButton, &ButtonControl::clicked, [longitudinalLayout, speedLimitControllerVisualPanel, this]() { - openSubSubPanel(); + ButtonControl *manageSLCVisualsButton = + new ButtonControl(title, tr("MANAGE"), desc); + QObject::connect( + manageSLCVisualsButton, &ButtonControl::clicked, + [longitudinalLayout, speedLimitControllerVisualPanel, this]() { + openSubSubPanel(); - longitudinalLayout->setCurrentWidget(speedLimitControllerVisualPanel); + longitudinalLayout->setCurrentWidget( + speedLimitControllerVisualPanel); - slcOpen = true; - }); + slcOpen = true; + }); longitudinalToggle = manageSLCVisualsButton; } else { @@ -517,146 +1089,257 @@ FrogPilotLongitudinalPanel::FrogPilotLongitudinalPanel(FrogPilotSettingsWindow * parentKeys.insert(param); } - if (FrogPilotManageControl *frogPilotManageToggle = qobject_cast(longitudinalToggle)) { - QObject::connect(frogPilotManageToggle, &FrogPilotManageControl::manageButtonClicked, [this]() { - emit openSubPanel(); - openDescriptions(forceOpenDescriptions, toggles); - }); + if (FrogPilotManageControl *frogPilotManageToggle = + qobject_cast(longitudinalToggle)) { + QObject::connect(frogPilotManageToggle, + &FrogPilotManageControl::manageButtonClicked, [this]() { + emit openSubPanel(); + openDescriptions(forceOpenDescriptions, toggles); + }); } - QObject::connect(longitudinalToggle, &AbstractControl::hideDescriptionEvent, [this]() { - update(); - }); - QObject::connect(longitudinalToggle, &AbstractControl::showDescriptionEvent, [this]() { - update(); - }); + QObject::connect(longitudinalToggle, &AbstractControl::hideDescriptionEvent, + [this]() { update(); }); + QObject::connect(longitudinalToggle, &AbstractControl::showDescriptionEvent, + [this]() { update(); }); } QSet forceUpdateKeys = {"HumanAcceleration", "LongitudinalTune"}; for (const QString &key : forceUpdateKeys) { - QObject::connect(static_cast(toggles[key]), &ToggleControl::toggleFlipped, this, &FrogPilotLongitudinalPanel::updateToggles); + QObject::connect(static_cast(toggles[key]), + &ToggleControl::toggleFlipped, this, + &FrogPilotLongitudinalPanel::updateToggles); } - FrogPilotParamValueControl *trafficFollowToggle = static_cast(toggles["TrafficFollow"]); - FrogPilotParamValueControl *trafficAccelerationToggle = static_cast(toggles["TrafficJerkAcceleration"]); - FrogPilotParamValueControl *trafficDecelerationToggle = static_cast(toggles["TrafficJerkDeceleration"]); - FrogPilotParamValueControl *trafficDangerToggle = static_cast(toggles["TrafficJerkDanger"]); - FrogPilotParamValueControl *trafficSpeedToggle = static_cast(toggles["TrafficJerkSpeed"]); - FrogPilotParamValueControl *trafficSpeedDecreaseToggle = static_cast(toggles["TrafficJerkSpeedDecrease"]); - FrogPilotButtonsControl *trafficResetButton = static_cast(toggles["ResetTrafficPersonality"]); - QObject::connect(trafficResetButton, &FrogPilotButtonsControl::buttonClicked, [=]() { - if (FrogPilotConfirmationDialog::yesorno(tr("Are you sure you want to completely reset your settings for Traffic Mode?"), this)) { - params.putFloat("TrafficFollow", params_default.getFloat("TrafficFollow")); - params.putFloat("TrafficJerkAcceleration", params_default.getFloat("TrafficJerkAcceleration")); - params.putFloat("TrafficJerkDeceleration", params_default.getFloat("TrafficJerkDeceleration")); - params.putFloat("TrafficJerkDanger", params_default.getFloat("TrafficJerkDanger")); - params.putFloat("TrafficJerkSpeed", params_default.getFloat("TrafficJerkSpeed")); - params.putFloat("TrafficJerkSpeedDecrease", params_default.getFloat("TrafficJerkSpeedDecrease")); + FrogPilotParamValueControl *trafficFollowToggle = + static_cast(toggles["TrafficFollow"]); + FrogPilotParamValueControl *trafficAccelerationToggle = + static_cast( + toggles["TrafficJerkAcceleration"]); + FrogPilotParamValueControl *trafficDecelerationToggle = + static_cast( + toggles["TrafficJerkDeceleration"]); + FrogPilotParamValueControl *trafficDangerToggle = + static_cast(toggles["TrafficJerkDanger"]); + FrogPilotParamValueControl *trafficSpeedToggle = + static_cast(toggles["TrafficJerkSpeed"]); + FrogPilotParamValueControl *trafficSpeedDecreaseToggle = + static_cast( + toggles["TrafficJerkSpeedDecrease"]); + FrogPilotButtonsControl *trafficResetButton = + static_cast( + toggles["ResetTrafficPersonality"]); + QObject::connect( + trafficResetButton, &FrogPilotButtonsControl::buttonClicked, [=]() { + if (FrogPilotConfirmationDialog::yesorno( + tr("Are you sure you want to completely reset your settings " + "for Traffic Mode?"), + this)) { + params.putFloat("TrafficFollow", + params_default.getFloat("TrafficFollow")); + params.putFloat("TrafficJerkAcceleration", + params_default.getFloat("TrafficJerkAcceleration")); + params.putFloat("TrafficJerkDeceleration", + params_default.getFloat("TrafficJerkDeceleration")); + params.putFloat("TrafficJerkDanger", + params_default.getFloat("TrafficJerkDanger")); + params.putFloat("TrafficJerkSpeed", + params_default.getFloat("TrafficJerkSpeed")); + params.putFloat("TrafficJerkSpeedDecrease", + params_default.getFloat("TrafficJerkSpeedDecrease")); - trafficFollowToggle->refresh(); - trafficAccelerationToggle->refresh(); - trafficDecelerationToggle->refresh(); - trafficDangerToggle->refresh(); - trafficSpeedToggle->refresh(); - trafficSpeedDecreaseToggle->refresh(); - } - }); + trafficFollowToggle->refresh(); + trafficAccelerationToggle->refresh(); + trafficDecelerationToggle->refresh(); + trafficDangerToggle->refresh(); + trafficSpeedToggle->refresh(); + trafficSpeedDecreaseToggle->refresh(); + } + }); - FrogPilotParamValueControl *aggressiveFollowToggle = static_cast(toggles["AggressiveFollow"]); - FrogPilotParamValueControl *aggressiveAccelerationToggle = static_cast(toggles["AggressiveJerkAcceleration"]); - FrogPilotParamValueControl *aggressiveDecelerationToggle = static_cast(toggles["AggressiveJerkDeceleration"]); - FrogPilotParamValueControl *aggressiveDangerToggle = static_cast(toggles["AggressiveJerkDanger"]); - FrogPilotParamValueControl *aggressiveSpeedToggle = static_cast(toggles["AggressiveJerkSpeed"]); - FrogPilotParamValueControl *aggressiveSpeedDecreaseToggle = static_cast(toggles["AggressiveJerkSpeedDecrease"]); - FrogPilotButtonsControl *aggressiveResetButton = static_cast(toggles["ResetAggressivePersonality"]); - QObject::connect(aggressiveResetButton, &FrogPilotButtonsControl::buttonClicked, [=]() { - if (FrogPilotConfirmationDialog::yesorno(tr("Are you sure you want to completely reset your settings for the Aggressive personality?"), this)) { - params.putFloat("AggressiveFollow", params_default.getFloat("AggressiveFollow")); - params.putFloat("AggressiveJerkAcceleration", params_default.getFloat("AggressiveJerkAcceleration")); - params.putFloat("AggressiveJerkDeceleration", params_default.getFloat("AggressiveJerkDeceleration")); - params.putFloat("AggressiveJerkDanger", params_default.getFloat("AggressiveJerkDanger")); - params.putFloat("AggressiveJerkSpeed", params_default.getFloat("AggressiveJerkSpeed")); - params.putFloat("AggressiveJerkSpeedDecrease", params_default.getFloat("AggressiveJerkSpeedDecrease")); + FrogPilotParamValueControl *aggressiveFollowToggle = + static_cast(toggles["AggressiveFollow"]); + FrogPilotParamValueControl *aggressiveFollowHighToggle = + static_cast( + toggles["AggressiveFollowHigh"]); + FrogPilotParamValueControl *aggressiveAccelerationToggle = + static_cast( + toggles["AggressiveJerkAcceleration"]); + FrogPilotParamValueControl *aggressiveDecelerationToggle = + static_cast( + toggles["AggressiveJerkDeceleration"]); + FrogPilotParamValueControl *aggressiveDangerToggle = + static_cast( + toggles["AggressiveJerkDanger"]); + FrogPilotParamValueControl *aggressiveSpeedToggle = + static_cast(toggles["AggressiveJerkSpeed"]); + FrogPilotParamValueControl *aggressiveSpeedDecreaseToggle = + static_cast( + toggles["AggressiveJerkSpeedDecrease"]); + FrogPilotButtonsControl *aggressiveResetButton = + static_cast( + toggles["ResetAggressivePersonality"]); + QObject::connect( + aggressiveResetButton, &FrogPilotButtonsControl::buttonClicked, [=]() { + if (FrogPilotConfirmationDialog::yesorno( + tr("Are you sure you want to completely reset your settings " + "for the Aggressive personality?"), + this)) { + params.putFloat("AggressiveFollow", + params_default.getFloat("AggressiveFollow")); + params.putFloat("AggressiveFollowHigh", + params_default.getFloat("AggressiveFollowHigh")); + params.putFloat( + "AggressiveJerkAcceleration", + params_default.getFloat("AggressiveJerkAcceleration")); + params.putFloat( + "AggressiveJerkDeceleration", + params_default.getFloat("AggressiveJerkDeceleration")); + params.putFloat("AggressiveJerkDanger", + params_default.getFloat("AggressiveJerkDanger")); + params.putFloat("AggressiveJerkSpeed", + params_default.getFloat("AggressiveJerkSpeed")); + params.putFloat( + "AggressiveJerkSpeedDecrease", + params_default.getFloat("AggressiveJerkSpeedDecrease")); - aggressiveFollowToggle->refresh(); - aggressiveAccelerationToggle->refresh(); - aggressiveDecelerationToggle->refresh(); - aggressiveDangerToggle->refresh(); - aggressiveSpeedToggle->refresh(); - aggressiveSpeedDecreaseToggle->refresh(); - } - }); + aggressiveFollowToggle->refresh(); + aggressiveFollowHighToggle->refresh(); + aggressiveAccelerationToggle->refresh(); + aggressiveDecelerationToggle->refresh(); + aggressiveDangerToggle->refresh(); + aggressiveSpeedToggle->refresh(); + aggressiveSpeedDecreaseToggle->refresh(); + } + }); - FrogPilotParamValueControl *standardFollowToggle = static_cast(toggles["StandardFollow"]); - FrogPilotParamValueControl *standardAccelerationToggle = static_cast(toggles["StandardJerkAcceleration"]); - FrogPilotParamValueControl *standardDecelerationToggle = static_cast(toggles["StandardJerkDeceleration"]); - FrogPilotParamValueControl *standardDangerToggle = static_cast(toggles["StandardJerkDanger"]); - FrogPilotParamValueControl *standardSpeedToggle = static_cast(toggles["StandardJerkSpeed"]); - FrogPilotParamValueControl *standardSpeedDecreaseToggle = static_cast(toggles["StandardJerkSpeedDecrease"]); - FrogPilotButtonsControl *standardResetButton = static_cast(toggles["ResetStandardPersonality"]); - QObject::connect(standardResetButton, &FrogPilotButtonsControl::buttonClicked, [=]() { - if (FrogPilotConfirmationDialog::yesorno(tr("Are you sure you want to completely reset your settings for the Standard personality?"), this)) { - params.putFloat("StandardFollow", params_default.getFloat("StandardFollow")); - params.putFloat("StandardJerkAcceleration", params_default.getFloat("StandardJerkAcceleration")); - params.putFloat("StandardJerkDeceleration", params_default.getFloat("StandardJerkDeceleration")); - params.putFloat("StandardJerkDanger", params_default.getFloat("StandardJerkDanger")); - params.putFloat("StandardJerkSpeed", params_default.getFloat("StandardJerkSpeed")); - params.putFloat("StandardJerkSpeedDecrease", params_default.getFloat("StandardJerkSpeedDecrease")); + FrogPilotParamValueControl *standardFollowToggle = + static_cast(toggles["StandardFollow"]); + FrogPilotParamValueControl *standardFollowHighToggle = + static_cast(toggles["StandardFollowHigh"]); + FrogPilotParamValueControl *standardAccelerationToggle = + static_cast( + toggles["StandardJerkAcceleration"]); + FrogPilotParamValueControl *standardDecelerationToggle = + static_cast( + toggles["StandardJerkDeceleration"]); + FrogPilotParamValueControl *standardDangerToggle = + static_cast(toggles["StandardJerkDanger"]); + FrogPilotParamValueControl *standardSpeedToggle = + static_cast(toggles["StandardJerkSpeed"]); + FrogPilotParamValueControl *standardSpeedDecreaseToggle = + static_cast( + toggles["StandardJerkSpeedDecrease"]); + FrogPilotButtonsControl *standardResetButton = + static_cast( + toggles["ResetStandardPersonality"]); + QObject::connect( + standardResetButton, &FrogPilotButtonsControl::buttonClicked, [=]() { + if (FrogPilotConfirmationDialog::yesorno( + tr("Are you sure you want to completely reset your settings " + "for the Standard personality?"), + this)) { + params.putFloat("StandardFollow", + params_default.getFloat("StandardFollow")); + params.putFloat("StandardFollowHigh", + params_default.getFloat("StandardFollowHigh")); + params.putFloat("StandardJerkAcceleration", + params_default.getFloat("StandardJerkAcceleration")); + params.putFloat("StandardJerkDeceleration", + params_default.getFloat("StandardJerkDeceleration")); + params.putFloat("StandardJerkDanger", + params_default.getFloat("StandardJerkDanger")); + params.putFloat("StandardJerkSpeed", + params_default.getFloat("StandardJerkSpeed")); + params.putFloat("StandardJerkSpeedDecrease", + params_default.getFloat("StandardJerkSpeedDecrease")); - standardFollowToggle->refresh(); - standardAccelerationToggle->refresh(); - standardDecelerationToggle->refresh(); - standardDangerToggle->refresh(); - standardSpeedToggle->refresh(); - standardSpeedDecreaseToggle->refresh(); - } - }); + standardFollowToggle->refresh(); + standardFollowHighToggle->refresh(); + standardAccelerationToggle->refresh(); + standardDecelerationToggle->refresh(); + standardDangerToggle->refresh(); + standardSpeedToggle->refresh(); + standardSpeedDecreaseToggle->refresh(); + } + }); - FrogPilotParamValueControl *relaxedFollowToggle = static_cast(toggles["RelaxedFollow"]); - FrogPilotParamValueControl *relaxedAccelerationToggle = static_cast(toggles["RelaxedJerkAcceleration"]); - FrogPilotParamValueControl *relaxedDecelerationToggle = static_cast(toggles["RelaxedJerkDeceleration"]); - FrogPilotParamValueControl *relaxedDangerToggle = static_cast(toggles["RelaxedJerkDanger"]); - FrogPilotParamValueControl *relaxedSpeedToggle = static_cast(toggles["RelaxedJerkSpeed"]); - FrogPilotParamValueControl *relaxedSpeedDecreaseToggle = static_cast(toggles["RelaxedJerkSpeedDecrease"]); - FrogPilotButtonsControl *relaxedResetButton = static_cast(toggles["ResetRelaxedPersonality"]); - QObject::connect(relaxedResetButton, &FrogPilotButtonsControl::buttonClicked, [=]() { - if (FrogPilotConfirmationDialog::yesorno(tr("Are you sure you want to completely reset your settings for the Relaxed personality?"), this)) { - params.putFloat("RelaxedFollow", params_default.getFloat("RelaxedFollow")); - params.putFloat("RelaxedJerkAcceleration", params_default.getFloat("RelaxedJerkAcceleration")); - params.putFloat("RelaxedJerkDeceleration", params_default.getFloat("RelaxedJerkDeceleration")); - params.putFloat("RelaxedJerkDanger", params_default.getFloat("RelaxedJerkDanger")); - params.putFloat("RelaxedJerkSpeed", params_default.getFloat("RelaxedJerkSpeed")); - params.putFloat("RelaxedJerkSpeedDecrease", params_default.getFloat("RelaxedJerkSpeedDecrease")); + FrogPilotParamValueControl *relaxedFollowToggle = + static_cast(toggles["RelaxedFollow"]); + FrogPilotParamValueControl *relaxedFollowHighToggle = + static_cast(toggles["RelaxedFollowHigh"]); + FrogPilotParamValueControl *relaxedAccelerationToggle = + static_cast( + toggles["RelaxedJerkAcceleration"]); + FrogPilotParamValueControl *relaxedDecelerationToggle = + static_cast( + toggles["RelaxedJerkDeceleration"]); + FrogPilotParamValueControl *relaxedDangerToggle = + static_cast(toggles["RelaxedJerkDanger"]); + FrogPilotParamValueControl *relaxedSpeedToggle = + static_cast(toggles["RelaxedJerkSpeed"]); + FrogPilotParamValueControl *relaxedSpeedDecreaseToggle = + static_cast( + toggles["RelaxedJerkSpeedDecrease"]); + FrogPilotButtonsControl *relaxedResetButton = + static_cast( + toggles["ResetRelaxedPersonality"]); + QObject::connect( + relaxedResetButton, &FrogPilotButtonsControl::buttonClicked, [=]() { + if (FrogPilotConfirmationDialog::yesorno( + tr("Are you sure you want to completely reset your settings " + "for the Relaxed personality?"), + this)) { + params.putFloat("RelaxedFollow", + params_default.getFloat("RelaxedFollow")); + params.putFloat("RelaxedFollowHigh", + params_default.getFloat("RelaxedFollowHigh")); + params.putFloat("RelaxedJerkAcceleration", + params_default.getFloat("RelaxedJerkAcceleration")); + params.putFloat("RelaxedJerkDeceleration", + params_default.getFloat("RelaxedJerkDeceleration")); + params.putFloat("RelaxedJerkDanger", + params_default.getFloat("RelaxedJerkDanger")); + params.putFloat("RelaxedJerkSpeed", + params_default.getFloat("RelaxedJerkSpeed")); + params.putFloat("RelaxedJerkSpeedDecrease", + params_default.getFloat("RelaxedJerkSpeedDecrease")); - relaxedFollowToggle->refresh(); - relaxedAccelerationToggle->refresh(); - relaxedDecelerationToggle->refresh(); - relaxedDangerToggle->refresh(); - relaxedSpeedToggle->refresh(); - relaxedSpeedDecreaseToggle->refresh(); - } - }); + relaxedFollowToggle->refresh(); + relaxedFollowHighToggle->refresh(); + relaxedAccelerationToggle->refresh(); + relaxedDecelerationToggle->refresh(); + relaxedDangerToggle->refresh(); + relaxedSpeedToggle->refresh(); + relaxedSpeedDecreaseToggle->refresh(); + } + }); openDescriptions(forceOpenDescriptions, toggles); - QObject::connect(parent, &FrogPilotSettingsWindow::closeSubPanel, [longitudinalLayout, longitudinalPanel, this] { - openDescriptions(forceOpenDescriptions, toggles); - longitudinalLayout->setCurrentWidget(longitudinalPanel); - }); - QObject::connect(parent, &FrogPilotSettingsWindow::closeSubSubPanel, [longitudinalLayout, customDrivingPersonalityPanel, speedLimitControllerPanel, this]() { - openDescriptions(forceOpenDescriptions, toggles); + QObject::connect(parent, &FrogPilotSettingsWindow::closeSubPanel, + [longitudinalLayout, longitudinalPanel, this] { + openDescriptions(forceOpenDescriptions, toggles); + longitudinalLayout->setCurrentWidget(longitudinalPanel); + }); + QObject::connect( + parent, &FrogPilotSettingsWindow::closeSubSubPanel, + [longitudinalLayout, customDrivingPersonalityPanel, + speedLimitControllerPanel, this]() { + openDescriptions(forceOpenDescriptions, toggles); - if (customPersonalityOpen) { - longitudinalLayout->setCurrentWidget(customDrivingPersonalityPanel); + if (customPersonalityOpen) { + longitudinalLayout->setCurrentWidget(customDrivingPersonalityPanel); - customPersonalityOpen = false; - } else if (slcOpen) { - longitudinalLayout->setCurrentWidget(speedLimitControllerPanel); + customPersonalityOpen = false; + } else if (slcOpen) { + longitudinalLayout->setCurrentWidget(speedLimitControllerPanel); - slcOpen = false; - } - }); - QObject::connect(parent, &FrogPilotSettingsWindow::updateMetric, this, &FrogPilotLongitudinalPanel::updateMetric); + slcOpen = false; + } + }); + QObject::connect(parent, &FrogPilotSettingsWindow::updateMetric, this, + &FrogPilotLongitudinalPanel::updateMetric); } void FrogPilotLongitudinalPanel::showEvent(QShowEvent *event) { @@ -675,15 +1358,27 @@ void FrogPilotLongitudinalPanel::showEvent(QShowEvent *event) { vEgoStarting = parent->vEgoStarting; vEgoStopping = parent->vEgoStopping; - calibratedLateralAccelerationLabel->setText(QString::number(params.getFloat("CalibratedLateralAcceleration"), 'f', 2) + tr(" m/s²")); - calibrationProgressLabel->setText(QString::number(params.getFloat("CalibrationProgress"), 'f', 2) + "%"); + calibratedLateralAccelerationLabel->setText( + QString::number(params.getFloat("CalibratedLateralAcceleration"), 'f', + 2) + + tr(" m/s²")); + calibrationProgressLabel->setText( + QString::number(params.getFloat("CalibrationProgress"), 'f', 2) + "%"); - longitudinalActuatorDelayToggle->setTitle(QString(tr("Actuator Delay (Default: %1)")).arg(QString::number(longitudinalActuatorDelay, 'f', 2))); - startAccelToggle->setTitle(QString(tr("Start Acceleration (Default: %1)")).arg(QString::number(startAccel, 'f', 2))); - stopAccelToggle->setTitle(QString(tr("Stop Acceleration (Default: %1)")).arg(QString::number(stopAccel, 'f', 2))); - stoppingDecelRateToggle->setTitle(QString(tr("Stopping Rate (Default: %1)")).arg(QString::number(stoppingDecelRate, 'f', 2))); - vEgoStartingToggle->setTitle(QString(tr("Start Speed (Default: %1)")).arg(QString::number(vEgoStarting, 'f', 2))); - vEgoStoppingToggle->setTitle(QString(tr("Stop Speed (Default: %1)")).arg(QString::number(vEgoStopping, 'f', 2))); + longitudinalActuatorDelayToggle->setTitle( + QString(tr("Actuator Delay (Default: %1)")) + .arg(QString::number(longitudinalActuatorDelay, 'f', 2))); + startAccelToggle->setTitle(QString(tr("Start Acceleration (Default: %1)")) + .arg(QString::number(startAccel, 'f', 2))); + stopAccelToggle->setTitle(QString(tr("Stop Acceleration (Default: %1)")) + .arg(QString::number(stopAccel, 'f', 2))); + stoppingDecelRateToggle->setTitle( + QString(tr("Stopping Rate (Default: %1)")) + .arg(QString::number(stoppingDecelRate, 'f', 2))); + vEgoStartingToggle->setTitle(QString(tr("Start Speed (Default: %1)")) + .arg(QString::number(vEgoStarting, 'f', 2))); + vEgoStoppingToggle->setTitle(QString(tr("Stop Speed (Default: %1)")) + .arg(QString::number(vEgoStopping, 'f', 2))); updateToggles(); } @@ -694,21 +1389,37 @@ void FrogPilotLongitudinalPanel::updateMetric(bool metric, bool bootRun) { double distanceConversion = metric ? FOOT_TO_METER : METER_TO_FOOT; double speedConversion = metric ? MILE_TO_KM : KM_TO_MILE; - params.putIntNonBlocking("IncreasedStoppedDistance", params.getInt("IncreasedStoppedDistance") * distanceConversion); + params.putIntNonBlocking("IncreasedStoppedDistance", + params.getInt("IncreasedStoppedDistance") * + distanceConversion); - params.putIntNonBlocking("CESignalSpeed", params.getInt("CESignalSpeed") * speedConversion); - params.putIntNonBlocking("CESpeed", params.getInt("CESpeed") * speedConversion); - params.putIntNonBlocking("CESpeedLead", params.getInt("CESpeedLead") * speedConversion); - params.putIntNonBlocking("CustomCruise", params.getInt("CustomCruise") * speedConversion); - params.putIntNonBlocking("CustomCruiseLong", params.getInt("CustomCruiseLong") * speedConversion); - params.putIntNonBlocking("Offset1", params.getInt("Offset1") * speedConversion); - params.putIntNonBlocking("Offset2", params.getInt("Offset2") * speedConversion); - params.putIntNonBlocking("Offset3", params.getInt("Offset3") * speedConversion); - params.putIntNonBlocking("Offset4", params.getInt("Offset4") * speedConversion); - params.putIntNonBlocking("Offset5", params.getInt("Offset5") * speedConversion); - params.putIntNonBlocking("Offset6", params.getInt("Offset6") * speedConversion); - params.putIntNonBlocking("Offset7", params.getInt("Offset7") * speedConversion); - params.putIntNonBlocking("SetSpeedOffset", params.getInt("SetSpeedOffset") * speedConversion); + params.putIntNonBlocking("CESignalSpeed", + params.getInt("CESignalSpeed") * speedConversion); + params.putIntNonBlocking("CESpeed", + params.getInt("CESpeed") * speedConversion); + params.putIntNonBlocking("CESpeedLead", + params.getInt("CESpeedLead") * speedConversion); + params.putIntNonBlocking("CustomCruise", + params.getInt("CustomCruise") * speedConversion); + params.putIntNonBlocking("CustomCruiseLong", + params.getInt("CustomCruiseLong") * + speedConversion); + params.putIntNonBlocking("Offset1", + params.getInt("Offset1") * speedConversion); + params.putIntNonBlocking("Offset2", + params.getInt("Offset2") * speedConversion); + params.putIntNonBlocking("Offset3", + params.getInt("Offset3") * speedConversion); + params.putIntNonBlocking("Offset4", + params.getInt("Offset4") * speedConversion); + params.putIntNonBlocking("Offset5", + params.getInt("Offset5") * speedConversion); + params.putIntNonBlocking("Offset6", + params.getInt("Offset6") * speedConversion); + params.putIntNonBlocking("Offset7", + params.getInt("Offset7") * speedConversion); + params.putIntNonBlocking("SetSpeedOffset", + params.getInt("SetSpeedOffset") * speedConversion); } previousMetric = metric; @@ -720,37 +1431,57 @@ void FrogPilotLongitudinalPanel::updateMetric(bool metric, bool bootRun) { static bool labelsInitialized = false; if (!labelsInitialized) { for (int i = 0; i <= 10; ++i) { - imperialDistanceLabels[i] = i == 0 ? tr("Off") : i == 1 ? QString::number(i) + tr(" foot") : QString::number(i) + tr(" feet"); + imperialDistanceLabels[i] = i == 0 ? tr("Off") + : i == 1 ? QString::number(i) + tr(" foot") + : QString::number(i) + tr(" feet"); } for (int i = 0; i <= 99; ++i) { - imperialSpeedLabels[i] = i == 0 ? tr("Off") : QString::number(i) + tr(" mph"); + imperialSpeedLabels[i] = + i == 0 ? tr("Off") : QString::number(i) + tr(" mph"); } for (int i = 0; i <= 3; ++i) { - metricDistanceLabels[i] = i == 0 ? tr("Off") : i == 1 ? QString::number(i) + tr(" meter") : QString::number(i) + tr(" meters"); + metricDistanceLabels[i] = i == 0 ? tr("Off") + : i == 1 ? QString::number(i) + tr(" meter") + : QString::number(i) + tr(" meters"); } for (int i = 0; i <= 150; ++i) { - metricSpeedLabels[i] = i == 0 ? tr("Off") : QString::number(i) + tr(" km/h"); + metricSpeedLabels[i] = + i == 0 ? tr("Off") : QString::number(i) + tr(" km/h"); } labelsInitialized = true; } - FrogPilotDualParamValueControl *ceSpeedToggle = reinterpret_cast(toggles["CESpeed"]); - FrogPilotParamValueButtonControl *ceSignal = static_cast(toggles["CESignalSpeed"]); - FrogPilotParamValueControl *customCruiseToggle = static_cast(toggles["CustomCruise"]); - FrogPilotParamValueControl *customCruiseLongToggle = static_cast(toggles["CustomCruiseLong"]); - FrogPilotParamValueControl *offset1Toggle = static_cast(toggles["Offset1"]); - FrogPilotParamValueControl *offset2Toggle = static_cast(toggles["Offset2"]); - FrogPilotParamValueControl *offset3Toggle = static_cast(toggles["Offset3"]); - FrogPilotParamValueControl *offset4Toggle = static_cast(toggles["Offset4"]); - FrogPilotParamValueControl *offset5Toggle = static_cast(toggles["Offset5"]); - FrogPilotParamValueControl *offset6Toggle = static_cast(toggles["Offset6"]); - FrogPilotParamValueControl *offset7Toggle = static_cast(toggles["Offset7"]); - FrogPilotParamValueControl *increasedStoppedDistanceToggle = static_cast(toggles["IncreasedStoppedDistance"]); - FrogPilotParamValueControl *setSpeedOffsetToggle = static_cast(toggles["SetSpeedOffset"]); + FrogPilotDualParamValueControl *ceSpeedToggle = + reinterpret_cast(toggles["CESpeed"]); + FrogPilotParamValueButtonControl *ceSignal = + static_cast(toggles["CESignalSpeed"]); + FrogPilotParamValueControl *customCruiseToggle = + static_cast(toggles["CustomCruise"]); + FrogPilotParamValueControl *customCruiseLongToggle = + static_cast(toggles["CustomCruiseLong"]); + FrogPilotParamValueControl *offset1Toggle = + static_cast(toggles["Offset1"]); + FrogPilotParamValueControl *offset2Toggle = + static_cast(toggles["Offset2"]); + FrogPilotParamValueControl *offset3Toggle = + static_cast(toggles["Offset3"]); + FrogPilotParamValueControl *offset4Toggle = + static_cast(toggles["Offset4"]); + FrogPilotParamValueControl *offset5Toggle = + static_cast(toggles["Offset5"]); + FrogPilotParamValueControl *offset6Toggle = + static_cast(toggles["Offset6"]); + FrogPilotParamValueControl *offset7Toggle = + static_cast(toggles["Offset7"]); + FrogPilotParamValueControl *increasedStoppedDistanceToggle = + static_cast( + toggles["IncreasedStoppedDistance"]); + FrogPilotParamValueControl *setSpeedOffsetToggle = + static_cast(toggles["SetSpeedOffset"]); if (metric) { offset1Toggle->setTitle(tr("Speed Offset (0–29 km/h)")); @@ -761,13 +1492,26 @@ void FrogPilotLongitudinalPanel::updateMetric(bool metric, bool bootRun) { offset6Toggle->setTitle(tr("Speed Offset (100–119 km/h)")); offset7Toggle->setTitle(tr("Speed Offset (120–140 km/h)")); - offset1Toggle->setDescription(tr("How much to offset posted speed-limits between 0 and 24 mph.")); - offset2Toggle->setDescription(tr("How much to offset posted speed-limits between 25 and 34 mph.")); - offset3Toggle->setDescription(tr("How much to offset posted speed-limits between 35 and 44 mph.")); - offset4Toggle->setDescription(tr("How much to offset posted speed-limits between 45 and 54 mph.")); - offset5Toggle->setDescription(tr("How much to offset posted speed-limits between 55 and 64 mph.")); - offset6Toggle->setDescription(tr("How much to offset posted speed-limits between 65 and 74 mph.")); - offset7Toggle->setDescription(tr("How much to offset posted speed-limits between 75 and 99 mph.")); + offset1Toggle->setDescription(tr( + "How much to offset posted speed-limits between 0 and 24 mph.")); + offset2Toggle->setDescription( + tr("How much to offset posted speed-limits between 25 and 34 " + "mph.")); + offset3Toggle->setDescription( + tr("How much to offset posted speed-limits between 35 and 44 " + "mph.")); + offset4Toggle->setDescription( + tr("How much to offset posted speed-limits between 45 and 54 " + "mph.")); + offset5Toggle->setDescription( + tr("How much to offset posted speed-limits between 55 and 64 " + "mph.")); + offset6Toggle->setDescription( + tr("How much to offset posted speed-limits between 65 and 74 " + "mph.")); + offset7Toggle->setDescription( + tr("How much to offset posted speed-limits between 75 and 99 " + "mph.")); increasedStoppedDistanceToggle->updateControl(0, 3, metricDistanceLabels); @@ -792,15 +1536,29 @@ void FrogPilotLongitudinalPanel::updateMetric(bool metric, bool bootRun) { offset6Toggle->setTitle(tr("Speed Offset (65–74 mph)")); offset7Toggle->setTitle(tr("Speed Offset (75–99 mph)")); - offset1Toggle->setDescription(tr("How much to offset posted speed-limits between 0 and 24 mph.")); - offset2Toggle->setDescription(tr("How much to offset posted speed-limits between 25 and 34 mph.")); - offset3Toggle->setDescription(tr("How much to offset posted speed-limits between 35 and 44 mph.")); - offset4Toggle->setDescription(tr("How much to offset posted speed-limits between 45 and 54 mph.")); - offset5Toggle->setDescription(tr("How much to offset posted speed-limits between 55 and 64 mph.")); - offset6Toggle->setDescription(tr("How much to offset posted speed-limits between 65 and 74 mph.")); - offset7Toggle->setDescription(tr("How much to offset posted speed-limits between 75 and 99 mph.")); + offset1Toggle->setDescription(tr( + "How much to offset posted speed-limits between 0 and 24 mph.")); + offset2Toggle->setDescription( + tr("How much to offset posted speed-limits between 25 and 34 " + "mph.")); + offset3Toggle->setDescription( + tr("How much to offset posted speed-limits between 35 and 44 " + "mph.")); + offset4Toggle->setDescription( + tr("How much to offset posted speed-limits between 45 and 54 " + "mph.")); + offset5Toggle->setDescription( + tr("How much to offset posted speed-limits between 55 and 64 " + "mph.")); + offset6Toggle->setDescription( + tr("How much to offset posted speed-limits between 65 and 74 " + "mph.")); + offset7Toggle->setDescription( + tr("How much to offset posted speed-limits between 75 and 99 " + "mph.")); - increasedStoppedDistanceToggle->updateControl(0, 10, imperialDistanceLabels); + increasedStoppedDistanceToggle->updateControl(0, 10, + imperialDistanceLabels); ceSignal->updateControl(0, 99, imperialSpeedLabels); ceSpeedToggle->updateControl(0, 99, imperialSpeedLabels); @@ -831,7 +1589,8 @@ void FrogPilotLongitudinalPanel::updateToggles() { bool setVisible = tuningLevel >= frogpilotToggleLevels[key].toDouble(); - if (key == "CustomCruise" || key == "CustomCruiseLong" || key == "SetSpeedLimit" || key == "SetSpeedOffset") { + if (key == "CustomCruise" || key == "CustomCruiseLong" || + key == "SetSpeedLimit" || key == "SetSpeedOffset") { setVisible &= !hasPCMCruise; } @@ -853,10 +1612,12 @@ void FrogPilotLongitudinalPanel::updateToggles() { } else if (key == "StartAccel") { - setVisible &= !(params.getBool("LongitudinalTune") && params.getBool("HumanAcceleration")); + setVisible &= !(params.getBool("LongitudinalTune") && + params.getBool("HumanAcceleration")); } - else if (key == "StoppingDecelRate" || key == "VEgoStarting" || key == "VEgoStopping") { + else if (key == "StoppingDecelRate" || key == "VEgoStarting" || + key == "VEgoStopping") { setVisible &= !isGM || !params.getBool("ExperimentalGMTune"); setVisible &= !isToyota || !params.getBool("FrogsGoMoosTweak"); } diff --git a/frogpilot/ui/qt/offroad/longitudinal_settings.h b/frogpilot/ui/qt/offroad/longitudinal_settings.h index 48467f0b0..e7226c5a1 100644 --- a/frogpilot/ui/qt/offroad/longitudinal_settings.h +++ b/frogpilot/ui/qt/offroad/longitudinal_settings.h @@ -41,18 +41,18 @@ private: std::map toggles; QSet advancedLongitudinalTuneKeys = {"LongitudinalActuatorDelay", "StartAccel", "StopAccel", "StoppingDecelRate", "VEgoStarting", "VEgoStopping"}; - QSet aggressivePersonalityKeys = {"AggressiveFollow", "AggressiveJerkAcceleration", "AggressiveJerkDeceleration", "AggressiveJerkDanger", "AggressiveJerkSpeed", "AggressiveJerkSpeedDecrease", "ResetAggressivePersonality"}; + QSet aggressivePersonalityKeys = {"AggressiveFollow", "AggressiveFollowHigh", "AggressiveJerkAcceleration", "AggressiveJerkDeceleration", "AggressiveJerkDanger", "AggressiveJerkSpeed", "AggressiveJerkSpeedDecrease", "ResetAggressivePersonality"}; QSet conditionalExperimentalKeys = {"CESpeed", "CESpeedLead", "CECurves", "CELead", "CEModelStopTime", "CENavigation", "CESignalSpeed", "ShowCEMStatus"}; QSet curveSpeedKeys = {"CalibratedLateralAcceleration", "CalibrationProgress", "ResetCurveData", "ShowCSCStatus"}; QSet customDrivingPersonalityKeys = {"AggressivePersonalityProfile", "RelaxedPersonalityProfile", "StandardPersonalityProfile", "TrafficPersonalityProfile"}; QSet longitudinalTuneKeys = {"AccelerationProfile", "DecelerationProfile", "HumanAcceleration", "HumanFollowing", "LeadDetectionThreshold", "MaxDesiredAcceleration", "TacoTune"}; QSet qolKeys = {"CustomCruise", "CustomCruiseLong", "ForceStops", "IncreasedStoppedDistance", "MapGears", "ReverseCruise", "SetSpeedOffset"}; - QSet relaxedPersonalityKeys = {"RelaxedFollow", "RelaxedJerkAcceleration", "RelaxedJerkDeceleration", "RelaxedJerkDanger", "RelaxedJerkSpeed", "RelaxedJerkSpeedDecrease", "ResetRelaxedPersonality"}; + QSet relaxedPersonalityKeys = {"RelaxedFollow", "RelaxedFollowHigh", "RelaxedJerkAcceleration", "RelaxedJerkDeceleration", "RelaxedJerkDanger", "RelaxedJerkSpeed", "RelaxedJerkSpeedDecrease", "ResetRelaxedPersonality"}; QSet speedLimitControllerKeys = {"SLCOffsets", "SLCFallback", "SLCOverride", "SLCPriority", "SLCQOL", "SLCVisuals"}; QSet speedLimitControllerOffsetsKeys = {"Offset1", "Offset2", "Offset3", "Offset4", "Offset5", "Offset6", "Offset7"}; QSet speedLimitControllerQOLKeys = {"ForceMPHDashboard", "SetSpeedLimit", "SLCConfirmation", "SLCLookaheadHigher", "SLCLookaheadLower", "SLCMapboxFiller"}; QSet speedLimitControllerVisualKeys = {"ShowSLCOffset", "SpeedLimitSources"}; - QSet standardPersonalityKeys = {"StandardFollow", "StandardJerkAcceleration", "StandardJerkDeceleration", "StandardJerkDanger", "StandardJerkSpeed", "StandardJerkSpeedDecrease", "ResetStandardPersonality"}; + QSet standardPersonalityKeys = {"StandardFollow", "StandardFollowHigh", "StandardJerkAcceleration", "StandardJerkDeceleration", "StandardJerkDanger", "StandardJerkSpeed", "StandardJerkSpeedDecrease", "ResetStandardPersonality"}; QSet trafficPersonalityKeys = {"TrafficFollow", "TrafficJerkAcceleration", "TrafficJerkDeceleration", "TrafficJerkDanger", "TrafficJerkSpeed", "TrafficJerkSpeedDecrease", "ResetTrafficPersonality"}; QSet parentKeys; diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index f32ca9ec1..734d4742c 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -37,7 +37,7 @@ EventName = car.CarEvent.EventName MAX_CTRL_SPEED = (V_CRUISE_MAX + 4) * CV.KPH_TO_MS ACCEL_MAX = 2.0 ACCEL_MIN = -3.5 -FRICTION_THRESHOLD = 0.3 +FRICTION_THRESHOLD = 0.2 TORQUE_PARAMS_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/params.toml') TORQUE_OVERRIDE_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/override.toml') diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index e9842c2a2..cf4c9fe6b 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -3,9 +3,9 @@ import numpy as np from collections import deque from cereal import log -from openpilot.common.filter_simple import FirstOrderFilter from openpilot.selfdrive.car.interfaces import FRICTION_THRESHOLD from openpilot.selfdrive.controls.lib.drive_helpers import MIN_SPEED, get_friction +from openpilot.common.filter_simple import FirstOrderFilter from openpilot.selfdrive.controls.lib.latcontrol import LatControl from openpilot.selfdrive.controls.lib.pid import PIDController from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY @@ -16,15 +16,22 @@ from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_G # wheel slip, or to speed. # This controller applies torque to achieve desired lateral -# accelerations. To compensate for the low speed effects we -# use a LOW_SPEED_FACTOR in the error. Additionally, there is -# friction in the steering wheel that needs to be overcome to -# move it at all, this is compensated for too. +# accelerations. To compensate for the low speed effects the +# proportional gain is increased at low speeds by the PID controller. +# Additionally, there is friction in the steering wheel that needs +# to be overcome to move it at all, this is compensated for too. -LOW_SPEED_X = [0, 10, 20, 30] -LOW_SPEED_Y = [15, 13, 10, 5] +KP = 0.6 +KI = 0.15 -MAX_LAT_JERK_UP = 2.5 # m/s^3 +INTERP_SPEEDS = [1, 1.5, 2.0, 3.0, 5, 7.5, 10, 15, 30] +KP_INTERP = [250, 120, 65, 30, 11.5, 5.5, 3.5, 2.0, KP] + +LP_FILTER_CUTOFF_HZ = 1.2 +JERK_LOOKAHEAD_SECONDS = 0.19 +JERK_GAIN = 0.3 +LAT_ACCEL_REQUEST_BUFFER_SECONDS = 1.0 +VERSION = 1 class LatControlTorque(LatControl): def __init__(self, CP, CI, dt): @@ -32,13 +39,13 @@ class LatControlTorque(LatControl): self.torque_params = CP.lateralTuning.torque self.torque_from_lateral_accel = CI.torque_from_lateral_accel() self.lateral_accel_from_torque = CI.lateral_accel_from_torque() - self.pid = PIDController(self.torque_params.kp, self.torque_params.ki, rate=1/self.dt) + self.pid = PIDController([INTERP_SPEEDS, KP_INTERP], KI, rate=1/self.dt) self.update_limits() self.steering_angle_deadzone_deg = self.torque_params.steeringAngleDeadzoneDeg - self.LATACCEL_REQUEST_BUFFER_NUM_FRAMES = int(1 / self.dt) - self.requested_lateral_accel_buffer = deque([0.] * self.LATACCEL_REQUEST_BUFFER_NUM_FRAMES , maxlen=self.LATACCEL_REQUEST_BUFFER_NUM_FRAMES) - self.previous_measurement = 0.0 - self.measurement_rate_filter = FirstOrderFilter(0.0, 1 / (2 * np.pi * (MAX_LAT_JERK_UP - 0.5)), self.dt) + self.lat_accel_request_buffer_len = int(LAT_ACCEL_REQUEST_BUFFER_SECONDS / self.dt) + self.lat_accel_request_buffer = deque([0.] * self.lat_accel_request_buffer_len , maxlen=self.lat_accel_request_buffer_len) + self.lookahead_frames = int(JERK_LOOKAHEAD_SECONDS / self.dt) + self.jerk_filter = FirstOrderFilter(0.0, 1 / (2 * np.pi * LP_FILTER_CUTOFF_HZ), self.dt) def update_live_torque_params(self, latAccelFactor, latAccelOffset, friction): self.torque_params.latAccelFactor = latAccelFactor @@ -52,6 +59,7 @@ class LatControlTorque(LatControl): def update(self, active, CS, VM, params, steer_limited_by_safety, desired_curvature, curvature_limited, lat_delay, llk, model_data, frogpilot_toggles): pid_log = log.ControlsState.LateralTorqueState.new_message() + pid_log.version = VERSION if not active: output_torque = 0.0 pid_log.active = False @@ -61,37 +69,28 @@ class LatControlTorque(LatControl): curvature_deadzone = abs(VM.calc_curvature(math.radians(self.steering_angle_deadzone_deg), CS.vEgo, 0.0)) lateral_accel_deadzone = curvature_deadzone * CS.vEgo ** 2 - delay_frames = int(np.clip(lat_delay / self.dt, 1, self.LATACCEL_REQUEST_BUFFER_NUM_FRAMES)) - expected_lateral_accel = self.requested_lateral_accel_buffer[-delay_frames] - # TODO factor out lateral jerk from error to later replace it with delay independent alternative + delay_frames = int(np.clip(lat_delay / self.dt, 1, self.lat_accel_request_buffer_len)) + expected_lateral_accel = self.lat_accel_request_buffer[-delay_frames] + lookahead_idx = int(np.clip(-delay_frames + self.lookahead_frames, -self.lat_accel_request_buffer_len+1, -2)) + raw_lateral_jerk = (self.lat_accel_request_buffer[lookahead_idx+1] - self.lat_accel_request_buffer[lookahead_idx-1]) / (2 * self.dt) + desired_lateral_jerk = self.jerk_filter.update(raw_lateral_jerk) future_desired_lateral_accel = desired_curvature * CS.vEgo ** 2 - self.requested_lateral_accel_buffer.append(future_desired_lateral_accel) + self.lat_accel_request_buffer.append(future_desired_lateral_accel) gravity_adjusted_future_lateral_accel = future_desired_lateral_accel - roll_compensation - desired_lateral_jerk = (future_desired_lateral_accel - expected_lateral_accel) / lat_delay + setpoint = expected_lateral_accel measurement = measured_curvature * CS.vEgo ** 2 - measurement_rate = self.measurement_rate_filter.update((measurement - self.previous_measurement) / self.dt) - self.previous_measurement = measurement - - low_speed_factor = (np.interp(CS.vEgo, LOW_SPEED_X, LOW_SPEED_Y) / max(CS.vEgo, MIN_SPEED)) ** 2 - setpoint = lat_delay * desired_lateral_jerk + expected_lateral_accel error = setpoint - measurement - error_lsf = error + low_speed_factor / self.torque_params.kp * error # do error correction in lateral acceleration space, convert at end to handle non-linear torque responses correctly - pid_log.error = float(error_lsf) + pid_log.error = float(error) ff = gravity_adjusted_future_lateral_accel # latAccelOffset corrects roll compensation bias from device roll misalignment relative to car roll ff -= self.torque_params.latAccelOffset - # TODO jerk is weighted by lat_delay for legacy reasons, but should be made independent of it - ff += get_friction(error, lateral_accel_deadzone, FRICTION_THRESHOLD, self.torque_params) + ff += get_friction(error + JERK_GAIN * desired_lateral_jerk, lateral_accel_deadzone, FRICTION_THRESHOLD, self.torque_params) freeze_integrator = steer_limited_by_safety or CS.steeringPressed or CS.vEgo < 5 - output_lataccel = self.pid.update(pid_log.error, - -measurement_rate, - feedforward=ff, - speed=CS.vEgo, - freeze_integrator=freeze_integrator) + output_lataccel = self.pid.update(pid_log.error, speed=CS.vEgo, feedforward=ff, freeze_integrator=freeze_integrator) output_torque = self.torque_from_lateral_accel(output_lataccel, self.torque_params) pid_log.active = True @@ -99,9 +98,10 @@ class LatControlTorque(LatControl): pid_log.i = float(self.pid.i) pid_log.d = float(self.pid.d) pid_log.f = float(self.pid.f) - pid_log.output = float(-output_torque) # TODO: log lat accel? + pid_log.output = float(-output_torque) # TODO: log lat accel? pid_log.actualLateralAccel = float(measurement) pid_log.desiredLateralAccel = float(setpoint) + pid_log.desiredLateralJerk = float(desired_lateral_jerk) pid_log.saturated = bool(self._check_saturation(self.steer_max - abs(output_torque) < 1e-3, CS, steer_limited_by_safety, curvature_limited)) # TODO left is positive in this convention diff --git a/selfdrive/controls/lib/longcontrol.py b/selfdrive/controls/lib/longcontrol.py index afb0a018f..68ce9d35d 100644 --- a/selfdrive/controls/lib/longcontrol.py +++ b/selfdrive/controls/lib/longcontrol.py @@ -179,6 +179,26 @@ class LongControl: else: output_accel = raw_output_accel + if self.long_control_state == LongCtrlState.pid: + # Smooth acceleration and deceleration with urgency-based rate limiting + base_rate = 1.0 + + if output_accel < self.last_output_accel: # Deceleration requested + decel_needed = self.last_output_accel - output_accel + # Use a safe default for ACCEL_MIN if not available, to prevent division by zero + max_decel = abs(CarControllerParams.ACCEL_MIN) if CarControllerParams.ACCEL_MIN != 0 else 4.0 + urgency = min(1.0, decel_needed / max_decel) + + # Adjust rate based on urgency (1.0 m/s^3 for low urgency, up to 4.0 m/s^3 for high urgency) + max_rate = 1.0 + 3.0 * urgency + else: + max_rate = base_rate # Acceleration is always smooth + + max_accel_change = max_rate * DT_CTRL + output_accel = clip(output_accel, + self.last_output_accel - max_accel_change, + self.last_output_accel + max_accel_change) + self.last_output_accel = clip(output_accel, accel_limits[0], accel_limits[1]) return self.last_output_accel diff --git a/selfdrive/ui/_spinner b/selfdrive/ui/_spinner index 4be91f40f..5f158809b 100755 Binary files a/selfdrive/ui/_spinner and b/selfdrive/ui/_spinner differ diff --git a/selfdrive/ui/_text b/selfdrive/ui/_text index 14551782f..69fb2b417 100755 Binary files a/selfdrive/ui/_text and b/selfdrive/ui/_text differ diff --git a/selfdrive/ui/translations/main_ar.ts b/selfdrive/ui/translations/main_ar.ts index 210be7283..545e0dd36 100644 --- a/selfdrive/ui/translations/main_ar.ts +++ b/selfdrive/ui/translations/main_ar.ts @@ -2110,6 +2110,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>سلوك متابعة يحاكي السائقين البشر</b> عبر تقليل الفجوات خلف المركبات الأسرع لانطلاق أسرع وضبط مسافة المتابعة المطلوبة ديناميكياً لكبح ألطف وأكثر كفاءة. + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_caveman.ts b/selfdrive/ui/translations/main_caveman.ts index a1d259c8f..e5db64d05 100644 --- a/selfdrive/ui/translations/main_caveman.ts +++ b/selfdrive/ui/translations/main_caveman.ts @@ -2112,6 +2112,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>Make car follow like human</b>. Close gap behind fast car for quick takeoff. Change follow distance on the fly for soft, smart brake. + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_de.ts b/selfdrive/ui/translations/main_de.ts index 424912fd5..82c1d271e 100644 --- a/selfdrive/ui/translations/main_de.ts +++ b/selfdrive/ui/translations/main_de.ts @@ -2110,6 +2110,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>Dem Fahrverhalten menschlicher Fahrer nachempfunden</b>, indem Lücken hinter schnelleren Fahrzeugen geschlossen werden, um schneller anzufahren, und der gewünschte Folgeabstand dynamisch angepasst wird, um sanfteres und effizienteres Bremsen zu ermöglichen. + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_duck.ts b/selfdrive/ui/translations/main_duck.ts index 2b497da89..2541fc5ba 100644 --- a/selfdrive/ui/translations/main_duck.ts +++ b/selfdrive/ui/translations/main_duck.ts @@ -2112,6 +2112,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>Quack! Mimic human drivers</b> by waddling up to close gaps behind faster cars for zippy takeoffs, and duckily tweak the following distance for smoother, more efficient braking. + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_es.ts b/selfdrive/ui/translations/main_es.ts index 7fdbd03d1..c33987528 100644 --- a/selfdrive/ui/translations/main_es.ts +++ b/selfdrive/ui/translations/main_es.ts @@ -2110,6 +2110,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>Comportamiento de seguimiento que imita a los conductores humanos</b> cerrando huecos detrás de vehículos más rápidos para salidas más rápidas y ajustando dinámicamente la distancia de seguimiento deseada para un frenado más suave y eficiente. + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_fr.ts b/selfdrive/ui/translations/main_fr.ts index d6aef5dc5..2eb84607c 100644 --- a/selfdrive/ui/translations/main_fr.ts +++ b/selfdrive/ui/translations/main_fr.ts @@ -2110,6 +2110,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>Un comportement de suivi qui imite les conducteurs humains</b> en réduisant les écarts derrière les véhicules plus rapides pour des départs plus rapides et en ajustant dynamiquement la distance de suivi souhaitée pour un freinage plus doux et plus efficace. + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_frog.ts b/selfdrive/ui/translations/main_frog.ts index 140ee57b1..e80cbf68b 100644 --- a/selfdrive/ui/translations/main_frog.ts +++ b/selfdrive/ui/translations/main_frog.ts @@ -2110,6 +2110,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>Croaky follow like humans</b>, ribbit! Hop to close gaps behind faster cars for quick takeoffs, and croak-adjust the follow distance for gentler, thriftier braking. + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_ja.ts b/selfdrive/ui/translations/main_ja.ts index 267784f17..41b3799b1 100644 --- a/selfdrive/ui/translations/main_ja.ts +++ b/selfdrive/ui/translations/main_ja.ts @@ -2110,6 +2110,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>人間のドライバーを模倣する追従挙動</b>。より速い車両の後方で車間を詰めて発進を素早くし、望ましい追従距離を動的に調整して、より穏やかで効率的な減速を実現します。 + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_ko.ts b/selfdrive/ui/translations/main_ko.ts index 06a415852..b351f5cd1 100644 --- a/selfdrive/ui/translations/main_ko.ts +++ b/selfdrive/ui/translations/main_ko.ts @@ -2110,6 +2110,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>사람 운전자와 유사한 추종 동작</b>으로, 더 빠른 차량 뒤 간격을 좁혀 신속한 출발을 돕고 원하는 추종 거리를 동적으로 조절해 더욱 부드럽고 효율적인 제동을 수행합니다. + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_pirate.ts b/selfdrive/ui/translations/main_pirate.ts index 9450ef377..59087853f 100644 --- a/selfdrive/ui/translations/main_pirate.ts +++ b/selfdrive/ui/translations/main_pirate.ts @@ -2110,6 +2110,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>Behavin’ like real hands at the wheel</b> by closin’ gaps astern o’ swifter wagons fer quicker shove-offs, an’ smartly trimmin’ the wanted followin’ distance fer gentler, more shipshape brak’n. + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_pt-BR.ts b/selfdrive/ui/translations/main_pt-BR.ts index 26247effa..fb9653673 100644 --- a/selfdrive/ui/translations/main_pt-BR.ts +++ b/selfdrive/ui/translations/main_pt-BR.ts @@ -2110,6 +2110,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>Comportamento de acompanhamento que imita motoristas humanos</b> ao fechar lacunas atrás de veículos mais rápidos para arrancadas mais rápidas e ajustar dinamicamente a distância de seguimento desejada para frenagens mais suaves e eficientes. + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_shakespearean.ts b/selfdrive/ui/translations/main_shakespearean.ts index 332880b25..813f9e945 100644 --- a/selfdrive/ui/translations/main_shakespearean.ts +++ b/selfdrive/ui/translations/main_shakespearean.ts @@ -2116,6 +2116,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>Following comportment that doth mirror mortal coachmen</b> by narrowing gaps behind swifter chariots for hastier set-offs and by dynamically tuning the desired following distance for gentler, more thrifty braking. + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_th.ts b/selfdrive/ui/translations/main_th.ts index 962dee3a2..e1ed279e1 100644 --- a/selfdrive/ui/translations/main_th.ts +++ b/selfdrive/ui/translations/main_th.ts @@ -2110,6 +2110,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>พฤติกรรมการตามที่เลียนแบบผู้ขับขี่มนุษย์</b> โดยปิดช่องว่างด้านหลังรถที่เร็วกว่าเพื่อออกตัวได้เร็วขึ้น และปรับระยะห่างที่ต้องการแบบไดนามิกเพื่อการเบรกที่นุ่มนวลและมีประสิทธิภาพมากขึ้น + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_tr.ts b/selfdrive/ui/translations/main_tr.ts index 95ad3ba0f..d03e560e6 100644 --- a/selfdrive/ui/translations/main_tr.ts +++ b/selfdrive/ui/translations/main_tr.ts @@ -2110,6 +2110,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>İnsan sürücüleri taklit eden takip davranışı</b>: Daha hızlı araçların arkasındaki boşlukları kapatarak daha hızlı kalkışlar ve daha yumuşak, daha verimli frenleme için istenen takip mesafesini dinamik olarak ayarlama. + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index eae71908a..6f0da5b05 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -2110,6 +2110,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>模仿人类驾驶员的跟车行为</b>,通过在更快车辆后方缩小车距以更快起步,并动态调整期望跟车距离,以实现更平顺、更高效的制动。 + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 4f51128be..2739954c7 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -2110,6 +2110,22 @@ <b>Following behavior that mimics human drivers</b> by closing gaps behind faster vehicles for quicker takeoffs and dynamically adjusting the desired following distance for gentler, more efficient braking. <b>模仿人類駕駛的跟車行為</b>,在後方有更快車輛時縮小間距以更快起步,並動態調整期望跟車距離,以實現更柔順且更高效的制動。 + + High Speed Following Distance + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Aggressive" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.25 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Standard" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.45 seconds. + + + + <b>How many seconds openpilot follows behind lead vehicles when using the "Relaxed" profile at high speeds.</b> Increase for more space; decrease for tighter gaps.<br><br>Default: 1.75 seconds. + + FrogPilotManageControl diff --git a/selfdrive/ui/ui b/selfdrive/ui/ui index 2e23f9baa..a7981ee04 100755 Binary files a/selfdrive/ui/ui and b/selfdrive/ui/ui differ