diff --git a/common/params_keys.h b/common/params_keys.h index fb334162f6..2cda89e18f 100644 --- a/common/params_keys.h +++ b/common/params_keys.h @@ -208,7 +208,7 @@ inline static std::unordered_map keys = { {"CECurves", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}}, {"CECurvesLead", {PERSISTENT, BOOL, "0", "0", 1}}, {"CELead", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}}, - {"CEModelStopTime", {PERSISTENT, FLOAT, "7.0", "0.0", 2, SETTINGS_SIMPLE}}, + {"CEModelStopTime", {PERSISTENT, FLOAT, "9.0", "0.0", 2, SETTINGS_SIMPLE}}, {"CESignalLaneDetection", {PERSISTENT, BOOL, "1", "0", 2}}, {"CESignalSpeed", {PERSISTENT, FLOAT, "0.0", "0.0", 2, SETTINGS_SIMPLE}}, {"CESlowerLead", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}}, @@ -289,11 +289,11 @@ inline static std::unordered_map keys = { {"DownloadAllModels", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, {"DownloadMaps", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}}, {"DriverCamera", {PERSISTENT, BOOL, "0", "0", 1, SETTINGS_SIMPLE}}, - {"Model", {PERSISTENT, STRING, "sc2", "sc2", 1}}, - {"ModelVersion", {PERSISTENT, STRING, "v11", "v11", 1}}, - {"DrivingModel", {PERSISTENT, STRING, "sc2", "sc2", 1}}, - {"DrivingModelName", {PERSISTENT, STRING, "South Carolina", "South Carolina", 1}}, - {"DrivingModelVersion", {PERSISTENT, STRING, "v11", "v11", 1}}, + {"Model", {PERSISTENT, STRING, "rdf", "rdf", 1}}, + {"ModelVersion", {PERSISTENT, STRING, "v15", "v15", 1}}, + {"DrivingModel", {PERSISTENT, STRING, "rdf", "rdf", 1}}, + {"DrivingModelName", {PERSISTENT, STRING, "Regret Driven Framework", "Regret Driven Framework", 1}}, + {"DrivingModelVersion", {PERSISTENT, STRING, "v15", "v15", 1}}, {"DynamicPathWidth", {PERSISTENT, BOOL, "0", "0", 2, SETTINGS_SIMPLE}}, {"DynamicPedalsOnUI", {PERSISTENT, BOOL, "1", "0", 1, SETTINGS_SIMPLE}}, {"EngageVolume", {PERSISTENT, INT, "101", "101", 2, SETTINGS_SIMPLE}}, diff --git a/opendbc_repo/opendbc/car/hyundai/carcontroller.py b/opendbc_repo/opendbc/car/hyundai/carcontroller.py index 9550a65cc6..2f84ec0edf 100644 --- a/opendbc_repo/opendbc/car/hyundai/carcontroller.py +++ b/opendbc_repo/opendbc/car/hyundai/carcontroller.py @@ -32,6 +32,7 @@ HYUNDAI_CANFD_SCC_DECEL_STEP = 12.5 / 50.0 IONIQ_6_RESPONSE_MULTIPLIER = 1.2 IONIQ_6_CANFD_SCC_ACCEL_STEP = (6.0 / 50.0) * IONIQ_6_RESPONSE_MULTIPLIER IONIQ_6_CANFD_SCC_DECEL_STEP = (15.0 / 50.0) * IONIQ_6_RESPONSE_MULTIPLIER +EV9_CANFD_SCC_DECEL_STEP = 10.0 / 50.0 GENESIS_G90_STOP_HOLD_SPEED_BP = [0.0, 0.03, 0.08, 0.16, 0.3, 0.5, 0.8, 1.2, 2.0, 3.0] GENESIS_G90_STOP_HOLD_ACCEL_V = [-0.10, -0.10, -0.12, -0.18, -0.30, -0.50, -0.75, -1.00, -1.40, -1.80] GENESIS_G90_STOP_HOLD_RELAX_SPEED_BP = [0.0, 0.08, 0.16, 0.3, 0.5, 0.8, 1.2, 2.0, 3.0] @@ -80,6 +81,10 @@ def egmp_dynamic_longitudinal_tuning(CP) -> bool: kia_ev6_gt_line_longitudinal_tuning(CP.carFingerprint, getattr(CP, "carVin", "")) +def get_canfd_scc_decel_step(CP) -> float: + return EV9_CANFD_SCC_DECEL_STEP if CP.carFingerprint == CAR.KIA_EV9 else IONIQ_6_CANFD_SCC_DECEL_STEP + + def should_reset_ev6_gt_line_longitudinal_tuning(CP, long_control_state: LongCtrlState) -> bool: return kia_ev6_gt_line_longitudinal_tuning(CP.carFingerprint, getattr(CP, "carVin", "")) and \ long_control_state == LongCtrlState.off @@ -627,8 +632,9 @@ class CarController(CarControllerBase): accel = self._ioniq_6_long_tuning.actual_accel stopping = self._ioniq_6_long_tuning.stopping else: + decel_step = get_canfd_scc_decel_step(self.CP) accel = float(np.clip(accel_cmd, - self.accel_last - IONIQ_6_CANFD_SCC_DECEL_STEP, + self.accel_last - decel_step, self.accel_last + IONIQ_6_CANFD_SCC_ACCEL_STEP)) self._ioniq_6_long_tuning.desired_accel = accel_cmd self._ioniq_6_long_tuning.actual_accel = accel diff --git a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py index f0651a9ee0..201babbbec 100644 --- a/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py +++ b/opendbc_repo/opendbc/car/hyundai/tests/test_hyundai.py @@ -13,6 +13,7 @@ from opendbc.car.hyundai.carcontroller import CarController, Ioniq6LongitudinalT reset_egmp_longitudinal_tuning, \ update_ioniq_6_longitudinal_tuning, \ update_genesis_g90_longitudinal_tuning, egmp_dynamic_longitudinal_tuning, \ + get_canfd_scc_decel_step, \ should_reset_ev6_gt_line_longitudinal_tuning, reset_ev6_gt_line_longitudinal_tuning, \ direct_angle_request_allowed, get_angle_smoothing_alpha, \ should_use_ev6_gt_line_stop_direct_tracking @@ -1319,6 +1320,13 @@ class TestHyundaiFingerprint: ioniq_6_cp = CarInterface.get_params(CAR.HYUNDAI_IONIQ_6, gen_empty_fingerprint(), [], True, False, False, toggles) assert CarInterface.get_pid_accel_limits(ioniq_6_cp, 0.0, 0.0)[1] == pytest.approx(CarControllerParams.ACCEL_MAX) + def test_ev9_uses_softer_direct_brake_handoff_than_ioniq_6(self): + ev9_cp = SimpleNamespace(carFingerprint=CAR.KIA_EV9) + ioniq_6_cp = SimpleNamespace(carFingerprint=CAR.HYUNDAI_IONIQ_6) + + assert get_canfd_scc_decel_step(ev9_cp) == pytest.approx(0.20) + assert get_canfd_scc_decel_step(ioniq_6_cp) == pytest.approx(0.36) + def test_ioniq_5_pe_longitudinal_params_match_observed_response(self): toggles = get_test_toggles() CP = CarInterface.get_params(CAR.HYUNDAI_IONIQ_5_PE, gen_empty_fingerprint(), [], True, False, False, toggles) diff --git a/opendbc_repo/opendbc/car/subaru/carstate.py b/opendbc_repo/opendbc/car/subaru/carstate.py index 8a15a4161c..928eb7dcb1 100644 --- a/opendbc_repo/opendbc/car/subaru/carstate.py +++ b/opendbc_repo/opendbc/car/subaru/carstate.py @@ -20,7 +20,8 @@ class CarState(CarStateBase): cp = can_parsers[Bus.pt] cp_cam = can_parsers[Bus.cam] cp_alt = can_parsers[Bus.alt] - cp_angle = cp_cam if self.CP.flags & SubaruFlags.D_PLATFORM else cp + cp_main = can_parsers[Bus.main] if self.CP.flags & SubaruFlags.D_PLATFORM else cp + cp_angle = cp_main if self.CP.flags & SubaruFlags.D_PLATFORM else cp ret = structs.CarState() throttle_msg = cp.vl["Throttle"] if not (self.CP.flags & SubaruFlags.HYBRID) else cp_alt.vl["Throttle_Hybrid"] @@ -55,7 +56,7 @@ class CarState(CarStateBase): cp.vl["Dashlights"]["RIGHT_BLINKER"]) if self.CP.enableBsm: - cp_bsm = cp_cam if self.CP.flags & SubaruFlags.D_PLATFORM else cp + cp_bsm = cp_main if self.CP.flags & SubaruFlags.D_PLATFORM else cp ret.leftBlindspot = (cp_bsm.vl["BSD_RCTA"]["L_ADJACENT"] == 1) or (cp_bsm.vl["BSD_RCTA"]["L_APPROACHING"] == 1) ret.rightBlindspot = (cp_bsm.vl["BSD_RCTA"]["R_ADJACENT"] == 1) or (cp_bsm.vl["BSD_RCTA"]["R_APPROACHING"] == 1) @@ -146,8 +147,11 @@ class CarState(CarStateBase): @staticmethod def get_can_parsers(CP): - return { + parsers = { Bus.pt: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus.main_for_cp(CP)), Bus.cam: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus.camera), Bus.alt: CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus.alt_for_cp(CP)) } + if CP.flags & SubaruFlags.D_PLATFORM: + parsers[Bus.main] = CANParser(DBC[CP.carFingerprint][Bus.pt], [], CanBus.main) + return parsers diff --git a/opendbc_repo/opendbc/car/subaru/interface.py b/opendbc_repo/opendbc/car/subaru/interface.py index 5518c85f79..75b2c0f9cb 100644 --- a/opendbc_repo/opendbc/car/subaru/interface.py +++ b/opendbc_repo/opendbc/car/subaru/interface.py @@ -29,7 +29,7 @@ class CarInterface(CarInterfaceBase): ret.enableBsm = 0x25c in fingerprint[0] ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.subaruPreglobal)] else: - bsm_bus = CanBus.camera if ret.flags & SubaruFlags.D_PLATFORM else CanBus.main + bsm_bus = CanBus.main ret.enableBsm = 0x228 in fingerprint[bsm_bus] ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.subaru)] if ret.flags & SubaruFlags.GLOBAL_GEN2: diff --git a/opendbc_repo/opendbc/car/subaru/tests/test_subaru.py b/opendbc_repo/opendbc/car/subaru/tests/test_subaru.py index 14750cb704..94c7ea384c 100644 --- a/opendbc_repo/opendbc/car/subaru/tests/test_subaru.py +++ b/opendbc_repo/opendbc/car/subaru/tests/test_subaru.py @@ -131,27 +131,35 @@ def test_torque_platform_does_not_enable_angle_safety(): def test_outback_2023_uses_d_platform_bus_layout(): CP = CarInterface.get_non_essential_params(CAR.SUBARU_OUTBACK_2023) parsers = CarState.get_can_parsers(CP) + controller = CarController({}, CP) assert CP.flags & SubaruFlags.D_PLATFORM assert CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.D_PLATFORM assert CanBus.main_for_cp(CP) == CanBus.alt - assert CanBus.angle_for_cp(CP) == CanBus.camera + assert CanBus.angle_for_cp(CP) == CanBus.main assert parsers[Bus.pt].bus == CanBus.alt assert parsers[Bus.cam].bus == CanBus.camera assert parsers[Bus.alt].bus == CanBus.alt + assert parsers[Bus.main].bus == CanBus.main + assert controller.angle_bus == CanBus.main + assert controller.status_bus == CanBus.camera def test_legacy_2025_uses_d_platform_bus_layout(): CP = CarInterface.get_non_essential_params(CAR.SUBARU_LEGACY_2025) parsers = CarState.get_can_parsers(CP) + controller = CarController({}, CP) assert CP.flags & SubaruFlags.D_PLATFORM assert CP.safetyConfigs[0].safetyParam & SubaruSafetyFlags.D_PLATFORM assert CanBus.main_for_cp(CP) == CanBus.alt - assert CanBus.angle_for_cp(CP) == CanBus.camera + assert CanBus.angle_for_cp(CP) == CanBus.main assert parsers[Bus.pt].bus == CanBus.alt assert parsers[Bus.cam].bus == CanBus.camera assert parsers[Bus.alt].bus == CanBus.alt + assert parsers[Bus.main].bus == CanBus.main + assert controller.angle_bus == CanBus.main + assert controller.status_bus == CanBus.camera def test_other_angle_platforms_keep_existing_bus_layout(): diff --git a/opendbc_repo/opendbc/car/subaru/values.py b/opendbc_repo/opendbc/car/subaru/values.py index ff5c756ef3..90b40eea5f 100644 --- a/opendbc_repo/opendbc/car/subaru/values.py +++ b/opendbc_repo/opendbc/car/subaru/values.py @@ -113,7 +113,7 @@ class CanBus: @staticmethod def angle_for_cp(CP): - return CanBus.camera if CP.flags & SubaruFlags.D_PLATFORM else CanBus.main + return CanBus.main class Footnote(Enum): diff --git a/opendbc_repo/opendbc/safety/modes/subaru.h b/opendbc_repo/opendbc/safety/modes/subaru.h index 94f69cedfe..ae7ca6cb9c 100644 --- a/opendbc_repo/opendbc/safety/modes/subaru.h +++ b/opendbc_repo/opendbc/safety/modes/subaru.h @@ -56,7 +56,7 @@ {MSG_SUBARU_ES_Distance, alt_bus, 8, .check_relay = false}, \ #define SUBARU_D_PLATFORM_ANGLE_TX_MSGS() \ - {MSG_SUBARU_ES_LKAS_ANGLE, SUBARU_CAM_BUS, 8, .check_relay = true}, \ + {MSG_SUBARU_ES_LKAS_ANGLE, SUBARU_MAIN_BUS, 8, .check_relay = true}, \ {MSG_SUBARU_ES_DashStatus, SUBARU_CAM_BUS, 8, .check_relay = true}, \ {MSG_SUBARU_ES_LKAS_State, SUBARU_CAM_BUS, 8, .check_relay = true}, \ {MSG_SUBARU_ES_Infotainment, SUBARU_CAM_BUS, 8, .check_relay = true}, \ @@ -93,8 +93,8 @@ #define SUBARU_D_PLATFORM_ANGLE_RX_CHECKS() \ {.msg = {{MSG_SUBARU_Throttle, SUBARU_ALT_BUS, 8, 100U, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ - {.msg = {{MSG_SUBARU_Steering_Torque, SUBARU_CAM_BUS, 8, 50U, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ - {.msg = {{MSG_SUBARU_Steering_2, SUBARU_CAM_BUS, 8, 50U, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ + {.msg = {{MSG_SUBARU_Steering_Torque, SUBARU_MAIN_BUS, 8, 50U, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ + {.msg = {{MSG_SUBARU_Steering_2, SUBARU_MAIN_BUS, 8, 50U, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ {.msg = {{MSG_SUBARU_Wheel_Speeds, SUBARU_ALT_BUS, 8, 50U, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ {.msg = {{MSG_SUBARU_Brake_Status, SUBARU_ALT_BUS, 8, 50U, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ {.msg = {{MSG_SUBARU_ES_Brake, SUBARU_ALT_BUS, 8, 50U, .max_counter = 15U, .ignore_quality_flag = true}, { 0 }, { 0 }}}, \ @@ -127,7 +127,7 @@ static uint32_t subaru_compute_checksum(const CANPacket_t *msg) { static void subaru_rx_hook(const CANPacket_t *msg) { const unsigned int alt_main_bus = subaru_gen2 ? SUBARU_ALT_BUS : SUBARU_MAIN_BUS; const unsigned int status_bus = subaru_gen2 ? SUBARU_ALT_BUS : SUBARU_CAM_BUS; - const unsigned int steering_bus = subaru_d_platform ? SUBARU_CAM_BUS : SUBARU_MAIN_BUS; + const unsigned int steering_bus = SUBARU_MAIN_BUS; const unsigned int main_bus = subaru_d_platform ? SUBARU_ALT_BUS : SUBARU_MAIN_BUS; if ((msg->addr == MSG_SUBARU_Steering_Torque) && (msg->bus == steering_bus)) { diff --git a/opendbc_repo/opendbc/safety/tests/common.py b/opendbc_repo/opendbc/safety/tests/common.py index ed80f95f4e..75f278e20c 100644 --- a/opendbc_repo/opendbc/safety/tests/common.py +++ b/opendbc_repo/opendbc/safety/tests/common.py @@ -967,6 +967,9 @@ class SafetyTest(SafetyTestBase): continue if attr.startswith('TestSubaruGen') and current_test.startswith('TestSubaruGen'): continue + if 'TestSubaruDPlatformAngleSafety' in {attr, current_test} and \ + 'Angle' in attr and 'Angle' in current_test: + continue if attr.startswith('TestSubaruPreglobal') and current_test.startswith('TestSubaruPreglobal'): continue if {attr, current_test}.issubset({'TestVolkswagenPqSafety', 'TestVolkswagenPqStockSafety', 'TestVolkswagenPqLongSafety'}): diff --git a/opendbc_repo/opendbc/safety/tests/test_subaru.py b/opendbc_repo/opendbc/safety/tests/test_subaru.py index 0b9099883e..9afb8e4e9b 100755 --- a/opendbc_repo/opendbc/safety/tests/test_subaru.py +++ b/opendbc_repo/opendbc/safety/tests/test_subaru.py @@ -343,21 +343,21 @@ class TestSubaruGen2AngleStockLongitudinalSafety(TestSubaruStockLongitudinalSafe class TestSubaruDPlatformAngleSafety(TestSubaruStockLongitudinalSafetyBase, TestSubaruAngleSafetyBase): FLAGS = SubaruSafetyFlags.GEN2 | SubaruSafetyFlags.LKAS_ANGLE | SubaruSafetyFlags.D_PLATFORM ALT_MAIN_BUS = SUBARU_ALT_BUS - TX_MSGS = [[SubaruMsg.ES_LKAS_ANGLE, SUBARU_CAM_BUS], + TX_MSGS = [[SubaruMsg.ES_LKAS_ANGLE, SUBARU_MAIN_BUS], [SubaruMsg.ES_DashStatus, SUBARU_CAM_BUS], [SubaruMsg.ES_LKAS_State, SUBARU_CAM_BUS], [SubaruMsg.ES_Infotainment, SUBARU_CAM_BUS], [SubaruMsg.ES_Distance, SUBARU_ALT_BUS]] - RELAY_MALFUNCTION_ADDRS = {SUBARU_CAM_BUS: (SubaruMsg.ES_LKAS_ANGLE, SubaruMsg.ES_DashStatus, - SubaruMsg.ES_LKAS_State, SubaruMsg.ES_Infotainment)} - D_PLATFORM_STATUS_ADDRS = (SubaruMsg.ES_LKAS_ANGLE, SubaruMsg.ES_DashStatus, - SubaruMsg.ES_LKAS_State, SubaruMsg.ES_Infotainment) + RELAY_MALFUNCTION_ADDRS = {SUBARU_MAIN_BUS: (SubaruMsg.ES_LKAS_ANGLE,), + SUBARU_CAM_BUS: (SubaruMsg.ES_DashStatus, SubaruMsg.ES_LKAS_State, + SubaruMsg.ES_Infotainment)} FWD_BLACKLISTED_ADDRS = { - SUBARU_MAIN_BUS: D_PLATFORM_STATUS_ADDRS, + SUBARU_MAIN_BUS: [SubaruMsg.ES_DashStatus, SubaruMsg.ES_LKAS_State, SubaruMsg.ES_Infotainment], + SUBARU_CAM_BUS: [SubaruMsg.ES_LKAS_ANGLE], } def _torque_driver_msg(self, torque): - return self.packer.make_can_msg_safety("Steering_Torque", SUBARU_CAM_BUS, {"Steer_Torque_Sensor": torque}) + return self.packer.make_can_msg_safety("Steering_Torque", SUBARU_MAIN_BUS, {"Steer_Torque_Sensor": torque}) def _user_gas_msg(self, gas): return self.packer.make_can_msg_safety("Throttle", SUBARU_ALT_BUS, {"Throttle_Pedal": gas}) @@ -367,10 +367,10 @@ class TestSubaruDPlatformAngleSafety(TestSubaruStockLongitudinalSafetyBase, Test self.safety.set_timer(self.angle_cmd_cnt * int(1e6 / self.LATERAL_FREQUENCY)) self.angle_cmd_cnt += 1 values = {"LKAS_Output": angle, "LKAS_Request": enabled, "SET_3": 3} - return self.packer.make_can_msg_safety("ES_LKAS_ANGLE", SUBARU_CAM_BUS, values) + return self.packer.make_can_msg_safety("ES_LKAS_ANGLE", SUBARU_MAIN_BUS, values) def _angle_meas_msg(self, angle): - return self.packer.make_can_msg_safety("Steering_2", SUBARU_CAM_BUS, {"Steering_Angle": angle}) + return self.packer.make_can_msg_safety("Steering_2", SUBARU_MAIN_BUS, {"Steering_Angle": angle}) class TestSubaruGen2LongitudinalSafety(TestSubaruLongitudinalSafetyBase, TestSubaruGen2TorqueSafetyBase): diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index 8d7aadae17..897d099259 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -362,6 +362,7 @@ class LatControlTorque(LatControl): friction_scale = get_prius_friction_scale(CS.vEgo, setpoint, desired_lateral_jerk) friction_scale = 1.0 + ((friction_scale - 1.0) * prius_center_taper) elif camry_active: + ff *= get_camry_ff_scale(setpoint, desired_lateral_jerk, CS.vEgo) friction_threshold = get_camry_friction_threshold(CS.vEgo, setpoint, desired_lateral_jerk) elif rav4_prime_active: ff *= get_rav4_prime_ff_scale(setpoint, desired_lateral_jerk, CS.vEgo) diff --git a/selfdrive/controls/lib/latcontrol_vehicle_tunes.py b/selfdrive/controls/lib/latcontrol_vehicle_tunes.py index 4a22faf298..eef2d79901 100644 --- a/selfdrive/controls/lib/latcontrol_vehicle_tunes.py +++ b/selfdrive/controls/lib/latcontrol_vehicle_tunes.py @@ -821,6 +821,11 @@ CAMRY_CENTER_FRICTION_THRESHOLD_LAT = 0.22 CAMRY_CENTER_FRICTION_THRESHOLD_LAT_WIDTH = 0.06 CAMRY_CENTER_FRICTION_THRESHOLD_SPEED = 18.0 CAMRY_CENTER_FRICTION_THRESHOLD_SPEED_WIDTH = 3.0 +CAMRY_UNWIND_FF_REDUCTION = 0.08 +CAMRY_UNWIND_LAT_ONSET = 0.18 +CAMRY_UNWIND_LAT_WIDTH = 0.07 +CAMRY_UNWIND_SPEED_ONSET = 15.0 +CAMRY_UNWIND_SPEED_WIDTH = 3.0 RAV4_PRIME_PHASE_SCALE = 0.12 RAV4_PRIME_TURN_IN_FF_BOOST_LEFT = 0.055 @@ -1191,6 +1196,15 @@ def get_camry_friction_threshold(v_ego: float, desired_lateral_accel: float = 0. return get_standard_friction_threshold(v_ego) * (1.0 + gain * speed_weight * center_weight) +def get_camry_ff_scale(desired_lateral_accel: float, desired_lateral_jerk: float, v_ego: float) -> float: + phase = math.tanh((desired_lateral_accel * desired_lateral_jerk) / 0.10) + unwind_weight = max(-phase, 0.0) + lat_weight = _sigmoid((abs(desired_lateral_accel) - CAMRY_UNWIND_LAT_ONSET) / CAMRY_UNWIND_LAT_WIDTH) + speed_weight = _sigmoid((v_ego - CAMRY_UNWIND_SPEED_ONSET) / CAMRY_UNWIND_SPEED_WIDTH) + reduction = _flm_vehicle_knob("toyota_camry.unwind_ff_reduction", CAMRY_UNWIND_FF_REDUCTION) + return 1.0 - reduction * unwind_weight * lat_weight * speed_weight + + def _rav4_prime_side_value(desired_lateral_accel: float, left_value: float, right_value: float) -> float: return left_value if desired_lateral_accel >= 0.0 else right_value @@ -3319,6 +3333,7 @@ FLM_SUPPORTED_VEHICLE_KNOBS = { "toyota_prius.unwind_threshold_increase_right": {"profile": "toyota_prius", "min": 0.0, "max": 0.90, "precision": 0.001, "deltaType": "absolute", "safeLiveTrial": True, "defaultValue": PRIUS_UNWIND_THRESHOLD_INCREASE_RIGHT}, "toyota_prius.center_friction_threshold_gain": {"profile": "toyota_prius", "min": 0.0, "max": 0.20, "precision": 0.001, "deltaType": "absolute", "safeLiveTrial": True, "defaultValue": PRIUS_CENTER_FRICTION_THRESHOLD_GAIN}, "toyota_camry.center_friction_threshold_gain": {"profile": "toyota_camry", "min": 0.0, "max": 0.15, "precision": 0.001, "deltaType": "absolute", "safeLiveTrial": True, "defaultValue": CAMRY_CENTER_FRICTION_THRESHOLD_GAIN}, + "toyota_camry.unwind_ff_reduction": {"profile": "toyota_camry", "min": 0.0, "max": 0.20, "precision": 0.001, "deltaType": "absolute", "safeLiveTrial": True, "defaultValue": CAMRY_UNWIND_FF_REDUCTION}, } diff --git a/selfdrive/controls/tests/test_latcontrol.py b/selfdrive/controls/tests/test_latcontrol.py index c64c842545..ec97995f11 100644 --- a/selfdrive/controls/tests/test_latcontrol.py +++ b/selfdrive/controls/tests/test_latcontrol.py @@ -81,6 +81,7 @@ from openpilot.selfdrive.controls.lib.latcontrol_torque import ( get_sienna_4th_gen_friction_threshold, get_sienna_4th_gen_high_speed_output_taper_scale, get_lexus_is_ff_scale, + get_camry_ff_scale, get_ioniq_5_ff_scale, get_ioniq_5_friction_scale, get_ioniq_5_friction_threshold, @@ -1086,6 +1087,11 @@ class TestLatControl: assert unwind_right < unwind_left < steady_left assert unwind_right < low_speed_unwind_right < 1.0 + def test_camry_ff_scale_reduces_high_speed_unwind(self): + assert get_camry_ff_scale(0.6, 0.0, 22.0) == pytest.approx(1.0) + assert get_camry_ff_scale(0.6, -0.5, 22.0) < 1.0 + assert get_camry_ff_scale(0.6, -0.5, 5.0) > get_camry_ff_scale(0.6, -0.5, 22.0) + def test_volt_plexy_friction_threshold_curve(self): base = get_gm_base_friction_threshold(6.0) left_turn_in = get_volt_plexy_friction_threshold(6.0, 0.7, 0.8) diff --git a/selfdrive/modeld/modeld.py b/selfdrive/modeld/modeld.py index e28d971f8d..1bd5b851bc 100755 --- a/selfdrive/modeld/modeld.py +++ b/selfdrive/modeld/modeld.py @@ -48,8 +48,9 @@ from openpilot.starpilot.common.starpilot_variables import get_starpilot_toggles PROCESS_NAME = "selfdrive.modeld.modeld" SEND_RAW_PRED = os.getenv('SEND_RAW_PRED') -BUILTIN_MODEL_KEY = "sc2" -BUILTIN_MODEL_ALIASES = {BUILTIN_MODEL_KEY, "sc"} +BUILTIN_MODEL_KEY = "rdf" +BUILTIN_MODEL_ALIASES = {BUILTIN_MODEL_KEY} +MODEL_ID_ALIASES = {"sc": "sc2"} LAT_SMOOTH_SECONDS = 0.1 @@ -116,7 +117,9 @@ def _resolve_mirrored_param(params: Params, primary_key: str, secondary_key: str def _canonical_model_id(model_id: str) -> str: key = (model_id or "").strip().lower() - return BUILTIN_MODEL_KEY if key in BUILTIN_MODEL_ALIASES else key + if key in BUILTIN_MODEL_ALIASES: + return BUILTIN_MODEL_KEY + return MODEL_ID_ALIASES.get(key, key) def get_action_from_model(model_output: dict[str, np.ndarray], prev_action: log.ModelDataV2.Action, @@ -301,9 +304,9 @@ class ModelState: model_version = str(json.loads(versions_path.read_text()).get(model_id) or "") except Exception: pass - if loaded_builtin and not use_builtin: - model_version = str(artifact.get("behavior_version") or "v11") - self.policy_generation = model_version or ("v11" if loaded_builtin else "v8") + if loaded_builtin: + model_version = str(artifact.get("behavior_version") or "v15") + self.policy_generation = model_version or ("v15" if loaded_builtin else "v8") self.is_v9 = self.policy_generation == "v9" self.is_v14 = self.policy_generation == "v14" self.is_v15 = self.policy_generation == "v15" diff --git a/selfdrive/modeld/models/driving_tinygrad.pkl b/selfdrive/modeld/models/driving_tinygrad.pkl.chunk01of03 similarity index 54% rename from selfdrive/modeld/models/driving_tinygrad.pkl rename to selfdrive/modeld/models/driving_tinygrad.pkl.chunk01of03 index fdb18cabde..1e69a6eee8 100644 Binary files a/selfdrive/modeld/models/driving_tinygrad.pkl and b/selfdrive/modeld/models/driving_tinygrad.pkl.chunk01of03 differ diff --git a/selfdrive/modeld/models/driving_tinygrad.pkl.chunk02of03 b/selfdrive/modeld/models/driving_tinygrad.pkl.chunk02of03 new file mode 100644 index 0000000000..15fed83149 Binary files /dev/null and b/selfdrive/modeld/models/driving_tinygrad.pkl.chunk02of03 differ diff --git a/selfdrive/modeld/models/driving_tinygrad.pkl.chunk03of03 b/selfdrive/modeld/models/driving_tinygrad.pkl.chunk03of03 new file mode 100644 index 0000000000..03f7848ef9 Binary files /dev/null and b/selfdrive/modeld/models/driving_tinygrad.pkl.chunk03of03 differ diff --git a/selfdrive/modeld/models/driving_tinygrad.pkl.chunkmanifest b/selfdrive/modeld/models/driving_tinygrad.pkl.chunkmanifest new file mode 100644 index 0000000000..e440e5c842 --- /dev/null +++ b/selfdrive/modeld/models/driving_tinygrad.pkl.chunkmanifest @@ -0,0 +1 @@ +3 \ No newline at end of file diff --git a/selfdrive/modeld/models/driving_tinygrad.pkl.sha256 b/selfdrive/modeld/models/driving_tinygrad.pkl.sha256 new file mode 100644 index 0000000000..a3b935ccc9 --- /dev/null +++ b/selfdrive/modeld/models/driving_tinygrad.pkl.sha256 @@ -0,0 +1 @@ +339e80b0864c7a955f197a47e5ff745025eefb3a5a5dcfff121d3bd50bc31018 driving_tinygrad.pkl diff --git a/selfdrive/ui/layouts/settings/starpilot/driving_model.py b/selfdrive/ui/layouts/settings/starpilot/driving_model.py index 8c4624730d..c503795758 100644 --- a/selfdrive/ui/layouts/settings/starpilot/driving_model.py +++ b/selfdrive/ui/layouts/settings/starpilot/driving_model.py @@ -820,19 +820,19 @@ class StarPilotDrivingModelLayout(_SettingsPage): default_key = self._params.get_default_value("Model") or self._params.get_default_value("DrivingModel") if isinstance(default_key, bytes): default_key = default_key.decode("utf-8", errors="ignore") - return canonical_model_key(str(default_key or "").strip()) or "sc2" + return canonical_model_key(str(default_key or "").strip()) or "rdf" def _default_model_name(self) -> str: default_name = self._params.get_default_value("DrivingModelName") if isinstance(default_name, bytes): default_name = default_name.decode("utf-8", errors="ignore") - return _clean_model_name(default_name or "") or "South Carolina" + return _clean_model_name(default_name or "") or "Regret Driven Framework" def _default_model_version(self) -> str: default_version = self._params.get_default_value("ModelVersion") or self._params.get_default_value("DrivingModelVersion") if isinstance(default_version, bytes): default_version = default_version.decode("utf-8", errors="ignore") - return str(default_version or "").strip() or "v11" + return str(default_version or "").strip() or "v15" def _current_selected_key(self) -> str: current_key = self._params.get("Model", encoding="utf-8") or self._params.get("DrivingModel", encoding="utf-8") or "" diff --git a/selfdrive/ui/layouts/settings/starpilot/longitudinal.py b/selfdrive/ui/layouts/settings/starpilot/longitudinal.py index e94a8a1651..1204cb8073 100644 --- a/selfdrive/ui/layouts/settings/starpilot/longitudinal.py +++ b/selfdrive/ui/layouts/settings/starpilot/longitudinal.py @@ -272,7 +272,7 @@ class ConditionalDriveModeView(AdjustorTogglesPanelView): "CESpeed": {"title": tr("Below Speed"), "subtitle": "", "min": 0, "max": max_speed, "step": 1.0, "unit": speed_unit, "presets": [0, 20, 35, 55, 75], "labels": {}, "get": lambda: float(self._controller._params.get_int("CESpeed"))}, "CESpeedLead": {"title": tr("Speed w/ Lead"), "subtitle": "", "min": 0, "max": max_speed, "step": 1.0, "unit": speed_unit, "presets": [0, 20, 35, 55, 75], "labels": {}, "get": lambda: float(self._controller._params.get_int("CESpeedLead"))}, "CESignalSpeed": {"title": tr("Turn Signal Below"), "subtitle": "", "min": 0, "max": max_speed, "step": 1.0, "unit": speed_unit, "presets": [0, 20, 35, 55, 75], "labels": {0.0: tr("Off")}, "get": lambda: float(self._controller._params.get_int("CESignalSpeed"))}, - "CEModelStopTime": {"title": tr("Predicted Stop In"), "subtitle": "", "min": 0, "max": 10.0, "step": 1.0, "unit": "s", "presets": [0, 3, 5, 7, 10], "labels": {0.0: tr("Off")}, "get": lambda: float(self._controller._params.get_int("CEModelStopTime"))}, + "CEModelStopTime": {"title": tr("Predicted Stop In"), "subtitle": "", "min": 0, "max": 10.0, "step": 1.0, "unit": "s", "presets": [0, 3, 5, 9, 10], "labels": {0.0: tr("Off")}, "get": lambda: float(self._controller._params.get_int("CEModelStopTime"))}, "CCMSpeed": {"title": tr("Above Speed"), "subtitle": "", "min": 0, "max": max_speed, "step": 1.0, "unit": speed_unit, "presets": [0, 35, 55, 65, 80], "labels": {}, "get": lambda: float(self._controller._params.get_int("CCMSpeed"))}, "CCMSpeedLead": {"title": tr("Speed w/ Lead"), "subtitle": "", "min": 0, "max": max_speed, "step": 1.0, "unit": speed_unit, "presets": [0, 35, 55, 65, 80], "labels": {}, "get": lambda: float(self._controller._params.get_int("CCMSpeedLead"))}, "CCMSetSpeedMargin": {"title": tr("Set Speed Margin"), "subtitle": "", "min": 0, "max": 30.0 if is_metric else 15.0, "step": 1.0, "unit": speed_unit, "presets": [0, 5, 10, 15], "labels": {}, "get": lambda: float(self._controller._params.get_int("CCMSetSpeedMargin"))}, @@ -306,7 +306,7 @@ class ConditionalDriveModeView(AdjustorTogglesPanelView): "CESpeed": {"title": tr("Below Speed"), "min": 0, "max": max_speed, "unit": speed_unit, "labels": {}, "presets": [0, 20, 35, 55, 75]}, "CESpeedLead": {"title": tr("Speed w/ Lead"), "min": 0, "max": max_speed, "unit": speed_unit, "labels": {}, "presets": [0, 20, 35, 55, 75]}, "CESignalSpeed": {"title": tr("Turn Signal Below"), "min": 0, "max": max_speed, "unit": speed_unit, "labels": {0.0: tr("Off")}, "presets": [0, 20, 35, 55, 75]}, - "CEModelStopTime": {"title": tr("Predicted Stop In"), "min": 0, "max": 10.0, "unit": "s", "labels": {0.0: tr("Off")}, "presets": [0, 3, 5, 7, 10]}, + "CEModelStopTime": {"title": tr("Predicted Stop In"), "min": 0, "max": 10.0, "unit": "s", "labels": {0.0: tr("Off")}, "presets": [0, 3, 5, 9, 10]}, "CCMSpeed": {"title": tr("Above Speed"), "min": 0, "max": max_speed, "unit": speed_unit, "labels": {}, "presets": [0, 35, 55, 65, 80]}, "CCMSpeedLead": {"title": tr("Speed w/ Lead"), "min": 0, "max": max_speed, "unit": speed_unit, "labels": {}, "presets": [0, 35, 55, 65, 80]}, "CCMSetSpeedMargin": {"title": tr("Set Speed Margin"), "min": 0, "max": 30.0 if is_metric else 15.0, "unit": speed_unit, "labels": {}, "presets": [0, 5, 10, 15]}, diff --git a/selfdrive/ui/mici/layouts/settings/driving_model.py b/selfdrive/ui/mici/layouts/settings/driving_model.py index e2bc259ae7..4365c26ecd 100644 --- a/selfdrive/ui/mici/layouts/settings/driving_model.py +++ b/selfdrive/ui/mici/layouts/settings/driving_model.py @@ -706,9 +706,9 @@ class DrivingModelBigButton(BigButton): default_key = default_key.decode("utf-8", errors="ignore") default_key = str(default_key or "").strip() if not default_key: - default_key = "sc" + default_key = "rdf" - # Manifest can expose legacy IDs like "sc2" while default remains "sc". + # Keep the built-in model selectable even when the manifest omits it. if key == default_key: return True if default_key.endswith("2") and key == default_key[:-1]: diff --git a/starpilot/assets/model_manager.py b/starpilot/assets/model_manager.py index af2318eb70..9d87b6af6a 100644 --- a/starpilot/assets/model_manager.py +++ b/starpilot/assets/model_manager.py @@ -24,13 +24,13 @@ from openpilot.starpilot.common.starpilot_utilities import delete_file from openpilot.starpilot.common.starpilot_variables import MODELS_PATH MANIFEST_CANDIDATES = ("v22",) -DEFAULT_MODEL_KEY = "sc2" +DEFAULT_MODEL_KEY = "rdf" LOCAL_MODEL_PREFIX = "local-" LOCAL_MODEL_SERIES = "Local Series" ARTIFACT_URLS_CACHE = ".model_artifact_urls.json" ARTIFACT_METADATA_CACHE = ".model_artifacts.json" MODEL_KEY_CANONICAL_MAP = { - "sc": DEFAULT_MODEL_KEY, + "sc": "sc2", } CANCEL_DOWNLOAD_PARAM = "CancelModelDownload" @@ -181,7 +181,7 @@ class ModelManager: selected_model = self._selected_model() current_version = self._resolve_mirrored_param("ModelVersion", "DrivingModelVersion") if not current_version: - current_version = self._default_param_text("ModelVersion") or self._default_param_text("DrivingModelVersion") or "v11" + current_version = self._default_param_text("ModelVersion") or self._default_param_text("DrivingModelVersion") or ("v15" if is_builtin_model_key(selected_model) else "v11") selected_name = self._param_text("DrivingModelName") if not selected_name and selected_model in self.available_models: @@ -359,7 +359,7 @@ class ModelManager: model_version = version_map.get(model_key) or version_map.get(canonical_key) or "" if not model_version and is_builtin_model_key(canonical_key): - model_version = self._default_param_text("ModelVersion") or self._default_param_text("DrivingModelVersion") or "v11" + model_version = self._default_param_text("ModelVersion") or self._default_param_text("DrivingModelVersion") or "v15" artifact_format = artifact_format_map.get(model_key) or artifact_format_map.get(canonical_key) or "" if not self._is_model_downloaded(model_key, artifact_format): @@ -415,7 +415,7 @@ class ModelManager: fallback_version = self._resolve_mirrored_param("ModelVersion", "DrivingModelVersion") if not fallback_version: - fallback_version = self._default_param_text("ModelVersion") or self._default_param_text("DrivingModelVersion") or "v11" + fallback_version = self._default_param_text("ModelVersion") or self._default_param_text("DrivingModelVersion") or ("v15" if is_builtin_model_key(selected) else "v11") self._set_model_param_keys(selected, name_map.get(selected, ""), fallback_version) @staticmethod @@ -590,12 +590,12 @@ class ModelManager: default_name = ( self.available_model_names[default_index] if default_index is not None and default_index < len(self.available_model_names) - else "South Carolina" + else "Regret Driven Framework" ) default_version = ( self.model_versions[default_index] if default_index is not None and default_index < len(self.model_versions) - else "v11" + else "v15" ) self._set_model_param_keys(DEFAULT_MODEL_KEY, default_name, default_version) self.params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Selected model unavailable; using built-in model.") diff --git a/starpilot/common/starpilot_variables.py b/starpilot/common/starpilot_variables.py index 4141181ce4..1803358bbc 100644 --- a/starpilot/common/starpilot_variables.py +++ b/starpilot/common/starpilot_variables.py @@ -1208,13 +1208,13 @@ class StarPilotVariables: toggle.recovery_power = self.get_value("RecoveryPower", cast=float, condition=longitudinal_tuning, default=1.0, min=0.5, max=2.0) toggle.taco_tune = self.get_value("TacoTune", condition=longitudinal_tuning) - toggle.model = self.get_value("Model", cast=None, default="sc2") + toggle.model = self.get_value("Model", cast=None, default="rdf") if not toggle.model: - toggle.model = self.get_value("DrivingModel", cast=None, default="sc2") - toggle.model_name = self.get_value("DrivingModelName", cast=None, default="South Carolina") - toggle.model_version = self.get_value("ModelVersion", cast=None, default="v11") + toggle.model = self.get_value("DrivingModel", cast=None, default="rdf") + toggle.model_name = self.get_value("DrivingModelName", cast=None, default="Regret Driven Framework") + toggle.model_version = self.get_value("ModelVersion", cast=None, default="v15") if not toggle.model_version: - toggle.model_version = self.get_value("DrivingModelVersion", cast=None, default="v11") + toggle.model_version = self.get_value("DrivingModelVersion", cast=None, default="v15") if isinstance(toggle.model, bytes): toggle.model = toggle.model.decode("utf-8", "ignore") if isinstance(toggle.model_name, bytes): diff --git a/starpilot/system/the_galaxy/the_galaxy.py b/starpilot/system/the_galaxy/the_galaxy.py index 6a9bdc9dd4..4c1905bc50 100644 --- a/starpilot/system/the_galaxy/the_galaxy.py +++ b/starpilot/system/the_galaxy/the_galaxy.py @@ -5363,14 +5363,14 @@ def setup(app): def _default_model_key(): default_key = _param_text(params.get_default_value("Model") or params.get_default_value("DrivingModel")) - return canonical_model_key(default_key) or "sc2" + return canonical_model_key(default_key) or "rdf" def _default_model_name(): - return _param_text(params.get_default_value("DrivingModelName")) or "South Carolina" + return _param_text(params.get_default_value("DrivingModelName")) or "Regret Driven Framework" def _default_model_version(): default_version = _param_text(params.get_default_value("ModelVersion") or params.get_default_value("DrivingModelVersion")) - return default_version or "v11" + return default_version or "v15" def _current_model_key(): current_model = _param_text(params.get("Model", encoding="utf-8") or params.get("DrivingModel", encoding="utf-8")) diff --git a/starpilot/ui/qt/offroad/model_settings.cc b/starpilot/ui/qt/offroad/model_settings.cc index 382869b7ad..487387313b 100644 --- a/starpilot/ui/qt/offroad/model_settings.cc +++ b/starpilot/ui/qt/offroad/model_settings.cc @@ -22,18 +22,18 @@ QString builtinDefaultModelKey(const Params ¶ms) { if (key.isEmpty()) { key = paramDefaultValue(params, "DrivingModel"); } - return key.isEmpty() ? QStringLiteral("sc2") : key; + return key.isEmpty() ? QStringLiteral("rdf") : key; } QString builtinDefaultModelName(const Params ¶ms) { QString name = paramDefaultValue(params, "DrivingModelName"); - return name.isEmpty() ? QStringLiteral("South Carolina") : name; + return name.isEmpty() ? QStringLiteral("Regret Driven Framework") : name; } QStringList builtinDefaultModelAliases(const QString &defaultKey) { QString canonical = defaultKey.trimmed(); if (canonical.isEmpty()) { - canonical = QStringLiteral("sc2"); + canonical = QStringLiteral("rdf"); } QStringList aliases{canonical}; diff --git a/system/manager/manager.py b/system/manager/manager.py index 2e460b12e0..8849df161c 100755 --- a/system/manager/manager.py +++ b/system/manager/manager.py @@ -67,6 +67,8 @@ STARPILOT_PARAM_RENAME_MIGRATION_FLAG = Path("/data") / "starpilot_param_rename_ STARPILOT_PARAM_CANONICALIZATION_MIGRATION_FLAG = Path("/data") / "starpilot_param_canonicalization_v1" STARPILOT_PC_ROOT_MIGRATION_FLAG = Path("/data") / "starpilot_pc_root_v1" STARPILOT_PARAMS_CACHE_MIGRATION_FLAG = Path("/data") / "starpilot_params_cache_v1" +STARPILOT_DEFAULT_MODEL_MIGRATION_FLAG = Path("/data") / "starpilot_default_model_rdf_v1" +STARPILOT_CE_MODEL_STOP_TIME_MIGRATION_FLAG = Path("/data") / "starpilot_ce_model_stop_time_v1" STARPILOT_LEGACY_CACHE_MARKER_KEYS = ("RemapCancelToDistance",) STARPILOT_REMOVED_PARAM_KEYS = ("CoastUpToLeads", "HumanAcceleration", "HumanFollowing", "PrioritizeSmoothFollowing") LEGACY_CARMODEL_MIGRATIONS = { @@ -559,8 +561,8 @@ def migrate_starpilot_default_parity(params: Params, params_cache: Params) -> No seeded_keys.append(key) if not _has_persisted_param_file(params, "CEModelStopTime") and not _has_persisted_param_file(params_cache, "CEModelStopTime"): - params.put_float("CEModelStopTime", 7.0) - params_cache.put_float("CEModelStopTime", 7.0) + params.put_float("CEModelStopTime", 9.0) + params_cache.put_float("CEModelStopTime", 9.0) seeded_keys.append("CEModelStopTime") # Rebase default regression fix: @@ -588,6 +590,75 @@ def migrate_starpilot_default_parity(params: Params, params_cache: Params) -> No cloudlog.exception(f"Failed to write migration flag: {STARPILOT_DEFAULTS_PARITY_MIGRATION_FLAG}") +def migrate_starpilot_default_model(params: Params, params_cache: Params) -> None: + """Move the old bundled South Carolina selection to the bundled RDF model once.""" + if STARPILOT_DEFAULT_MODEL_MIGRATION_FLAG.exists(): + return + + def persisted_text(key: str) -> str: + for params_obj in (params, params_cache): + raw_value = _read_raw_param_bytes(params_obj, key) + if raw_value: + return _to_text(raw_value).strip() + return "" + + selected_model = persisted_text("Model") or persisted_text("DrivingModel") + selected_version = persisted_text("ModelVersion") or persisted_text("DrivingModelVersion") + selected_name = persisted_text("DrivingModelName").lower() + + is_legacy_default = selected_model.lower() in {"sc", "sc2"} + is_legacy_metadata = (not selected_version or selected_version.lower() == "v11") and (not selected_name or selected_name.startswith("south carolina")) + if is_legacy_default and is_legacy_metadata: + for key, value in { + "Model": "rdf", + "DrivingModel": "rdf", + "DrivingModelName": "Regret Driven Framework", + "ModelVersion": "v15", + "DrivingModelVersion": "v15", + }.items(): + params.put(key, value) + params_cache.put(key, value) + cloudlog.warning("Migrated the bundled default model from South Carolina to RDF") + + try: + STARPILOT_DEFAULT_MODEL_MIGRATION_FLAG.parent.mkdir(parents=True, exist_ok=True) + STARPILOT_DEFAULT_MODEL_MIGRATION_FLAG.write_text(f"{datetime.datetime.now(datetime.UTC).isoformat()}\n") + except Exception: + cloudlog.exception(f"Failed to write migration flag: {STARPILOT_DEFAULT_MODEL_MIGRATION_FLAG}") + + +def migrate_starpilot_ce_model_stop_time(params: Params, params_cache: Params) -> None: + """Move the old persisted 7-second stop prediction default to 9 seconds once.""" + if STARPILOT_CE_MODEL_STOP_TIME_MIGRATION_FLAG.exists(): + return + + legacy_default_detected = False + for params_obj in (params, params_cache): + raw_value = _read_raw_param_bytes(params_obj, "CEModelStopTime") + if not raw_value: + continue + + try: + parsed_value = float(raw_value.decode("utf-8", errors="strict").strip()) + except Exception: + continue + + if abs(parsed_value - 7.0) < 1e-6: + legacy_default_detected = True + break + + if legacy_default_detected: + params.put_float("CEModelStopTime", 9.0) + params_cache.put_float("CEModelStopTime", 9.0) + cloudlog.warning("Migrated CEModelStopTime from 7 seconds to 9 seconds") + + try: + STARPILOT_CE_MODEL_STOP_TIME_MIGRATION_FLAG.parent.mkdir(parents=True, exist_ok=True) + STARPILOT_CE_MODEL_STOP_TIME_MIGRATION_FLAG.write_text(f"{datetime.datetime.now(datetime.UTC).isoformat()}\n") + except Exception: + cloudlog.exception(f"Failed to write migration flag: {STARPILOT_CE_MODEL_STOP_TIME_MIGRATION_FLAG}") + + def migrate_disable_humanlike_defaults(params: Params, params_cache: Params) -> None: if STARPILOT_HUMANLIKE_DISABLE_MIGRATION_FLAG.exists(): return @@ -922,6 +993,8 @@ def manager_init() -> None: migrate_param_type_canonicalization(params) cleanup_removed_starpilot_params(params, params_cache) migrate_starpilot_default_parity(params, params_cache) + migrate_starpilot_default_model(params, params_cache) + migrate_starpilot_ce_model_stop_time(params, params_cache) migrate_disable_humanlike_defaults(params, params_cache) migrate_cluster_offset_default(params, params_cache) migrate_traffic_mode_smooth_defaults(params, params_cache) diff --git a/system/manager/test/test_manager.py b/system/manager/test/test_manager.py index b9fe4d1a20..9e8863d409 100644 --- a/system/manager/test/test_manager.py +++ b/system/manager/test/test_manager.py @@ -240,6 +240,39 @@ class TestManager: assert params.get("CEModelStopTime") == "3.5" assert params_cache.get_bool("NNFF") + def test_migrate_starpilot_default_model(self, tmp_path, monkeypatch): + monkeypatch.setattr(manager, "STARPILOT_DEFAULT_MODEL_MIGRATION_FLAG", tmp_path / "starpilot_default_model_rdf_v1") + + params = FileBackedFakeParams(tmp_path / "params", { + "Model": "sc2", + "DrivingModel": "sc2", + "DrivingModelName": "South Carolina", + "ModelVersion": "v11", + "DrivingModelVersion": "v11", + }) + params_cache = FileBackedFakeParams(tmp_path / "cache") + + manager.migrate_starpilot_default_model(params, params_cache) + + assert params.get("Model") == "rdf" + assert params.get("DrivingModel") == "rdf" + assert params.get("DrivingModelName") == "Regret Driven Framework" + assert params.get("ModelVersion") == "v15" + assert params_cache.get("DrivingModel") == "rdf" + assert manager.STARPILOT_DEFAULT_MODEL_MIGRATION_FLAG.exists() + + def test_migrate_starpilot_ce_model_stop_time(self, tmp_path, monkeypatch): + monkeypatch.setattr(manager, "STARPILOT_CE_MODEL_STOP_TIME_MIGRATION_FLAG", tmp_path / "starpilot_ce_model_stop_time_v1") + + params = FileBackedFakeParams(tmp_path / "params", {"CEModelStopTime": 7.0}) + params_cache = FileBackedFakeParams(tmp_path / "cache") + + manager.migrate_starpilot_ce_model_stop_time(params, params_cache) + + assert params.get("CEModelStopTime") == "9.0" + assert params_cache.get("CEModelStopTime") == "9.0" + assert manager.STARPILOT_CE_MODEL_STOP_TIME_MIGRATION_FLAG.exists() + def test_migrate_disable_humanlike_defaults(self, tmp_path, monkeypatch): monkeypatch.setattr(manager, "STARPILOT_HUMANLIKE_DISABLE_MIGRATION_FLAG", tmp_path / "starpilot_humanlike_disable_v1") diff --git a/tinygrad_repo/tinygrad/runtime/support/usb.py b/tinygrad_repo/tinygrad/runtime/support/usb.py index 77dcfb1a75..37cf6815ab 100644 --- a/tinygrad_repo/tinygrad/runtime/support/usb.py +++ b/tinygrad_repo/tinygrad/runtime/support/usb.py @@ -222,10 +222,11 @@ class CustomASM24Controller: self._f0_out_buf, self._f0_out_mv = alloc_cbuffer(0x1000) # for f0 and e4, allocate big enough for e4 self._f0_in_buf, _ = alloc_cbuffer(8) - # Custom firmware now boots with PCIe off. Power it on before probing the link. - ltssm = self.read(0xB450, 1)[0] - if ltssm != 0x78: self.set_pcie_power(True) - ltssm = self.read(0xB450, 1)[0] + if (ltssm := self.read(0xB450, 1)[0]) != 0x78: + self.set_pcie_power(True) + grace_period = time.monotonic() + 5.0 + while time.monotonic() < grace_period and (ltssm := self.read(0xB450, 1)[0]) != 0x78: + time.sleep(0.1) if ltssm != 0x78: raise RuntimeError(f"PCIe link not up (LTSSM=0x{ltssm:02X}), custom firmware not ready") def set_pcie_power(self, enabled:bool, timeout:int=10000):