From 70bc99f802a376b9094fc224b49be94e7e3ea3d5 Mon Sep 17 00:00:00 2001 From: Comma Device Date: Wed, 19 Aug 2026 18:09:36 +0800 Subject: [PATCH] cruise planner: fix decel jerk from cruise (#38653) Applied upstream commit 3d09a47a: always apply cruise jerk limit in get_cruise_accel, init a_cruise/output_a_target properly, and reset from aEgo on reset_state. --- .../controls/lib/longitudinal_planner.py | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/openpilot/selfdrive/controls/lib/longitudinal_planner.py b/openpilot/selfdrive/controls/lib/longitudinal_planner.py index 8b62808dc..ca3d44b5e 100755 --- a/openpilot/selfdrive/controls/lib/longitudinal_planner.py +++ b/openpilot/selfdrive/controls/lib/longitudinal_planner.py @@ -49,9 +49,8 @@ def get_cruise_accel(e2e, v_cruise, v_ego, a_cruise_prev, angle_steers, CP, dt, max_accel = min(max_accel, coast_limit) target_accel = np.clip(v_cruise - v_ego, A_CRUISE_MIN, max_accel) - if not e2e: - j_cruise = np.interp(v_ego, A_CRUISE_MAX_BP, J_CRUISE_VALS) - target_accel = float(np.clip(target_accel, a_cruise_prev - j_cruise * dt, a_cruise_prev + j_cruise * dt)) + j_cruise = np.interp(v_ego, A_CRUISE_MAX_BP, J_CRUISE_VALS) + target_accel = float(np.clip(target_accel, a_cruise_prev - j_cruise * dt, a_cruise_prev + j_cruise * dt)) return target_accel @@ -65,10 +64,9 @@ class LongitudinalPlanner(LongitudinalPlannerSP): self.dt = dt self.allow_throttle = True - self.a_desired = init_a self.v_desired_filter = FirstOrderFilter(init_v, 2.0, self.dt) - self.a_cruise = 0.0 - self.output_a_target = 0.0 + self.a_cruise = init_a + self.output_a_target = init_a self.output_should_stop = False self.v_desired_trajectory = np.zeros(CONTROL_N) @@ -105,7 +103,8 @@ class LongitudinalPlanner(LongitudinalPlannerSP): if reset_state: self.v_desired_filter.x = v_ego - self.a_desired = np.clip(sm['carState'].aEgo, ACCEL_MIN, ACCEL_MAX) + self.output_a_target = np.clip(sm['carState'].aEgo, ACCEL_MIN, ACCEL_MAX) + self.a_cruise = self.output_a_target # Prevent divergence, smooth in current v_ego self.v_desired_filter.x = max(0.0, self.v_desired_filter.update(v_ego)) @@ -117,7 +116,7 @@ class LongitudinalPlanner(LongitudinalPlannerSP): v_cruise, self.a_desired = LongitudinalPlannerSP.update_targets(self, sm, self.v_desired_filter.x, self.a_desired, v_cruise) self.mpc.set_weights(prev_accel_constraint, personality=sm['selfdriveState'].personality) - self.mpc.set_cur_state(self.v_desired_filter.x, self.a_desired) + self.mpc.set_cur_state(self.v_desired_filter.x, self.output_a_target) self.mpc.update(sm['radarState'], personality=sm['selfdriveState'].personality) self.v_desired_trajectory = np.interp(CONTROL_N_T_IDX, T_IDXS_MPC, self.mpc.v_solution) @@ -130,7 +129,7 @@ class LongitudinalPlanner(LongitudinalPlannerSP): cloudlog.info("FCW triggered") # Save starting point for next iteration - a_prev = self.a_desired + a_prev = self.output_a_target action_t = self.CP.longitudinalActuatorDelay + DT_MDL output_a_target_mpc = get_accel_from_plan(self.v_desired_trajectory, self.a_desired_trajectory, CONTROL_N_T_IDX, @@ -155,7 +154,6 @@ class LongitudinalPlanner(LongitudinalPlannerSP): self.output_should_stop = any(should_stop for _, _, should_stop in candidates) self.output_a_target = np.clip(output_a_target, ACCEL_MIN, ACCEL_MAX) - self.a_desired = float(self.output_a_target) self.v_desired_filter.x = self.v_desired_filter.x + self.dt * (self.output_a_target + a_prev) / 2.0 def publish(self, sm, pm):