From ba63eb73df5382a9d41092e97a48992aedae9eef Mon Sep 17 00:00:00 2001 From: ajouatom Date: Mon, 10 Feb 2025 16:07:28 +0900 Subject: [PATCH] nnff sound, pathOffset, latTune and etc (kans pr) --- cereal/log.capnp | 1 + common/params.cc | 10 ++-- opendbc_repo/opendbc/car/gm/carcontroller.py | 11 ++-- opendbc_repo/opendbc/car/gm/carstate.py | 5 +- opendbc_repo/opendbc/car/gm/interface.py | 6 +-- panda/board/safety/safety_gm.h | 8 +-- selfdrive/assets/sounds/nnff.wav | Bin 0 -> 98454 bytes selfdrive/car/cruise.py | 7 ++- selfdrive/carrot_settings.json | 52 +++++++++++++++++++ selfdrive/controls/lib/latcontrol_torque.py | 6 +++ selfdrive/controls/lib/lateral_planner.py | 4 +- selfdrive/selfdrived/events.py | 24 +++++++-- selfdrive/selfdrived/selfdrived.py | 3 +- selfdrive/ui/qt/offroad/settings.cc | 29 ++++++++++- selfdrive/ui/qt/offroad/settings.h | 2 + system/manager/manager.py | 4 ++ 16 files changed, 141 insertions(+), 31 deletions(-) create mode 100644 selfdrive/assets/sounds/nnff.wav diff --git a/cereal/log.capnp b/cereal/log.capnp index 2685758..091f7cb 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -149,6 +149,7 @@ struct OnroadEvent @0xc4fa6047f024e718 { audio10 @113; audio0 @114; + torqueNNLoad @115; soundsUnavailableDEPRECATED @47; } diff --git a/common/params.cc b/common/params.cc index b1bd9d8..ecefe31 100644 --- a/common/params.cc +++ b/common/params.cc @@ -310,16 +310,20 @@ std::unordered_map keys = { {"MaxAngleFrames", PERSISTENT}, {"SoftHoldMode", PERSISTENT}, {"CarrotLatControl", PERSISTENT}, - {"LatMpcPathCost", PERSISTENT }, - {"LatMpcMotionCost", PERSISTENT }, - {"LatMpcMotionCost2", PERSISTENT }, + {"LatMpcPathCost", PERSISTENT}, + {"LatMpcMotionCost", PERSISTENT}, + {"LatMpcMotionCost2", PERSISTENT}, {"LatMpcAccelCost", PERSISTENT}, {"LatMpcJerkCost", PERSISTENT}, {"LatMpcSteeringRateCost", PERSISTENT}, {"DampingFactor", PERSISTENT}, + {"PathOffset", PERSISTENT}, {"LateralTorqueCustom", PERSISTENT}, {"LateralTorqueAccelFactor", PERSISTENT}, {"LateralTorqueFriction", PERSISTENT}, + {"LateralTorqueKpV", PERSISTENT}, + {"LateralTorqueKiV", PERSISTENT}, + {"LateralTorqueKf", PERSISTENT}, {"LateralTorqueKd", PERSISTENT}, {"CustomSteerMax", PERSISTENT}, {"CustomSteerDeltaUp", PERSISTENT}, diff --git a/opendbc_repo/opendbc/car/gm/carcontroller.py b/opendbc_repo/opendbc/car/gm/carcontroller.py index fac0276..7ebe030 100644 --- a/opendbc_repo/opendbc/car/gm/carcontroller.py +++ b/opendbc_repo/opendbc/car/gm/carcontroller.py @@ -56,7 +56,6 @@ class CarController(CarControllerBase): self.accel_g = 0.0 # GM: AutoResume self.activateCruise_after_brake = False - self.pressed_decel_button = False # Auto Cruise @staticmethod def calc_pedal_command(accel: float, long_active: bool, car_velocity) -> tuple[float, bool]: @@ -155,15 +154,14 @@ class CarController(CarControllerBase): brake_force = -0.5 #롱컨캔슬을 위한 브레이크값(0.0 이하) apply_brake = self.brake_input(brake_force) # 브레이크신호 전송(롱컨 꺼짐) - can_sends.append(gmcan.create_brake_command(self.packer_pt, CanBus.POWERTRAIN, apply_brake, idx)) + can_sends.append(gmcan.create_brake_command(self.packer_ch, CanBus.CHASSIS, apply_brake, idx)) Params().put_bool_nonblocking("ActivateCruiseAfterBrake", True) # cruise.py에 브레이크 ON신호 전달 self.activateCruise_after_brake = True # 브레이크신호는 한번만 보내고 초기화 else: if CS.out.activateCruise and not CS.out.cruiseState.enabled: - if (self.frame - self.last_button_frame) * DT_CTRL > 0.04 and not self.pressed_decel_button: # 25Hz(40ms 버튼주기) - can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, (CS.buttons_counter + 1) % 4, CruiseButtons.DECEL_SET)) + if (self.frame - self.last_button_frame) * DT_CTRL > 0.04: self.last_button_frame = self.frame - self.pressed_decel_button = True # 버튼신호는 한번만 보내고 초기화 + can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, button_counter, CruiseButtons.DECEL_SET)) # Gas/regen, brakes, and UI commands - all at 25Hz if self.frame % 4 == 0: @@ -247,8 +245,7 @@ class CarController(CarControllerBase): if actuators.longControlState in [LongCtrlState.stopping, LongCtrlState.starting]: if (self.frame - self.last_button_frame) * DT_CTRL > 0.2: self.last_button_frame = self.frame - for i in range(12): - can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, CS.buttons_counter, CruiseButtons.RES_ACCEL)) + can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, CS.buttons_counter, CruiseButtons.RES_ACCEL)) # GasRegenCmdActive needs to be 1 to avoid cruise faults. It describes the ACC state, not actuation can_sends.append(gmcan.create_gas_regen_command(self.packer_pt, CanBus.POWERTRAIN, self.apply_gas, idx, acc_engaged, at_full_stop)) can_sends.append(gmcan.create_friction_brake_command(self.packer_ch, friction_brake_bus, self.apply_brake, diff --git a/opendbc_repo/opendbc/car/gm/carstate.py b/opendbc_repo/opendbc/car/gm/carstate.py index 1b6ba08..60a0624 100644 --- a/opendbc_repo/opendbc/car/gm/carstate.py +++ b/opendbc_repo/opendbc/car/gm/carstate.py @@ -116,7 +116,7 @@ class CarState(CarStateBase): # that the brake is being intermittently pressed without user interaction. # To avoid a cruise fault we need to use a conservative brake position threshold # https://static.nhtsa.gov/odi/tsbs/2017/MC-10137629-9999.pdf - ret.brakePressed = ret.brake >= 8 + ret.brakePressed = ret.brake >= 10 # Regen braking is braking if self.CP.transmissionType == TransmissionType.direct: @@ -194,7 +194,7 @@ class CarState(CarStateBase): ret.accFaulted = False ret.cruiseState.speed = pt_cp.vl["ECMCruiseControl"]["CruiseSetSpeed"] * CV.KPH_TO_MS ret.cruiseState.enabled = pt_cp.vl["ECMCruiseControl"]["CruiseActive"] != 0 - # 위에서 삭제된 것을 아랫줄에 위치했습니다. + self.pcm_acc_status = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] if self.CP.carFingerprint in (CAR.CHEVROLET_TRAX, CAR.CHEVROLET_TRAILBLAZER, CAR.CHEVROLET_TRAILBLAZER_CC): ret.vCluRatio = 0.96 @@ -207,7 +207,6 @@ class CarState(CarStateBase): vEgoClu, aEgoClu = self.update_clu_speed_kf(ret.vEgoCluster) if self.CP.carFingerprint in CAR.CHEVROLET_VOLT: ret.vCluRatio = (ret.vEgo / vEgoClu) if (vEgoClu > 3. and ret.vEgo > 3.) else 1.0 - #print("vCluRatio={}".format(ret.vCluRatio)) else: ret.vCluRatio = 0.96 diff --git a/opendbc_repo/opendbc/car/gm/interface.py b/opendbc_repo/opendbc/car/gm/interface.py index 7e86d78..02e19c5 100644 --- a/opendbc_repo/opendbc/car/gm/interface.py +++ b/opendbc_repo/opendbc/car/gm/interface.py @@ -181,19 +181,19 @@ class CarInterface(CarInterfaceBase): ret.longitudinalTuning.kpBP = [0.] ret.longitudinalTuning.kpV = [1.0] ret.longitudinalTuning.kiBP = [0.] - ret.longitudinalTuning.kiV = [.3] + ret.longitudinalTuning.kiV = [.35] ret.longitudinalTuning.kf = 1.0 ret.stoppingDecelRate = 0.2 # brake_travel/s while trying to stop ret.stopAccel = -0.5 ret.startingState = True - ret.startAccel = 1.5 + ret.startAccel = 1.9 # softer long tune for ev table if useEVTables: ret.longitudinalTuning.kpBP = [0.] ret.longitudinalTuning.kpV = [1.0] ret.longitudinalTuning.kiBP = [0.] - ret.longitudinalTuning.kiV = [.05] + ret.longitudinalTuning.kiV = [.35] ret.longitudinalTuning.kf = 1.0 ret.stoppingDecelRate = 1.0 # brake_travel/s while trying to stop ret.stopAccel = -0.5 diff --git a/panda/board/safety/safety_gm.h b/panda/board/safety/safety_gm.h index ca9510d..c97d6f2 100644 --- a/panda/board/safety/safety_gm.h +++ b/panda/board/safety/safety_gm.h @@ -75,7 +75,7 @@ static void gm_rx_hook(const CANPacket_t *to_push) { // Reference for brake pressed signals: // https://github.com/commaai/openpilot/blob/master/selfdrive/car/gm/carstate.py if ((addr == 0xBE) && (gm_hw == GM_ASCM)) { - brake_pressed = GET_BYTE(to_push, 1) >= 8U; + brake_pressed = GET_BYTE(to_push, 1) >= 10U; } if ((addr == 0xC9) && ((gm_hw == GM_CAM) || (gm_hw == GM_SDGM))) { @@ -105,11 +105,7 @@ static void gm_rx_hook(const CANPacket_t *to_push) { } if (addr == 0xBD) { - regen_braking = (GET_BYTE(to_push, 0) >> 4) != 0U; // 1. 리젠 브레이크 상태 확인 - // 2. 롱컨트롤 허용 여부 확인 - if (!get_longitudinal_allowed()) { - //tx = false; - } + regen_braking = (GET_BYTE(to_push, 0) >> 4) != 0U; } // Pedal Interceptor diff --git a/selfdrive/assets/sounds/nnff.wav b/selfdrive/assets/sounds/nnff.wav new file mode 100644 index 0000000000000000000000000000000000000000..9ada6a160d3dd834f220e95d9ee009ed1d65cdc3 GIT binary patch literal 98454 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

H_zb{u)8m6n(BpO{sVGm&G=5w-}I#MWW|WP;2a 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 literal 0 HcmV?d00001 diff --git a/selfdrive/car/cruise.py b/selfdrive/car/cruise.py index 3a7c186..e28a38b 100644 --- a/selfdrive/car/cruise.py +++ b/selfdrive/car/cruise.py @@ -612,7 +612,10 @@ class VCruiseCarrot: v_cruise_kph = self._v_cruise_desired(CS, v_cruise_kph) elif self._gas_pressed_count == -1: if 0 < self.d_rel < CS.vEgo * 0.8: - self._cruise_control(-1, 0, "Cruise off (lead car too close)") + if CS.vEgo < 1.0: + self._cruise_control(1, -1 if self.aTarget > 0.0 else 0, "Cruise on (safe speed)") + else: + self._cruise_control(-1, 0, "Cruise off (lead car too close)") elif self.v_ego_kph_set < 30: self._cruise_control(-1, 0, "Cruise off (gas speed)") elif self.xState == 3: @@ -622,7 +625,7 @@ class VCruiseCarrot: v_cruise_kph = self.v_ego_kph_set self._cruise_control(1, -1 if self.aTarget > 0.0 else 0, "Cruise on (gas pressed)") elif self._brake_pressed_count == -1 and self._soft_hold_active == 0: - if 40 < self.v_ego_kph_set: + if self.v_ego_kph_set > 40: v_cruise_kph = self.v_ego_kph_set self._cruise_control(1, -1 if self.aTarget > 0.0 else 0, "Cruise on (speed)") elif abs(CS.steeringAngleDeg) < 20: diff --git a/selfdrive/carrot_settings.json b/selfdrive/carrot_settings.json index 4efcf52..261e11f 100644 --- a/selfdrive/carrot_settings.json +++ b/selfdrive/carrot_settings.json @@ -1,6 +1,19 @@ { "apilot": 20220111, "params": [ + { + "group": "조향일반", + "name": "PathOffset", + "title": "차선치우침 좌우보정(0)", + "descr": "(-)좌측,(+)우측", + "egroup": "LAT", + "etitle": "PathOffset (0)", + "edescr": "(-)Left,(+)Right", + "min": -150, + "max": 150, + "default": 0, + "unit": 1 + }, { "group": "조향튜닝", "name": "LateralTorqueCustom", @@ -40,6 +53,45 @@ "default": 100, "unit": 10 }, + { + "group": "조향튜닝", + "name": "LateralTorqueKpV", + "title": "_LateralTorqueKpV*0.01(100)", + "descr": "", + "egroup": "LAT", + "etitle": "_LateralTorqueKpV*0.01(100)", + "edescr": "", + "min": 0, + "max": 200, + "default": 100, + "unit": 1 + }, + { + "group": "조향튜닝", + "name": "LateralTorqueKiV", + "title": "_LateralTorqueKiV*0.01(10)", + "descr": "", + "egroup": "LAT", + "etitle": "_LateralTorqueKiV*0.01(10)", + "edescr": "", + "min": 0, + "max": 200, + "default": 10, + "unit": 1 + }, + { + "group": "조향튜닝", + "name": "LateralTorqueKf", + "title": "_LateralTorqueKf*0.01(100)", + "descr": "", + "egroup": "LAT", + "etitle": "_LateralTorqueKf*0.001(100)", + "edescr": "", + "min": 0, + "max": 200, + "default": 100, + "unit": 1 + }, { "group": "조향튜닝", "name": "LateralTorqueKd", diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index 4ffb199..ea4fabb 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -148,7 +148,13 @@ class LatControlTorque(LatControl): if lateralTorqueCustom > 0: self.torque_params.latAccelFactor = self.params.get_float("LateralTorqueAccelFactor")*0.001 self.torque_params.friction = self.params.get_float("LateralTorqueFriction")*0.001 + lateralTorqueKp = self.params.get_float("LateralTorqueKpV")*0.01 + lateralTorqueKi = self.params.get_float("LateralTorqueKiV")*0.01 + lateralTorqueKf = self.params.get_float("LateralTorqueKf")*0.01 lateralTorqueKd = self.params.get_float("LateralTorqueKd")*0.01 + self.pid._k_p = [[0], [lateralTorqueKp]] + self.pid._k_i = [[0], [lateralTorqueKi]] + self.pid.k_f = lateralTorqueKf self.pid._k_d = [[0], [lateralTorqueKd]] self.torque_params.latAccelOffset = self.latAccelOffset_default elif self.lateralTorqueCustom > 1: # 1 -> 0, reset to default diff --git a/selfdrive/controls/lib/lateral_planner.py b/selfdrive/controls/lib/lateral_planner.py index 6da9549..edf62cf 100644 --- a/selfdrive/controls/lib/lateral_planner.py +++ b/selfdrive/controls/lib/lateral_planner.py @@ -60,7 +60,7 @@ class LateralPlanner: self.lanelines_active_tmp = False self.useLaneLineSpeedApply = self.params.get_int("UseLaneLineSpeedApply") - self.pathOffset = 0.0 #float(self.params.get_int("PathOffset")) * 0.01 + self.pathOffset = float(self.params.get_int("PathOffset")) * 0.01 self.useLaneLineMode = False self.plan_a = np.zeros((TRAJECTORY_SIZE, )) self.plan_yaw = np.zeros((TRAJECTORY_SIZE,)) @@ -86,7 +86,7 @@ class LateralPlanner: if self.readParams <= 0: self.readParams = 100 self.useLaneLineSpeedApply = self.params.get_int("UseLaneLineSpeedApply") - self.pathOffset = 0.0 #float(self.params.get_int("PathOffset")) * 0.01 + self.pathOffset = float(self.params.get_int("PathOffset")) * 0.01 PATH_COST = self.params.get_float("LatMpcPathCost") * 0.01 self.lateralMotionCost = self.params.get_float("LatMpcMotionCost") * 0.01 self.lateralMotionCost2 = self.params.get_float("LatMpcMotionCost2") * 0.01 diff --git a/selfdrive/selfdrived/events.py b/selfdrive/selfdrived/events.py index 100e6cd..f044d0f 100755 --- a/selfdrive/selfdrived/events.py +++ b/selfdrive/selfdrived/events.py @@ -9,6 +9,7 @@ from cereal import log, car import cereal.messaging as messaging from openpilot.common.conversions import Conversions as CV from openpilot.common.git import get_short_branch +from openpilot.common.params import Params from openpilot.common.realtime import DT_CTRL from openpilot.selfdrive.locationd.calibrationd import MIN_SPEED_FILTER @@ -251,6 +252,20 @@ def calibration_incomplete_alert(CP: car.CarParams, CS: car.CarState, sm: messag AlertStatus.normal, AlertSize.mid, Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2) +def torque_nn_load_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, personality) -> Alert: + model_name = Params().get("NNFFModelName", encoding='utf-8') + if model_name == "": + return Alert( + "NNFF Torque Controller not available", + "Donate logs to Twilsonco to get it added!", + AlertStatus.userPrompt, AlertSize.mid, + Priority.LOW, VisualAlert.none, AudibleAlert.prompt, 6.0) + else: + return Alert( + "NNFF Torque Controller loaded", + model_name, + AlertStatus.userPrompt, AlertSize.mid, + Priority.LOW, VisualAlert.none, AudibleAlert.nnff, 5.0) # *** debug alerts *** @@ -905,9 +920,9 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = { ET.PERMANENT: Alert( "Reverse\nGear", "", - AlertStatus.normal, AlertSize.full, - Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2, creation_delay=0.5), - ET.USER_DISABLE: ImmediateDisableAlert("Reverse Gear"), + AlertStatus.normal, AlertSize.none, + Priority.LOWEST, VisualAlert.none, AudibleAlert.reverseGear, .2, creation_delay=0.5), + ET.SOFT_DISABLE: SoftDisableAlert("Reverse Gear"), ET.NO_ENTRY: NoEntryAlert("Reverse Gear"), }, @@ -1048,6 +1063,9 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = { EventName.audio0: { ET.WARNING: EngagementAlert(AudibleAlert.longDisengaged), }, + EventName.torqueNNLoad: { + ET.PERMANENT: torque_nn_load_alert, + }, } diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index a02383f..e93a81f 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -377,7 +377,8 @@ class SelfdriveD: if self.sm['modelV2'].frameDropPerc > 20: self.events.add(EventName.modeldLagging) - + if self.sm.frame == 550 and Params().get("NNFFModelName", encoding='utf-8') is not None: + self.events.add(EventName.torqueNNLoad) # decrement personality on distance button press #if self.CP.openpilotLongitudinalControl: # if any(not be.pressed and be.type == ButtonType.gapAdjustCruise for be in CS.buttonEvents): diff --git a/selfdrive/ui/qt/offroad/settings.cc b/selfdrive/ui/qt/offroad/settings.cc index c3b12c2..4a67c20 100644 --- a/selfdrive/ui/qt/offroad/settings.cc +++ b/selfdrive/ui/qt/offroad/settings.cc @@ -3,6 +3,7 @@ #include #include #include +#include //차선캘리 #include #include @@ -181,6 +182,11 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { reboot_btn->setObjectName("reboot_btn"); power_layout->addWidget(reboot_btn); QObject::connect(reboot_btn, &QPushButton::clicked, this, &DevicePanel::reboot); + //차선캘리 + QPushButton *reset_CalibBtn = new QPushButton(tr("ReCalibration")); + reset_CalibBtn->setObjectName("reset_CalibBtn"); + power_layout->addWidget(reset_CalibBtn); + QObject::connect(reset_CalibBtn, &QPushButton::clicked, this, &DevicePanel::calibration); QPushButton* poweroff_btn = new QPushButton(tr("Power Off")); poweroff_btn->setObjectName("poweroff_btn"); @@ -268,6 +274,8 @@ DevicePanel::DevicePanel(SettingsWindow *parent) : ListWidget(parent) { setStyleSheet(R"( #reboot_btn { height: 120px; border-radius: 15px; background-color: #2CE22C; } #reboot_btn:pressed { background-color: #24FF24; } + #reset_CalibBtn { height: 120px; border-radius: 15px; background-color: #FFBB00; } + #reset_CalibBtn:pressed { background-color: #FF2424; } #poweroff_btn { height: 120px; border-radius: 15px; background-color: #E22C2C; } #poweroff_btn:pressed { background-color: #FF2424; } #init_btn { height: 120px; border-radius: 15px; background-color: #2C2CE2; } @@ -388,6 +396,25 @@ void DevicePanel::reboot() { } } +//차선캘리 +void execAndReboot(const std::string& cmd) { + system(cmd.c_str()); + Params().putBool("DoReboot", true); +} + +void DevicePanel::calibration() { + if (!uiState()->engaged()) { + if (ConfirmationDialog::confirm(tr("Are you sure you want to reset calibration?"), tr("ReCalibration"), this)) { + if (!uiState()->engaged()) { + std::thread worker(execAndReboot, "cd /data/params/d_tmp; rm -f CalibrationParams"); + worker.detach(); + } + } + } else { + ConfirmationDialog::alert(tr("Reboot & Disengage to Calibration"), this); + } +} + void DevicePanel::poweroff() { if (!uiState()->engaged()) { if (ConfirmationDialog::confirm(tr("Are you sure you want to power off?"), tr("Power Off"), this)) { @@ -643,7 +670,7 @@ CarrotPanel::CarrotPanel(QWidget* parent) : QWidget(parent) { latLongToggles->addItem(new CValueControl("AdjustLaneTime", "AdjustLaneTimeOffset(5)x0.01s", "", "../assets/offroad/icon_logic.png", 0, 20, 1)); latLongToggles->addItem(new CValueControl("CustomSR", "LAT: SteerRatiox0.1(0)", "Custom SteerRatio", "../assets/offroad/icon_logic.png", 0, 300, 1)); latLongToggles->addItem(new CValueControl("SteerRatioRate", "LAT: SteerRatioRatex0.01(100)", "SteerRatio apply rate", "../assets/offroad/icon_logic.png", 30, 170, 1)); - //latLongToggles->addItem(new CValueControl("PathOffset", "PathOffset", "(-)left, (+)right, when UseLaneLineSpeed > 0", "../assets/offroad/icon_road.png", -50, 50, 1)); + latLongToggles->addItem(new CValueControl("PathOffset", "LAT: PathOffset", "(-)left, (+)right", "../assets/offroad/icon_logic.png", -150, 150, 1)); //latLongToggles->addItem(horizontal_line()); //latLongToggles->addItem(new CValueControl("JerkStartLimit", "LONG: JERK START(10)x0.1", "Starting Jerk.", "../assets/offroad/icon_road.png", 1, 50, 1)); //latLongToggles->addItem(new CValueControl("LongitudinalTuningApi", "LONG: ControlType", "0:velocity pid, 1:accel pid, 2:accel pid(comma)", "../assets/offroad/icon_road.png", 0, 2, 1)); diff --git a/selfdrive/ui/qt/offroad/settings.h b/selfdrive/ui/qt/offroad/settings.h index 74c3550..3f37c9c 100644 --- a/selfdrive/ui/qt/offroad/settings.h +++ b/selfdrive/ui/qt/offroad/settings.h @@ -50,6 +50,8 @@ signals: private slots: void poweroff(); void reboot(); + //re_Calibration + void calibration(); void updateCalibDescription(); private: diff --git a/system/manager/manager.py b/system/manager/manager.py index 9a56e4e..04aa508 100755 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -116,6 +116,7 @@ def get_default_params(): ("DynamicTFollowLC", "100"), ("HapticFeedbackWhenSpeedCamera", "0"), ("UseLaneLineSpeed", "0"), + ("PathOffset", "0"), ("UseLaneLineCurveSpeed", "0"), ("UseLaneLineSpeedApply", "0"), ("AdjustLaneOffset", "0"), @@ -128,6 +129,9 @@ def get_default_params(): ("LateralTorqueCustom", "0"), ("LateralTorqueAccelFactor", "2500"), ("LateralTorqueFriction", "100"), + ("LateralTorqueKpV", "100"), + ("LateralTorqueKiV", "10"), + ("LateralTorqueKf", "100"), ("LateralTorqueKd", "0"), ("LatMpcPathCost", "100"), ("LatMpcMotionCost", "11"),