From 52f10ca29a965798dab6a43648f50e7967e1ede0 Mon Sep 17 00:00:00 2001 From: carrot <43668841+ajouatom@users.noreply.github.com> Date: Wed, 4 Jun 2025 07:20:24 +0900 Subject: [PATCH] fix waze, add cruise button mode 3 (#180) * enable detect redlight during regen decel.. * button mode 2 decel.. * lanemode timeadjust 0.05 -> 0.07 * limit_accel_in_turn: unstable decel during cornering * roadLimitSpeed from Car. * fix roadlimitSpeed display.. * fix lanemode model condition.. * fix.. typo * fix. * test for SK3 * fix.. standstill * Revert "test for SK3" This reverts commit b7ab995c5ef2e482b65704fb18c7bc5a3bcf1171. * fix.. loadLimitSpeed.. * fix roadSpeedLimit(hkg can) * initial "gas" state for bump * fix.. lane mode adjust time.. 5 -> 7 -> 6 * test lanemode (curve -> straight) * fix.. lane * revert * fix. laneline curv -> straight.. * fix.. revert * fix.. lanemode... again.. * canfd 0x1b5 * disp CarVolt * fix.. * LatMpc Input/Output offset * kisa waze & roadlimitspeed. * fix.. * test * ff * ff * fix.. * add roadlimitspeed offset * fix.speed limit.. * fix.. waze * fix.. mph * fix.. ccnc * fix.. * fix.. * Update carrot.cc * fix estimate radar dt.. * fix feet... * fix police.. * test lanemode curve to straight * fix police.. * fix comment.. * fix curvature & no siren (#179) * fix dos,tres siren * fix curvature * cruise button mode3 * add lane chane delay.. * fix.. volt display.. * fix.. roadlimit speed limitation.. * fix.. typo * test * fix.. * fix.. * fix.. tpms * fix.. * fix.. * fix. tpms * collision detect... dashcam mode... --------- Co-authored-by: Lee Jong Mun <43285072+crwusiz@users.noreply.github.com> --- common/params_keys.h | 11 +- opendbc_repo/opendbc/car/hyundai/carstate.py | 5 +- .../opendbc/car/hyundai/hyundaicanfd.py | 16 +- opendbc_repo/opendbc/car/hyundai/interface.py | 3 + opendbc_repo/opendbc/car/hyundai/values.py | 1 + opendbc_repo/opendbc/car/interfaces.py | 4 +- opendbc_repo/opendbc/dbc/hyundai_canfd.dbc | 3 +- panda/board/boards/dos.h | 8 +- panda/board/boards/tres.h | 2 +- selfdrive/car/cruise.py | 18 +- selfdrive/carrot/carrot_man.py | 157 ++++++++++- selfdrive/carrot_settings.json | 251 +++++++++++++----- selfdrive/controls/controlsd.py | 11 +- selfdrive/controls/lib/desire_helper.py | 9 +- selfdrive/controls/lib/drive_helpers.py | 16 +- selfdrive/controls/lib/lane_planner_2.py | 2 +- selfdrive/ui/carrot.cc | 77 ++++-- selfdrive/ui/qt/offroad/settings.cc | 2 + selfdrive/ui/ui.cc | 1 + system/manager/manager.py | 9 + 20 files changed, 480 insertions(+), 126 deletions(-) diff --git a/common/params_keys.h b/common/params_keys.h index 1c49eff..e4d258b 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -172,6 +172,7 @@ inline static std::unordered_map keys = { {"AutoTurnMapChange", PERSISTENT }, {"AutoNaviSpeedCtrlEnd", PERSISTENT}, {"AutoNaviSpeedCtrlMode", PERSISTENT}, + {"AutoRoadSpeedLimitOffset", PERSISTENT}, {"AutoNaviSpeedBumpTime", PERSISTENT}, {"AutoNaviSpeedBumpSpeed", PERSISTENT}, {"AutoNaviSpeedDecelRate", PERSISTENT}, @@ -191,6 +192,11 @@ inline static std::unordered_map keys = { {"CruiseButtonTest2", PERSISTENT}, {"CruiseButtonTest3", PERSISTENT}, {"CruiseSpeedUnit", PERSISTENT}, + {"CruiseSpeed1", PERSISTENT}, + {"CruiseSpeed2", PERSISTENT}, + {"CruiseSpeed3", PERSISTENT}, + {"CruiseSpeed4", PERSISTENT}, + {"CruiseSpeed5", PERSISTENT}, {"PaddleMode", PERSISTENT}, {"MyDrivingMode", PERSISTENT}, {"MyDrivingModeAuto", PERSISTENT}, @@ -231,6 +237,7 @@ inline static std::unordered_map keys = { {"UseLaneLineSpeedApply", PERSISTENT}, {"AdjustLaneOffset", PERSISTENT}, {"LaneChangeNeedTorque", PERSISTENT}, + {"LaneChangeDelay", PERSISTENT }, {"LaneChangeBsd", PERSISTENT}, {"MaxAngleFrames", PERSISTENT}, {"SoftHoldMode", PERSISTENT}, @@ -238,7 +245,9 @@ inline static std::unordered_map keys = { {"LatMpcMotionCost", PERSISTENT}, {"LatMpcAccelCost", PERSISTENT}, {"LatMpcJerkCost", PERSISTENT}, - {"LatMpcSteeringRateCost", PERSISTENT}, + {"LatMpcSteeringRateCost", PERSISTENT }, + {"LatMpcInputOffset", PERSISTENT}, + {"LatMpcOutputOffset", PERSISTENT}, {"PathOffset", PERSISTENT}, {"LateralTorqueCustom", PERSISTENT}, {"LateralTorqueAccelFactor", PERSISTENT}, diff --git a/opendbc_repo/opendbc/car/hyundai/carstate.py b/opendbc_repo/opendbc/car/hyundai/carstate.py index 24d25a6..1ff9922 100644 --- a/opendbc_repo/opendbc/car/hyundai/carstate.py +++ b/opendbc_repo/opendbc/car/hyundai/carstate.py @@ -449,6 +449,8 @@ class CarState(CarStateBase): if "HDA_INFO_4A3" in cp.vl: self.hda_info_4a3 = copy.copy(cp.vl.get("HDA_INFO_4A3", {})) speedLimit = self.hda_info_4a3["SPEED_LIMIT"] + if not self.is_metric: + speedLimit = CV.MPH_TO_KPH ret.speedLimit = speedLimit if speedLimit < 255 else 0 if int(self.hda_info_4a3["NEW_SIGNAL_4"]) == 17: speed_limit_cam = True @@ -586,10 +588,9 @@ class CarState(CarStateBase): ("SCC_CONTROL", 50), ] - if CP.flags & HyundaiFlags.CANFD_HDA2 and CP.flags & HyundaiFlags.CAMERA_SCC: + if CP.extFlags & HyundaiExtFlags.CANFD_4A3: pt_messages += [ ("HDA_INFO_4A3", 5), - #("NEW_MSG_4B4", 10), # G80 hda2개조차량은 안나옴. 원래그런건지.. 어짜피 안쓰는데이터이니깐... ] #if CP.flags & HyundaiFlags.CANFD_HDA2 and CP.extFlags & HyundaiExtFlags.NAVI_CLUSTER.value and not (CP.extFlags & HyundaiExtFlags.SCC_BUS2.value): # 어떤차는 bus2에 있음, 내차는 bus0에 있는데.... 이건 옆두부와 관련이 없나? diff --git a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py index 9d1ac2b..3fbcf82 100644 --- a/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py +++ b/opendbc_repo/opendbc/car/hyundai/hyundaicanfd.py @@ -421,7 +421,7 @@ def forward_button_message(packer, CAN, frame, CS, cruise_button, MainMode_ACC_t pass elif LFA_trigger > 0: values["LFA_BTN"] = 1 - + ret.append(packer.make_can_msg(CS.cruise_btns_msg_canfd, CAN.CAM, values)) return ret @@ -509,11 +509,11 @@ def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control, disp_angle if values["ALERTS_5"] in [11] and CS.softHoldActive == 0: values["ALERTS_5"] = 0 - curvature = { - i: (31 if i == -1 else 13 - abs(i + 15)) if i < 0 else 15 + i - for i in range(-15, 16) - } - values["LANELINE_CURVATURE"] = curvature.get(max(-15, min(round(disp_angle / 3), 15)), 14) + curvature = round(CS.out.steeringAngleDeg / 3) + + values["LANELINE_CURVATURE"] = (min(abs(curvature), 15) + (-1 if curvature < 0 else 0)) if lat_active else 0 + values["LANELINE_CURVATURE_DIRECTION"] = 1 if curvature < 0 and lat_active else 0 + if hud_control.leftLaneDepart: values["LANELINE_LEFT"] = 4 if (frame // 50) % 2 == 0 else 1 else: @@ -522,8 +522,8 @@ def create_ccnc_messages(CP, packer, CAN, frame, CC, CS, hud_control, disp_angle values["LANELINE_RIGHT"] = 4 if (frame // 50) % 2 == 0 else 1 else: values["LANELINE_RIGHT"] = 2 if hud_control.rightLaneVisible else 0 - values["LANELINE_LEFT_POSITION"] = 15 - values["LANELINE_RIGHT_POSITION"] = 15 + #values["LANELINE_LEFT_POSITION"] = 15 + #values["LANELINE_RIGHT_POSITION"] = 15 values["LCA_LEFT_ARROW"] = 2 if CS.out.leftBlinker else 0 values["LCA_RIGHT_ARROW"] = 2 if CS.out.rightBlinker else 0 diff --git a/opendbc_repo/opendbc/car/hyundai/interface.py b/opendbc_repo/opendbc/car/hyundai/interface.py index 5a83fa9..f28b179 100644 --- a/opendbc_repo/opendbc/car/hyundai/interface.py +++ b/opendbc_repo/opendbc/car/hyundai/interface.py @@ -54,6 +54,9 @@ class CarInterface(CarInterfaceBase): if 0x105 in fingerprint[CAN.ECAN]: ret.flags |= HyundaiFlags.HYBRID.value + if 0x4a3 in fingerprint[CAN.ECAN]: + ret.extFlags |= HyundaiExtFlags.CANFD_4A3.value + # detect HDA2 with ADAS Driving ECU if hda2: print("$$$CANFD HDA2") diff --git a/opendbc_repo/opendbc/car/hyundai/values.py b/opendbc_repo/opendbc/car/hyundai/values.py index bc1a443..bd98e43 100644 --- a/opendbc_repo/opendbc/car/hyundai/values.py +++ b/opendbc_repo/opendbc/car/hyundai/values.py @@ -155,6 +155,7 @@ class HyundaiExtFlags(IntFlag): CANFD_161 = 2 ** 11 CRUISE_BUTTON_ALT = 2 ** 12 # for CASPER_EV STEER_TOUCH = 2 ** 13 + CANFD_4A3 = 2 ** 14 class Footnote(Enum): CANFD = CarFootnote( diff --git a/opendbc_repo/opendbc/car/interfaces.py b/opendbc_repo/opendbc/car/interfaces.py index f1e2699..ef8a77a 100644 --- a/opendbc_repo/opendbc/car/interfaces.py +++ b/opendbc_repo/opendbc/car/interfaces.py @@ -154,8 +154,8 @@ class RadarInterfaceBase(ABC): self.init_done = False def estimate_dt(self, rcv_time): - if len(self.init_samples) > 20: - estimated_dt = np.mean(np.diff(self.init_samples)) + if len(self.init_samples) > 50: + estimated_dt = np.mean(np.diff(self.init_samples[20:])) self.dt = estimated_dt self.init_done = True print(f"Estimated radar dt: {self.dt} sec") diff --git a/opendbc_repo/opendbc/dbc/hyundai_canfd.dbc b/opendbc_repo/opendbc/dbc/hyundai_canfd.dbc index 4ab37f3..30993f3 100644 --- a/opendbc_repo/opendbc/dbc/hyundai_canfd.dbc +++ b/opendbc_repo/opendbc/dbc/hyundai_canfd.dbc @@ -280,7 +280,8 @@ BO_ 353 ADRV_0x161: 32 ADRV SG_ LANELINE_LEFT_POSITION : 84|6@1+ (1,0) [0|15] "" XXX SG_ LANELINE_RIGHT : 90|4@1+ (1,0) [0|15] "" XXX SG_ LANELINE_RIGHT_POSITION : 94|6@1+ (1,0) [0|15] "" XXX - SG_ LANELINE_CURVATURE : 100|5@1- (1,15) [0|31] "" XXX + SG_ LANELINE_CURVATURE : 100|4@1+ (1,0) [0|31] "" XXX + SG_ LANELINE_CURVATURE_DIRECTION : 104|1@0+ (1,0) [0|1] "" XXX SG_ LANE_HIGHLIGHT : 105|4@1+ (1,0) [0|15] "" XXX SG_ LANE_HIGHLIGHT_DISTANCE : 109|11@1+ (0.1,0) [0|204.7] "m" XXX SG_ LANE_LEFT : 120|3@1+ (1,0) [0|7] "" XXX diff --git a/panda/board/boards/dos.h b/panda/board/boards/dos.h index 661f91f..47e6ce7 100644 --- a/panda/board/boards/dos.h +++ b/panda/board/boards/dos.h @@ -75,9 +75,9 @@ static void dos_set_fan_enabled(bool enabled){ set_gpio_output(GPIOA, 1, enabled); } -static void dos_set_siren(bool enabled){ - set_gpio_output(GPIOC, 12, enabled); -} +//static void dos_set_siren(bool enabled){ +// set_gpio_output(GPIOC, 12, enabled); +//} static bool dos_read_som_gpio (void){ return (get_gpio_input(GPIOC, 2) != 0); @@ -147,7 +147,7 @@ board board_dos = { .read_current_mA = unused_read_current, .set_fan_enabled = dos_set_fan_enabled, .set_ir_power = dos_set_ir_power, - .set_siren = dos_set_siren, + .set_siren = unused_set_siren, .set_bootkick = dos_set_bootkick, .read_som_gpio = dos_read_som_gpio, .set_amp_enabled = unused_set_amp_enabled diff --git a/panda/board/boards/tres.h b/panda/board/boards/tres.h index 811314a..3e4ff32 100644 --- a/panda/board/boards/tres.h +++ b/panda/board/boards/tres.h @@ -166,7 +166,7 @@ board board_tres = { .read_current_mA = unused_read_current, .set_fan_enabled = tres_set_fan_enabled, .set_ir_power = tres_set_ir_power, - .set_siren = fake_siren_set, + .set_siren = unused_set_siren, .set_bootkick = tres_set_bootkick, .read_som_gpio = tres_read_som_gpio, .set_amp_enabled = unused_set_amp_enabled diff --git a/selfdrive/car/cruise.py b/selfdrive/car/cruise.py index cd77b63..0efdcbd 100644 --- a/selfdrive/car/cruise.py +++ b/selfdrive/car/cruise.py @@ -253,6 +253,12 @@ class VCruiseCarrot: self._cruise_button_mode = self.params.get_int("CruiseButtonMode") self._lfa_button_mode = self.params.get_int("LfaButtonMode") self.cruiseOnDist = self.params.get_float("CruiseOnDist") * 0.01 + cruiseSpeed1 = self.params.get_float("CruiseSpeed1") + cruiseSpeed2 = self.params.get_float("CruiseSpeed2") + cruiseSpeed3 = self.params.get_float("CruiseSpeed3") + cruiseSpeed4 = self.params.get_float("CruiseSpeed4") + cruiseSpeed5 = self.params.get_float("CruiseSpeed5") + self._cruise_speed_table = [cruiseSpeed1, cruiseSpeed2, cruiseSpeed3, cruiseSpeed4, cruiseSpeed5] def update_v_cruise(self, CS, sm, is_metric): self._add_log("") @@ -490,7 +496,7 @@ class VCruiseCarrot: pass elif not CC.enabled: v_cruise_kph = max(self.v_ego_kph_set, self._cruise_speed_min) - elif self.v_ego_kph_set > v_cruise_kph + 2 and self._cruise_button_mode in [2]: + elif self.v_ego_kph_set > v_cruise_kph + 2 and self._cruise_button_mode in [2, 3]: v_cruise_kph = max(self.v_ego_kph_set, self._cruise_speed_min) elif self._cruise_button_mode in [0, 1]: v_cruise_kph = button_kph @@ -562,7 +568,15 @@ class VCruiseCarrot: # nRoadLimitSpeed, vTurnSpeed # gasPressed, brakePressed, standstill def _v_cruise_desired(self, CS, v_cruise_kph): - if v_cruise_kph < 30: #self.nRoadLimitSpeed: + if self._cruise_button_mode == 3: + for speed in self._cruise_speed_table: + if v_cruise_kph < speed: + v_cruise_kph = speed + break + else: + v_cruise_kph = ((v_cruise_kph // self._cruise_speed_unit) + 1) * self._cruise_speed_unit + + elif v_cruise_kph < 30: #self.nRoadLimitSpeed: v_cruise_kph = 30 #self.nRoadLimitSpeed else: for speed in range (40, 160, self._cruise_speed_unit): diff --git a/selfdrive/carrot/carrot_man.py b/selfdrive/carrot/carrot_man.py index 94057e4..8d0e4c9 100644 --- a/selfdrive/carrot/carrot_man.py +++ b/selfdrive/carrot/carrot_man.py @@ -19,6 +19,7 @@ from openpilot.common.params import Params from openpilot.common.filter_simple import MyMovingAverage from openpilot.system.hardware import PC, TICI from openpilot.selfdrive.navd.helpers import Coordinate +from opendbc.car.common.conversions import Conversions as CV try: from shapely.geometry import LineString @@ -278,6 +279,8 @@ class CarrotMan: self.active_carrot_last = False + self.is_metric = self.params.get_bool("IsMetric") + def get_broadcast_address(self): if PC: iface = b'br0' @@ -583,6 +586,81 @@ class CarrotMan: print(f"Network error, retrying...: {e}") time.sleep(2) + + def parse_kisa_data(self, data: bytes): + result = {} + + try: + decoded = data.decode('utf-8') + except UnicodeDecodeError: + print("Decoding error:", data) + return result + + parts = decoded.split('/') + for part in parts: + if ':' in part: + key, value = part.split(':', 1) + try: + result[key] = int(value) + except ValueError: + result[key] = value + return result + + def kisa_app_thread(self): + while True: + try: + with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock: + sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) + sock.settimeout(10) # 소켓 타임아웃 설정 (10초) + sock.bind(('', 12345)) # UDP 포트 바인딩 + print("#########kisa_app_thread: UDP thread started...") + + while True: + try: + #self.remote_addr = None + # 데이터 수신 (UDP는 recvfrom 사용) + try: + data, remote_addr = sock.recvfrom(4096) # 최대 4096 바이트 수신 + #print(f"Received data from {self.remote_addr}") + + if not data: + raise ConnectionError("No data received") + + #if self.remote_addr is None: + # print("Connected to: ", remote_addr) + #self.remote_addr = remote_addr + try: + print(data) + kisa_data = self.parse_kisa_data(data) + self.carrot_serv.update_kisa(kisa_data) + #json_obj = json.loads(data.decode()) + #print(json_obj) + except Exception as e: + traceback.print_exc() + print(f"kisa_app_thread: json error...: {e}") + print(data) + + except TimeoutError: + print("Waiting for data (timeout)...") + #self.remote_addr = None + time.sleep(1) + + except Exception as e: + print(f"kisa_app_thread: error...: {e}") + #self.remote_addr = None + break + + except Exception as e: + print(f"kisa_app_thread: recv error...: {e}") + #self.remote_addr = None + break + + time.sleep(1) + except Exception as e: + #self.remote_addr = None + print(f"Network error, retrying...: {e}") + time.sleep(2) + def make_tmux_data(self): try: subprocess.run("rm /data/media/tmux.log; tmux capture-pane -pq -S-1000 > /data/media/tmux.log", shell=True, capture_output=True, text=False) @@ -886,6 +964,7 @@ class CarrotServ: self.params_memory = Params("/dev/shm/params") self.nRoadLimitSpeed = 30 + self.nRoadLimitSpeed_last = 30 self.nRoadLimitSpeed_counter = 0 self.active_carrot = 0 ## 1: CarrotMan Active, 2: sdi active , 3: speed decel active, 4: section active, 5: bump active, 6: speed limit active @@ -893,6 +972,8 @@ class CarrotServ: self.active_sdi_count = 0 self.active_sdi_count_max = 200 # 20 sec + self.active_kisa_count = 0 + self.nSdiType = -1 self.nSdiSpeedLimit = 0 self.nSdiSection = 0 @@ -1006,6 +1087,8 @@ class CarrotServ: self.autoTurnControlTurnEnd = self.params.get_int("AutoTurnControlTurnEnd") #self.autoNaviSpeedDecelRate = float(self.params.get_int("AutoNaviSpeedDecelRate")) * 0.01 self.autoCurveSpeedLowerLimit = int(self.params.get("AutoCurveSpeedLowerLimit")) + self.is_metric = self.params.get_bool("IsMetric") + self.autoRoadSpeedLimitOffset = self.params.get_int("AutoRoadSpeedLimitOffset") def _update_cmd(self): @@ -1440,6 +1523,44 @@ class CarrotServ: self.debugText = f"{self.nRoadLimitSpeed},{msg_nav.maneuverType},{msg_nav.maneuverModifier} " #print(msg_nav) #print(f"navInstruction: {self.xTurnInfo}, {self.xDistToTurn}, {self.szTBTMainText}") + + def update_kisa(self, data): + self.active_kisa_count = 100 + if "kisawazecurrentspd" in data: + pass + if "kisawazeroadspdlimit" in data: + road_limit_speed = data["kisawazeroadspdlimit"] + if road_limit_speed > 0: + print(f"kisawazeroadspdlimit: {road_limit_speed} km/h") + if not self.is_metric: + road_limit_speed *= CV.MPH_TO_KPH + self.nRoadLimitSpeed = road_limit_speed + if "kisawazealert" in data: + pass + if "kisawazeendalert" in data: + pass + if "kisawazeroadname" in data: + print(f"kisawazeroadname: {data['kisawazeroadname']}") + self.szPosRoadName = data["kisawazeroadname"] + if "kisawazereportid" in data and "kisawazealertdist" in data: + id_str = data["kisawazereportid"] + dist_str = data["kisawazealertdist"].lower() + import re + match = re.search(r'(\d+)', dist_str) + distance = int(match.group(1)) if match else 0 + if not self.is_metric: + distance = int(distance * 0.3048) + print(f"{id_str}: {distance} m") + xSpdType = -1 + if 'camera' in id_str: + xSpdType = 1 + elif 'police' in id_str: + xSpdType = 100 + + if xSpdType >= 0: + self.xSpdLimit = self.nRoadLimitSpeed + self.xSpdDist = distance + self.xSpdType =xSpdType def update_navi(self, remote_ip, sm, pm, vturn_speed, coords, distances, route_speed): @@ -1452,26 +1573,41 @@ class CarrotServ: distanceTraveled = sm['selfdriveState'].distanceTraveled delta_dist = distanceTraveled - self.totalDistance self.totalDistance = distanceTraveled - if CS.speedLimit > 0: + if CS.speedLimit > 0 and self.active_carrot <= 1: self.nRoadLimitSpeed = CS.speedLimit else: v_ego = v_ego_kph = 0 delta_dist = 0 CS = None + road_speed_limit_changed = True if self.nRoadLimitSpeed != self.nRoadLimitSpeed_last else False + self.nRoadLimitSpeed_last = self.nRoadLimitSpeed #self.bearing = self.nPosAngle #self._update_gps(v_ego, sm) self.bearing = self._update_gps(v_ego, sm) - self.xSpdDist = max(self.xSpdDist - delta_dist, 0) + self.xSpdDist = max(self.xSpdDist - delta_dist, -1000) self.xDistToTurn = max(self.xDistToTurn - delta_dist, 0) self.xDistToTurnNext = max(self.xDistToTurnNext - delta_dist, 0) self.active_count = max(self.active_count - 1, 0) self.active_sdi_count = max(self.active_sdi_count - 1, 0) - if self.active_count > 0: + self.active_kisa_count = max(self.active_kisa_count - 1, 0) + if self.active_kisa_count > 0: + self.active_carrot = 2 + + elif self.active_count > 0: self.active_carrot = 2 if self.active_sdi_count > 0 else 1 else: self.active_carrot = 0 + if self.autoRoadSpeedLimitOffset >= 0 and self.active_carrot>=2: + if self.nRoadLimitSpeed >= 30: + road_speed_limit_offset = self.autoRoadSpeedLimitOffset + if not self.is_metric: + road_speed_limit_offset *= CV.KPH_TO_MPH + limit_speed = self.nRoadLimitSpeed + road_speed_limit_offset + else: + limit_speed = 200 + if self.active_carrot <= 1: self.xSpdType = self.navType = self.xTurnInfo = self.xTurnInfoNext = -1 self.nSdiType = self.nSdiBlockType = self.nSdiPlusBlockType = -1 @@ -1480,7 +1616,7 @@ class CarrotServ: self.nGoPosDist = 0 self.update_nav_instruction(sm) - if self.xSpdType < 0 or self.xSpdDist <= 0: + if self.xSpdType < 0 or (self.xSpdType != 100 and self.xSpdDist <= 0) or (self.xSpdType == 100 and self.xSpdDist < -250): self.xSpdType = -1 self.xSpdDist = self.xSpdLimit = 0 if self.xTurnInfo < 0 or self.xDistToTurn < -50: @@ -1491,13 +1627,13 @@ class CarrotServ: sdi_speed = 250 hda_active = False - ### 과속카메라, 사고방지턱 - if self.xSpdDist > 0 and self.active_carrot > 0: + ### 과속카메라, 사고방지턱 + if (self.xSpdDist > 0 or self.xSpdType == 100) and self.active_carrot > 0: safe_sec = self.autoNaviSpeedBumpTime if self.xSpdType == 22 else self.autoNaviSpeedCtrlEnd decel = self.autoNaviSpeedDecelRate sdi_speed = min(sdi_speed, self.calculate_current_speed(self.xSpdDist, self.xSpdLimit, safe_sec, decel)) self.active_carrot = 5 if self.xSpdType == 22 else 3 - if self.xSpdType == 4: + if self.xSpdType == 4 or (self.xSpdType == 100 and self.xSpdDist <= 0): sdi_speed = self.xSpdLimit self.active_carrot = 4 elif CS is not None and CS.speedLimit > 0 and CS.speedLimitDistance > 0: @@ -1509,6 +1645,7 @@ class CarrotServ: #self.active_carrot = 6 hda_active = True + #print(f"sdi_speed: {sdi_speed}, hda_active: {hda_active}, xSpdType: {self.xSpdType}, xSpdDist: {self.xSpdDist}, active_carrot: {self.active_carrot}, v_ego_kph: {v_ego_kph}, nRoadLimitSpeed: {self.nRoadLimitSpeed}") ### TBT 속도제어 atc_desired, self.atcType, self.atcSpeed, self.atcDist = self.update_auto_turn(v_ego*3.6, sm, self.xTurnInfo, self.xDistToTurn, True) atc_desired_next, _, _, _ = self.update_auto_turn(v_ego*3.6, sm, self.xTurnInfoNext, self.xDistToTurnNext, False) @@ -1539,7 +1676,8 @@ class CarrotServ: speed_n_sources = [ (atc_desired, "atc"), (atc_desired_next, "atc2"), - (sdi_speed, "hda" if hda_active else "bump" if self.xSpdType == 22 else "section" if self.xSpdType == 4 else "cam"), + (sdi_speed, "hda" if hda_active else "bump" if self.xSpdType == 22 else "section" if self.xSpdType == 4 else "police" if self.xSpdType == 100 else "cam"), + (limit_speed, "road"), ] if self.turnSpeedControlMode in [1,2]: speed_n_sources.append((max(abs(vturn_speed), self.autoCurveSpeedLowerLimit), "vturn")) @@ -1557,7 +1695,7 @@ class CarrotServ: if source != self.source_last: self.gas_override_speed = 0 self.gas_pressed_state = CS.gasPressed - if CS.vEgo < 0.1 or desired_speed > 150 or source in ["cam", "section"] or CS.brakePressed: + if CS.vEgo < 0.1 or desired_speed > 150 or source in ["cam", "section", "police"] or CS.brakePressed or road_speed_limit_changed: self.gas_override_speed = 0 elif CS.gasPressed and not self.gas_pressed_state: self.gas_override_speed = max(v_ego_kph, self.gas_override_speed) @@ -1867,6 +2005,7 @@ def main(): carrot_man = CarrotMan() print(f"CarrotMan {carrot_man}") + threading.Thread(target=carrot_man.kisa_app_thread).start() while True: try: carrot_man.carrot_man_thread() diff --git a/selfdrive/carrot_settings.json b/selfdrive/carrot_settings.json index 2c83d3e..987f380 100644 --- a/selfdrive/carrot_settings.json +++ b/selfdrive/carrot_settings.json @@ -5,10 +5,10 @@ "group": "조향일반", "name": "PathOffset", "title": "차선치우침 좌우보정(0)", - "descr": "(-)좌측,(+)우측", + "descr": "LaneMode only: (-)좌측,(+)우측", "egroup": "LAT", "etitle": "PathOffset (0)", - "edescr": "(-)Left,(+)Right", + "edescr": "LaneMode only: (-)Left,(+)Right", "min": -150, "max": 150, "default": 0, @@ -21,7 +21,7 @@ "descr": "0:LiveTorque, 1:CustomTorque", "egroup": "LAT", "etitle": "_LateralTorqueCustom(0)", - "edescr": "", + "edescr": "0:LiveToruque, 1:CustomTorque", "min": 0, "max": 1, "default": 1, @@ -56,10 +56,10 @@ { "group": "조향튜닝", "name": "LateralTorqueKpV", - "title": "_LateralTorqueKpV*0.01(100)", + "title": "_LateralTorqueKp*0.01(100)", "descr": "", "egroup": "LAT", - "etitle": "_LateralTorqueKpV*0.01(100)", + "etitle": "_LateralTorqueKp*0.01(100)", "edescr": "", "min": 0, "max": 200, @@ -69,10 +69,10 @@ { "group": "조향튜닝", "name": "LateralTorqueKiV", - "title": "_LateralTorqueKiV*0.01(10)", + "title": "_LateralTorqueKi*0.01(10)", "descr": "", "egroup": "LAT", - "etitle": "_LateralTorqueKiV*0.01(10)", + "etitle": "_LateralTorqueKi*0.01(10)", "edescr": "", "min": 0, "max": 200, @@ -170,14 +170,40 @@ "default": 1, "unit": 100 }, + { + "group": "조향튜닝", + "name": "LatMpcInputOffset", + "title": "*LATMPC.InputOffset(6)", + "descr": "LaneMode Mpc입력보상, 값이 크면 일찍커브에 진입함", + "egroup": "LAT", + "etitle": "*LATMPC.InputOffset(6)", + "edescr": "LaneMode MPC input compensation: higher value, earlier curve entry", + "min": 0, + "max": 20, + "default": 1, + "unit": 1 + }, + { + "group": "조향튜닝", + "name": "LatMpcOutputOffset", + "title": "*LATMPC.OutputOffset(5)", + "descr": "LaneMode Mpc지연보상, 값이 크면??", + "egroup": "LAT", + "etitle": "*LATMPC.OutputOffset(5)", + "edescr": "", + "min": 0, + "max": 20, + "default": 1, + "unit": 1 + }, { "group": "조향튜닝", "name": "CustomSteerMax", "title": "_CustomSteerMax(0)", - "descr": "토크제어: 270,384,409", + "descr": "최대조향토크: 270,384,409", "egroup": "LAT", "etitle": "_CustomSteerMax(0)", - "edescr": "", + "edescr": "MaxSteerTorque: 270, 384, 409", "min": 0, "max": 30000, "default": 0, @@ -242,7 +268,7 @@ "descr": "목표속도를 일시적으로 올림", "egroup": "CRUISE", "etitle": "CruiseEcoControl(2km/h)", - "edescr": "", + "edescr": "Temporarily increases the target speed", "min": 0, "max": 10, "default": 2, @@ -252,7 +278,7 @@ "group": "조향튜닝", "name": "CustomSR", "title": "CustomSteerRatiox0.1(0)", - "descr": "0: LiveSteerRatio사용, 단위:0.1", + "descr": "0: LiveSteerRatio사용", "egroup": "LAT", "etitle": "CustomSteerRatiox0.1(0)", "edescr": "0: Use LiveSteerRatio", @@ -278,10 +304,10 @@ "group": "가속설정", "name": "CruiseMaxVals1", "title": "가속설정1:0km/h(160)", - "descr": "Normal mode only (x0.01m/s^2)", + "descr": "", "egroup": "ACCEL", "etitle": "AccelSet1:0km/h(160)", - "edescr": "Normal mode only (x0.01m/s^2)", + "edescr": "", "min": 1, "max": 250, "default": 160, @@ -291,10 +317,10 @@ "group": "가속설정", "name": "CruiseMaxVals2", "title": "가속설정2:40km/h(120)", - "descr": "Normal mode only (x0.01m/s^2)", + "descr": "", "egroup": "ACCEL", "etitle": "AccelSet2:40km/h(120)", - "edescr": "Normal mode only (x0.01m/s^2)", + "edescr": "", "min": 1, "max": 250, "default": 120, @@ -304,10 +330,10 @@ "group": "가속설정", "name": "CruiseMaxVals3", "title": "가속설정3:60km/h(100)", - "descr": "Normal mode only (x0.01m/s^2)", + "descr": "", "egroup": "ACCEL", "etitle": "AccelSet3:60km/h(100)", - "edescr": "Normal mode only (x0.01m/s^2)", + "edescr": "", "min": 1, "max": 250, "default": 100, @@ -317,10 +343,10 @@ "group": "가속설정", "name": "CruiseMaxVals4", "title": "가속설정4:80km/h(80)", - "descr": "Normal mode only (x0.01m/s^2)", + "descr": "", "egroup": "ACCEL", "etitle": "AccelSet4:80km/h(80)", - "edescr": "Normal mode only (x0.01m/s^2)", + "edescr": "", "min": 1, "max": 250, "default": 80, @@ -330,10 +356,10 @@ "group": "가속설정", "name": "CruiseMaxVals5", "title": "가속설정5:110km/h(70)", - "descr": "Normal mode only (x0.01m/s^2)", + "descr": "", "egroup": "ACCEL", "etitle": "AccelSet5:110km/h(70)", - "edescr": "Normal mode only (x0.01m/s^2)", + "edescr": "", "min": 1, "max": 250, "default": 70, @@ -343,10 +369,10 @@ "group": "가속설정", "name": "CruiseMaxVals6", "title": "가속설정6:140km/h(60)", - "descr": "Normal mode only (x0.01m/s^2)", + "descr": "", "egroup": "ACCEL", "etitle": "AccelSet6:140km/h(60)", - "edescr": "(x0.01m/s^2)", + "edescr": "", "min": 1, "max": 250, "default": 60, @@ -372,7 +398,7 @@ "descr": "값이 크면 전방차량의 가속도변화율에 민감하게 반응", "egroup": "LONG", "etitle": "JerkLeadFactor(0)", - "edescr": "", + "edescr": "Higher value makes more sensitive to lead jerk", "min": 0, "max": 100, "default": 0, @@ -382,10 +408,10 @@ "group": "주행튜닝", "name": "LongTuningKpV", "title": "Long KpV(100)x0.01", - "descr": "HKG: AccelPid:0, VelocityPid:100", + "descr": "Hyundai: 100으로 설정", "egroup": "LONG", "etitle": "Long KpV(100)x0.01", - "edescr": "HKG: AccelPid:0, VelocityPid:100", + "edescr": "Hyundai: 100", "min": 0, "max": 200, "default": 100, @@ -395,10 +421,10 @@ "group": "주행튜닝", "name": "LongTuningKf", "title": "Long Kf(100)x0.01", - "descr": "", + "descr": "Hyundai: 100", "egroup": "LONG", "etitle": "Long Kf(100)x0.01", - "edescr": "", + "edescr": "Hyundai: 100", "min": 0, "max": 200, "default": 0, @@ -408,10 +434,10 @@ "group": "주행튜닝", "name": "LongTuningKiV", "title": "Long KiV(0)x0.01", - "descr": "", + "descr": "Hyundai: 0", "egroup": "LONG", "etitle": "Long KiV(0)x0.01", - "edescr": "", + "edescr": "Hyundai: 0", "min": 0, "max": 2000, "default": 0, @@ -421,10 +447,10 @@ "group": "주행튜닝", "name": "LongActuatorDelay", "title": "LongActuatorDelay(20)x0.01", - "descr": "", + "descr": "Hyundai: 20", "egroup": "LONG", "etitle": "LongActuatorDelay(20)x0.01", - "edescr": "", + "edescr": "Hyundai: 20", "min": 0, "max": 200, "default": 20, @@ -437,7 +463,7 @@ "descr": "값을 올리면 늦게 출발함, 너무낮추면 추돌위험이 있을수 있음.", "egroup": "LONG", "etitle": "VEgoStopping(50)x0.01", - "edescr": "", + "edescr": "Higher value: later start; too low: collision risk", "min": 1, "max": 100, "default": 50, @@ -450,7 +476,7 @@ "descr": "값이 낮아지면 선행차량에 대한 반응이 빨라짐.", "egroup": "LONG", "etitle": "Radar reaction factor (100)%", - "edescr": "", + "edescr": "Lower value: faster response to lead car", "min": 0, "max": 200, "default": 100, @@ -489,7 +515,7 @@ "descr": "0:사용안함,1:차선변경, 2:차선변경+속도, 3:속도", "egroup": "LATSET", "etitle": "ATC: AutoTurnControl", - "edescr": "0: Not used, 1:laneChange, 2:laneChange+speed, 3:speed", + "edescr": "(TMAP)0: Not used, 1:laneChange, 2:laneChange+speed, 3:speed", "min": 0, "max": 3, "default": 0, @@ -502,7 +528,7 @@ "descr": "0:사용안함, 턴시 적용속도", "egroup": "LATSET", "etitle": "ATC: Turn Speed(20)", - "edescr": "0: Not used, Turn Speed", + "edescr": "(TMAP)0: Not used, Turn Speed", "min": 0, "max": 100, "default": 20, @@ -515,7 +541,7 @@ "descr": "NOO완료 시간거리(속도*시간)", "egroup": "LATSET", "etitle": "ATC: Speed Ctrl left Time(3)", - "edescr": "", + "edescr": "(TMAP)", "min": 0, "max": 30, "default": 6, @@ -528,7 +554,7 @@ "descr": "ATC 작동시 자동맵전환", "egroup": "LATSET", "etitle": "ATC Helper Map display(0)", - "edescr": "", + "edescr": "(TMAP)", "min": 0, "max": 1, "default": 0, @@ -538,12 +564,12 @@ "group": "버튼설정", "name": "CruiseButtonMode", "title": "크루즈버튼작동모드(0)", - "descr": "0:일반,1:사용자1,2:사용자2", + "descr": "0:일반,1:사용자1,2:사용자2,3:사용자3", "egroup": "BUTN", "etitle": "Cruise Button Mode(0)", - "edescr": "0:General,1:User1,2:User2", + "edescr": "0:General,1:User1,2:User2,3:User3", "min": 0, - "max": 2, + "max": 3, "default": 0, "unit": 1 }, @@ -612,6 +638,71 @@ "default": 10, "unit": 1 }, + { + "group": "버튼설정", + "name": "CruiseSpeed1", + "title": "크루즈속도1(30)", + "descr": "버튼모드3, 단계별속도", + "egroup": "BUTN", + "etitle": "Cruise Speed1(30)", + "edescr": "CruiseButtonMode2, prefer speed", + "min": 1, + "max": 160, + "default": 10, + "unit": 10 + }, + { + "group": "버튼설정", + "name": "CruiseSpeed2", + "title": "크루즈속도2(50)", + "descr": "버튼모드3, 단계별속도", + "egroup": "BUTN", + "etitle": "Cruise Speed2(50)", + "edescr": "CruiseButtonMode2, prefer speed", + "min": 1, + "max": 160, + "default": 10, + "unit": 10 + }, + { + "group": "버튼설정", + "name": "CruiseSpeed3", + "title": "크루즈속도3(80)", + "descr": "버튼모드3, 단계별속도", + "egroup": "BUTN", + "etitle": "Cruise Speed3(80)", + "edescr": "CruiseButtonMode2, prefer speed", + "min": 1, + "max": 160, + "default": 10, + "unit": 10 + }, + { + "group": "버튼설정", + "name": "CruiseSpeed4", + "title": "크루즈속도4(110)", + "descr": "버튼모드3, 단계별속도", + "egroup": "BUTN", + "etitle": "Cruise Speed4(110)", + "edescr": "CruiseButtonMode2, prefer speed", + "min": 1, + "max": 160, + "default": 10, + "unit": 10 + }, + { + "group": "버튼설정", + "name": "CruiseSpeed5", + "title": "크루즈속도5(130)", + "descr": "버튼모드3, 단계별속도", + "egroup": "BUTN", + "etitle": "Cruise Speed5(130)", + "edescr": "CruiseButtonMode2, prefer speed", + "min": 1, + "max": 160, + "default": 10, + "unit": 10 + }, { "group": "버튼설정", "name": "PaddleMode", @@ -632,7 +723,7 @@ "descr": "1:SOFTHOLD, Auto Cruise, 2:SoftHold오류시", "egroup": "START", "etitle": "Auto Cruise control(HKG only)", - "edescr": "Softhold, Auto Cruise ON/OFF control", + "edescr": "Softhold, Auto Cruise ON/OFF control, 2:if softhold error", "min": 0, "max": 3, "default": 0, @@ -641,11 +732,11 @@ { "group": "시작", "name": "AutoGasTokSpeed", - "title": "오토크루즈: 엑셀톡 속도", + "title": "오토크루즈: 엑셀톡 시작속도", "descr": "해당속도 이상에서만 작동함.", "egroup": "START", - "etitle": "Auto Cruise: Gas Tok speed", - "edescr": "", + "etitle": "Auto Cruise: Gas Tok enable speed", + "edescr": "Gas Tok(Gas tab): enable speed", "min": 0, "max": 200, "default": 0, @@ -707,10 +798,10 @@ "group": "시작", "name": "DisableMinSteerSpeed", "title": "저속조향제한해제", - "descr": "저속조향이 안되나, SMDPS장착차량", + "descr": "SMDPS장착차량: 1", "egroup": "START", "etitle": "DisableMinSteerSpeed", - "edescr": "", + "edescr": "smdps equiped: 1", "min": 0, "max": 1, "default": 0, @@ -788,7 +879,7 @@ "descr": "전방차량에 따라 자동속도증가. 로드스피드*비율 까지 자동속도올림.", "egroup": "CRUISE", "etitle": "AutoSpeedUpx:(100)%", - "edescr": "", + "edescr": "Automatically increases speed on lead car, up to (road speed x ratio)", "min": 0, "max": 200, "default": 0, @@ -906,7 +997,7 @@ "descr": "0:안함,1:표시함,2:상대위치,3:정지차량", "egroup": "DISP", "etitle": "Show Radar Info", - "edescr": "", + "edescr": "0:None,1:display,2:+relative pos, 3:stopped obstacle", "min": 0, "max": 3, "default": 0, @@ -919,7 +1010,7 @@ "descr": "0:안함,1:표시함", "egroup": "DISP", "etitle": "Show Route Info", - "edescr": "", + "edescr": "(TMAP)", "min": 0, "max": 1, "default": 0, @@ -932,7 +1023,7 @@ "descr": "0:일반,1,2:사각,3,4:^^,5,6:사각,7,8:^^,9,10,11:smooth^^,12:smooth2^^,13:3줄,14:2줄,15:1줄", "egroup": "DISP", "etitle": "Show Path Mode:LaneLess(9)", - "edescr": "", + "edescr": "0:stock,1,2:REC,3,4:^^,5,6:REC,7,8:^^,9,10,11:smooth^^,12:smooth2^^,13:3lines,14:2lines,15:1lines", "min": 0, "max": 15, "default": 9, @@ -945,7 +1036,7 @@ "descr": "(+10:띠)0:빨,1:주,2:노,3:초,4:파,5:남,6:보,7:고,8:흰,9:검", "egroup": "DISP", "etitle": "Show Path Color:LaneLess(12)", - "edescr": "", + "edescr": "(+10:stroke)0(R),1(O),2(Y),3(B),5(N),6(V),7(K),8(W),9(B)", "min": 0, "max": 19, "default": 12, @@ -958,7 +1049,7 @@ "descr": "0:일반,1,2:사각,3,4:^^,5,6:사각,7,8:^^,9,10,11:smooth^^,12:smooth2^^,13:3줄,14:2줄,15:1줄", "egroup": "DISP", "etitle": "Show Path Mode:CruiseOFF(9)", - "edescr": "", + "edescr": "0:stock,1,2:REC,3,4:^^,5,6:REC,7,8:^^,9,10,11:smooth^^,12:smooth2^^,13:3lines,14:2lines,15:1lines", "min": 0, "max": 15, "default": 9, @@ -971,7 +1062,7 @@ "descr": "(+10:띠)0:빨,1:주,2:노,3:초,4:파,5:남,6:보,7:고,8:흰,9:검", "egroup": "DISP", "etitle": "Show Path Color:CruiseOFF(1)", - "edescr": "", + "edescr": "(+10:stroke)0(R),1(O),2(Y),3(B),5(N),6(V),7(K),8(W),9(B)", "min": 0, "max": 19, "default": 1, @@ -984,7 +1075,7 @@ "descr": "0:일반,1,2:사각,3,4:^^,5,6:사각,7,8:^^,9,10,11:smooth^^,12:smooth2^^,13:3줄,14:2줄,15:1줄", "egroup": "DISP", "etitle": "Show Path Mode:LaneMode(11)", - "edescr": "", + "edescr": "0:stock,1,2:REC,3,4:^^,5,6:REC,7,8:^^,9,10,11:smooth^^,12:smooth2^^,13:3lines,14:2lines,15:1lines", "min": 0, "max": 15, "default": 11, @@ -997,7 +1088,7 @@ "descr": "(+10:띠)0:빨,1:주,2:노,3:초,4:파,5:남,6:보,7:고,8:흰,9:검", "egroup": "DISP", "etitle": "Show Path Color:LaneMode(3)", - "edescr": "", + "edescr": "(+10:stroke)0(R),1(O),2(Y),3(B),5(N),6(V),7(K),8(W),9(B)", "min": 0, "max": 19, "default": 3, @@ -1023,7 +1114,7 @@ "descr": "레인(차선)모드 사용하면 기존의 조향제어(lat_mpc)를 사용합니다.", "egroup": "LAT", "etitle": "Laneline: Speed(0)", - "edescr": "Lainline mode, lat_mpc control used", + "edescr": "Lainline mode speed, lat_mpc control used", "min": 0, "max": 200, "default": 0, @@ -1062,12 +1153,25 @@ "descr": "0: 즉시 차선변경, 1: 토크필요, -1:자동차선변경사용안함", "egroup": "LAT", "etitle": "LaneChange use steering torque", - "edescr": "1: need torque", + "edescr": "0:immediate, 1: need torque(nudge), -1: auto lane change off", "min": -1, "max": 1, "default": 0, "unit": 1 }, + { + "group": "조향일반", + "name": "LaneChangeDelay", + "title": "차선변경 지연x0.1s(0)", + "descr": "", + "egroup": "LAT", + "etitle": "LaneChange delayx0.1s(0)", + "edescr": "", + "min": 0, + "max": 100, + "default": 0, + "unit": 10 + }, { "group": "조향일반", "name": "LaneChangeBsd", @@ -1100,7 +1204,7 @@ "title": "MaxAngleFrames(89)", "descr": "89:기본값", "egroup": "START", - "etitle": "MaxAngleFrames(1)", + "etitle": "MaxAngleFrames(89)", "edescr": "", "min": 80, "max": 100, @@ -1127,7 +1231,7 @@ "descr": "1: HDA2 강제인식, 2: HDA2+BSM", "egroup": "START", "etitle": "CANFD HDA2(0)", - "edescr": "", + "edescr": "0:HDA1, 1: HDA2, 2: HDA2+BSM", "min": 0, "max": 2, "default": 0, @@ -1361,7 +1465,7 @@ "descr": "감속종료시점을 설정합니다.", "egroup": "SPEED", "etitle": "NaviSpeedEndingPoint(6s)", - "edescr": "Deceleration completion point", + "edescr": "Time until decel completes, based on speed x time", "min": 3, "max": 20, "default": 6, @@ -1374,12 +1478,25 @@ "descr": "0:감속안함,1:과속카메라,2:+사고방지턱,3:+이동식카메라", "egroup": "SPEED", "etitle": "NaviSpeedControlMode(2)", - "edescr": "", + "edescr": "0:Not used, 1:Speed cam, 2:+speed bump, 3:+mobile speed cam", "min": 0, "max": 3, "default": 2, "unit": 1 }, + { + "group": "감속제어", + "name": "AutoRoadSpeedLimitOffset", + "title": "도로제한속도맞춤(-1)", + "descr": "-1:안함, 도로제한속도 + 설정값", + "egroup": "SPEED", + "etitle": "RoadSpeedLimitOffset(-1)", + "edescr": "-1:NotUsed, RoadLimitSpeed+Offset", + "min": -1, + "max": 100, + "default": -1, + "unit": 1 + }, { "group": "감속제어", "name": "AutoNaviSpeedBumpTime", @@ -1413,7 +1530,7 @@ "descr": "낮으면 멀리서부터 감속함", "egroup": "SPEED", "etitle": "NaviSpeedDecelRate 0.01m/s^2x(200)", - "edescr": "", + "edescr": "Lower value deceleration starts earlier", "min": 50, "max": 300, "default": 200, @@ -1426,7 +1543,7 @@ "descr": "0: 알림없음, 1: 턴지점+속도, 2: 턴지점+속도+방지턱", "egroup": "SPEED", "etitle": "NaviCountDownMode", - "edescr": "", + "edescr": "0:not used, 1: turn point + speed, 2:+speed bump", "min": 0, "max": 2, "default": 2, @@ -1439,7 +1556,7 @@ "descr": "0: 속도제어안함,1:비젼,2:비젼+경로(TBT),3:경로(항상)", "egroup": "SPEED", "etitle": "TurnSpeedControlMode", - "edescr": "", + "edescr": "0:not used, 1:vision turn, 2:+route, 3:route(allways)", "min": 0, "max": 3, "default": 1, @@ -1452,7 +1569,7 @@ "descr": "작으면 속도가 줄어듬", "egroup": "SPEED", "etitle": "MapTurnSpeedFactor", - "edescr": "", + "edescr": "lower value, slower speed", "min": 50, "max": 300, "default": 100, @@ -1465,7 +1582,7 @@ "descr": "", "egroup": "SPEED", "etitle": "NaviSpeedLimitRatio(105)%", - "edescr": "", + "edescr": "speed(roadlimitspeed) apply ratio", "min": 80, "max": 120, "default": 105, diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 509371f..f5ab18c 100644 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -136,7 +136,7 @@ class Controls: curve_speed_abs > self.params.get_int("UseLaneLineCurveSpeed")) lat_smooth_seconds = LAT_SMOOTH_SECONDS #self.params.get_float("SteerSmoothSec") * 0.01 steer_actuator_delay = self.params.get_float("SteerActuatorDelay") * 0.01 - mpc_delay_offset = 0.05 + mpc_output_offset = self.params.get_float("LatMpcOutputOffset") * 0.01 # 0.05 if steer_actuator_delay == 0.0: steer_actuator_delay = self.sm['liveDelay'].lateralDelay @@ -156,7 +156,7 @@ class Controls: alpha = 1 - np.exp(-DT_CTRL / tau) if tau > 0 else 1 return alpha * val + (1 - alpha) * prev_val - curvature = get_lag_adjusted_curvature(self.CP, CS.vEgo, lat_plan.psis, lat_plan.curvatures, steer_actuator_delay + lat_smooth_seconds + mpc_delay_offset, lat_plan.distances) + curvature = get_lag_adjusted_curvature(self.CP, CS.vEgo, lat_plan.psis, lat_plan.curvatures, steer_actuator_delay + lat_smooth_seconds + mpc_output_offset, lat_plan.distances) new_desired_curvature = smooth_value(curvature, self.desired_curvature, lat_smooth_seconds) else: @@ -195,6 +195,13 @@ class Controls: if len(angular_rate_value) > 2: CC.angularVelocity = angular_rate_value + acceleration_value = list(self.sm['liveLocationKalman'].accelerationCalibrated.value) + if len(acceleration_value) > 2: + if abs(acceleration_value[0]) > 16.0: + print("Collision detected. disable openpilot, restart") + self.params.put_bool("OpenpilotEnabledToggle", False) + self.params.put_int("SoftRestartTriggered", 1) + CC.cruiseControl.override = CC.enabled and not CC.longActive and self.CP.openpilotLongitudinalControl CC.cruiseControl.cancel = CS.cruiseState.enabled and (not CC.enabled or not self.CP.pcmCruise) diff --git a/selfdrive/controls/lib/desire_helper.py b/selfdrive/controls/lib/desire_helper.py index 6cd7e52..5ef56e7 100644 --- a/selfdrive/controls/lib/desire_helper.py +++ b/selfdrive/controls/lib/desire_helper.py @@ -125,10 +125,12 @@ class DesireHelper: self.lane_available_last = False self.edge_available_last = False - self.object_detected_count = 0 + self.object_detected_count = 0 self.laneChangeNeedTorque = 0 self.laneChangeBsd = 0 + self.laneChangeDelay = 0 + self.lane_change_delay = 0.0 self.driver_blinker_state = BLINKER_NONE self.atc_type = "" @@ -172,9 +174,11 @@ class DesireHelper: if self.frame % 100 == 0: self.laneChangeNeedTorque = self.params.get_int("LaneChangeNeedTorque") self.laneChangeBsd = self.params.get_int("LaneChangeBsd") + self.laneChangeDelay = self.params.get_float("LaneChangeDelay") * 0.1 self.frame += 1 self.carrot_lane_change_count = max(0, self.carrot_lane_change_count - 1) + self.lane_change_delay = max(0, self.lane_change_delay - DT_MDL) v_ego = carstate.vEgo below_lane_change_speed = v_ego < LANE_CHANGE_SPEED_MIN @@ -290,6 +294,7 @@ class DesireHelper: if self.lane_change_state == LaneChangeState.off and desire_enabled and not self.prev_desire_enabled and not below_lane_change_speed: self.lane_change_state = LaneChangeState.preLaneChange self.lane_change_ll_prob = 1.0 + self.lane_change_delay = self.laneChangeDelay # LaneChangeState.preLaneChange elif self.lane_change_state == LaneChangeState.preLaneChange: @@ -314,7 +319,7 @@ class DesireHelper: self.lane_change_state = LaneChangeState.off self.lane_change_direction = LaneChangeDirection.none else: - if lane_available: + if lane_available and self.lane_change_delay == 0: if self.blindspot_detected_counter > 0 and not ignore_bsd: # BSD검출시 if torque_applied and not block_lanechange_bsd: self.lane_change_state = LaneChangeState.laneChangeStarting diff --git a/selfdrive/controls/lib/drive_helpers.py b/selfdrive/controls/lib/drive_helpers.py index 25c5c9b..8b6a428 100644 --- a/selfdrive/controls/lib/drive_helpers.py +++ b/selfdrive/controls/lib/drive_helpers.py @@ -47,15 +47,19 @@ def get_lag_adjusted_curvature(CP, v_ego, psis, curvatures, steer_actuator_delay distance = max(np.interp(delay, ModelConstants.T_IDXS[:CONTROL_N], distances), 0.001) #average_curvature_desired = psi / (v_ego * delay) + + # curve -> straight or reverse curve + if abs(current_curvature_desired) > 0.002 and \ + (abs(future_curvature_desired) < 0.001 or np.sign(current_curvature_desired) != np.sign(future_curvature_desired)): + psis_damping = 0.2 + else: + psis_damping = 1.0 + psi *= psis_damping + + average_curvature_desired = psi / distance desired_curvature = 2 * average_curvature_desired - current_curvature_desired - #curv_now = np.mean([abs(c) for c in curvatures[0:3]]) - #curv_future = np.mean([abs(c) for c in curvatures[9:13]]) - if (abs(current_curvature_desired) - abs(future_curvature_desired)) > 0.002 and abs(future_curvature_desired) < 0.001: - desired_curvature = delayed_curvature_desired - - # This is the "desired rate of the setpoint" not an actual desired rate max_curvature_rate = MAX_LATERAL_JERK / (v_ego**2) # inexact calculation, check https://github.com/commaai/openpilot/pull/24755 safe_desired_curvature = np.clip(desired_curvature, diff --git a/selfdrive/controls/lib/lane_planner_2.py b/selfdrive/controls/lib/lane_planner_2.py index 94af1b8..27da0b4 100644 --- a/selfdrive/controls/lib/lane_planner_2.py +++ b/selfdrive/controls/lib/lane_planner_2.py @@ -230,7 +230,7 @@ class LanePlanner: # self.d_prob, self.lanefull_mode, # self.lane_width_left_filtered.x, self.lane_width, self.lane_width_right_filtered.x) - adjustLaneTime = 0.06 #self.params.get_int("AdjustLaneTime") * 0.01 + adjustLaneTime = self.params.get_float("LatMpcInputOffset") * 0.01 # 0.06 laneline_active = False self.d_prob_count = self.d_prob_count + 1 if self.d_prob > 0.3 else 0 if self.lanefull_mode and self.d_prob_count > int(1 / DT_MDL): diff --git a/selfdrive/ui/carrot.cc b/selfdrive/ui/carrot.cc index a71167a..f9ed1f3 100644 --- a/selfdrive/ui/carrot.cc +++ b/selfdrive/ui/carrot.cc @@ -1024,13 +1024,13 @@ protected: nvgCircle(s->vg, bx, by, 110 / 2 * scale); nvgFillColor(s->vg, COLOR_WHITE); nvgFill(s->vg); - sprintf(str, "%d", xSpdLimit); + sprintf(str, "%d", (int)(xSpdLimit * ((s->scene.is_metric)?1:KM_TO_MILE) + 0.5)); ui_draw_text(s, bx, by + 25 * scale - 6 * (1 - scale), str, 60 * scale, COLOR_BLACK, BOLD, 0.0f, 0.0f); } } } - void drawTurnInfoHud(const UIState* s) { - if (s->fb_w < 1200) return; + int drawTurnInfoHud(const UIState* s) { + if (s->fb_w < 1200) return -1; #ifdef __UI_TEST active_carrot = 2; nGoPosDist = 500000; @@ -1054,7 +1054,7 @@ protected: ui_fill_rect(s->vg, { tbt_x, 5, 790, s->fb_h - 15 }, COLOR_BLACK_ALPHA(120), 30, 2, &stroke_color); } if (nGoPosDist > 0 && nGoPosTime > 0); - else return; + else return -1; if (s->scene._current_carrot_display == 3); else { ui_fill_rect(s->vg, { tbt_x, tbt_y - 60, 790, 240 + 60 }, COLOR_BLACK_ALPHA(120), 30, 2, &stroke_color); @@ -1116,14 +1116,15 @@ protected: sprintf(str, "%.1fkm", nGoPosDist / 1000.); ui_draw_text(s, tbt_x + 190 + 120, tbt_y + 130, str, 50, COLOR_WHITE, BOLD); } + return 0; } public: - void draw(const UIState* s) { + int draw(const UIState* s) { nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BOTTOM); SubMaster& sm = *(s->sm); if (!sm.alive("modelV2") || !sm.alive("carrotMan") || !sm.alive("carState")) { active_carrot = -1; - return; + return -1; } const auto carrot_man = sm["carrotMan"].getCarrotMan(); @@ -1172,7 +1173,7 @@ public: #endif drawTurnInfo(s); drawSpeedLimit(s); - drawTurnInfoHud(s); + return drawTurnInfoHud(s); } }; @@ -1607,7 +1608,7 @@ public: if (!make_data(s)) return; int temp = params.getInt("UseLaneLineSpeedApply"); if (temp != use_lane_line_speed_apply) { - ui_draw_text_a(s, 0, 0, (temp>0)?"LaneMode":"Laneless", 30, COLOR_GREEN, BOLD); + ui_draw_text_a(s, 0, 0, (temp>0)?"LaneMode":"Laneless", 30, (temp>0)?COLOR_GREEN:COLOR_YELLOW, BOLD); use_lane_line_speed_apply = temp; } static bool forward = true; @@ -2104,13 +2105,16 @@ public: int gap_last = 0; char gear_str_last[32] = ""; int blink_timer = 0; + int disp_timer = 0; float cpuTemp = 0.0f; float cpuUsage = 0.0f; int memoryUsage = 0; float freeSpace = 0.0f; + float voltage = 0.0f; void drawHud(UIState* s) { int show_device_state = params.getInt("ShowDeviceState"); blink_timer = (blink_timer + 1) % 16; + disp_timer = (disp_timer + 1) % 64; nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BOTTOM); int x = 140;// 120; @@ -2161,7 +2165,7 @@ public: char cruise_speed[32]; int cruise_x = bx + 170; int cruise_y = by + 15; - if(longActive) sprintf(cruise_speed, "%.0f", (s->scene.is_metric)?v_cruise: v_cruise * KM_TO_MILE); + if(longActive) sprintf(cruise_speed, "%d", (int)((s->scene.is_metric)?v_cruise: v_cruise * KM_TO_MILE + 0.5)); else sprintf(cruise_speed, "--"); if (strcmp(cruise_speed_last, cruise_speed) != 0) { strcpy(cruise_speed_last, cruise_speed); @@ -2178,13 +2182,13 @@ public: int apply_y = by - 50; if (apply_source.length()) { - sprintf(apply_speed_str, "%.0f", (s->scene.is_metric)?apply_speed:apply_speed * KM_TO_MILE); + sprintf(apply_speed_str, "%d", (int)((s->scene.is_metric)?apply_speed:apply_speed * KM_TO_MILE + 0.5)); textColor = COLOR_OCHRE; // apply speed가 작동되면... 색을 바꾸자. ui_draw_text(s, apply_x, apply_y, apply_speed_str, 50, textColor, BOLD, 1.0, 5.0, COLOR_BLACK, COLOR_BLACK); ui_draw_text(s, apply_x, apply_y - 50, apply_source.toStdString().c_str(), 30, textColor, BOLD, 1.0, 5.0, COLOR_BLACK, COLOR_BLACK); } else if(abs(cruiseTarget - v_cruise) > 0.5) { - sprintf(apply_speed_str, "%.0f", (s->scene.is_metric)?cruiseTarget: cruiseTarget * KM_TO_MILE); + sprintf(apply_speed_str, "%d", (int)((s->scene.is_metric)?cruiseTarget: cruiseTarget * KM_TO_MILE + 0.5)); ui_draw_text(s, apply_x, apply_y, apply_speed_str, 50, textColor, BOLD, 1.0, 5.0, COLOR_BLACK, COLOR_BLACK); ui_draw_text(s, apply_x, apply_y - 50, "eco", 30, textColor, BOLD, 1.0, 5.0, COLOR_BLACK, COLOR_BLACK); } @@ -2295,13 +2299,14 @@ public: int disp_speed = 0; NVGcolor limit_color = COLOR_GREEN_ALPHA(210); if (xSpdLimit > 0 && xSignType != 22) { - disp_speed = xSpdLimit; + disp_speed = (int)(xSpdLimit * ((s->scene.is_metric)?1:KM_TO_MILE) + 0.5); limit_color = (blink_timer <= 8) ? COLOR_RED_ALPHA(210) : COLOR_YELLOW_ALPHA(210); ui_draw_text(s, dx, dy-45, "CAM", 30, COLOR_WHITE, BOLD); } else { disp_speed = nRoadLimitSpeed; - limit_color = (v_ego * 3.6 > nRoadLimitSpeed + 2) ? COLOR_RED_ALPHA(210) : COLOR_WHITE_ALPHA(210); + disp_speed = (int)(disp_speed * ((s->scene.is_metric)?1.0:KM_TO_MILE) + 0.5); + limit_color = (v_ego * 3.6 > disp_speed + 2) ? COLOR_RED_ALPHA(210) : COLOR_WHITE_ALPHA(210); ui_draw_text(s, dx, dy - 45, "LIMIT", 30, COLOR_WHITE, BOLD); } @@ -2326,10 +2331,18 @@ public: ui_draw_text(s, dx, dy + 40, str, 40, COLOR_WHITE, BOLD); dx += 150; - ui_fill_rect(s->vg, { dx - 65, dy - 38, 130, 90 }, mode_color, 15, 2); - ui_draw_text(s, dx, dy-5, "DISK", 25, COLOR_WHITE, BOLD); - sprintf(str, "%.0f%%", 100 - freeSpace); - ui_draw_text(s, dx, dy + 40, str, 40, COLOR_WHITE, BOLD); + if (disp_timer < 32) { + ui_fill_rect(s->vg, { dx - 65, dy - 38, 130, 90 }, mode_color, 15, 2); + ui_draw_text(s, dx, dy - 5, "DISK", 25, COLOR_WHITE, BOLD); + sprintf(str, "%.0f%%", 100 - freeSpace); + ui_draw_text(s, dx, dy + 40, str, 40, COLOR_WHITE, BOLD); + } + else { + ui_fill_rect(s->vg, { dx - 65, dy - 38, 130, 90 }, mode_color, 15, 2); + ui_draw_text(s, dx, dy - 5, "VOLT", 25, COLOR_WHITE, BOLD); + sprintf(str, "%.1fV", voltage); + ui_draw_text(s, dx, dy + 40, str, 40, COLOR_WHITE, BOLD); + } } } void drawDateTime(const UIState* s) { @@ -2446,6 +2459,27 @@ public: ui_draw_text(s, bx - dw, by + 70, get_tpms_text(rl), 40, get_tpms_color(rl), BOLD); ui_draw_text(s, bx + dw, by + 70, get_tpms_text(rr), 40, get_tpms_color(rr), BOLD); } + void drawTpms3(const UIState* s) { + nvgTextAlign(s->vg, NVG_ALIGN_CENTER | NVG_ALIGN_BOTTOM); + SubMaster& sm = *(s->sm); + auto car_state = sm["carState"].getCarState(); + + int bx = s->fb_w - 125; + int by = s->fb_h - 280 / 2 + 15; + auto tpms = car_state.getTpms(); + float fl = tpms.getFl(); + float fr = tpms.getFr(); + float rl = tpms.getRl(); + float rr = tpms.getRr(); +#ifdef __UI_TEST + fl = fr = rl = rr = 29; +#endif + int dw = 80; + ui_draw_text(s, bx - dw, by - 55, get_tpms_text(fl), 40, get_tpms_color(fl), BOLD); + ui_draw_text(s, bx + dw, by - 55, get_tpms_text(fr), 40, get_tpms_color(fr), BOLD); + ui_draw_text(s, bx - dw, by + 70, get_tpms_text(rl), 40, get_tpms_color(rl), BOLD); + ui_draw_text(s, bx + dw, by + 70, get_tpms_text(rr), 40, get_tpms_color(rr), BOLD); + } void makeDeviceInfo(const UIState* s) { SubMaster& sm = *(s->sm); auto deviceState = sm["deviceState"].getDeviceState(); @@ -2469,6 +2503,9 @@ public: } if (cpu_size > 0) cpuUsage /= cpu_size; } + + auto peripheralState = sm["peripheralState"].getPeripheralState(); + voltage = peripheralState.getVoltage() / 1000.0; } void drawDeviceInfo(const UIState* s) { #ifdef WSL2 @@ -2642,7 +2679,11 @@ void ui_draw(UIState *s, ModelRenderer* model_renderer, int w, int h) { drawCarrot.drawDeviceInfo(s); drawCarrot.drawTpms2(s); - drawTurnInfo.draw(s); + int draw_turn_info = drawTurnInfo.draw(s); + + if (draw_turn_info < 0) { + drawCarrot.drawTpms3(s); + } ui_draw_text_a2(s); diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index 9320afd..f264264 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -696,6 +696,7 @@ CarrotPanel::CarrotPanel(QWidget* parent) : QWidget(parent) { //latLongToggles->addItem(new CValueControl("StartAccelApply", "LONG: StartingAccel 2.0x(0)%", "정지->출발시 가속도의 가속율을 지정합니다 0: 사용안함.", "../assets/offroad/icon_road.png", 0, 100, 10)); //latLongToggles->addItem(new CValueControl("StopAccelApply", "LONG: StoppingAccel -2.0x(0)%", "정지유지시 브레이크압을 조정합니다. 0: 사용안함. ", "../assets/offroad/icon_road.png", 0, 100, 10)); latLongToggles->addItem(new CValueControl("LaneChangeNeedTorque", "LaneChange need torque", "-1:Disable lanechange, 0: no need torque, 1:need torque", "../assets/offroad/icon_logic.png", -1, 1, 1)); + latLongToggles->addItem(new CValueControl("LaneChangeDelay", "LaneChange delay", "x0.1sec", "../assets/offroad/icon_logic.png", 0, 100, 5)); latLongToggles->addItem(new CValueControl("LaneChangeBsd", "LaneChange Bsd", "-1:ignore bsd, 0:BSD detect, 1: block steer torque", "../assets/offroad/icon_logic.png", -1, 1, 1)); latLongToggles->addItem(new CValueControl("StoppingAccel", "LONG: StoppingStartAccelx0.01(-40)", "", "../assets/offroad/icon_logic.png", -100, 0, 5)); latLongToggles->addItem(new CValueControl("StopDistanceCarrot", "LONG: StopDistance (600)cm", "", "../assets/offroad/icon_logic.png", 300, 1000, 10)); @@ -836,6 +837,7 @@ CarrotPanel::CarrotPanel(QWidget* parent) : QWidget(parent) { speedToggles->addItem(new CValueControl("AutoNaviSpeedSafetyFactor", "SpeedCameraSafetyFactor(105%)", "", "../assets/offroad/icon_road.png", 80, 120, 1)); speedToggles->addItem(new CValueControl("AutoNaviSpeedBumpTime", "SpeedBumpTimeDistance(1s)", "", "../assets/offroad/icon_road.png", 1, 50, 1)); speedToggles->addItem(new CValueControl("AutoNaviSpeedBumpSpeed", "SpeedBumpSpeed(35Km/h)", "", "../assets/offroad/icon_road.png", 10, 100, 5)); + speedToggles->addItem(new CValueControl("AutoRoadSpeedLimitOffset", "RoadSpeedLimitOffset(-1)", "-1:NotUsed,RoadLimitSpeed+Offset", "../assets/offroad/icon_road.png", -1, 100, 1)); speedToggles->addItem(new CValueControl("AutoNaviCountDownMode", "NaviCountDown mode(2)", "0: off, 1:tbt+camera, 2:tbt+camera+bump", "../assets/offroad/icon_road.png", 0, 2, 1)); speedToggles->addItem(new CValueControl("TurnSpeedControlMode", "Turn Speed control mode(1)", "0: off, 1:vision, 2:vision+route, 3: route", "../assets/offroad/icon_road.png", 0, 3, 1)); speedToggles->addItem(new CValueControl("MapTurnSpeedFactor", "Map TurnSpeed Factor(100)", "", "../assets/offroad/icon_map.png", 50, 300, 5)); diff --git a/selfdrive/ui/ui.cc b/selfdrive/ui/ui.cc index 9e6e0e6..34913a5 100644 --- a/selfdrive/ui/ui.cc +++ b/selfdrive/ui/ui.cc @@ -105,6 +105,7 @@ UIState::UIState(QObject *parent) : QObject(parent) { "longitudinalPlan", "carControl", "carrotMan", "liveTorqueParameters", "lateralPlan", "liveParameters", "navRoute", "navInstruction", "navInstructionCarrot", "liveLocationKalman", "liveDelay", + "peripheralState", }); prime_state = new PrimeState(this); language = QString::fromStdString(Params().get("LanguageSetting")); diff --git a/system/manager/manager.py b/system/manager/manager.py index cf2e0df..8be7010 100755 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -79,6 +79,7 @@ def get_default_params(): ("AutoNaviSpeedBumpSpeed", "35"), ("AutoNaviSpeedSafetyFactor", "105"), ("AutoNaviSpeedDecelRate", "120"), + ("AutoRoadSpeedLimitOffset", "-1"), ("AutoNaviCountDownMode", "2"), ("TurnSpeedControlMode", "1"), ("MapTurnSpeedFactor", "90"), @@ -91,6 +92,11 @@ def get_default_params(): ("CruiseButtonTest2", "30"), ("CruiseButtonTest3", "1"), ("CruiseSpeedUnit", "10"), + ("CruiseSpeed1", "30"), + ("CruiseSpeed2", "50"), + ("CruiseSpeed3", "80"), + ("CruiseSpeed4", "110"), + ("CruiseSpeed5", "130"), ("PaddleMode", "0"), ("MyDrivingMode", "3"), ("MyDrivingModeAuto", "0"), @@ -126,6 +132,7 @@ def get_default_params(): ("UseLaneLineSpeedApply", "0"), ("AdjustLaneOffset", "0"), ("LaneChangeNeedTorque", "0"), + ("LaneChangeDelay", "0"), ("LaneChangeBsd", "0"), ("MaxAngleFrames", "89"), ("LateralTorqueCustom", "0"), @@ -140,6 +147,8 @@ def get_default_params(): ("LatMpcAccelCost", "0"), ("LatMpcJerkCost", "4"), ("LatMpcSteeringRateCost", "700"), + ("LatMpcInputOffset", "6"), + ("LatMpcOutputOffset", "5"), ("CustomSteerMax", "0"), ("CustomSteerDeltaUp", "0"), ("CustomSteerDeltaDown", "0"),