diff --git a/frogpilot/common/frogpilot_variables.py b/frogpilot/common/frogpilot_variables.py index 05e698b25a..f02179890a 100644 --- a/frogpilot/common/frogpilot_variables.py +++ b/frogpilot/common/frogpilot_variables.py @@ -740,7 +740,13 @@ class FrogPilotVariables: toggle.human_acceleration = self.get_value("HumanAcceleration", condition=longitudinal_tuning) toggle.human_following = self.get_value("HumanFollowing", condition=longitudinal_tuning) toggle.human_lane_changes = has_radar and self.get_value("HumanLaneChanges", condition=longitudinal_tuning) - toggle.lead_detection_probability = self.get_value("LeadDetectionThreshold", cast=float, condition=longitudinal_tuning, conversion=0.01, min=0.25, max=0.5) + # Keep lead detection sensitivity normalized even when longitudinal tuning is disabled. + # Some branches can return raw integer defaults (e.g. 35) when condition=False. + lead_detection_probability = self.get_value("LeadDetectionThreshold", cast=float, condition=toggle.openpilot_longitudinal, + conversion=0.01, default=0.35, min=0.25, max=0.5) + if isinstance(lead_detection_probability, (int, float)) and lead_detection_probability > 1.0: + lead_detection_probability = float(np.clip(lead_detection_probability * 0.01, 0.25, 0.5)) + toggle.lead_detection_probability = lead_detection_probability toggle.recovery_power = self.get_value("RecoveryPower", cast=float, condition=longitudinal_tuning, default=1.0, min=0.5, max=2.0) toggle.stop_distance = self.get_value("StopDistance", cast=float, condition=longitudinal_tuning, default=6.0) toggle.taco_tune = self.get_value("TacoTune", condition=longitudinal_tuning) diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index c29f2b8244..5caa0b3a6a 100644 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -215,8 +215,13 @@ def get_lead(v_ego: float, ready: bool, tracks: dict[int, Track], lead_msg: capn model_v_ego: float, model_data: capnp._DynamicStructReader, frogpilot_plan: capnp._DynamicStructReader, frogpilot_toggles: SimpleNamespace, low_speed_override: bool = True) -> dict[str, Any]: + lead_detection_probability = float(getattr(frogpilot_toggles, "lead_detection_probability", 0.35) or 0.35) + if lead_detection_probability > 1.0: + lead_detection_probability *= 0.01 + lead_detection_probability = float(np.clip(lead_detection_probability, 0.25, 0.5)) + # Determine leads, this is where the essential logic happens - if len(tracks) > 0 and ready and lead_msg.prob > frogpilot_toggles.lead_detection_probability: + if len(tracks) > 0 and ready and lead_msg.prob > lead_detection_probability: track = match_vision_to_track(v_ego, lead_msg, model_data, tracks, frogpilot_toggles) else: track = None @@ -224,7 +229,7 @@ def get_lead(v_ego: float, ready: bool, tracks: dict[int, Track], lead_msg: capn lead_dict = {'status': False} if track is not None: lead_dict = track.get_RadarState(lead_msg.prob) - elif (track is None) and ready and (lead_msg.prob > frogpilot_toggles.lead_detection_probability): + elif (track is None) and ready and (lead_msg.prob > lead_detection_probability): lead_dict = get_RadarState_from_vision(lead_msg, v_ego, model_v_ego) if low_speed_override: