Haberdashery

This commit is contained in:
firestar5683
2026-06-07 20:16:35 -05:00
parent 9c51a6024e
commit cf1c99cf78
11 changed files with 29 additions and 160 deletions
-1
View File
@@ -284,7 +284,6 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
{"FlashPanda", {CLEAR_ON_MANAGER_START, BOOL, "0", "0"}},
{"GMDashSpoofOffsets", {PERSISTENT, BOOL, "0", "0", 2}},
{"GMPedalLongitudinal", {PERSISTENT, BOOL, "1", "1", 2}},
{"GMStockDashWhenNotEngaged", {PERSISTENT, BOOL, "0", "0", 2}},
{"LongPitch", {PERSISTENT, BOOL, "1", "0", 2}},
{"RemoteStartBootsComma", {PERSISTENT, BOOL, "0", "0"}},
{"RemapCancelToDistance", {PERSISTENT, BOOL, "0", "0"}},
+5 -31
View File
@@ -68,14 +68,13 @@ def should_spoof_dash_speed(CP, starpilot_toggles):
return True
def should_send_acc_dashboard_status(CP, dash_speed_spoof_active, enabled=True, stock_dash_when_not_engaged=False):
def should_send_acc_dashboard_status(CP, dash_speed_spoof_active):
status_car = CP.carFingerprint not in CC_ONLY_CAR or CP.carFingerprint == CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL
volt_camera_no_camera = (
CP.carFingerprint == CAR.CHEVROLET_VOLT_CAMERA and
bool(getattr(CP, "flags", 0) & GMFlags.NO_CAMERA.value)
)
should_spoof = dash_speed_spoof_active and (enabled or not stock_dash_when_not_engaged)
return status_car and (should_spoof or volt_camera_no_camera)
return status_car and (dash_speed_spoof_active or volt_camera_no_camera)
def get_acc_dashboard_fcw_alert(hud_alert, CS):
@@ -93,29 +92,6 @@ def get_acc_dashboard_fcw_alert(hud_alert, CS):
return 0
def get_acc_dashboard_status_values(enabled, target_speed_kph, hud_control, CS):
if enabled:
return {
"ACCCruiseState": 0,
"ACCLeadCar": int(hud_control.leadVisible) & 0x1,
"ACCResumeButton": 0,
"ACCSpeedSetpoint": target_speed_kph,
"ACCGapLevel": int(hud_control.leadDistanceBars) & 0x3,
"ACCCmdActive": 1,
}
# Replay the stock camera dashboard context when openpilot long is enabled
# but openpilot itself is not actively driving the ACC cluster state.
return {
"ACCCruiseState": int(getattr(CS, "stock_acc_cruise_state", 0)) & 0x7,
"ACCLeadCar": int(getattr(CS, "stock_acc_lead_car", 0)) & 0x1,
"ACCResumeButton": int(getattr(CS, "stock_acc_resume_button", 0)) & 0x1,
"ACCSpeedSetpoint": float(getattr(CS, "stock_acc_speed_setpoint_kph", 0.0)),
"ACCGapLevel": int(getattr(CS, "stock_acc_gap_level", 0)) & 0x3,
"ACCCmdActive": int(getattr(CS, "stock_acc_cmd_active", 0)) & 0x1,
}
ECM_CRUISE_SPOOF_CARS = {
CAR.CHEVROLET_BOLT_CC_2017,
CAR.CHEVROLET_BOLT_CC_2018_2021,
@@ -726,12 +702,10 @@ class CarController(CarControllerBase):
idx, CC.enabled, near_stop, at_full_stop, self.CP))
CS.auto_hold_engaged = False
stock_dash_when_not_engaged = getattr(starpilot_toggles, "gm_stock_dash_when_not_engaged", False)
if should_send_acc_dashboard_status(self.CP, dash_speed_spoof_active, CC.enabled, stock_dash_when_not_engaged):
acc_dashboard_status = get_acc_dashboard_status_values(CC.enabled, hud_v_cruise * CV.MS_TO_KPH, hud_control, CS)
if should_send_acc_dashboard_status(self.CP, dash_speed_spoof_active):
fcw_alert = get_acc_dashboard_fcw_alert(hud_alert, CS)
can_sends.append(gmcan.create_acc_dashboard_command(self.packer_pt, CanBus.POWERTRAIN,
acc_dashboard_status, fcw_alert))
can_sends.append(gmcan.create_acc_dashboard_command(self.packer_pt, CanBus.POWERTRAIN, CC.enabled,
hud_v_cruise * CV.MS_TO_KPH, hud_control, fcw_alert))
# Radar needs to know current speed and yaw rate (50hz),
# and that ADAS is alive (10hz)
-12
View File
@@ -90,12 +90,6 @@ class CarState(CarStateBase):
self.lkas_enabled = 0
self.pcm_acc_status = AccState.OFF
self.stock_fcw_alert = 0
self.stock_acc_cruise_state = 0
self.stock_acc_lead_car = 0
self.stock_acc_resume_button = 0
self.stock_acc_speed_setpoint_kph = 0.0
self.stock_acc_gap_level = 0
self.stock_acc_cmd_active = 0
def update_button_enable(self, buttonEvents: list[structs.CarState.ButtonEvent]):
if not self.CP.pcmCruise:
@@ -307,12 +301,6 @@ class CarState(CarStateBase):
acc_dashboard_status = cam_cp.vl["ASCMActiveCruiseControlStatus"]
if self.CP.carFingerprint not in CC_ONLY_CAR:
ret.cruiseState.speed = acc_dashboard_status["ACCSpeedSetpoint"] * CV.KPH_TO_MS
self.stock_acc_cruise_state = int(acc_dashboard_status["ACCCruiseState"])
self.stock_acc_lead_car = int(acc_dashboard_status["ACCLeadCar"])
self.stock_acc_resume_button = int(acc_dashboard_status["ACCResumeButton"])
self.stock_acc_speed_setpoint_kph = float(acc_dashboard_status["ACCSpeedSetpoint"])
self.stock_acc_gap_level = int(acc_dashboard_status["ACCGapLevel"])
self.stock_acc_cmd_active = int(acc_dashboard_status["ACCCmdActive"])
# Preserve the stock camera FCW level from 0x370 so the controller can
# replay it when that message is blocked and spoofed by openpilot long.
self.stock_fcw_alert = int(acc_dashboard_status["FCWAlert"])
+6 -7
View File
@@ -209,18 +209,17 @@ def create_friction_brake_command(packer, bus, apply_brake, idx, enabled, near_s
return packer.make_can_msg("EBCMFrictionBrakeCmd", bus, values)
def create_acc_dashboard_command(packer, bus, status_values, fcw_alert):
target_speed = min(max(float(status_values.get("ACCSpeedSetpoint", 0.0)), 0.0), 255.0)
def create_acc_dashboard_command(packer, bus, enabled, target_speed_kph, hud_control, fcw_alert):
target_speed = min(target_speed_kph, 255)
values = {
"ACCAlwaysOne": 1,
"ACCCruiseState": int(status_values.get("ACCCruiseState", 0)) & 0x7,
"ACCResumeButton": int(status_values.get("ACCResumeButton", 0)) & 0x1,
"ACCResumeButton": 0,
"ACCSpeedSetpoint": target_speed,
"ACCGapLevel": int(status_values.get("ACCGapLevel", 0)) & 0x3,
"ACCCmdActive": int(status_values.get("ACCCmdActive", 0)) & 0x1,
"ACCGapLevel": hud_control.leadDistanceBars * enabled, # 3 "far", 0 "inactive"
"ACCCmdActive": enabled,
"ACCAlwaysOne2": 1,
"ACCLeadCar": int(status_values.get("ACCLeadCar", 0)) & 0x1,
"ACCLeadCar": hud_control.leadVisible,
"FCWAlert": int(fcw_alert) & 0x3,
}
+16 -88
View File
@@ -10,7 +10,6 @@ from opendbc.car.gm.carstate import CarState as GMCarState, get_hard_cruise_butt
from opendbc.car.gm.carcontroller import (
VisualAlert,
get_acc_dashboard_fcw_alert,
get_acc_dashboard_status_values,
should_send_acc_dashboard_status,
should_send_cc_button_spam,
should_spoof_dash_speed,
@@ -265,33 +264,6 @@ class TestGMCarController:
assert should_send_acc_dashboard_status(cp, dash_speed_spoof_active=False)
def test_stock_dash_toggle_suppresses_disabled_dash_spoof(self):
cp = SimpleNamespace(carFingerprint=CAR.CADILLAC_XT4, flags=0)
assert should_send_acc_dashboard_status(cp, dash_speed_spoof_active=True, enabled=False)
assert not should_send_acc_dashboard_status(
cp,
dash_speed_spoof_active=True,
enabled=False,
stock_dash_when_not_engaged=True,
)
assert should_send_acc_dashboard_status(
cp,
dash_speed_spoof_active=True,
enabled=True,
stock_dash_when_not_engaged=True,
)
def test_stock_dash_toggle_keeps_no_camera_exception(self):
cp = SimpleNamespace(carFingerprint=CAR.CHEVROLET_VOLT_CAMERA, flags=GMFlags.NO_CAMERA.value)
assert should_send_acc_dashboard_status(
cp,
dash_speed_spoof_active=True,
enabled=False,
stock_dash_when_not_engaged=True,
)
def test_acc_dashboard_no_camera_exception_is_volt_camera_only(self):
assert not should_send_acc_dashboard_status(
SimpleNamespace(carFingerprint=CAR.CHEVROLET_VOLT_CAMERA, flags=0),
@@ -385,14 +357,9 @@ class TestGMCarController:
msg = gmcan.create_acc_dashboard_command(
packer,
0,
{
"ACCCruiseState": 0,
"ACCLeadCar": 1,
"ACCResumeButton": 0,
"ACCSpeedSetpoint": 100,
"ACCGapLevel": 3,
"ACCCmdActive": 1,
},
True,
100,
SimpleNamespace(leadDistanceBars=3, leadVisible=True),
0x2,
)
@@ -400,23 +367,26 @@ class TestGMCarController:
assert parser.vl["ASCMActiveCruiseControlStatus"]["FCWAlert"] == 2
def test_acc_dashboard_command_can_replay_stock_status_payload(self):
def test_acc_dashboard_command_uses_openpilot_hud_when_disengaged(self):
packer = CANPacker(DBC[CAR.CHEVROLET_VOLT_ASCM][Bus.pt])
parser = CANParser(DBC[CAR.CHEVROLET_VOLT_ASCM][Bus.pt], [("ASCMActiveCruiseControlStatus", 0)], 0)
msg = gmcan.create_acc_dashboard_command(
packer,
0,
{
"ACCCruiseState": 0,
"ACCLeadCar": 1,
"ACCResumeButton": 0,
"ACCSpeedSetpoint": 50,
"ACCGapLevel": 2,
"ACCCmdActive": 0,
},
False,
50,
SimpleNamespace(leadDistanceBars=2, leadVisible=True),
0x3,
)
assert msg[1].hex() == "010023200113"
parser.update([0, [msg]])
values = parser.vl["ASCMActiveCruiseControlStatus"]
assert values["ACCSpeedSetpoint"] == 50
assert values["ACCGapLevel"] == 0
assert values["ACCCmdActive"] == 0
assert values["ACCLeadCar"] == 1
assert values["FCWAlert"] == 3
def test_acc_dashboard_fcw_alert_prefers_openpilot_alert(self):
cs = SimpleNamespace(
@@ -449,45 +419,3 @@ class TestGMCarController:
)
assert get_acc_dashboard_fcw_alert(VisualAlert.none, cs) == 0x3
def test_acc_dashboard_status_values_use_openpilot_hud_when_enabled(self):
cs = SimpleNamespace(
stock_acc_cruise_state=5,
stock_acc_lead_car=0,
stock_acc_resume_button=1,
stock_acc_speed_setpoint_kph=42.0,
stock_acc_gap_level=1,
stock_acc_cmd_active=0,
)
values = get_acc_dashboard_status_values(True, 105.0, SimpleNamespace(leadDistanceBars=3, leadVisible=True), cs)
assert values == {
"ACCCruiseState": 0,
"ACCLeadCar": 1,
"ACCResumeButton": 0,
"ACCSpeedSetpoint": 105.0,
"ACCGapLevel": 3,
"ACCCmdActive": 1,
}
def test_acc_dashboard_status_values_reuse_stock_camera_status_when_disabled(self):
cs = SimpleNamespace(
stock_acc_cruise_state=0,
stock_acc_lead_car=1,
stock_acc_resume_button=0,
stock_acc_speed_setpoint_kph=50.0,
stock_acc_gap_level=2,
stock_acc_cmd_active=0,
)
values = get_acc_dashboard_status_values(False, 0.0, SimpleNamespace(leadDistanceBars=0, leadVisible=False), cs)
assert values == {
"ACCCruiseState": 0,
"ACCLeadCar": 1,
"ACCResumeButton": 0,
"ACCSpeedSetpoint": 50.0,
"ACCGapLevel": 2,
"ACCCmdActive": 0,
}
@@ -145,12 +145,6 @@ class VehicleSettingsManagerView(AetherInteractiveMixin, Widget):
"set_state": lambda s: self._controller._on_toggle("GMDashSpoofOffsets"),
})
if cs.isGM and cs.hasOpenpilotLongitudinal:
toggles.append({
"title": tr("Stock Dash Disengaged"),
"subtitle": tr("Use the stock GM dash set speed while openpilot is not engaged."),
"get_state": lambda: self._controller._params.get_bool("GMStockDashWhenNotEngaged"),
"set_state": lambda s: self._controller._on_toggle("GMStockDashWhenNotEngaged"),
})
toggles.append({
"title": tr("Remote Start Panda"),
"get_state": lambda: self._controller._params.get_bool("RemoteStartBootsComma"),
-1
View File
@@ -184,7 +184,6 @@ SAFE_MODE_MANAGED_KEYS = (
"GMAutoHold",
"GMPedalLongitudinal",
"GMDashSpoofOffsets",
"GMStockDashWhenNotEngaged",
"LongPitch",
)
-4
View File
@@ -1329,10 +1329,6 @@ class StarPilotVariables:
"GMDashSpoofOffsets",
condition=toggle.car_make == "gm" and toggle.has_pedal,
)
toggle.gm_stock_dash_when_not_engaged = self.get_value(
"GMStockDashWhenNotEngaged",
condition=toggle.car_make == "gm" and toggle.openpilot_longitudinal,
)
toggle.long_pitch = self.get_value(
"LongPitch",
condition=toggle.openpilot_longitudinal and toggle.car_make == "gm",
@@ -2417,13 +2417,6 @@
"data_type": "bool",
"ui_type": "toggle"
},
{
"key": "GMStockDashWhenNotEngaged",
"label": "Stock Dash When Disengaged",
"description": "Use the stock GM dashboard set speed while openpilot is not engaged. When off, StarPilot keeps the existing dashboard spoof behavior.",
"data_type": "bool",
"ui_type": "toggle"
},
{
"key": "LongPitch",
"label": "Smooth Pedal Response on Hills",
@@ -173,7 +173,6 @@ StarPilotVehiclesPanel::StarPilotVehiclesPanel(StarPilotSettingsWindow *parent,
{"GMToggles", tr("General Motors Settings"), tr("<b>StarPilot features for General Motors vehicles.</b>"), ""},
{"GMPedalLongitudinal", tr("Use Pedal For Longitudinal"), tr("<b>Use the pedal interceptor for full longitudinal control</b> on supported GM vehicles."), ""},
{"GMDashSpoofOffsets", tr("Apply Offsets To Dash Spoof"), tr("<b>On GM pedal-long cars, add the configured set-speed offset</b> to the spoofed dash set speed so it matches the on-screen set speed."), ""},
{"GMStockDashWhenNotEngaged", tr("Stock Dash When Disengaged"), tr("<b>Use the stock GM dashboard set speed while openpilot is not engaged.</b><br><br>When off, StarPilot keeps the existing dashboard spoof behavior."), ""},
{"LongPitch", tr("Smooth Pedal Response on Hills"), tr("<b>Smoothen acceleration and braking</b> when driving downhill/uphill."), ""},
{"RemoteStartBootsComma", tr("Remote Start Boots comma"), tr("<b>Use the remote-start GM panda firmware at boot.</b><br><br>Required for GM remote-start startup signal behavior."), ""},
{"RemapCancelToDistance", tr("Remap Cancel Button"), tr("<b>On pedal-interceptor Bolts, treat the steering-wheel CANCEL button as an extra mappable button.</b>"), ""},
+2 -2
View File
@@ -23,8 +23,8 @@ private:
std::map<QString, AbstractControl*> toggles;
QSet<QString> gmKeys = {"GMPedalLongitudinal", "GMDashSpoofOffsets", "GMStockDashWhenNotEngaged", "LongPitch", "RemoteStartBootsComma", "RemapCancelToDistance", "VoltSNG"};
QSet<QString> longitudinalKeys = {"FrogsGoMoosTweak", "GMDashSpoofOffsets", "GMStockDashWhenNotEngaged", "LongPitch", "RemapCancelToDistance", "SNGHack", "VoltSNG"};
QSet<QString> gmKeys = {"GMPedalLongitudinal", "GMDashSpoofOffsets", "LongPitch", "RemoteStartBootsComma", "RemapCancelToDistance", "VoltSNG"};
QSet<QString> longitudinalKeys = {"FrogsGoMoosTweak", "GMDashSpoofOffsets", "LongPitch", "RemapCancelToDistance", "SNGHack", "VoltSNG"};
QSet<QString> subaruKeys = {"SubaruSNG"};
QSet<QString> toyotaKeys = {"ClusterOffset", "FrogsGoMoosTweak", "LockDoorsTimer", "SNGHack", "ToyotaDoors"};
QSet<QString> vehicleInfoKeys = {"BlindSpotSupport", "HardwareDetected", "OpenpilotLongitudinal", "PedalSupport", "RadarSupport", "SDSUSupport", "SNGSupport"};