From e1e5617a7dc7ec800037b531db39a337394fe0f6 Mon Sep 17 00:00:00 2001 From: happymaj11r Date: Wed, 25 Feb 2026 13:27:08 +0900 Subject: [PATCH 1/4] =?UTF-8?q?=EC=B0=A8=EC=84=A0=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EC=B0=A8=EC=84=A0=ED=8C=90=EB=8B=A8=20=EC=84=A4=EC=A0=95=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80=20(LaneLineCheck)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 색상 오인식 문제 대응: 0=색상+타입(기존), 1=타입만(점선/실선) Co-Authored-By: Claude Opus 4.6 --- common/params_keys.h | 1 + selfdrive/carrot_settings.json | 16 ++++++++++++++++ selfdrive/controls/lib/desire_helper.py | 12 ++++++++++-- selfdrive/ui/qt/offroad/settings.cc | 1 + 4 files changed, 28 insertions(+), 2 deletions(-) diff --git a/common/params_keys.h b/common/params_keys.h index d3ba8e4640..a7e9865eeb 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -278,6 +278,7 @@ inline static std::unordered_map keys = { {"LaneChangeNeedTorque", {PERSISTENT, INT, "0"}}, {"LaneChangeDelay", {PERSISTENT, INT, "0"}}, {"LaneChangeBsd", {PERSISTENT, INT, "0"}}, + {"LaneLineCheck", {PERSISTENT, INT, "0"}}, {"MaxAngleFrames", {PERSISTENT, INT, "89"}}, {"SoftHoldMode", {PERSISTENT, INT, "0"}}, diff --git a/selfdrive/carrot_settings.json b/selfdrive/carrot_settings.json index ad3dab898b..11abd47fa7 100644 --- a/selfdrive/carrot_settings.json +++ b/selfdrive/carrot_settings.json @@ -1649,6 +1649,22 @@ "ctitle": "变道盲点监测 (BSD)", "cdescr": "0: BSD 检测 (允许转向力矩), 1: 阻止转向力矩, -1: 忽略 BSD" }, + { + "group": "조향일반", + "name": "LaneLineCheck", + "title": "차선변경 차선판단", + "descr": "0: 색상+타입(노란선차단)\n1: 타입만(점선/실선)", + "egroup": "LAT", + "etitle": "LaneChange LineCheck", + "edescr": "0: Color+Type(block yellow), 1: Type only(dashed/solid)", + "min": 0, + "max": 1, + "default": 0, + "unit": 1, + "cgroup": "转向", + "ctitle": "变道车道判断", + "cdescr": "0: 颜色+类型(黄线阻止), 1: 仅类型(虚线/实线)" + }, { "group": "시작", "name": "HapticFeedbackWhenSpeedCamera", diff --git a/selfdrive/controls/lib/desire_helper.py b/selfdrive/controls/lib/desire_helper.py index aa74865c69..13ded2feda 100644 --- a/selfdrive/controls/lib/desire_helper.py +++ b/selfdrive/controls/lib/desire_helper.py @@ -57,6 +57,7 @@ def __init__(self): # params self.laneChangeNeedTorque = 0 self.laneChangeBsd = 0 + self.laneLineCheck = 0 self.laneChangeDelay = 0.0 self.modelTurnSpeedFactor = 0.0 self.model_turn_speed = 200.0 @@ -76,6 +77,7 @@ def _update_params_periodic(self): if self.frame % 100 == 0: self.laneChangeNeedTorque = self.params.get_int("LaneChangeNeedTorque") self.laneChangeBsd = self.params.get_int("LaneChangeBsd") + self.laneLineCheck = self.params.get_int("LaneLineCheck") self.laneChangeDelay = self.params.get_float("LaneChangeDelay") * 0.1 self.modelTurnSpeedFactor = self.params.get_float("ModelTurnSpeedFactor") * 0.1 @@ -191,8 +193,14 @@ def _process_sides(self, carstate, modeldata, radarState): self.right.update_obstacles(v_ego, radarState.leadRight, carstate.rightBlindspot, ignore_bsd, bsd_hold_sec=2.0) # compute available (include BSD+object) - self.left.compute_lane_change_available(lane_line_info_lt_20=(self.left.lane_line_info_raw < 20), ignore_bsd=ignore_bsd) - self.right.compute_lane_change_available(lane_line_info_lt_20=(self.right.lane_line_info_raw < 20), ignore_bsd=ignore_bsd) + if self.laneLineCheck == 1: + left_line_ok = self.left.lane_line_info_mod in (0, 5) + right_line_ok = self.right.lane_line_info_mod in (0, 5) + else: + left_line_ok = self.left.lane_line_info_raw < 20 + right_line_ok = self.right.lane_line_info_raw < 20 + self.left.compute_lane_change_available(lane_line_info_lt_20=left_line_ok, ignore_bsd=ignore_bsd) + self.right.compute_lane_change_available(lane_line_info_lt_20=right_line_ok, ignore_bsd=ignore_bsd) self.left.update_triggers() self.right.update_triggers() diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 5074d077f5..d6f01ee6a2 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -698,6 +698,7 @@ CarrotPanel::CarrotPanel(QWidget* parent) : QWidget(parent) { latLongToggles->addItem(new CValueControl("LaneChangeNeedTorque", tr("LaneChange need torque"), tr("-1:Disable lanechange, 0: no need torque, 1:need torque"), -1, 1, 1)); latLongToggles->addItem(new CValueControl("LaneChangeDelay", tr("LaneChange delay"), tr("x0.1sec"), 0, 100, 5)); latLongToggles->addItem(new CValueControl("LaneChangeBsd", tr("LaneChange Bsd"), tr("-1:ignore bsd, 0:BSD detect, 1: block steer torque"), -1, 1, 1)); + latLongToggles->addItem(new CValueControl("LaneLineCheck", tr("LaneChange LineCheck"), tr("0:Color+Type, 1:Type only(dashed/solid)"), 0, 1, 1)); latLongToggles->addItem(new CValueControl("CustomSR", tr("LAT: SteerRatiox0.1(0)"), tr("Custom SteerRatio"), 0, 300, 1)); latLongToggles->addItem(new CValueControl("SteerRatioRate", tr("LAT: SteerRatioRatex0.01(100)"), tr("SteerRatio apply rate"), 30, 170, 1)); latLongToggles->addItem(new CValueControl("PathOffset", tr("LAT: PathOffset"), tr("(-)left, (+)right"), -150, 150, 1)); From bde35ac3e750635a98ca5e0aa5b9dad6efef50c1 Mon Sep 17 00:00:00 2001 From: happymaj11r Date: Wed, 25 Feb 2026 14:20:32 +0900 Subject: [PATCH 2/4] =?UTF-8?q?LaneLineCheck=3D2=20=EC=98=B5=EC=85=98=20?= =?UTF-8?q?=EC=B6=94=EA=B0=80:=20=EC=8B=A4=EC=84=A0=EC=97=90=EC=84=9C=20?= =?UTF-8?q?=ED=86=A0=ED=81=AC=20override=20=ED=97=88=EC=9A=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 점선은 바로 차선변경, 실선은 토크 넣으면 override Co-Authored-By: Claude Opus 4.6 --- selfdrive/carrot_settings.json | 8 ++++---- selfdrive/controls/lib/desire_helper.py | 12 +++++++++--- selfdrive/ui/qt/offroad/settings.cc | 2 +- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/selfdrive/carrot_settings.json b/selfdrive/carrot_settings.json index 11abd47fa7..fc6c5e533d 100644 --- a/selfdrive/carrot_settings.json +++ b/selfdrive/carrot_settings.json @@ -1653,17 +1653,17 @@ "group": "조향일반", "name": "LaneLineCheck", "title": "차선변경 차선판단", - "descr": "0: 색상+타입(노란선차단)\n1: 타입만(점선/실선)", + "descr": "0: 색상+타입(노란선차단)\n1: 타입만(점선/실선)\n2: 타입만+실선토크override", "egroup": "LAT", "etitle": "LaneChange LineCheck", - "edescr": "0: Color+Type(block yellow), 1: Type only(dashed/solid)", + "edescr": "0: Color+Type(block yellow), 1: Type only, 2: Type+torque override solid", "min": 0, - "max": 1, + "max": 2, "default": 0, "unit": 1, "cgroup": "转向", "ctitle": "变道车道判断", - "cdescr": "0: 颜色+类型(黄线阻止), 1: 仅类型(虚线/实线)" + "cdescr": "0: 颜色+类型(黄线阻止), 1: 仅类型(虚线/实线), 2: 仅类型+实线扭矩override" }, { "group": "시작", diff --git a/selfdrive/controls/lib/desire_helper.py b/selfdrive/controls/lib/desire_helper.py index 13ded2feda..5e98419c1e 100644 --- a/selfdrive/controls/lib/desire_helper.py +++ b/selfdrive/controls/lib/desire_helper.py @@ -193,7 +193,7 @@ def _process_sides(self, carstate, modeldata, radarState): self.right.update_obstacles(v_ego, radarState.leadRight, carstate.rightBlindspot, ignore_bsd, bsd_hold_sec=2.0) # compute available (include BSD+object) - if self.laneLineCheck == 1: + if self.laneLineCheck >= 1: left_line_ok = self.left.lane_line_info_mod in (0, 5) right_line_ok = self.right.lane_line_info_mod in (0, 5) else: @@ -358,10 +358,16 @@ def update(self, carstate, modeldata, lateral_active, lane_change_prob, carrotMa # 차선변경 시작 조건: # - side.lane_change_available는 BSD+object 포함(요구사항) # - 하지만 BSD 중에도 torque override 허용해야 하므로, BSD 분기를 별도로 둠(원본 동작 유지) - start_gate = (side.lane_change_available_geom and self.lane_change_delay == 0) or side.lane_line_info_edge_detect + # LaneLineCheck=2: 실선에서도 토크 override 허용 + solid_line_blocked = (self.laneLineCheck >= 2) and (not side.lane_change_available_geom) and \ + (side.lane_available or side.edge_available) + start_gate = (side.lane_change_available_geom and self.lane_change_delay == 0) or \ + side.lane_line_info_edge_detect or solid_line_blocked if start_gate: - if bsd_active: + if solid_line_blocked and not torque_applied: + pass # 실선: 토크 없으면 대기 + elif bsd_active: if torque_applied and (not block_lanechange_bsd): self.lane_change_state = LaneChangeState.laneChangeStarting elif self.laneChangeNeedTorque > 0 or self.next_lane_change: diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index d6f01ee6a2..d802586301 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -698,7 +698,7 @@ CarrotPanel::CarrotPanel(QWidget* parent) : QWidget(parent) { latLongToggles->addItem(new CValueControl("LaneChangeNeedTorque", tr("LaneChange need torque"), tr("-1:Disable lanechange, 0: no need torque, 1:need torque"), -1, 1, 1)); latLongToggles->addItem(new CValueControl("LaneChangeDelay", tr("LaneChange delay"), tr("x0.1sec"), 0, 100, 5)); latLongToggles->addItem(new CValueControl("LaneChangeBsd", tr("LaneChange Bsd"), tr("-1:ignore bsd, 0:BSD detect, 1: block steer torque"), -1, 1, 1)); - latLongToggles->addItem(new CValueControl("LaneLineCheck", tr("LaneChange LineCheck"), tr("0:Color+Type, 1:Type only(dashed/solid)"), 0, 1, 1)); + latLongToggles->addItem(new CValueControl("LaneLineCheck", tr("LaneChange LineCheck"), tr("0:Color+Type, 1:Type only, 2:Type+torque override solid"), 0, 2, 1)); latLongToggles->addItem(new CValueControl("CustomSR", tr("LAT: SteerRatiox0.1(0)"), tr("Custom SteerRatio"), 0, 300, 1)); latLongToggles->addItem(new CValueControl("SteerRatioRate", tr("LAT: SteerRatioRatex0.01(100)"), tr("SteerRatio apply rate"), 30, 170, 1)); latLongToggles->addItem(new CValueControl("PathOffset", tr("LAT: PathOffset"), tr("(-)left, (+)right"), -150, 150, 1)); From 68e1fd089f330028c32356da8e4afde30b323bae Mon Sep 17 00:00:00 2001 From: happymaj11r Date: Wed, 25 Feb 2026 15:49:26 +0900 Subject: [PATCH 3/4] =?UTF-8?q?LaneLineCheck=3D2=20=EC=8B=A4=EC=84=A0=20?= =?UTF-8?q?=ED=86=A0=ED=81=AC=20override=20=EB=B2=84=EA=B7=B8=20=EC=88=98?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit solid_line_blocked일 때 토크+BSD 체크 후 바로 laneChangeStarting으로 전환하도록 수정. 기존에는 이후 분기의 lane_change_available 체크에 걸려서 실선 토크 override가 동작하지 않았음. Co-Authored-By: Claude Opus 4.6 --- selfdrive/controls/lib/desire_helper.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/selfdrive/controls/lib/desire_helper.py b/selfdrive/controls/lib/desire_helper.py index 5e98419c1e..5f6ad9a50c 100644 --- a/selfdrive/controls/lib/desire_helper.py +++ b/selfdrive/controls/lib/desire_helper.py @@ -365,8 +365,9 @@ def update(self, carstate, modeldata, lateral_active, lane_change_prob, carrotMa side.lane_line_info_edge_detect or solid_line_blocked if start_gate: - if solid_line_blocked and not torque_applied: - pass # 실선: 토크 없으면 대기 + if solid_line_blocked: + if torque_applied and not (bsd_active and block_lanechange_bsd): + self.lane_change_state = LaneChangeState.laneChangeStarting elif bsd_active: if torque_applied and (not block_lanechange_bsd): self.lane_change_state = LaneChangeState.laneChangeStarting From 7927f2655d6dc0ee1a3ebb51be060dee346f3d35 Mon Sep 17 00:00:00 2001 From: happymaj11r Date: Wed, 25 Feb 2026 16:09:47 +0900 Subject: [PATCH 4/4] =?UTF-8?q?HUD=20=EC=B0=A8=EC=84=A0=20=EC=83=89?= =?UTF-8?q?=EC=83=81=20=ED=91=9C=EC=8B=9C=EB=A5=BC=20LaneLineCheck=20?= =?UTF-8?q?=EC=98=B5=EC=85=98=EC=97=90=20=EC=97=B0=EB=8F=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit LaneLineCheck>=1일 때 HUD 차선 색상을 색상 raw값 대신 타입(점선/실선) 기준으로 판단하도록 변경하여 차선변경 로직과 HUD 표시 간 불일치 해소 Co-Authored-By: Claude Opus 4.6 --- opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py index 6b463e46ed..bc06d22ac2 100644 --- a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py +++ b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py @@ -644,6 +644,9 @@ def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control, ret = [] md = CS.MD + if not hasattr(create_ccnc_messages, '_lane_line_check') or frame % 100 == 0: + create_ccnc_messages._lane_line_check = Params().get_int("LaneLineCheck") + lane_line_check = create_ccnc_messages._lane_line_check desire, lane_changing = _get_desire_and_lane_changing(md) if CP.flags & HyundaiFlags.CAMERA_SCC.value: @@ -743,14 +746,22 @@ def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control, values["LANELINE_CURVATURE_DIRECTION"] = 1 if curvature < 0 and lat_active else 0 lane_color = 6 if md is not None and md.meta.laneChangeAvailableLeft else 2 - lane_color = 4 if CS.out.leftLaneLine >= 20 or CS.out.leftBlindspot else lane_color + if lane_line_check >= 1: + lane_line_warn_left = CS.out.leftLaneLine % 10 not in (0, 5) # 실선이면 주황 + else: + lane_line_warn_left = CS.out.leftLaneLine >= 20 # 노란색이면 주황 + lane_color = 4 if lane_line_warn_left or CS.out.leftBlindspot else lane_color if hud_control.leftLaneDepart: values["LANELINE_LEFT"] = 4 if (frame // 50) % 2 == 0 else 1 else: values["LANELINE_LEFT"] = lane_color if hud_control.leftLaneVisible else 0 lane_color = 6 if md is not None and md.meta.laneChangeAvailableRight else 2 - lane_color = 4 if CS.out.rightLaneLine >= 20 or CS.out.rightBlindspot else lane_color + if lane_line_check >= 1: + lane_line_warn_right = CS.out.rightLaneLine % 10 not in (0, 5) + else: + lane_line_warn_right = CS.out.rightLaneLine >= 20 + lane_color = 4 if lane_line_warn_right or CS.out.rightBlindspot else lane_color if hud_control.rightLaneDepart: values["LANELINE_RIGHT"] = 4 if (frame // 50) % 2 == 0 else 1 else: