mirror of
https://github.com/firestar5683/StarPilot.git
synced 2026-07-10 20:02:13 +08:00
Remember Your Roots
This commit is contained in:
Binary file not shown.
@@ -374,6 +374,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
{"NavigationUI", {PERSISTENT, BOOL, "1", "0", 1}},
|
||||
{"NNFF", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||
{"NNFFLite", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||
{"NostalgiaMode", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||
{"NNFFModelName", {CLEAR_ON_MANAGER_START, STRING, "", "", 0}},
|
||||
{"NoLogging", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||
{"NoUploads", {PERSISTENT, BOOL, "0", "0", 2}},
|
||||
|
||||
Binary file not shown.
@@ -48,6 +48,7 @@ class CarState(CarStateBase):
|
||||
self.cruise_buttons: deque = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES)
|
||||
self.main_buttons: deque = deque([Buttons.NONE] * PREV_BUTTON_SAMPLES, maxlen=PREV_BUTTON_SAMPLES)
|
||||
self.lda_button = 0
|
||||
self.left_paddle = 0
|
||||
self.mode_button = 0
|
||||
self.custom_button = 0
|
||||
|
||||
@@ -315,9 +316,13 @@ class CarState(CarStateBase):
|
||||
prev_cruise_buttons = self.cruise_buttons[-1]
|
||||
prev_main_buttons = self.main_buttons[-1]
|
||||
prev_lda_button = self.lda_button
|
||||
prev_left_paddle = self.left_paddle
|
||||
self.cruise_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"])
|
||||
self.main_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["ADAPTIVE_CRUISE_MAIN_BTN"])
|
||||
self.lda_button = cp.vl[self.cruise_btns_msg_canfd]["LDA_BTN"]
|
||||
self.left_paddle = 0
|
||||
if self.CP.carFingerprint == CAR.HYUNDAI_IONIQ_6:
|
||||
self.left_paddle = cp.vl["CRUISE_BUTTONS"]["LEFT_PADDLE"]
|
||||
self.buttons_counter = cp.vl[self.cruise_btns_msg_canfd]["COUNTER"]
|
||||
ret.accFaulted = cp.vl["TCS"]["ACCEnable"] != 0 # 0 ACC CONTROL ENABLED, 1-3 ACC CONTROL DISABLED
|
||||
|
||||
@@ -327,7 +332,8 @@ class CarState(CarStateBase):
|
||||
|
||||
ret.buttonEvents = [*create_button_events(self.cruise_buttons[-1], prev_cruise_buttons, BUTTONS_DICT),
|
||||
*create_button_events(self.main_buttons[-1], prev_main_buttons, {1: ButtonType.mainCruise}),
|
||||
*create_button_events(self.lda_button, prev_lda_button, {1: ButtonType.lkas})]
|
||||
*create_button_events(self.lda_button, prev_lda_button, {1: ButtonType.lkas}),
|
||||
*create_button_events(self.left_paddle, prev_left_paddle, {1: ButtonType.altButton2})]
|
||||
|
||||
ret.blockPcmEnable = not self.recent_button_interaction()
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
from hypothesis import settings, given, strategies as st
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
|
||||
from opendbc.can import CANPacker
|
||||
from opendbc.car import Bus, gen_empty_fingerprint
|
||||
from opendbc.car import Bus, ButtonType, gen_empty_fingerprint
|
||||
from opendbc.car.structs import CarParams
|
||||
from opendbc.car.fw_versions import build_fw_dict
|
||||
from opendbc.car.hyundai.carstate import CarState
|
||||
@@ -47,6 +48,10 @@ NO_DATES_PLATFORMS = {
|
||||
CANFD_EXPECTED_ECUS = {Ecu.fwdCamera, Ecu.fwdRadar}
|
||||
|
||||
|
||||
def get_test_toggles() -> SimpleNamespace:
|
||||
return SimpleNamespace(always_on_lateral_lkas=False, force_torque_controller=False, nnff=False, nnff_lite=False)
|
||||
|
||||
|
||||
class TestHyundaiFingerprint:
|
||||
def test_feature_detection(self):
|
||||
# LKA steering
|
||||
@@ -122,6 +127,37 @@ class TestHyundaiFingerprint:
|
||||
assert CarState.get_canfd_blinker_sig_names(CAR.HYUNDAI_KONA_EV_2ND_GEN, False) == ("LEFT_LAMP_ALT", "RIGHT_LAMP_ALT")
|
||||
assert CarState.get_canfd_blinker_sig_names(CAR.KIA_EV6, False) == ("LEFT_LAMP", "RIGHT_LAMP")
|
||||
|
||||
@pytest.mark.parametrize("alpha_long", [False, True])
|
||||
def test_ioniq_6_left_paddle_button_event(self, alpha_long):
|
||||
toggles = get_test_toggles()
|
||||
fingerprint = gen_empty_fingerprint()
|
||||
CP = CarInterface.get_params(CAR.HYUNDAI_IONIQ_6, fingerprint, [], alpha_long, False, False, toggles)
|
||||
FPCP = CarInterface.get_starpilot_params(CAR.HYUNDAI_IONIQ_6, fingerprint, [], CP, toggles)
|
||||
|
||||
car_state = CarState(CP, FPCP)
|
||||
can_parsers = car_state.get_can_parsers(CP)
|
||||
packer = CANPacker(DBC[CP.carFingerprint][Bus.pt])
|
||||
can_bus = CanBus(CP).ECAN
|
||||
|
||||
def update(left_paddle: int, frame: int):
|
||||
msg = packer.make_can_msg("CRUISE_BUTTONS", can_bus, {
|
||||
"SET_ME_1": 1,
|
||||
"CRUISE_BUTTONS": 0,
|
||||
"ADAPTIVE_CRUISE_MAIN_BTN": 0,
|
||||
"LDA_BTN": 0,
|
||||
"LEFT_PADDLE": left_paddle,
|
||||
"RIGHT_PADDLE": 0,
|
||||
})
|
||||
can_parsers[Bus.pt].update([(frame, [msg])])
|
||||
return car_state.update(can_parsers, toggles)[0]
|
||||
|
||||
update(0, 1)
|
||||
ret = update(1, 2)
|
||||
assert any(be.type == ButtonType.altButton2 and be.pressed for be in ret.buttonEvents)
|
||||
|
||||
ret = update(0, 3)
|
||||
assert any(be.type == ButtonType.altButton2 and not be.pressed for be in ret.buttonEvents)
|
||||
|
||||
def test_sportage_angle_steering_uses_adas_cmd_with_send_lfa(self):
|
||||
fingerprint = gen_empty_fingerprint()
|
||||
cam_can = CanBus(None, fingerprint).CAM
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,2 +1,2 @@
|
||||
extern const uint8_t gitversion[19];
|
||||
const uint8_t gitversion[19] = "DEV-0024516f-DEBUG";
|
||||
const uint8_t gitversion[19] = "DEV-1c85fed7-DEBUG";
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1 +1 @@
|
||||
DEV-0024516f-DEBUG
|
||||
DEV-1c85fed7-DEBUG
|
||||
Binary file not shown.
@@ -33,6 +33,15 @@ class StarPilotWheelLayout(StarPilotPanel):
|
||||
"set_state": self._set_cancel_remap_state,
|
||||
"color": "#64748B",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Nostalgia Mode"),
|
||||
"desc": tr_noop("Use the left paddle to pause openpilot acceleration and braking while Always On Lateral stays active on supported Hyundai CAN-FD cars."),
|
||||
"type": "toggle",
|
||||
"get_state": lambda: self._params.get_bool("NostalgiaMode"),
|
||||
"set_state": lambda s: self._params.put_bool("NostalgiaMode", s),
|
||||
"key": "NostalgiaMode",
|
||||
"color": "#64748B",
|
||||
},
|
||||
{
|
||||
"title": tr_noop("Distance Button"),
|
||||
"type": "value",
|
||||
@@ -181,6 +190,8 @@ class StarPilotWheelLayout(StarPilotPanel):
|
||||
if key == "LKASButtonControl":
|
||||
visible &= not cs.isSubaru
|
||||
visible &= not (cs.lkasAllowedForAOL and self._params.get_bool("AlwaysOnLateral") and self._params.get_bool("AlwaysOnLateralLKAS"))
|
||||
if key == "NostalgiaMode":
|
||||
visible &= cs.isHKGCanFd and cs.hasOpenpilotLongitudinal
|
||||
if key in ("ModeButtonControl", "LongModeButtonControl", "VeryLongModeButtonControl",
|
||||
"StarButtonControl", "LongStarButtonControl", "VeryLongStarButtonControl"):
|
||||
visible &= cs.hasModeStarButtons
|
||||
|
||||
Binary file not shown.
@@ -16,7 +16,7 @@ from cereal import car, custom, log
|
||||
from opendbc.car import gen_empty_fingerprint
|
||||
from opendbc.car.car_helpers import interfaces
|
||||
from opendbc.car.gm.values import CAR as GM_CAR, EV_CAR as GM_EV_CAR, GMFlags
|
||||
from opendbc.car.hyundai.values import EV_CAR as HYUNDAI_EV_CAR, HyundaiFlags
|
||||
from opendbc.car.hyundai.values import CAR as HYUNDAI_CAR, EV_CAR as HYUNDAI_EV_CAR, HyundaiFlags
|
||||
from opendbc.car.interfaces import TORQUE_SUBSTITUTE_PATH, CarInterfaceBase, GearShifter
|
||||
from opendbc.car.mock.values import CAR as MOCK
|
||||
from opendbc.car.subaru.values import SubaruFlags
|
||||
@@ -758,6 +758,8 @@ class StarPilotVariables:
|
||||
toggle.no_uploads = self.get_value("NoUploads", condition=device_management and not self.vetting_branch)
|
||||
toggle.no_onroad_uploads = self.get_value("DisableOnroadUploads", condition=toggle.no_uploads)
|
||||
|
||||
toggle.nostalgia_mode = self.get_value("NostalgiaMode", condition=toggle.openpilot_longitudinal and toggle.car_model == HYUNDAI_CAR.HYUNDAI_IONIQ_6)
|
||||
|
||||
distance_button_control = self.get_value("DistanceButtonControl", cast=float)
|
||||
toggle.experimental_mode_via_distance = toggle.openpilot_longitudinal and distance_button_control == BUTTON_FUNCTIONS["EXPERIMENTAL_MODE"]
|
||||
toggle.experimental_mode_via_press = toggle.experimental_mode_via_distance
|
||||
|
||||
@@ -0,0 +1,121 @@
|
||||
from types import SimpleNamespace
|
||||
|
||||
from openpilot.selfdrive.car.cruise import ButtonType
|
||||
from openpilot.starpilot.controls import starpilot_card as sc
|
||||
|
||||
|
||||
class FakeParams:
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.values = {}
|
||||
|
||||
def get_bool(self, key):
|
||||
return bool(self.values.get(key, False))
|
||||
|
||||
def get_int(self, key, default=0):
|
||||
return int(self.values.get(key, default))
|
||||
|
||||
def put_bool(self, key, value):
|
||||
self.values[key] = bool(value)
|
||||
|
||||
def put_int(self, key, value):
|
||||
self.values[key] = int(value)
|
||||
|
||||
def put_bool_nonblocking(self, key, value):
|
||||
self.put_bool(key, value)
|
||||
|
||||
|
||||
class FakeSubMaster(dict):
|
||||
def __init__(self, *args, updated=None, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.updated = updated or {}
|
||||
|
||||
|
||||
def build_card(monkeypatch):
|
||||
monkeypatch.setattr(sc, "Params", FakeParams)
|
||||
monkeypatch.setattr(sc.messaging, "PubMaster", lambda *_args, **_kwargs: SimpleNamespace(send=lambda *_a, **_k: None))
|
||||
monkeypatch.setattr(sc, "is_FrogsGoMoo", lambda: False)
|
||||
|
||||
cp = SimpleNamespace(brand="hyundai", openpilotLongitudinalControl=True)
|
||||
fpcp = SimpleNamespace(alternativeExperience=0)
|
||||
return sc.StarPilotCard(cp, fpcp)
|
||||
|
||||
|
||||
def build_sm(long_active):
|
||||
return FakeSubMaster({
|
||||
"carControl": SimpleNamespace(longActive=long_active),
|
||||
"selfdriveState": SimpleNamespace(active=True, enabled=True, experimentalMode=False, alertType=[]),
|
||||
"starpilotPlan": SimpleNamespace(lateralCheck=True),
|
||||
"liveCalibration": SimpleNamespace(calPerc=1),
|
||||
"starpilotSelfdriveState": SimpleNamespace(alertType=[]),
|
||||
}, updated={"starpilotPlan": False})
|
||||
|
||||
|
||||
def build_car_state(button_events):
|
||||
return SimpleNamespace(
|
||||
buttonEvents=button_events,
|
||||
cruiseState=SimpleNamespace(available=False),
|
||||
gearShifter=sc.GearShifter.drive,
|
||||
brakePressed=False,
|
||||
gasPressed=False,
|
||||
standstill=False,
|
||||
vEgo=15.0,
|
||||
)
|
||||
|
||||
|
||||
def build_starpilot_car_state():
|
||||
return SimpleNamespace(
|
||||
distancePressed=False,
|
||||
modePressed=False,
|
||||
customPressed=False,
|
||||
)
|
||||
|
||||
|
||||
def build_toggles(nostalgia_mode):
|
||||
return SimpleNamespace(
|
||||
nostalgia_mode=nostalgia_mode,
|
||||
always_on_lateral_lkas=False,
|
||||
always_on_lateral_main=False,
|
||||
always_on_lateral_pause_speed=0.0,
|
||||
has_canfd_media_buttons=False,
|
||||
)
|
||||
|
||||
|
||||
def test_nostalgia_mode_paddle_pauses_longitudinal(monkeypatch):
|
||||
card = build_card(monkeypatch)
|
||||
car_state = build_car_state([SimpleNamespace(type=ButtonType.altButton2, pressed=True)])
|
||||
starpilot_car_state = build_starpilot_car_state()
|
||||
|
||||
ret = card.update(car_state, starpilot_car_state, build_sm(True), build_toggles(True))
|
||||
|
||||
assert ret.pauseLongitudinal is True
|
||||
|
||||
|
||||
def test_nostalgia_mode_resume_button_clears_pause(monkeypatch):
|
||||
card = build_card(monkeypatch)
|
||||
toggles = build_toggles(True)
|
||||
|
||||
card.update(
|
||||
build_car_state([SimpleNamespace(type=ButtonType.altButton2, pressed=True)]),
|
||||
build_starpilot_car_state(),
|
||||
build_sm(True),
|
||||
toggles,
|
||||
)
|
||||
|
||||
ret = card.update(
|
||||
build_car_state([SimpleNamespace(type=ButtonType.resumeCruise, pressed=True)]),
|
||||
build_starpilot_car_state(),
|
||||
build_sm(False),
|
||||
toggles,
|
||||
)
|
||||
|
||||
assert ret.pauseLongitudinal is False
|
||||
|
||||
|
||||
def test_nostalgia_mode_off_ignores_paddle(monkeypatch):
|
||||
card = build_card(monkeypatch)
|
||||
car_state = build_car_state([SimpleNamespace(type=ButtonType.altButton2, pressed=True)])
|
||||
starpilot_car_state = build_starpilot_car_state()
|
||||
|
||||
ret = card.update(car_state, starpilot_car_state, build_sm(True), build_toggles(False))
|
||||
|
||||
assert ret.pauseLongitudinal is False
|
||||
@@ -30,6 +30,7 @@ class StarPilotCard:
|
||||
self.force_coast = False
|
||||
self.modePressed_previously = False
|
||||
self.mode_counter = 0
|
||||
self.nostalgia_pause_longitudinal = False
|
||||
self.customPressed_previously = False
|
||||
self.custom_counter = 0
|
||||
self.pause_lateral = False
|
||||
@@ -82,6 +83,7 @@ class StarPilotCard:
|
||||
|
||||
def update(self, carState, starpilotCarState, sm, starpilot_toggles):
|
||||
self.switchback_mode_enabled = self.params_memory.get_bool("SwitchbackModeEnabled")
|
||||
nostalgia_mode = getattr(starpilot_toggles, "nostalgia_mode", False)
|
||||
|
||||
if self.CP.brand == "hyundai":
|
||||
for be in carState.buttonEvents:
|
||||
@@ -133,6 +135,15 @@ class StarPilotCard:
|
||||
if any(be.pressed and be.type == ButtonType.lkas for be in carState.buttonEvents):
|
||||
self.handle_button_event("lkas", sm, starpilot_toggles)
|
||||
|
||||
if not nostalgia_mode or not self.CP.openpilotLongitudinalControl or not sm["selfdriveState"].enabled:
|
||||
self.nostalgia_pause_longitudinal = False
|
||||
else:
|
||||
if any(be.pressed and be.type == ButtonType.altButton2 for be in carState.buttonEvents) and sm["carControl"].longActive:
|
||||
self.nostalgia_pause_longitudinal = True
|
||||
if any(be.pressed and be.type in (ButtonType.accelCruise, ButtonType.resumeCruise,
|
||||
ButtonType.decelCruise, ButtonType.setCruise) for be in carState.buttonEvents):
|
||||
self.nostalgia_pause_longitudinal = False
|
||||
|
||||
if getattr(starpilot_toggles, "has_canfd_media_buttons", False):
|
||||
if starpilotCarState.modePressed:
|
||||
self.mode_counter += 1
|
||||
@@ -173,7 +184,7 @@ class StarPilotCard:
|
||||
starpilotCarState.forceCoast = self.force_coast
|
||||
starpilotCarState.isParked = carState.gearShifter == GearShifter.park
|
||||
starpilotCarState.pauseLateral = self.pause_lateral
|
||||
starpilotCarState.pauseLongitudinal = self.pause_longitudinal
|
||||
starpilotCarState.pauseLongitudinal = self.pause_longitudinal or self.nostalgia_pause_longitudinal
|
||||
starpilotCarState.trafficModeEnabled = self.traffic_mode_enabled
|
||||
|
||||
return starpilotCarState
|
||||
|
||||
@@ -2220,6 +2220,13 @@
|
||||
"data_type": "bool",
|
||||
"ui_type": "toggle"
|
||||
},
|
||||
{
|
||||
"key": "NostalgiaMode",
|
||||
"label": "Nostalgia Mode",
|
||||
"description": "Use the left paddle to pause openpilot acceleration and braking while Always On Lateral stays active on supported Hyundai CAN-FD cars.",
|
||||
"data_type": "bool",
|
||||
"ui_type": "toggle"
|
||||
},
|
||||
{
|
||||
"key": "DistanceButtonControl",
|
||||
"label": "Distance Button (Short Press)",
|
||||
|
||||
@@ -53,6 +53,21 @@ bool lockLkasButtonIfNeeded(Params ¶ms) {
|
||||
StarPilotWheelPanel::StarPilotWheelPanel(StarPilotSettingsWindow *parent, bool forceOpen) : StarPilotListWidget(parent), parent(parent) {
|
||||
forceOpenDescriptions = forceOpen;
|
||||
|
||||
ParamControl *nostalgiaModeToggle = new ParamControl(
|
||||
"NostalgiaMode",
|
||||
tr("Nostalgia Mode"),
|
||||
tr("<b>Use the left paddle to pause openpilot acceleration and braking while Always On Lateral stays active on supported Hyundai CAN-FD cars.</b>"),
|
||||
"../../starpilot/assets/toggle_icons/icon_mute.png"
|
||||
);
|
||||
toggles["NostalgiaMode"] = nostalgiaModeToggle;
|
||||
addItem(nostalgiaModeToggle);
|
||||
QObject::connect(nostalgiaModeToggle, &AbstractControl::hideDescriptionEvent, [this]() {
|
||||
update();
|
||||
});
|
||||
QObject::connect(nostalgiaModeToggle, &AbstractControl::showDescriptionEvent, [this]() {
|
||||
update();
|
||||
});
|
||||
|
||||
const std::vector<std::tuple<QString, QString, QString, QString>> wheelToggles {
|
||||
{"DistanceButtonControl", tr("Distance Button"), tr("<b>Action performed when the \"Distance\" button is pressed.</b>"), "../../starpilot/assets/toggle_icons/icon_mute.png"},
|
||||
{"LongDistanceButtonControl", tr("Distance Button (Long Press)"), tr("<b>Action performed when the \"Distance\" button is pressed for more than 0.5 seconds.</b>"), "../../starpilot/assets/toggle_icons/icon_mute.png"},
|
||||
@@ -128,6 +143,11 @@ void StarPilotWheelPanel::updateToggles() {
|
||||
setVisible &= !parent->lkasAllowedForAOL || !(params.getBool("AlwaysOnLateral") && params.getBool("AlwaysOnLateralLKAS"));
|
||||
}
|
||||
|
||||
if (!showAllToggles && key == "NostalgiaMode") {
|
||||
setVisible &= parent->isHKGCanFd;
|
||||
setVisible &= parent->hasOpenpilotLongitudinal;
|
||||
}
|
||||
|
||||
if (!showAllToggles && (
|
||||
key == "ModeButtonControl" ||
|
||||
key == "LongModeButtonControl" ||
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Reference in New Issue
Block a user