From b5a46ee191849b00c8441e5b03d5a559867c7621 Mon Sep 17 00:00:00 2001 From: firestar5683 <168790843+firestar5683@users.noreply.github.com> Date: Fri, 12 Dec 2025 01:01:16 -0600 Subject: [PATCH] Trailer Load --- common/params.cc | 1 + frogpilot/common/frogpilot_variables.py | 2 ++ frogpilot/ui/qt/offroad/longitudinal_settings.cc | 9 +++++++++ frogpilot/ui/qt/offroad/longitudinal_settings.h | 2 +- selfdrive/car/interfaces.py | 3 +++ 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/common/params.cc b/common/params.cc index 699e863f69..838fb45a8d 100644 --- a/common/params.cc +++ b/common/params.cc @@ -548,6 +548,7 @@ std::unordered_map keys = { {"StoppedTimer", PERSISTENT}, {"TacoTune", PERSISTENT}, {"TacoTuneHacks", PERSISTENT}, + {"TrailerLoad", PERSISTENT}, {"TestAlert", CLEAR_ON_MANAGER_START}, {"TetheringEnabled", PERSISTENT}, {"ThemeDownloadProgress", CLEAR_ON_MANAGER_START}, diff --git a/frogpilot/common/frogpilot_variables.py b/frogpilot/common/frogpilot_variables.py index 395b361671..9f700f263d 100644 --- a/frogpilot/common/frogpilot_variables.py +++ b/frogpilot/common/frogpilot_variables.py @@ -271,6 +271,7 @@ frogpilot_default_params: list[tuple[str, str | bytes, int, str]] = [ ("LongitudinalActuatorDelay", "", 3, ""), ("LongitudinalActuatorDelayStock", "", 3, ""), ("LongitudinalTune", "1", 0, "0"), + ("TrailerLoad", "0", 2, "0"), ("LongPitch", "1", 2, "0"), ("LoudBlindspotAlert", "0", 0, "0"), ("LowVoltageShutdown", str(VBATT_PAUSE_CHARGING), 2, str(VBATT_PAUSE_CHARGING)), @@ -835,6 +836,7 @@ class FrogPilotVariables: toggle.human_following = longitudinal_tuning and (params.get_bool("HumanFollowing") if tuning_level >= level["HumanFollowing"] else default.get_bool("HumanFollowing")) toggle.lead_detection_probability = np.clip(params.get_int("LeadDetectionThreshold") / 100, 0.25, 0.50) if longitudinal_tuning and tuning_level >= level["LeadDetectionThreshold"] else default.get_int("LeadDetectionThreshold") / 100 toggle.max_desired_acceleration = np.clip(params.get_float("MaxDesiredAcceleration"), 0.1, 4.0) if longitudinal_tuning and tuning_level >= level["MaxDesiredAcceleration"] else default.get_float("MaxDesiredAcceleration") + toggle.trailer_load_kg = (np.clip(params.get_int("TrailerLoad"), 0, 15000) if longitudinal_tuning and tuning_level >= level["TrailerLoad"] else default.get_int("TrailerLoad")) * CV.LB_TO_KG toggle.taco_tune = longitudinal_tuning and (params.get_bool("TacoTune") if tuning_level >= level["TacoTune"] else default.get_bool("TacoTune")) toggle.available_models = params.get("AvailableModels", encoding="utf-8") or "" diff --git a/frogpilot/ui/qt/offroad/longitudinal_settings.cc b/frogpilot/ui/qt/offroad/longitudinal_settings.cc index eca9c44646..90716e2fe2 100644 --- a/frogpilot/ui/qt/offroad/longitudinal_settings.cc +++ b/frogpilot/ui/qt/offroad/longitudinal_settings.cc @@ -428,6 +428,11 @@ FrogPilotLongitudinalPanel::FrogPilotLongitudinalPanel( {"MaxDesiredAcceleration", tr("Maximum Acceleration"), tr("Limit the strongest acceleration openpilot can command."), ""}, + {"TrailerLoad", tr("Trailer Load"), + tr("Increase the vehicle mass to account for towing. Adjust " + "in 500 lb steps up to 15,000 lbs to fine-tune gas and brake " + "behavior when pulling a trailer."), + ""}, {"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."), @@ -871,6 +876,10 @@ FrogPilotLongitudinalPanel::FrogPilotLongitudinalPanel( longitudinalToggle = new FrogPilotParamValueControl( param, title, desc, icon, 0.1, 4.0, tr(" m/s²"), std::map(), 0.1); + } else if (param == "TrailerLoad") { + longitudinalToggle = new FrogPilotParamValueControl( + param, title, desc, icon, 0, 15000, tr(" lbs"), + std::map(), 500); } else if (param == "QOLLongitudinal") { FrogPilotManageControl *qolLongitudinalToggle = diff --git a/frogpilot/ui/qt/offroad/longitudinal_settings.h b/frogpilot/ui/qt/offroad/longitudinal_settings.h index e7226c5a15..fb5ebf31a7 100644 --- a/frogpilot/ui/qt/offroad/longitudinal_settings.h +++ b/frogpilot/ui/qt/offroad/longitudinal_settings.h @@ -45,7 +45,7 @@ private: 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 longitudinalTuneKeys = {"AccelerationProfile", "DecelerationProfile", "HumanAcceleration", "HumanFollowing", "LeadDetectionThreshold", "MaxDesiredAcceleration", "TrailerLoad", "TacoTune"}; QSet qolKeys = {"CustomCruise", "CustomCruiseLong", "ForceStops", "IncreasedStoppedDistance", "MapGears", "ReverseCruise", "SetSpeedOffset"}; QSet relaxedPersonalityKeys = {"RelaxedFollow", "RelaxedFollowHigh", "RelaxedJerkAcceleration", "RelaxedJerkDeceleration", "RelaxedJerkDanger", "RelaxedJerkSpeed", "RelaxedJerkSpeedDecrease", "ResetRelaxedPersonality"}; QSet speedLimitControllerKeys = {"SLCOffsets", "SLCFallback", "SLCOverride", "SLCPriority", "SLCQOL", "SLCVisuals"}; diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index 00e2522e61..df4ae22033 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -152,8 +152,11 @@ class CarInterfaceBase(ABC): ret = cls._get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs, frogpilot_toggles) + trailer_load_kg = getattr(frogpilot_toggles, "trailer_load_kg", 0) + # Vehicle mass is published curb weight plus assumed payload such as a human driver; notCars have no assumed payload if not ret.notCar: + ret.mass = ret.mass + trailer_load_kg ret.mass = ret.mass + STD_CARGO_KG # Set params dependent on values set by the car interface