mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-09-30 06:13:43 +08:00
fix(long): SPORT's jerk_scale
This commit is contained in:
@@ -15,7 +15,6 @@ from cereal import custom
|
||||
AccelerationPersonality = custom.LongitudinalPlanSP.AccelerationPersonality
|
||||
ECO = AccelerationPersonality.eco
|
||||
NORMAL = AccelerationPersonality.normal
|
||||
SPORT = AccelerationPersonality.sport
|
||||
|
||||
PERSONALITY_MIN = min(AccelerationPersonality.schema.enumerants.values())
|
||||
PERSONALITY_MAX = max(AccelerationPersonality.schema.enumerants.values())
|
||||
@@ -51,11 +50,18 @@ RISE_RATE_V = {
|
||||
# upstream get_jerk_factor(personality) -- stock 1.0 for relaxed/standard, 0.5 for aggressive. JERK_SCALE
|
||||
# multiplies into that same upstream factor (same lever stock's aggressive tier already uses), bounded to
|
||||
# near a stop and ramped back to 1.0 (stock) by cruise speed.
|
||||
# The v=0 knot is NOT monotone with personality -- verified via a closed-loop MPC harness (dead stop +
|
||||
# departing lead, 3 scenarios): 0.60/0.45 both measurably beat stock 1.0 (0.3-0.65s faster to cross the
|
||||
# should_stop 0.1 m/s^2 gate, 0 solver resets), but pushing lower is NOT "more relaxed = faster" -- 0.30 came
|
||||
# back SLOWER than stock in all 3 scenarios (the MPC back-loads the ramp instead of front-loading it once
|
||||
# A_CHANGE_COST/J_EGO_COST get too cheap to bother avoiding), and below ~0.15 the solver itself destabilizes
|
||||
# (46-68% QP resets). SPORT's knot is pinned to the verified-good value (tied with NORMAL) rather than pushed
|
||||
# lower for tier-consistency -- lower is not safe or effective here, unlike every other tier table in this file.
|
||||
JERK_SCALE_BP = [0., 5.] # m/s
|
||||
JERK_SCALE_V = {
|
||||
ECO: [0.60, 1.0],
|
||||
NORMAL: [0.45, 1.0],
|
||||
SPORT: [0.30, 1.0],
|
||||
SPORT: [0.45, 1.0],
|
||||
}
|
||||
|
||||
# --- Onset jerk-cost relaxation (MPC INPUT: general accel<->decel-direction change, not just launch) ------
|
||||
|
||||
@@ -155,7 +155,7 @@ def test_jerk_scale_disabled_is_stock():
|
||||
|
||||
|
||||
def test_jerk_scale_relaxed_near_stop_flat_at_speed():
|
||||
for personality, relaxed in ((ECO, 0.60), (NORMAL, 0.45), (SPORT, 0.30)):
|
||||
for personality, relaxed in ((ECO, 0.60), (NORMAL, 0.45), (SPORT, 0.45)):
|
||||
ctrl = make_controller(personality=personality)
|
||||
assert ctrl.get_jerk_scale(0.0) == pytest.approx(relaxed)
|
||||
assert ctrl.get_jerk_scale(5.0) == pytest.approx(1.0) # back to stock by the v=5 knot
|
||||
@@ -171,10 +171,15 @@ def test_jerk_scale_never_exceeds_stock():
|
||||
|
||||
|
||||
def test_jerk_scale_tier_ordering_at_stop():
|
||||
# NOT a strict SPORT<NORMAL<ECO ordering here (unlike every other tier table in this file) -- verified via
|
||||
# a closed-loop MPC harness that pushing the v=0 knot lower than ~0.45 is counterproductive (the MPC
|
||||
# back-loads the ramp instead of front-loading it), so SPORT is pinned to NORMAL's value instead of being
|
||||
# pushed lower for tier-consistency. See the JERK_SCALE_V comment in constants.py.
|
||||
eco = make_controller(personality=ECO).get_jerk_scale(0.0)
|
||||
nrm = make_controller(personality=NORMAL).get_jerk_scale(0.0)
|
||||
spt = make_controller(personality=SPORT).get_jerk_scale(0.0)
|
||||
assert spt < nrm < eco # SPORT relaxes the most (most responsive launch), ECO the least
|
||||
assert spt == pytest.approx(nrm)
|
||||
assert nrm < eco
|
||||
|
||||
|
||||
def test_jerk_scale_table_matches_constants():
|
||||
@@ -184,6 +189,15 @@ def test_jerk_scale_table_matches_constants():
|
||||
assert ctrl.get_jerk_scale(v) == pytest.approx(np.interp(v, JERK_SCALE_BP, JERK_SCALE_V[personality]))
|
||||
|
||||
|
||||
def test_jerk_scale_v0_knot_stays_out_of_the_counterproductive_zone():
|
||||
# Regression guard for the verified finding: pushing the v=0 knot below ~0.45 stops helping and starts
|
||||
# hurting (measured via a closed-loop MPC harness -- 0.30 came back slower than stock in every scenario
|
||||
# tested, and below ~0.15 the solver itself destabilizes). No tier's launch floor should regress into that
|
||||
# zone even if someone re-tunes ECO/NORMAL/SPORT independently later.
|
||||
for personality in (ECO, NORMAL, SPORT):
|
||||
assert JERK_SCALE_V[personality][0] >= 0.40
|
||||
|
||||
|
||||
# --- onset relax: fresh accel<->decel direction change, any speed ------------------------------------------
|
||||
|
||||
def test_onset_disabled_is_stock():
|
||||
|
||||
Reference in New Issue
Block a user