diff --git a/common/params_keys.h b/common/params_keys.h index 5a3c989771..60e8e4f808 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -272,6 +272,7 @@ inline static std::unordered_map keys = { {"TFollowGap2", {PERSISTENT, INT, "120"}}, {"TFollowGap3", {PERSISTENT, INT, "140"}}, {"TFollowGap4", {PERSISTENT, INT, "160"}}, + {"TFollowSpeedFactor", {PERSISTENT, INT, "0"}}, {"DynamicTFollow", {PERSISTENT, INT, "0"}}, {"DynamicTFollowLC", {PERSISTENT, INT, "100"}}, diff --git a/selfdrive/carrot/carrot_functions.py b/selfdrive/carrot/carrot_functions.py index 8544efa20d..a79b96cd21 100644 --- a/selfdrive/carrot/carrot_functions.py +++ b/selfdrive/carrot/carrot_functions.py @@ -137,6 +137,7 @@ def __init__(self): self.xDistToTurn = 0 self.atcType = "" self.atc_active = False + self.tFollowSpeedFactor = 0.0 # 고속 주행 시 추가 차간 거리 가중치 self._stop_x_rl = None self.last_event_time = 0.0 @@ -165,6 +166,7 @@ def _params_update(self): self.tFollowGap2 = self.params.get_float("TFollowGap2") / 100. self.tFollowGap3 = self.params.get_float("TFollowGap3") / 100. self.tFollowGap4 = self.params.get_float("TFollowGap4") / 100. + self.tFollowSpeedFactor = self.params.get_float("TFollowSpeedFactor") / 100. self.dynamicTFollow = self.params.get_float("DynamicTFollow") / 100. self.dynamicTFollowLC = self.params.get_float("DynamicTFollowLC") / 100. self.enableSpeedTF = self.params.get_int("EnableSpeedTF") @@ -253,6 +255,12 @@ def _apply_speed_t_follow_scale(self, tf_base, v_ego): scale = (1.0 - reduce) + reduce * s tf_target *= scale + # 고속 주행 시 추가 차간 거리 가중치 (TFollowSpeedFactor) + # v_ego가 높을수록 차간 거리를 추가로 확보함 + if self.tFollowSpeedFactor > 0: + speed_boost = float(np.clip((v_ego * CV.MS_TO_KPH - 60.0) / 100.0, 0.0, 1.0)) + tf_target += speed_boost * self.tFollowSpeedFactor + return float(tf_target) diff --git a/selfdrive/carrot/carrot_learning.py b/selfdrive/carrot/carrot_learning.py index f7a8b7b684..352265961c 100644 --- a/selfdrive/carrot/carrot_learning.py +++ b/selfdrive/carrot/carrot_learning.py @@ -55,7 +55,7 @@ # ── Phase 3 상수 ───────────────────────────────────────────────────── _BRAKE_MIN_COUNT = 5 # 추천을 위한 최소 수동 브레이크 횟수 -_JLEAD_STEP_UNIT = 10 # JLeadFactor3 한 번 추천 시 변화량 +_JLEAD_STEP_UNIT = 20 # JLeadFactor3 한 번 추천 시 변화량 (강화: 10 -> 20) _JLEAD_REDUCE_STEP = -7 # 제동 과다 시 변화량 _JLEAD_GAS_THRESHOLD_SEC = 5.0 # 제동 중 가속 개입 누적 기준 (초) @@ -82,6 +82,7 @@ _TFOLLOW_MIN_V_KPH = 60.0 # 고속도로 주행 구간에서만 학습 _TFOLLOW_WIDEN_STEP = 5 # 증가 추천 (+0.05s) _TFOLLOW_BRAKE_THRESHOLD_SEC = 10.0 # 거리 부족으로 인한 브레이크 누적 기준 (초) +_TFOLLOW_SPEED_FACTOR_STEP = 5 # 고속 보정치 증가 단위 (+0.05) _AUTO_HUNTING_THRESHOLD = 0.8 # 자율 주행 중 가감속 변동(Hunting) 감지 임계치 (m/s^2) # ── 공통 ───────────────────────────────────────────────────────────── @@ -128,6 +129,7 @@ def __init__(self): self._tfollow_gas_acc = [0.0] * 4 self._tfollow_brake_acc = [0.0] * 4 # 수동 브레이크 개입 self._tfollow_brake_auto_acc = [0.0] * 4 # 자율 주행 중 헌팅 감지 + self._tfollow_speed_brake_acc = 0.0 # 고속 주행 시 브레이크 개입 누적 self._current_gap = 1 # 현재 활성화된 GAP 단계 (1~4) # Phase 5 (DynamicTFollow / TFollowDecelBoost) self._dyn_brake_count = 0 # 앞차 급감속 중 브레이크 개입 횟수 @@ -254,8 +256,12 @@ def update(self, v_ego_kph: float, gas_pressed: bool, engaged: bool, gear_park: if (self._prev_a_ego > 0.3 and a_ego < -0.3) or (self._prev_a_ego < -0.3 and a_ego > 0.3): self._accel_swing_count += 1 if self._accel_swing_count > 8: - self._tfollow_brake_acc[gap_idx] += _DT * 0.2 + self._tfollow_brake_auto_acc[gap_idx] += _DT * 2.0 self._accel_swing_count = 0 + + # 고속 주행(80km/h 이상) 시 추가 거리 보정 학습 + if v_ego_kph >= 80.0 and brake_pressed: + self._tfollow_speed_brake_acc += _DT # 주차 감지 (이전에 주차가 아니었고, 주행을 한 번이라도 한 경우에만 발동) if gear_park and not self._prev_gear_park and self._has_driven: @@ -325,6 +331,7 @@ def _load(self): loaded4_auto = data.get("tfollow_brake_auto_acc", [0.0] * 4) if len(loaded4_auto) == 4: self._tfollow_brake_auto_acc = [float(x) for x in loaded4_auto] + self._tfollow_speed_brake_acc = float(data.get("tfollow_speed_brake_acc", 0.0)) # Phase 5 p5 = data.get("phase5", {}) self._dyn_brake_count = int(p5.get("dyn_brake_count", 0)) @@ -350,6 +357,7 @@ def _save(self): "tfollow_gas_acc": self._tfollow_gas_acc, "tfollow_brake_acc": self._tfollow_brake_acc, "tfollow_brake_auto_acc": self._tfollow_brake_auto_acc, + "tfollow_speed_brake_acc": self._tfollow_speed_brake_acc, "gas_dec_auto_acc": self._gas_dec_auto_acc, "phase5": { "dyn_brake_count": self._dyn_brake_count, @@ -494,6 +502,18 @@ def _calc_recommendations(self) -> dict: else: continue + # ── Phase 6: TFollowSpeedFactor (고속 차간 거리 보정) ─────────── + if self._tfollow_speed_brake_acc >= _TFOLLOW_BRAKE_THRESHOLD_SEC: + current_sf = self._params.get_int("TFollowSpeedFactor") + recommended_sf = min(100, current_sf + _TFOLLOW_SPEED_FACTOR_STEP) + if recommended_sf != current_sf: + result["거리 (Following Distance)"]["TFollowSpeedFactor"] = { + "current": current_sf, + "recommended": recommended_sf, + "band_kph": "high-speed safety (>80km/h)", + "sec": round(self._tfollow_speed_brake_acc, 1), + } + if recommended_val != current_val: result["거리 (Following Distance)"][key] = { "current": current_val, @@ -586,6 +606,7 @@ def apply_recommendations(self): self._tfollow_gas_acc = [0.0] * 4 self._tfollow_brake_acc = [0.0] * 4 self._tfollow_brake_auto_acc = [0.0] * 4 + self._tfollow_speed_brake_acc = 0.0 self._dyn_brake_count = 0 self._decel_brake_count = 0 self._params.remove("CarrotLearningData") diff --git a/selfdrive/carrot_settings.json b/selfdrive/carrot_settings.json index 5123d926fe..55416a5cb0 100644 --- a/selfdrive/carrot_settings.json +++ b/selfdrive/carrot_settings.json @@ -2001,6 +2001,19 @@ "ctitle": "跟车时间(4): TimeFollow4x0.01s(160)", "cdescr": "跟车距离 4 级" }, + { + "group": "차량간격", + "name": "TFollowSpeedFactor", + "title": "고속 차간거리 보정x0.01s(0)", + "descr": "80km/h 이상의 고속 주행 시 추가로 확보할 차간 거리 가중치", + "egroup": "FDIST", + "etitle": "TFollow Speed Factor", + "edescr": "Additional following distance factor at high speeds (>80km/h)", + "min": 0, + "max": 100, + "default": 0, + "unit": 5 + }, { "group": "차량간격", "name": "DynamicTFollow", diff --git a/selfdrive/ui/qt/home.cc b/selfdrive/ui/qt/home.cc index c38e7d1ff5..2ac1cac2bb 100644 --- a/selfdrive/ui/qt/home.cc +++ b/selfdrive/ui/qt/home.cc @@ -206,7 +206,9 @@ class AutoTunerDialog : public DialogBase { - CruiseMaxVals0~6: Increases accel limits per speed band to fix sluggish starts and acceleration.
🚙 [Driving]
Adjusts longitudinal (brake) control.
- - JLeadFactor3: If the driver brakes frequently, it tunes the system to start braking earlier and smoother.
+ - JLeadFactor3: Controls how early the car starts braking for a lead vehicle. Higher values = earlier, smoother braking (range 50~200).
+ - TFollowSpeedFactor: Automatically widens the following distance as speed increases above 80km/h for high-speed cruising safety.
+ - DynamicTFollow: Adjusts gap based on lead vehicle's sudden acceleration or deceleration.
🛣️ [Following Distance]
Optimizes highway following distance. If gas is pressed often while following a lead car at speed, it means the gap is too wide. Recommends decreasing TFollowGap for that gap level.
- TFollowGap1~4: Per-GAP-level time-gap setting (seconds x100). Lower = closer.
@@ -242,8 +244,9 @@ class AutoTunerDialog : public DialogBase { - CruiseMaxVals0~6: 속도 대역별 가속 한계치를 높여 굼뜬 출발과 답답한 가속을 개선합니다.
🚙 [주행] (Driving)
종방향(브레이크) 제어 능력을 조정합니다.
- - JLeadFactor3: 운전자가 브레이크를 자주 밟을 경우, 앞차가 가까워질 때 조금 더 일찍 감속을 시작하도록 유도합니다.
- 🛣️ [거리] (Following Distance)
+ - JLeadFactor3: 선행차에 대한 제동 시작 시점입니다. 수치가 높을수록 더 멀리서 부드럽게 감속을 시작합니다. (범위 50~200)
+ - TFollowSpeedFactor: 80km/h 이상의 고속 주행 시 자동으로 차간 거리를 추가로 확보하여 안전 마진을 늘려줍니다.
+ - DynamicTFollow: 선행차의 거친 움직임(급가감속)에 대응하여 일시적으로 거리를 조절합니다.
고속도 주행 중 선행차 추종 거리를 최적화합니다. 선행차가 있는데도 가속 페달을 자주 밟는다면, 시스템이 지나치게 거리를 넓게 유지하는 것으로 판단하여 해당 GAP의 TFollowGap 값을 줄이는 방향으로 추천합니다.
- TFollowGap1~4: GAP 단계별 추종 거리 시간(x0.01초). 낙을수록 가깄워집니다. 최소 0.70초 보장.
🎛️ [동적제어] (Dynamic Control)