Compare commits

..

76 Commits

Author SHA1 Message Date
firestar5683 3d1a99f2af User adjustable offsets 2026-02-07 23:33:16 -06:00
firestar5683 a4d61232c6 Integrator Smooth On Handoff 2026-02-06 15:48:45 -06:00
firestar5683 5881c17c59 Lights 2026-02-05 22:40:42 -06:00
firestar5683 d5e971c32b New Models 2026-02-05 15:07:42 -06:00
firestar5683 3024ed42f5 Revert "merry christmas"
This reverts commit 8a9d0e5e6a.
2026-02-05 13:33:58 -06:00
firestar5683 09a073c242 Increase Fault Resilience 2026-02-05 13:29:00 -06:00
firestarsdog 231ef85bed Stats 2026-02-02 01:05:58 -05:00
firestarsdog 740668c973 Stats 2026-02-01 22:47:02 -06:00
firestar5683 b343c6aa98 Revert "Mac Update"
This reverts commit c32a5fda39.
2026-01-19 11:44:30 -06:00
firestarsdog cc1a0e4697 Add SASCM to vehicle settings detection/stats 2026-01-19 10:37:27 -06:00
firestar5683 c32a5fda39 Mac Update 2026-01-18 22:21:59 -06:00
firestarsdog af14724e78 Stats 2026-01-18 22:17:50 -06:00
firestar5683 c85a34f324 Update carcontroller.py 2026-01-15 22:52:25 -06:00
firestar5683 70260c0ed2 fix redneck v2 2026-01-14 13:58:43 -06:00
firestar5683 0110bec1af Remove lat smooth seconds 2026-01-14 13:50:35 -06:00
firestar5683 94d881211c frogpilot migration 2026-01-12 22:12:07 -06:00
firestar5683 cea5b9cada More defaults 2026-01-12 22:04:34 -06:00
firestar5683 4269bb2309 Update defaults 2026-01-12 22:01:01 -06:00
firestar5683 5cc94240cd Big Mac 2026-01-11 16:58:51 -06:00
firestar5683 201458c3d6 Try Higher Friction 2026-01-10 14:05:27 -06:00
firestar5683 1af7a5ba65 Autotune Off 2026-01-09 22:42:42 -06:00
firestar5683 fb3d1a1392 merry christmas 2025-12-24 22:05:56 -06:00
firestar5683 d650757ff9 ds2 2025-12-24 21:30:15 -06:00
firestar5683 91e273e489 Try friction adjustment 2025-12-16 14:39:42 -06:00
firestar5683 d620145cdc Update frogpilot_tracking.py 2025-12-15 00:55:16 -06:00
firestar5683 23a5bedabc minsteer speed 2025-12-14 14:46:42 -06:00
firestar5683 ea45cbf382 Update Percentages 2025-12-13 19:14:46 -06:00
firestar5683 a1f7b451a6 Trailer Load Gas Tuning 2025-12-12 10:52:53 -06:00
firestar5683 1fabfd04bd Live Friction 2025-12-11 16:54:55 -06:00
firestar5683 8630693f7a Zero error 2025-12-11 15:13:40 -06:00
firestar5683 6df0333380 Updates
Update latcontrol_torque.py

interp friction threshold
2025-12-09 20:01:30 -06:00
firestar5683 8708ab2496 LattyBoi2.0 2025-12-03 23:30:46 -06:00
firestar5683 01ed483036 Latty Boi
Revert "Latty Boi"

This reverts commit af687e501cc4bdcda7840453d06595d7ea674148.

Reapply "Latty Boi"

This reverts commit ff5566d4439f5e4997fe83f4f21d0be62b75d75d.
2025-12-02 20:31:00 -06:00
firestar5683 23fb048ba6 Recovery Power 2025-12-02 17:18:59 -06:00
firestar5683 bee7628900 New planplus 2025-12-02 12:11:19 -06:00
Woohyun Rho 9b84afc5a8 Update 2025-11-28 17:14:08 -06:00
firestar5683 5f94a5b9e0 New Lateral Changes 2025-11-18 20:49:21 -06:00
firestar5683 41d69c31e7 Update 2025-11-15 14:47:04 -06:00
firestar5683 f6c89beebd Revert "Upstream Lateral"
This reverts commit 62c1345b2a.
2025-11-10 23:09:15 -06:00
firestar5683 62c1345b2a Upstream Lateral
Revert "Upstream Lateral"

This reverts commit 20f7d6631bb152860781b46533bb0e96223be132.

Reapply "Upstream Lateral"

This reverts commit 2a7a563e219a1b688529d341919fc377fed5038e.

Update latcontrol_torque.py

more lateral

Update ui
2025-11-07 00:14:57 -06:00
firestar5683 97bfbfbb0d Update carcontroller.py 2025-10-25 16:22:22 -05:00
firestar5683 67c9a8b52e Update 2025-10-25 15:46:56 -05:00
firestar5683 2f253174e9 Medium Fanta 2025-10-22 22:27:22 -05:00
firestar5683 5a39fa4ac1 Update interfaces.py 2025-10-20 13:50:27 -05:00
firestar5683 8a54eb5733 no nnff 2025-10-19 18:00:23 -05:00
firestar5683 a1edc6d6e7 Scene Complexity 2025-10-18 14:24:54 -05:00
firestar5683 05ded9d10b Update interface.py 2025-10-17 18:13:42 -05:00
firestar5683 d387c7934f CEM 2025-10-17 17:40:21 -05:00
firestar5683 4c9d393e37 lite 2025-10-17 17:14:41 -05:00
firestar5683 c14680edcb Modify torque tuning parameters in interfaces.py
Adjusted torque tuning parameters for improved performance.
2025-10-17 17:02:13 -05:00
firestar5683 95ea985218 Hurts Donut 2025-10-16 23:57:42 -05:00
firestar5683 376aeff9e3 Smoothy Boi 2025-10-16 23:40:06 -05:00
firestar5683 680c3acaf0 lat3 2025-10-15 22:21:08 -05:00
firestar5683 9cc2c20cdc Honda? 2025-10-12 00:30:14 -05:00
firestar5683 8c81eadf5d oopsie doopsie 2025-10-12 00:12:03 -05:00
firestar5683 88a29c67d0 Revert "Humanlanechanges fix"
This reverts commit 5e88e5beff.
2025-10-12 00:11:50 -05:00
firestar5683 6fe8f8b722 Revert "Duh"
This reverts commit b5b942a108.
2025-10-12 00:11:48 -05:00
firestarsdog b5b942a108 Duh 2025-10-11 20:56:35 -04:00
niknak6 5e88e5beff Humanlanechanges fix 2025-10-11 19:37:40 -04:00
firestar5683 8f27c4937c New Lateral Changes 2025-10-10 20:59:30 -05:00
firestar5683 c95f8fa8fc Fix Standard 2025-10-10 19:25:57 -05:00
firestar5683 8b55472a90 error? 2025-10-09 13:29:53 -05:00
firestar5683 9bcfeb1cf3 Honda2 2025-10-09 13:29:53 -05:00
firestar5683 93713aaacf honda 2025-10-08 22:38:53 -05:00
firestar5683 602641856d Fix New Devices 2025-10-08 22:20:55 -05:00
firestar5683 1f0d2092a3 No positive P-response for long control if user-selected parameter set 2025-10-08 07:44:53 -05:00
firestar5683 587dc140b7 Automatic updates 2025-10-04 16:03:30 -05:00
firestar5683 63ee52b4aa Steer Alerts 2025-10-04 01:48:56 -05:00
firestar5683 eb19b336e2 Update frogpilot_acceleration.py 2025-10-03 22:36:15 -05:00
firestar5683 06f95d0dcd SteerAlerts
Revert "SteerAlerts"

This reverts commit cbaba399c5b9caac5a8faf3917f0929d747a0acc.

Update controlsd.py
2025-10-03 22:14:06 -05:00
firestar5683 cd7f2f8bc6 Donut DM 2025-10-03 20:49:04 -05:00
firestar5683 82af86e04c Update gm_global_a_powertrain_generated.dbc 2025-10-03 16:41:03 -05:00
firestar5683 6934f375d5 Update 2025-10-03 00:43:23 -05:00
firestar5683 09afc383fd firehose 2025-09-30 20:47:05 -05:00
firestar5683 19f7685744 Update 2025-09-30 14:31:30 -05:00
firestar5683 6477ba6a5e Dom
Revert "Dom"

This reverts commit eb2218e733.

Dom
2025-09-30 13:06:51 -05:00
25 changed files with 176 additions and 475 deletions
Binary file not shown.

Before

Width:  |  Height:  |  Size: 858 KiB

After

Width:  |  Height:  |  Size: 503 KiB

+2 -2
View File
@@ -620,9 +620,9 @@ class FrogPilotVariables:
toggle.steer_offset = np.clip(params.get_float("SteerOffset"), -0.2, 0.2) if advanced_lateral_tuning and tuning_level >= level["SteerOffset"] and toggle.car_make == "gm" else 0.0
toggle.use_custom_friction = bool(round(toggle.friction, 2) != round(friction, 2)) and is_torque_car and not toggle.force_auto_tune or toggle.force_auto_tune_off
toggle.steerKp = [[0], [np.clip(params.get_float("SteerKP"), steerKp * 0.5, steerKp * 1.5) if advanced_lateral_tuning and is_torque_car and tuning_level >= level["SteerKP"] else steerKp]]
toggle.latAccelFactor = np.clip(params.get_float("SteerLatAccel"), latAccelFactor * 0.5, latAccelFactor * 1.25) if advanced_lateral_tuning and tuning_level >= level["SteerLatAccel"] else latAccelFactor
toggle.latAccelFactor = np.clip(params.get_float("SteerLatAccel"), latAccelFactor * 0.75, latAccelFactor * 1.25) if advanced_lateral_tuning and tuning_level >= level["SteerLatAccel"] else latAccelFactor
toggle.use_custom_latAccelFactor = bool(round(toggle.latAccelFactor, 2) != round(latAccelFactor, 2)) and is_torque_car and not toggle.force_auto_tune or toggle.force_auto_tune_off
toggle.steerRatio = np.clip(params.get_float("SteerRatio"), steerRatio * 0.25, steerRatio * 1.5) if advanced_lateral_tuning and tuning_level >= level["SteerRatio"] else steerRatio
toggle.steerRatio = np.clip(params.get_float("SteerRatio"), steerRatio * 0.5, steerRatio * 1.5) if advanced_lateral_tuning and tuning_level >= level["SteerRatio"] else steerRatio
toggle.use_custom_steerRatio = bool(round(toggle.steerRatio, 2) != round(steerRatio, 2)) and not toggle.force_auto_tune or toggle.force_auto_tune_off
advanced_longitudinal_tuning = params.get_bool("AdvancedLongitudinalTune") if tuning_level >= level["AdvancedLongitudinalTune"] else default.get_bool("AdvancedLongitudinalTune")
+4 -4
View File
@@ -96,10 +96,10 @@ FrogPilotLateralPanel::FrogPilotLateralPanel(FrogPilotSettingsWindow *parent) :
lateralToggle = new FrogPilotParamValueButtonControl(param, title, desc, icon, parent->steerKp * 0.5, parent->steerKp * 1.5, QString(), std::map<float, QString>(), 0.01, false, {}, steerKPButton, false, false);
} else if (param == "SteerLatAccel") {
std::vector<QString> steerLatAccelButton{"Reset"};
lateralToggle = new FrogPilotParamValueButtonControl(param, title, desc, icon, parent->latAccelFactor * 0.5, parent->latAccelFactor * 1.25, QString(), std::map<float, QString>(), 0.01, false, {}, steerLatAccelButton, false, false);
lateralToggle = new FrogPilotParamValueButtonControl(param, title, desc, icon, parent->latAccelFactor * 0.75, parent->latAccelFactor * 1.25, QString(), std::map<float, QString>(), 0.01, false, {}, steerLatAccelButton, false, false);
} else if (param == "SteerRatio") {
std::vector<QString> steerRatioButton{"Reset"};
lateralToggle = new FrogPilotParamValueButtonControl(param, title, desc, icon, parent->steerRatio * 0.25, parent->steerRatio * 1.5, QString(), std::map<float, QString>(), 0.01, false, {}, steerRatioButton, false, false);
lateralToggle = new FrogPilotParamValueButtonControl(param, title, desc, icon, parent->steerRatio * 0.5, parent->steerRatio * 1.5, QString(), std::map<float, QString>(), 0.01, false, {}, steerRatioButton, false, false);
} else if (param == "AlwaysOnLateral") {
FrogPilotManageControl *aolToggle = new FrogPilotManageControl(param, title, desc, icon);
@@ -271,9 +271,9 @@ void FrogPilotLateralPanel::showEvent(QShowEvent *event) {
steerKPToggle->setTitle(QString(tr("Kp Factor (Default: %1)")).arg(QString::number(parent->steerKp, 'f', 2)));
steerKPToggle->updateControl(parent->steerKp * 0.5, parent->steerKp * 1.5);
steerLatAccelToggle->setTitle(QString(tr("Lateral Accel (Default: %1)")).arg(QString::number(parent->latAccelFactor, 'f', 2)));
steerLatAccelToggle->updateControl(parent->latAccelFactor * 0.5, parent->latAccelFactor * 1.25);
steerLatAccelToggle->updateControl(parent->latAccelFactor * 0.75, parent->latAccelFactor * 1.25);
steerRatioToggle->setTitle(QString(tr("Steer Ratio (Default: %1)")).arg(QString::number(parent->steerRatio, 'f', 2)));
steerRatioToggle->updateControl(parent->steerRatio * 0.25, parent->steerRatio * 1.5);
steerRatioToggle->updateControl(parent->steerRatio * 0.5, parent->steerRatio * 1.5);
updateToggles();
}
+5 -16
View File
@@ -82,12 +82,6 @@ VAL_TABLE_ HandsOffSWDetectionMode 2 "Failed" 1 "Enabled" 0 "Disabled" ;
BO_ 189 EBCMRegenPaddle: 7 K17_EBCM
SG_ RegenPaddle : 7|4@0+ (1,0) [0|0] "" NEO
SG_ Byte1 : 8|8@1+ (1,0) [0|255] "" NEO
SG_ Byte2 : 16|8@1+ (1,0) [0|255] "" NEO
SG_ Byte3 : 24|8@1+ (1,0) [0|255] "" NEO
SG_ Byte4 : 32|8@1+ (1,0) [0|255] "" NEO
SG_ Byte5 : 40|8@1+ (1,0) [0|255] "" NEO
SG_ Byte6 : 48|8@1+ (1,0) [0|255] "" NEO
BO_ 190 ECMAcceleratorPos: 6 K20_ECM
SG_ BrakePedalPos : 15|8@0+ (1,0) [0|0] "sticky" NEO
@@ -198,15 +192,10 @@ BO_ 500 SportMode: 6 XXX
SG_ SportMode : 15|1@0+ (1,0) [0|1] "" XXX
BO_ 501 ECMPRDNL2: 8 K20_ECM
SG_ Byte0 : 0|8@1+ (1,0) [0|255] "" NEO
SG_ Byte1 : 8|8@1+ (1,0) [0|255] "" NEO
SG_ Byte2 : 16|8@1+ (1,0) [0|255] "" NEO
SG_ PRNDL2 : 27|4@0+ (1,0) [0|255] "" NEO
SG_ Byte4 : 32|8@1+ (1,0) [0|255] "" NEO
SG_ ManualMode : 41|1@0+ (1,0) [0|1] "" NEO
SG_ TransmissionState : 48|4@1+ (1,0) [0|7] "" NEO
SG_ Byte7 : 56|8@1+ (1,0) [0|255] "" NEO
SG_ PRNDL2 : 27|4@0+ (1,0) [0|255] "" NEO
SG_ ManualMode : 41|1@0+ (1,0) [0|1] "" NEO
BO_ 532 BRAKE_RELATED: 6 XXX
SG_ UserBrakePressure : 0|9@0+ (1,0) [0|511] "" XXX
@@ -233,7 +222,7 @@ BO_ 715 ASCMGasRegenCmd: 8 K124_ASCM
SG_ GasRegenCmdActive : 0|1@0+ (1,0) [0|0] "" NEO
SG_ RollingCounter : 7|2@0+ (1,0) [0|0] "" NEO
SG_ GasRegenAlwaysOne3 : 23|1@0+ (1,0) [0|1] "" NEO
SG_ GasRegenCmd : 22|12@0+ (1,0) [0|0] "" NEO
SG_ GasRegenCmd : 8|14@0+ (1,0) [0|0] "" NEO
BO_ 717 ASCM_2CD: 5 K124_ASCM
@@ -381,6 +370,6 @@ VAL_ 715 GasRegenCmdActive 1 "Active" 0 "Inactive" ;
VAL_ 320 Intellibeam 1 "Active" 0 "Inactive" ;
VAL_ 320 HighBeamsActive 1 "Active" 0 "Inactive" ;
VAL_ 320 HighBeamsTemporary 1 "Active" 0 "Inactive" ;
VAL_ 501 PRNDL2 7 "L2" 6 "L" 5 "L3" 4 "D" 3 "N" 2 "R" 1 "P" 0 "Shifting";
VAL_ 501 PRNDL2 6 "L" 4 "D" 3 "N" 2 "R" 1 "P" 0 "Shifting";
VAL_ 501 TransmissionState 11 "Shifting" 10 "Reverse" 9 "Forward" 8 "Disengaged";
VAL_ 501 ManualMode 1 "Active" 0 "Inactive"
+3 -3
View File
@@ -202,9 +202,9 @@ void ignition_can_hook(CANPacket_t *to_push) {
int len = GET_LEN(to_push);
// GM exception
if ((addr == 0xC9) && (len == 8)) {
// Matches SystemPowerMode (1=Run, 0=Off)
ignition_can = (GET_BYTE(to_push, 6) & 0x10U) != 0U;
if ((addr == 0x1F1) && (len == 8)) {
// SystemPowerMode (2=Run, 3=Crank Request)
ignition_can = (GET_BYTE(to_push, 0) & 0x2U) != 0U;
ignition_can_cnt = 0U;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -88,7 +88,7 @@ int safety_fwd_hook(int bus_num, int addr) {
}
bool get_longitudinal_allowed(void) {
return controls_allowed && !gas_pressed;
return controls_allowed && !gas_pressed_prev;
}
// Given a CRC-8 poly, generate a static lookup table to use with a fast CRC-8
+16 -58
View File
@@ -1,11 +1,11 @@
const SteeringLimits GM_STEERING_LIMITS = {
.max_steer = 450,
.max_rate_up = 15,
.max_rate_down = 34,
.driver_torque_allowance = 78,
.driver_torque_factor = 6,
.max_rt_delta = 345,
.max_rt_interval = 200000,
.max_steer = 300,
.max_rate_up = 10,
.max_rate_down = 15,
.driver_torque_allowance = 65,
.driver_torque_factor = 4,
.max_rt_delta = 128,
.max_rt_interval = 250000,
.type = TorqueDriverLimited,
};
@@ -29,23 +29,23 @@ const int GM_STANDSTILL_THRSLD = 10; // 0.311kph
// panda interceptor threshold needs to be equivalent to openpilot threshold to avoid controls mismatches
// If thresholds are mismatched then it is possible for panda to see the gas fall and rise while openpilot is in the pre-enabled state
const int GM_GAS_INTERCEPTOR_THRESHOLD = 595; // (675 + 355) / 2 ratio between offset and gain from dbc file
const int GM_GAS_INTERCEPTOR_THRESHOLD = 515; // (675 + 355) / 2 ratio between offset and gain from dbc file
#define GM_GET_INTERCEPTOR(msg) (((GET_BYTE((msg), 0) << 8) + GET_BYTE((msg), 1) + (GET_BYTE((msg), 2) << 8) + GET_BYTE((msg), 3)) / 2U) // avg between 2 tracks
const CanMsg GM_ASCM_TX_MSGS[] = {{0x180, 0, 4}, {0x409, 0, 7}, {0x40A, 0, 7}, {0x2CB, 0, 8}, {0x370, 0, 6}, {0x200, 0, 6}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus
const CanMsg GM_ASCM_TX_MSGS[] = {{0x180, 0, 4}, {0x409, 0, 7}, {0x40A, 0, 7}, {0x2CB, 0, 8}, {0x370, 0, 6}, {0x200, 0, 6}, // pt bus
{0xA1, 1, 7}, {0x306, 1, 8}, {0x308, 1, 7}, {0x310, 1, 2}, // obs bus
{0x315, 2, 5}}; // ch bus
const CanMsg GM_CAM_TX_MSGS[] = {{0x180, 0, 4}, {0x200, 0, 6}, {0x1E1, 0, 7}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus
const CanMsg GM_CAM_TX_MSGS[] = {{0x180, 0, 4}, {0x200, 0, 6}, {0x1E1, 0, 7}, // pt bus
{0x1E1, 2, 7}, {0x184, 2, 8}}; // camera bus
const CanMsg GM_CAM_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x315, 0, 5}, {0x2CB, 0, 8}, {0x370, 0, 6}, {0x200, 0, 6}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus
const CanMsg GM_CAM_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x315, 0, 5}, {0x2CB, 0, 8}, {0x370, 0, 6}, {0x200, 0, 6}, // pt bus
{0x1E1, 2, 7}, {0x184, 2, 8}}; // camera bus
const CanMsg GM_SDGM_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus
const CanMsg GM_SDGM_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, // pt bus
{0x184, 2, 8}}; // camera bus
const CanMsg GM_CC_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus
const CanMsg GM_CC_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, // pt bus
{0x184, 2, 8}, {0x1E1, 2, 7}}; // camera bus
// TODO: do checksum and counter checks. Add correct timestep, 0.1s for now.
@@ -172,13 +172,6 @@ static void gm_rx_hook(const CANPacket_t *to_push) {
}
}
// Cruise check for ACC models with pedal interceptor - block stock ACC
if ((addr == 0x1C4) && gm_has_acc && enable_gas_interceptor) {
// When pedal interceptor is active on ACC models, ignore stock cruise state
// to prevent conflicts between pedal interceptor and stock ACC
cruise_engaged_prev = false;
}
if (addr == 0xBD) {
regen_braking = (GET_BYTE(to_push, 0) >> 4) != 0U;
}
@@ -199,12 +192,6 @@ static void gm_rx_hook(const CANPacket_t *to_push) {
}
generic_rx_checks(stock_ecu_detected);
}
// Cruise check for Gen2 Bolt (ASCMActiveCruiseControlStatus on bus 2)
int addr = GET_ADDR(to_push);
if ((addr == 0x370) && (GET_BUS(to_push) == 2U)) {
bool cruise_engaged = (GET_BYTE(to_push, 2) >> 7) != 0U; // ACCCmdActive
cruise_engaged_prev = cruise_engaged;
}
}
static bool gm_tx_hook(const CANPacket_t *to_send) {
@@ -245,7 +232,7 @@ static bool gm_tx_hook(const CANPacket_t *to_send) {
int gas_regen = ((GET_BYTE(to_send, 2) & 0x7FU) << 5) + ((GET_BYTE(to_send, 3) & 0xF8U) >> 3);
bool violation = false;
// Allow apply bit in pre-enabled and overriding states, except for inactive gas // Allow apply bit in pre-enabled and overriding states
// Allow apply bit in pre-enabled and overriding states
violation |= !controls_allowed && apply;
violation |= longitudinal_gas_checks(gas_regen, *gm_long_limits);
@@ -259,11 +246,6 @@ static bool gm_tx_hook(const CANPacket_t *to_send) {
int button = (GET_BYTE(to_send, 5) >> 4) & 0x7U;
bool allowed_btn = (button == GM_BTN_CANCEL) && cruise_engaged_prev;
// For ACC cars with pedal interceptor, allow cancel even if cruise_engaged_prev is false
// (since we set it to false to prevent conflicts, but still need to cancel cruise)
if (gm_hw == GM_CAM && enable_gas_interceptor && button == GM_BTN_CANCEL) {
allowed_btn = true;
}
// For standard CC, allow spamming of SET / RESUME
if (gm_cc_long) {
allowed_btn |= cruise_engaged_prev && (button == GM_BTN_SET || button == GM_BTN_RESUME || button == GM_BTN_UNPRESS);
@@ -274,22 +256,6 @@ static bool gm_tx_hook(const CANPacket_t *to_send) {
}
}
// REGEN PADDLE
if (addr == 0xBD) {
bool regen_apply = GET_BIT(to_send, 7) || GET_BIT(to_send, 6) || GET_BIT(to_send, 5) || GET_BIT(to_send, 4);
if (!controls_allowed && regen_apply) {
tx = false;
}
}
// PRNDL2 regen check (7 for Gen0, Gen1. 5 For Gen2)
if (addr == 0x1F5) {
uint8_t prndl2 = GET_BYTE(to_send, 3) & 0xF;
bool prndl_apply = (prndl2 == 7) || (prndl2 == 5);
if (!controls_allowed && prndl_apply) {
tx = false;
}
}
return tx;
}
@@ -306,13 +272,9 @@ static int gm_fwd_hook(int bus_num, int addr) {
}
if (bus_num == 2) {
// block lkas message and acc messages
// Block 0x370 only for experimental long without pedal interceptor
// block lkas message and acc messages if gm_cam_long, forward all others
bool is_lkas_msg = (addr == 0x180);
bool is_acc_msg = (addr == 0x315) || (addr == 0x2CB);
if (gm_cam_long && !enable_gas_interceptor) {
is_acc_msg = is_acc_msg || (addr == 0x370);
}
bool is_acc_msg = (addr == 0x315) || (addr == 0x2CB) || (addr == 0x370);
bool block_msg = is_lkas_msg || (is_acc_msg && gm_cam_long);
if (!block_msg) {
bus_fwd = 0;
@@ -344,10 +306,6 @@ static safety_config gm_init(uint16_t param) {
gm_pedal_long = GET_FLAG(param, GM_PARAM_PEDAL_LONG);
gm_cc_long = GET_FLAG(param, GM_PARAM_CC_LONG);
gm_cam_long = GET_FLAG(param, GM_PARAM_HW_CAM_LONG) && !gm_cc_long;
// Block ACC messages when pedal interceptor is active on ACC models
if (gm_hw == GM_CAM && enable_gas_interceptor) {
gm_cam_long = true;
}
gm_pcm_cruise = ((gm_hw == GM_CAM) && (!gm_cam_long || gm_cc_long) && !gm_force_ascm && !gm_pedal_long) || (gm_hw == GM_SDGM);
gm_skip_relay_check = GET_FLAG(param, GM_PARAM_NO_CAMERA);
gm_has_acc = !GET_FLAG(param, GM_PARAM_NO_ACC);
Binary file not shown.

Before

Width:  |  Height:  |  Size: 671 KiB

After

Width:  |  Height:  |  Size: 418 KiB

+31 -253
View File
@@ -1,5 +1,3 @@
from typing import Tuple
import time
from cereal import car
from openpilot.common.conversions import Conversions as CV
from openpilot.common.filter_simple import FirstOrderFilter
@@ -9,11 +7,10 @@ from openpilot.common.params_pyx import Params
from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import apply_driver_steer_torque_limits, create_gas_interceptor_command
from openpilot.selfdrive.car.gm import gmcan
from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, CarControllerParams, CruiseButtons, GMFlags, CC_ONLY_CAR, SDGM_CAR, EV_CAR, CC_REGEN_PADDLE_CAR
from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, CarControllerParams, CruiseButtons, GMFlags, CC_ONLY_CAR, SDGM_CAR, EV_CAR
from openpilot.selfdrive.car.interfaces import CarControllerBase
from openpilot.selfdrive.controls.lib.drive_helpers import apply_deadzone
from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY
from openpilot.common.swaglog import cloudlog
VisualAlert = car.CarControl.HUDControl.VisualAlert
NetworkLocation = car.CarParams.NetworkLocation
@@ -25,15 +22,7 @@ TransmissionType = car.CarParams.TransmissionType
CAMERA_CANCEL_DELAY_FRAMES = 10
# Enforce a minimum interval between steering messages to avoid a fault
MIN_STEER_MSG_INTERVAL_MS = 15
# Twosided spacing tuned for ~33 Hz steer; target a 10 ms wide window per interval
# Paddle spoofing and scheduling constants
PADDLE_STEER_GAP_MIN_NS = 5_000_000 # ≥5 ms each side (EPS guard)
PADDLE_STEER_GAP_MAX_NS = 12_000_000 # cap for long intervals
PADDLE_GAP_TARGET_NS = 5_000_000 # aim perside gap even if interval//2 early is larger
PADDLE_NONBLOCK_GAP_NS = 1_000_000 # ≥1 ms since last paddle send
PADDLE_SLOT_EARLY_NS = 1_000_000 # allow firing up to 1 ms before slot
OVERFLOW_THRESH = 1.00 # fire one extra slot whenever credits ≥ 1.0
PADDLE_TARGET_HZ = 42.0 # desired paddle rate (Hz) when regen active; steer is ~33 Hz
# Constants for pitch compensation
BRAKE_PITCH_FACTOR_BP = [5., 10.] # [m/s] smoothly revert to planned accel at low speeds
BRAKE_PITCH_FACTOR_V = [0., 1.] # [unitless in [0,1]]; don't touch
@@ -49,11 +38,6 @@ class CarController(CarControllerBase):
self.apply_speed = 0
self.frame = 0
self.last_steer_frame = 0
self.last_steer_ts_ns = 0
self.last_regen_active = False
self.prev_steer_ts_ns = 0
self.last_spoof_ts_ns = 0
self.last_paddle_ts_ns = 0
self.last_button_frame = 0
self.cancel_counter = 0
self.pedal_steady = 0.
@@ -72,86 +56,25 @@ class CarController(CarControllerBase):
self.accel_g = 0.0
self.pitch = FirstOrderFilter(0., 0.09 * 4, DT_CTRL * 4) # runs at 25 Hz
self.accel_g = 0.0
self.regen_paddle_pressed = False
self.aego = 0.0
self.regen_paddle_timer = 0
self.planner_regen_hold = False
@staticmethod
def calc_pedal_command(accel: float, long_active: bool) -> float:
if not long_active: return 0.
zero = 0.15625 # 40/256
if accel > 0.:
# Scales the accel from 0-1 to 0.156-1
pedal_gas = clip(((1 - zero) * accel + zero), 0., 1.)
else:
# if accel is negative, -0.1 -> 0.015625
pedal_gas = clip(zero + accel, 0., zero) # Make brake the same size as gas, but clip to regen
# Midpoint + overflow spoof accumulator and flags
self.spoof_accum = 0.0
self.spoof_mid_sent = False
self.spoof_over_sent = False
self.last_interval_ns = 0
def calc_pedal_command(self, accel: float, long_active: bool, car_velocity) -> Tuple[float, bool]:
if not long_active:
self.planner_regen_hold = False
return 0., False
# Regen paddle hysteresis (frame-based): hold 10 frames, with decrement dead-zone
if not hasattr(self, 'regen_paddle_timer'):
self.regen_paddle_timer = 0 # frames
# Regen paddle hysteresis (framebased): count frames when decelerating hard, decrement only when truly released
if self.aego < -0.7:
self.regen_paddle_timer += 1
elif self.aego > -0.3:
self.regen_paddle_timer = max(self.regen_paddle_timer - 1, 0)
# else: hold timer between -0.7 and -0.3
# Base paddle press hysteresis
self.regen_paddle_pressed = self.regen_paddle_timer >= 10 # 10 frames
press_regen_paddle = self.regen_paddle_pressed or self.planner_regen_hold
# Regen gain ratios from bin-averaged 600 deceleration sweep; Calculates stronger decel from paddle
speed_mps = [0.559, 1.678, 2.797, 3.916, 5.035, 6.154, 7.273, 8.392, 9.511, 10.63,
11.749, 12.868, 13.987, 15.106, 16.225, 17.344, 18.463, 19.582, 20.701, 21.820,
22.939, 24.058, 25.177, 26.296]
regen_gain_ratio = [
1.000000, 1.057308, 1.131123, 1.220611, 1.270247, 1.300253, 1.339543, 1.361002,
1.388410, 1.403253, 1.414721, 1.430949, 1.420289, 1.436787, 1.434116, 1.436805,
1.417508, 1.402213, 1.395360, 1.360921, 1.342030, 1.292219, 1.270048, 1.239172
]
gain = interp(car_velocity, speed_mps, regen_gain_ratio)
pedaloffset = interp(car_velocity, [0., 3, 6, 30], [0.10, 0.175, 0.240, 0.240])
# Compute raw pedal gas
raw_pedal_gas = clip((pedaloffset + (accel / gain) * 0.6), 0.0, 1.0) if press_regen_paddle else clip((pedaloffset + accel * 0.6), 0.0, 1.0)
# --- Immediate application of raw pedal gas, no blending ---
pedal_gas = raw_pedal_gas
# Safety cap: ramp from 22% at 0 m/s to 37.25% at 10 mph (4.47 m/s), then allow full throttle
pedal_gas_max = interp(car_velocity, [0.0, 4.47, 4.48], [0.22, 0.3725, 1.0])
pedal_gas = clip(pedal_gas, 0.0, pedal_gas_max)
return pedal_gas, press_regen_paddle
return pedal_gas
def update(self, CC, CS, now_nanos, frogpilot_toggles):
self.CS = CS
self.aego = CS.out.aEgo
actuators = CC.actuators
accel = brake_accel = actuators.accel
press_regen_paddle = False
# Planner-driven regen hold: gate by car support and OP long active, use commanded accel thresholds
if (self.CP.enableGasInterceptor and self.CP.carFingerprint in CC_REGEN_PADDLE_CAR
and self.CP.openpilotLongitudinalControl and CC.longActive):
# Match original hysteresis intent: vehicle can usually stop without paddle up to ~1.0 m/s^2
# Use the same thresholds as the aEgo-based hysteresis, but on commanded accel for preemption
planner_press_threshold = -0.7
planner_release_threshold = -0.3
if accel <= planner_press_threshold:
self.planner_regen_hold = True
elif accel >= planner_release_threshold:
self.planner_regen_hold = False
else:
self.planner_regen_hold = False
hud_control = CC.hudControl
hud_alert = hud_control.visualAlert
hud_v_cruise = hud_control.setSpeed
@@ -160,138 +83,6 @@ class CarController(CarControllerBase):
# Send CAN commands.
can_sends = []
paddle_sends = []
raw_regen_active = (
self.CP.carFingerprint in CC_REGEN_PADDLE_CAR and
self.CP.openpilotLongitudinalControl and
CC.longActive and
self.CP.enableGasInterceptor and
(self.regen_paddle_timer >= 10 or self.planner_regen_hold) # hysteresis or planner hint
)
regen_active = raw_regen_active
# === Spoof scheduling: midpoint + overflow (~target Hz) ===
# Rising-edge reset on regen start
if raw_regen_active and not self.last_regen_active:
self.prev_steer_ts_ns = self.last_steer_ts_ns
self.last_spoof_ts_ns = 0
self.spoof_accum = 0.0
self.spoof_mid_sent = False
self.spoof_over_sent = False
if raw_regen_active:
# Interval between last two bus-0 steer sends
interval_ns = self.last_steer_ts_ns - self.prev_steer_ts_ns
# Adaptive twosided gap sized to the current steer interval, but capped to a target so the window stays wide enough
gap_ns = (PADDLE_STEER_GAP_MIN_NS if interval_ns <= 0 else
max(PADDLE_STEER_GAP_MIN_NS,
min(PADDLE_STEER_GAP_MAX_NS,
min((interval_ns // 2) - PADDLE_SLOT_EARLY_NS, PADDLE_GAP_TARGET_NS))))
# New steer interval? clear per-interval flags and add credits to reach target Hz
if interval_ns != self.last_interval_ns:
self.spoof_mid_sent = False
self.spoof_over_sent = False
self.last_interval_ns = interval_ns
# Add credits once per new steer interval to reach the desired paddle rate
if interval_ns > 0:
steer_hz = 1e9 / float(interval_ns)
extra_needed = max(0.0, (PADDLE_TARGET_HZ / steer_hz) - 1.0) # e.g., 42/33 1 ≈ 0.2727
self.spoof_accum += extra_needed
# Midpoint spoof: one per interval
if not self.spoof_mid_sent and interval_ns > 0:
midpoint_ns = self.prev_steer_ts_ns + interval_ns // 2
cloudlog.error("PADDLE MID: Δafter=%.1fms Δbefore=%.1fms credits=%.3f timer=%d",
(now_nanos - self.last_steer_ts_ns) * 1e-6,
(now_nanos - self.prev_steer_ts_ns) * 1e-6,
self.spoof_accum,
self.regen_paddle_timer)
# Compute spacing to last and next steer (two-sided guard)
next_steer_ts_ns = self.last_steer_ts_ns + interval_ns if interval_ns > 0 else 0
delta_after_ns = now_nanos - self.last_steer_ts_ns
delta_before_ns = (next_steer_ts_ns - now_nanos) if interval_ns > 0 else 1_000_000_000
if (CS.out.vEgo > 2.68
and now_nanos >= (midpoint_ns - PADDLE_SLOT_EARLY_NS)
and delta_after_ns >= gap_ns
and delta_before_ns >= gap_ns):
# Non-blocking 1 ms spacing for paddle frames
if now_nanos - self.last_paddle_ts_ns >= PADDLE_NONBLOCK_GAP_NS:
paddle_sends.append(gmcan.create_prndl2_command(self.packer_pt, CanBus.POWERTRAIN, True))
paddle_sends.append(gmcan.create_regen_paddle_command(self.packer_pt, CanBus.POWERTRAIN, True))
self.last_paddle_ts_ns = now_nanos
self.last_spoof_ts_ns = now_nanos
self.spoof_mid_sent = True
# Overflow spoof: insert extra when accumulator allows
if self.spoof_accum >= OVERFLOW_THRESH and not self.spoof_over_sent and interval_ns > 0:
slot2_ns = self.prev_steer_ts_ns + (interval_ns * 2) // 3
cloudlog.error("PADDLE OFL: Δafter=%.1fms Δbefore=%.1fms credits=%.3f thresh=%.1f timer=%d",
(now_nanos - self.last_steer_ts_ns) * 1e-6,
(now_nanos - self.prev_steer_ts_ns) * 1e-6,
self.spoof_accum,
OVERFLOW_THRESH,
self.regen_paddle_timer)
# Two-sided spacing relative to steer
next_steer_ts_ns = self.last_steer_ts_ns + interval_ns if interval_ns > 0 else 0
delta_after_ns = now_nanos - self.last_steer_ts_ns
delta_before_ns = (next_steer_ts_ns - now_nanos) if interval_ns > 0 else 1_000_000_000
if (CS.out.vEgo > 2.68
and now_nanos >= (slot2_ns - PADDLE_SLOT_EARLY_NS)
and delta_after_ns >= gap_ns
and delta_before_ns >= gap_ns):
# Non-blocking 1 ms spacing for paddle frames
if now_nanos - self.last_paddle_ts_ns >= PADDLE_NONBLOCK_GAP_NS:
paddle_sends.append(gmcan.create_prndl2_command(self.packer_pt, CanBus.POWERTRAIN, True))
paddle_sends.append(gmcan.create_regen_paddle_command(self.packer_pt, CanBus.POWERTRAIN, True))
self.last_paddle_ts_ns = now_nanos
self.last_spoof_ts_ns = now_nanos
self.spoof_over_sent = True
self.spoof_accum -= OVERFLOW_THRESH
# === End Spoof scheduling ===
# === Off-pulse scheduling on regen release ===
if not raw_regen_active and self.last_regen_active:
# schedule two off-slots at 1/3 and 2/3 of the last steer interval
if self.prev_steer_ts_ns and self.last_steer_ts_ns:
intv = self.last_steer_ts_ns - self.prev_steer_ts_ns
self.off_schedule_ns = [
self.prev_steer_ts_ns + intv // 3,
self.prev_steer_ts_ns + (2 * intv) // 3
]
self.off_sent = [False, False]
if hasattr(self, "off_schedule_ns"):
for i, t_ns in enumerate(self.off_schedule_ns):
if not self.off_sent[i] and now_nanos >= (t_ns - PADDLE_SLOT_EARLY_NS):
cloudlog.error("PADDLE OFF %d: Δafter=%.1fms Δto_slot=%.1fms timer=%d",
i,
(now_nanos - self.last_steer_ts_ns) * 1e-6,
(now_nanos - t_ns) * 1e-6,
self.regen_paddle_timer)
# Two-sided spacing to steer before sending
interval_ns = self.last_steer_ts_ns - self.prev_steer_ts_ns
gap_ns = (PADDLE_STEER_GAP_MIN_NS if interval_ns <= 0 else
max(PADDLE_STEER_GAP_MIN_NS,
min(PADDLE_STEER_GAP_MAX_NS,
min((interval_ns // 2) - PADDLE_SLOT_EARLY_NS, PADDLE_GAP_TARGET_NS))))
next_steer_ts_ns = self.last_steer_ts_ns + interval_ns if interval_ns > 0 else 0
delta_after_ns = now_nanos - self.last_steer_ts_ns
delta_before_ns = (next_steer_ts_ns - now_nanos) if interval_ns > 0 else 1_000_000_000
if (delta_after_ns >= gap_ns and delta_before_ns >= gap_ns):
# Non-blocking 1 ms spacing for paddle frames
if now_nanos - self.last_paddle_ts_ns >= PADDLE_NONBLOCK_GAP_NS:
paddle_sends.append(gmcan.create_prndl2_command(self.packer_pt, CanBus.POWERTRAIN, False))
paddle_sends.append(gmcan.create_regen_paddle_command(self.packer_pt, CanBus.POWERTRAIN, False))
self.last_paddle_ts_ns = now_nanos
self.off_sent[i] = True
# clean up once both off pulses are sent
if hasattr(self, "off_sent") and all(self.off_sent):
del self.off_schedule_ns
del self.off_sent
# === End off-pulse scheduling ===
# Steering (Active: 50Hz, inactive: 10Hz)
steer_step = self.params.STEER_STEP if CC.latActive else self.params.INACTIVE_STEER_STEP
@@ -321,30 +112,11 @@ class CarController(CarControllerBase):
else:
apply_steer = 0
if (self.CP.flags & GMFlags.CC_LONG.value) and CC.enabled and not CS.out.cruiseState.enabled: # Send 0 so Panda doesn't error
apply_steer = 0
# shift previous steer timestamp
self.prev_steer_ts_ns = self.last_steer_ts_ns
self.last_steer_ts_ns = now_nanos
self.last_steer_frame = self.frame
self.apply_steer_last = apply_steer
idx = self.lka_steering_cmd_counter % 4
can_sends.append(gmcan.create_steering_control(self.packer_pt, CanBus.POWERTRAIN, apply_steer, idx, CC.latActive))
# Update regen_active state and last_regen_paddle_pressed for next loop
self.last_regen_active = regen_active
self.last_regen_paddle_pressed = self.regen_paddle_pressed or self.planner_regen_hold
if paddle_sends:
interval_ns = self.last_steer_ts_ns - self.prev_steer_ts_ns
flush_gap_ns = (PADDLE_STEER_GAP_MIN_NS if interval_ns <= 0 else
max(PADDLE_STEER_GAP_MIN_NS,
min(PADDLE_STEER_GAP_MAX_NS,
min((interval_ns // 2) - PADDLE_SLOT_EARLY_NS, PADDLE_GAP_TARGET_NS))))
if now_nanos - self.last_steer_ts_ns >= flush_gap_ns:
can_sends.extend(paddle_sends)
if self.CP.openpilotLongitudinalControl:
# Gas/regen, brakes, and UI commands - all at 25Hz
if self.frame % 4 == 0:
@@ -370,15 +142,20 @@ class CarController(CarControllerBase):
self.apply_brake = int(min(-100 * frogpilot_toggles.stopAccel, self.params.MAX_BRAKE))
else:
# Normal operation
self.apply_gas = int(round(interp(accel, self.params.GAS_LOOKUP_BP, self.params.GAS_LOOKUP_V)))
self.apply_brake = int(round(interp(brake_accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V)))
if self.CP.carFingerprint in EV_CAR:
self.params.update_ev_gas_brake_threshold(CS.out.vEgo)
self.apply_gas = int(round(interp(accel, self.params.EV_GAS_LOOKUP_BP, self.params.GAS_LOOKUP_V)))
self.apply_brake = int(round(interp(brake_accel, self.params.EV_BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V)))
else:
self.apply_gas = int(round(interp(accel, self.params.GAS_LOOKUP_BP, self.params.GAS_LOOKUP_V)))
self.apply_brake = int(round(interp(brake_accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V)))
# Don't allow any gas above inactive regen while stopping
# FIXME: brakes aren't applied immediately when enabling at a stop
if stopping:
self.apply_gas = self.params.INACTIVE_REGEN
if self.CP.carFingerprint in CC_ONLY_CAR:
# gas interceptor only used for full long control on cars without ACC
interceptor_gas_cmd, press_regen_paddle = self.calc_pedal_command(actuators.accel, CC.longActive, CS.out.vEgo)
interceptor_gas_cmd = self.calc_pedal_command(actuators.accel, CC.longActive)
if self.CP.enableGasInterceptor and self.apply_gas > self.params.INACTIVE_REGEN and CS.out.cruiseState.standstill:
# "Tap" the accelerator pedal to re-engage ACC
@@ -391,10 +168,7 @@ class CarController(CarControllerBase):
if self.CP.flags & GMFlags.CC_LONG.value:
if CC.longActive and CS.out.cruiseState.enabled and CS.out.vEgo > self.CP.minEnableSpeed:
# Using extend instead of append since the message is only sent intermittently
can_sends.extend(gmcan.create_gm_cc_spam_command(self.packer_pt, self, CS, actuators, frogpilot_toggles))
elif (CS.out.cruiseState.enabled and CC.enabled and self.frame % 52 == 0 and
CS.cruise_buttons == CruiseButtons.UNPRESS and CS.out.gasPressed and CS.out.cruiseState.speed < CS.out.vEgo < hud_v_cruise):
can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, (CS.buttons_counter + 1) % 4, CruiseButtons.DECEL_SET))
can_sends.extend(gmcan.create_gm_cc_spam_command(self.packer_pt, self, CS, actuators))
if self.CP.enableGasInterceptor:
can_sends.append(create_gas_interceptor_command(self.packer_pt, interceptor_gas_cmd, idx))
if self.CP.carFingerprint not in CC_ONLY_CAR:
@@ -417,7 +191,7 @@ class CarController(CarControllerBase):
# GasRegenCmdActive needs to be 1 to avoid cruise faults. It describes the ACC state, not actuation
can_sends.append(gmcan.create_gas_regen_command(self.packer_pt, CanBus.POWERTRAIN, self.apply_gas, idx, acc_engaged, at_full_stop))
can_sends.append(gmcan.create_friction_brake_command(self.packer_ch, friction_brake_bus, self.apply_brake,
idx, CC.enabled, near_stop, at_full_stop, self.CP))
idx, CC.enabled, near_stop, at_full_stop, self.CP))
# Send dashboard UI commands (ACC status)
send_fcw = hud_alert == VisualAlert.fcw
@@ -428,18 +202,22 @@ class CarController(CarControllerBase):
accel += self.accel_g
# Radar needs to know current speed and yaw rate (50hz),
# and that ADAS is alive (5hz, previously 10hz)
# and that ADAS is alive (10hz)
if not self.CP.radarUnavailable:
tt = self.frame * DT_CTRL
time_and_headlights_step = 20
time_and_headlights_step = 10
if self.frame % time_and_headlights_step == 0:
idx = (self.frame // time_and_headlights_step) % 4
can_sends.append(gmcan.create_adas_time_status(CanBus.OBSTACLE, int((tt - self.start_time) * 60), idx))
can_sends.append(gmcan.create_adas_headlights_status(self.packer_obj, CanBus.OBSTACLE))
speed_and_accelerometer_step = 2
if self.frame % speed_and_accelerometer_step == 0:
idx = (self.frame // speed_and_accelerometer_step) % 4
can_sends.append(gmcan.create_adas_steering_status(CanBus.OBSTACLE, idx))
can_sends.append(gmcan.create_adas_accelerometer_speed_status(CanBus.OBSTACLE, CS.out.vEgo, idx))
if self.CP.networkLocation == NetworkLocation.gateway and self.frame % (self.params.ADAS_KEEPALIVE_STEP * 2) == 0:
if self.CP.networkLocation == NetworkLocation.gateway and self.frame % self.params.ADAS_KEEPALIVE_STEP == 0:
can_sends += gmcan.create_adas_keepalive(CanBus.POWERTRAIN)
# TODO: integrate this with the code block below?
@@ -467,7 +245,7 @@ class CarController(CarControllerBase):
if self.CP.networkLocation == NetworkLocation.fwdCamera:
# Silence "Take Steering" alert sent by camera, forward PSCMStatus with HandsOffSWlDetectionStatus=1
if self.frame % 20 == 0:
if self.frame % 10 == 0:
can_sends.append(gmcan.create_pscm_status(self.packer_pt, CanBus.CAMERA, CS.pscm_status))
new_actuators = actuators.as_builder()
+9 -13
View File
@@ -5,7 +5,7 @@ from openpilot.common.numpy_fast import mean
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car.interfaces import CarStateBase
from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, STEER_THRESHOLD, GMFlags, CC_ONLY_CAR, CAMERA_ACC_CAR, SDGM_CAR, CC_REGEN_PADDLE_CAR
from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, STEER_THRESHOLD, GMFlags, CC_ONLY_CAR, CAMERA_ACC_CAR, SDGM_CAR
TransmissionType = car.CarParams.TransmissionType
NetworkLocation = car.CarParams.NetworkLocation
@@ -56,13 +56,6 @@ class CarState(CarStateBase):
self.loopback_lka_steering_cmd_updated = len(loopback_cp.vl_all["ASCMLKASteeringCmd"]["RollingCounter"]) > 0
if self.loopback_lka_steering_cmd_updated:
self.loopback_lka_steering_cmd_ts_nanos = loopback_cp.ts_nanos["ASCMLKASteeringCmd"]["RollingCounter"]
# Track timestamps for OEM PRNDL2 and Regen Paddle messages (used to sync spoofing timing)
self.prndl2_ts_nanos = pt_cp.ts_nanos["ECMPRDNL2"]["PRNDL2"]
if self.CP.carFingerprint in CC_REGEN_PADDLE_CAR:
self.regen_paddle_ts_nanos = pt_cp.ts_nanos["EBCMRegenPaddle"]["RegenPaddle"]
else:
self.regen_paddle_ts_nanos = 0
if self.CP.networkLocation == NetworkLocation.fwdCamera and not self.CP.flags & GMFlags.NO_CAMERA.value:
self.pt_lka_steering_cmd_counter = pt_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"]
self.cam_lka_steering_cmd_counter = cam_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"]
@@ -78,7 +71,10 @@ class CarState(CarStateBase):
# sample rear wheel speeds, standstill=True if ECM allows engagement with brake
ret.standstill = ret.wheelSpeeds.rl <= STANDSTILL_THRESHOLD and ret.wheelSpeeds.rr <= STANDSTILL_THRESHOLD
ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(pt_cp.vl["ECMPRDNL2"]["PRNDL2"], None))
if pt_cp.vl["ECMPRDNL2"]["ManualMode"] == 1:
ret.gearShifter = self.parse_gear_shifter("T")
else:
ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(pt_cp.vl["ECMPRDNL2"]["PRNDL2"], None))
if self.CP.flags & GMFlags.NO_ACCELERATOR_POS_MSG.value:
ret.brake = pt_cp.vl["EBCMBrakePedalPosition"]["BrakePedalPosition"] / 0xd0
@@ -100,7 +96,7 @@ class CarState(CarStateBase):
if self.CP.enableGasInterceptor:
ret.gas = (pt_cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS"] + pt_cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS2"]) / 2.
threshold = 23 if self.CP.carFingerprint in CAMERA_ACC_CAR else 4 # Panda 595 threshold = 23.65. Set lower to avoid panda blocking messages and GasInterceptor faulting.
threshold = 10 if self.CP.carFingerprint in CAMERA_ACC_CAR else 4 # Panda 515 threshold = 10.88. Set lower to avoid panda blocking messages and GasInterceptor faulting.
ret.gasPressed = ret.gas > threshold
else:
ret.gas = pt_cp.vl["AcceleratorPedal2"]["AcceleratorPedal2"] / 254.
@@ -173,7 +169,7 @@ class CarState(CarStateBase):
ret.leftBlindspot = cam_cp.vl["BCMBlindSpotMonitor"]["LeftBSM"] == 1
ret.rightBlindspot = cam_cp.vl["BCMBlindSpotMonitor"]["RightBSM"] == 1
# FrogPilot CarState functions
self.lkas_previously_enabled = self.lkas_enabled
if self.CP.carFingerprint in SDGM_CAR:
self.lkas_enabled = cam_cp.vl["ASCMSteeringButton"]["LKAButton"]
@@ -234,7 +230,7 @@ class CarState(CarStateBase):
]
else:
messages += [
("ECMPRDNL2", 40),
("ECMPRDNL2", 10),
("AcceleratorPedal2", 33),
("ECMEngineStatus", 100),
("BCMTurnSignals", 1),
@@ -256,7 +252,7 @@ class CarState(CarStateBase):
if CP.transmissionType == TransmissionType.direct:
messages += [
("EBCMRegenPaddle", 40),
("EBCMRegenPaddle", 50),
("EVDriveMode", 0),
]
+24 -48
View File
@@ -177,69 +177,45 @@ def create_lka_icon_command(bus, active, critical, steer):
dat = b"\x00\x00\x00"
return make_can_msg(0x104c006c, dat, bus)
def create_prndl2_command(packer, bus, press_regen_paddle):
prndl2_value = 7 if press_regen_paddle else 6
manual_mode = 1 if press_regen_paddle else 0
values = {
"Byte0": 0x0C,
"Byte1": 0x0C,
"Byte2": 0x00,
"PRNDL2": prndl2_value,
"Byte4": 0x00,
"ManualMode": manual_mode,
"TransmissionState": 1,
"Byte7": 0x00
}
return packer.make_can_msg("ECMPRDNL2", bus, values)
def create_regen_paddle_command(packer, bus, press_regen_paddle):
regen_paddle_value = 2 if press_regen_paddle else 0
values = {
"RegenPaddle": regen_paddle_value,
"Byte1": 0,
"Byte2": 0,
"Byte3": 0,
"Byte4": 0,
"Byte5": 0,
"Byte6": 0
}
return packer.make_can_msg("EBCMRegenPaddle", bus, values)
def create_gm_cc_spam_command(packer, controller, CS, actuators):
if controller.params_.get_bool("IsMetric"):
_CV = CV.MS_TO_KPH
RATE_UP_MAX = 0.04
RATE_DOWN_MAX = 0.04
else:
_CV = CV.MS_TO_MPH
RATE_UP_MAX = 0.2
RATE_DOWN_MAX = 0.2
def create_gm_cc_spam_command(packer, controller, CS, actuators, frogpilot_toggles):
accel = actuators.accel
Vego = CS.out.vEgo
accel = actuators.accel * _CV # m/s/s to mph/s
speedSetPoint = int(round(CS.out.cruiseState.speed * _CV))
cruiseBtn = CruiseButtons.INIT
if abs(accel) <= 0.15:
rate = 1
else:
rate = 0.2
MS_CONVERT = CV.MS_TO_KPH if frogpilot_toggles.is_metric else CV.MS_TO_MPH
speedSetPoint = int(round(CS.out.cruiseState.speed * MS_CONVERT))
if accel > 0:
DesiredSetPoint = int(round((Vego * 1.01 + 3 * accel) * MS_CONVERT)) # 1.01 factor to match cluster speed better
else: # accel <= 0
DesiredSetPoint = int(round((Vego * 1.01 + 3 * accel) * MS_CONVERT))
if CS.CP.minEnableSpeed - (DesiredSetPoint / MS_CONVERT) > 3.25:
if speedSetPoint == CS.CP.minEnableSpeed and accel < -1:
cruiseBtn = CruiseButtons.CANCEL
controller.apply_speed = 0
elif DesiredSetPoint < speedSetPoint and speedSetPoint > CS.CP.minEnableSpeed * MS_CONVERT + 1:
rate = 0.04
elif accel < 0:
cruiseBtn = CruiseButtons.DECEL_SET
if speedSetPoint > (CS.out.vEgo * _CV) + 3.0: # If accel is changing directions, bring set speed to current speed as fast as possible
rate = RATE_DOWN_MAX
else:
rate = max(-1 / accel, RATE_DOWN_MAX)
controller.apply_speed = speedSetPoint - 1
elif DesiredSetPoint > speedSetPoint:
elif accel > 0:
cruiseBtn = CruiseButtons.RES_ACCEL
if speedSetPoint < (CS.out.vEgo * _CV) - 3.0:
rate = RATE_UP_MAX
else:
rate = max(1 / accel, RATE_UP_MAX)
controller.apply_speed = speedSetPoint + 1
else:
cruiseBtn = CruiseButtons.INIT
controller.apply_speed = speedSetPoint
rate = float('inf')
# Check rlogs closely - our message shouldn't show up on the pt bus for us
# Or bus 2, since we're forwarding... but I think it does
# TODO: Cleanup the timing - normal is every 30ms...
if (cruiseBtn != CruiseButtons.INIT) and ((controller.frame - controller.last_button_frame) * DT_CTRL > rate):
controller.last_button_frame = controller.frame
idx = (CS.buttons_counter + 1) % 4 # Need to predict the next idx for '22-23 EUV
+23 -25
View File
@@ -27,8 +27,8 @@ CAM_MSG = 0x320 # AEBCmd
ACCELERATOR_POS_MSG = 0xbe
NON_LINEAR_TORQUE_PARAMS = {
CAR.CHEVROLET_BOLT_EUV: [2.15, 1.0, 0.21, 0.0],
CAR.CHEVROLET_BOLT_CC: [2.15, 1.0, 0.21, 0.0],
CAR.CHEVROLET_BOLT_EUV: [2.6531724862969748, 1.0, 0.1919764879840985, 0.009054123646805178],
CAR.CHEVROLET_BOLT_CC: [2.6531724862969748, 1.0, 0.1919764879840985, 0.009054123646805178],
CAR.GMC_ACADIA: [4.78003305, 1.0, 0.3122, 0.05591772],
CAR.CHEVROLET_SILVERADO: [3.29974374, 1.0, 0.25571356, 0.0465122]
}
@@ -64,10 +64,10 @@ class CarInterface(CarInterfaceBase):
# This has big effect on the stability about 0 (noise when going straight)
non_linear_torque_params = NON_LINEAR_TORQUE_PARAMS.get(self.CP.carFingerprint)
assert non_linear_torque_params, "The params are not defined"
a, b, c, d = non_linear_torque_params
a, b, c, _ = non_linear_torque_params
sig_input = a * lateral_acceleration
sig = np.sign(sig_input) * (1 / (1 + exp(-fabs(sig_input))) - 0.5)
steer_torque = (sig * b) + (lateral_acceleration * c) + d
steer_torque = (sig * b) + (lateral_acceleration * c)
return float(steer_torque)
lataccel_values = np.arange(-5.0, 5.0, 0.01)
@@ -117,15 +117,13 @@ class CarInterface(CarInterfaceBase):
if PEDAL_MSG in fingerprint[0]:
ret.enableGasInterceptor = True
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_GAS_INTERCEPTOR
# When a pedal interceptor is present, always use normal longitudinal (block stock cruise)
experimental_long = False
if candidate in EV_CAR:
ret.transmissionType = TransmissionType.direct
else:
ret.transmissionType = TransmissionType.automatic
ret.longitudinalTuning.kiBP = [5., 35., 60.]
ret.longitudinalTuning.kiBP = [5., 35.]
if candidate in CAMERA_ACC_CAR:
ret.experimentalLongitudinalAvailable = candidate not in CC_ONLY_CAR
@@ -137,14 +135,13 @@ class CarInterface(CarInterfaceBase):
ret.minSteerSpeed = 10 * CV.KPH_TO_MS
# Tuning for experimental long
ret.longitudinalTuning.kiV = [0.5, 0.5, 0.5]
ret.longitudinalTuning.kiV = [2.0, 1.5]
ret.vEgoStopping = 0.1
ret.vEgoStarting = 0.1
ret.stoppingDecelRate = 1.0 # reach brake quickly after enabling
ret.stoppingDecelRate = 2.0 # reach brake quickly after enabling
ret.vEgoStopping = 0.25
ret.vEgoStarting = 0.25
ret.stopAccel = -0.25
if ret.experimentalLongitudinalAvailable and experimental_long:
ret.pcmCruise = False
@@ -152,7 +149,7 @@ class CarInterface(CarInterfaceBase):
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM_LONG
elif candidate in SDGM_CAR:
ret.longitudinalTuning.kiV = [0., 0., 0.] # TODO: tuning
ret.longitudinalTuning.kiV = [0., 0.] # TODO: tuning
ret.experimentalLongitudinalAvailable = False
ret.networkLocation = NetworkLocation.fwdCamera
ret.pcmCruise = True
@@ -171,7 +168,7 @@ class CarInterface(CarInterfaceBase):
ret.minSteerSpeed = 7 * CV.MPH_TO_MS
# Tuning
ret.longitudinalTuning.kiV = [0.5, 0.5, 0.5]
ret.longitudinalTuning.kiV = [2.4, 1.5]
if ret.enableGasInterceptor:
# Need to set ASCM long limits when using pedal interceptor, instead of camera ACC long limits
@@ -289,13 +286,13 @@ class CarInterface(CarInterfaceBase):
ret.stoppingControl = True
ret.autoResumeSng = True
if candidate in CC_ONLY_CAR: #pedal interceptor tuning
if candidate in CC_ONLY_CAR:
ret.flags |= GMFlags.PEDAL_LONG.value
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_PEDAL_LONG
# Note: Low speed, stop and go not tested. Should be fairly smooth on highway
ret.longitudinalTuning.kiBP = [0., 3., 6., 35.]
ret.longitudinalTuning.kiV = [0.125, 0.175, 0.225, 0.33]
ret.longitudinalTuning.kfDEPRECATED = 0.25
ret.longitudinalTuning.kiBP = [0.0, 5., 35.]
ret.longitudinalTuning.kiV = [0.0, 0.35, 0.5]
ret.longitudinalTuning.kfDEPRECATED = 0.15
ret.stoppingDecelRate = 0.8
else: # Pedal used for SNG, ACC for longitudinal control otherwise
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM_LONG
@@ -312,15 +309,16 @@ class CarInterface(CarInterfaceBase):
ret.openpilotLongitudinalControl = not frogpilot_toggles.disable_openpilot_long
ret.pcmCruise = False
if not ret.enableGasInterceptor and candidate in CC_ONLY_CAR: #redneck tuning
ret.longitudinalTuning.kpBP = [10.7, 10.8, 28.] # 10.7 m/s == 24 mph
ret.longitudinalTuning.kpV = [0., 5., 2.] # set lower end to 0 since we can't drive below that speed
ret.longitudinalTuning.deadzoneBP = [0., 1.]
ret.longitudinalTuning.deadzoneV = [0.9, 0.9] # == 2 km/h/s, 1.25 mph/s
ret.longitudinalActuatorDelay = 1. # TODO: measure this
ret.longitudinalTuning.kiBP = [0.]
ret.longitudinalTuning.kiV = [0.1]
ret.stoppingDecelRate = 11.18 # == 25 mph/s (.04 rate)
ret.stoppingDecelRate = 11.18 # == 25 mph/s (.04 rate)
ret.longitudinalTuning.deadzoneBP = [0.]
ret.longitudinalTuning.deadzoneV = [0.56] # == 2 km/h/s, 1.25 mph/s
ret.longitudinalActuatorDelay = 1. # TODO: measure this
ret.longitudinalTuning.kpBP = [10.7, 10.8, 28.] # 10.7 m/s == 24 mph
ret.longitudinalTuning.kpV = [0., 20., 20.] # set lower end to 0 since we can't drive below that speed
ret.longitudinalTuning.kiBP = [0.]
ret.longitudinalTuning.kiV = [0.1]
if candidate in CC_ONLY_CAR:
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_NO_ACC
+36 -33
View File
@@ -11,13 +11,13 @@ Ecu = car.CarParams.Ecu
class CarControllerParams:
STEER_MAX = 450 # GM limit is 3Nm. Used by carcontroller to generate LKA output
STEER_MAX = 300 # GM limit is 3Nm. Used by carcontroller to generate LKA output
STEER_STEP = 3 # Active control frames per command (~33hz)
INACTIVE_STEER_STEP = 10 # Inactive control frames per command (10hz)
STEER_DELTA_UP = 15 # Delta rates require review due to observed EPS weakness
STEER_DELTA_DOWN = 34
STEER_DRIVER_ALLOWANCE = 78
STEER_DRIVER_MULTIPLIER = 6
STEER_DELTA_UP = 10 # Delta rates require review due to observed EPS weakness
STEER_DELTA_DOWN = 15
STEER_DRIVER_ALLOWANCE = 65
STEER_DRIVER_MULTIPLIER = 4
STEER_DRIVER_FACTOR = 100
NEAR_STOP_BRAKE_PHASE = 0.25 # m/s
SNG_INTERCEPTOR_GAS = 18. / 255.
@@ -33,47 +33,51 @@ class CarControllerParams:
# Our controller should still keep the 2 second average above
# -3.5 m/s^2 as per planner limits
ACCEL_MAX = 2. # m/s^2
ACCEL_MAX_PLUS = 4. # m/s^2
ACCEL_MIN = -4. # m/s^2
def __init__(self, CP):
# Gas/brake lookups
self.ZERO_GAS = 6144 # Coasting
self.ZERO_GAS = 2048 # Coasting
self.MAX_BRAKE = 400 # ~ -4.0 m/s^2 with regen
if CP.carFingerprint in CAMERA_ACC_CAR and CP.carFingerprint not in CC_ONLY_CAR and CP.carFingerprint != CAR.CHEVROLET_BOLT_EUV:
self.MAX_GAS = 7496
self.MAX_GAS_PLUS = 8848
self.MAX_ACC_REGEN = 5610
self.INACTIVE_REGEN = 5650
if CP.carFingerprint in CAMERA_ACC_CAR and CP.carFingerprint not in CC_ONLY_CAR:
self.MAX_GAS = 3400
self.MAX_ACC_REGEN = 1514
self.INACTIVE_REGEN = 1554
# Camera ACC vehicles have no regen while enabled.
# Camera transitions to MAX_ACC_REGEN from ZERO_GAS and uses friction brakes instantly
self.max_regen_acceleration = 0.
max_regen_acceleration = 0.
elif CP.carFingerprint in SDGM_CAR:
self.MAX_GAS = 7496
self.MAX_GAS_PLUS = 7496
self.MAX_ACC_REGEN = 7110
self.INACTIVE_REGEN = 5650
self.max_regen_acceleration = 0.
self.MAX_GAS = 3400
self.MAX_ACC_REGEN = 1514
self.INACTIVE_REGEN = 1554
max_regen_acceleration = 0.
else:
self.MAX_GAS = 7168 # Safety limit, not ACC max. Stock ACC >8192 from standstill.
self.MAX_GAS_PLUS = 8191 # 8292 uses new bit, possible but not tested. Matches Twilsonco tw-main max
self.MAX_ACC_REGEN = 7110 # Increased for stronger regen braking
self.INACTIVE_REGEN = 5500
self.MAX_GAS = 3072 # Safety limit, not ACC max. Stock ACC >4096 from standstill.
self.MAX_ACC_REGEN = 1404 # Max ACC regen is slightly less than max paddle regen
self.INACTIVE_REGEN = 1404
# ICE has much less engine braking force compared to regen in EVs,
# lower threshold removes some braking deadzone
self.max_regen_acceleration = -3. if CP.carFingerprint in EV_CAR else -0.1 # More aggressive regen for EVs
max_regen_acceleration = -1. if CP.carFingerprint in EV_CAR else -0.1
self.GAS_LOOKUP_BP = [self.max_regen_acceleration, 0., self.ACCEL_MAX]
self.GAS_LOOKUP_BP_PLUS = [self.max_regen_acceleration, 0., self.ACCEL_MAX_PLUS]
self.GAS_LOOKUP_BP = [max_regen_acceleration, 0., self.ACCEL_MAX]
self.GAS_LOOKUP_V = [self.MAX_ACC_REGEN, self.ZERO_GAS, self.MAX_GAS]
self.GAS_LOOKUP_V_PLUS = [self.MAX_ACC_REGEN, self.ZERO_GAS, self.MAX_GAS_PLUS]
self.BRAKE_LOOKUP_BP = [self.ACCEL_MIN, self.max_regen_acceleration]
self.BRAKE_LOOKUP_BP = [self.ACCEL_MIN, max_regen_acceleration]
self.BRAKE_LOOKUP_V = [self.MAX_BRAKE, 0.]
# determined by letting Volt regen to a stop in L gear from 89mph,
# and by letting off gas and allowing car to creep, for determining
# the positive threshold values at very low speed
EV_GAS_BRAKE_THRESHOLD_BP = [1.29, 1.52, 1.55, 1.6, 1.7, 1.8, 2.0, 2.2, 2.5, 5.52, 9.6, 20.5, 23.5, 35.0] # [m/s]
EV_GAS_BRAKE_THRESHOLD_V = [0.0, -0.14, -0.16, -0.18, -0.215, -0.255, -0.32, -0.41, -0.5, -0.72, -0.895, -1.125, -1.145, -1.16] # [m/s^s]
def update_ev_gas_brake_threshold(self, v_ego):
gas_brake_threshold = interp(v_ego, self.EV_GAS_BRAKE_THRESHOLD_BP, self.EV_GAS_BRAKE_THRESHOLD_V)
self.EV_GAS_LOOKUP_BP = [gas_brake_threshold, max(0., gas_brake_threshold), self.ACCEL_MAX]
self.EV_BRAKE_LOOKUP_BP = [self.ACCEL_MIN, gas_brake_threshold]
@dataclass
@@ -194,15 +198,15 @@ class CAR(Platforms):
CHEVROLET_SUBURBAN.specs,
)
GMC_YUKON_CC = GMPlatformConfig(
[GMCarDocs("GMC Yukon No ACC")],
[GMCarDocs("GMC Yukon - No-ACC")],
CarSpecs(mass=2541, wheelbase=2.95, steerRatio=16.3, centerToFrontRatio=0.4),
)
CADILLAC_CT6_CC = GMPlatformConfig(
[GMCarDocs("Cadillac CT6 No ACC")],
[GMCarDocs("Cadillac CT6 - No-ACC")],
CarSpecs(mass=2358, wheelbase=3.11, steerRatio=17.7, centerToFrontRatio=0.4),
)
CHEVROLET_TRAILBLAZER_CC = GMPlatformConfig(
[GMCarDocs("Chevrolet Trailblazer 2021-22")],
[GMCarDocs("Chevrolet Trailblazer 2021-22 - No-ACC")],
CHEVROLET_TRAILBLAZER.specs,
)
CADILLAC_XT4 = GMPlatformConfig(
@@ -210,7 +214,7 @@ class CAR(Platforms):
CarSpecs(mass=1660, wheelbase=2.78, steerRatio=14.4, centerToFrontRatio=0.4),
)
CADILLAC_XT5_CC = GMPlatformConfig(
[GMCarDocs("Cadillac XT5 No ACC")],
[GMCarDocs("Cadillac XT5 - No-ACC")],
CarSpecs(mass=1810, wheelbase=2.86, steerRatio=16.34, centerToFrontRatio=0.5),
)
CHEVROLET_TRAVERSE = GMPlatformConfig(
@@ -222,7 +226,7 @@ class CAR(Platforms):
CarSpecs(mass=2050, wheelbase=2.86, steerRatio=16.0, centerToFrontRatio=0.5),
)
CHEVROLET_MALIBU_CC = GMPlatformConfig(
[GMCarDocs("Chevrolet Malibu 2023 No ACC")],
[GMCarDocs("Chevrolet Malibu 2023 - No-ACC")],
CarSpecs(mass=1450, wheelbase=2.8, steerRatio=15.8, centerToFrontRatio=0.4),
)
CHEVROLET_TRAX = GMPlatformConfig(
@@ -313,7 +317,6 @@ FW_QUERY_CONFIG = FwQueryConfig(
EV_CAR = {CAR.CHEVROLET_VOLT, CAR.CHEVROLET_BOLT_EUV, CAR.CHEVROLET_VOLT_CC, CAR.CHEVROLET_BOLT_CC}
CC_ONLY_CAR = {CAR.CHEVROLET_VOLT_CC, CAR.CHEVROLET_BOLT_CC, CAR.CHEVROLET_EQUINOX_CC, CAR.CHEVROLET_SUBURBAN_CC, CAR.GMC_YUKON_CC, CAR.CADILLAC_CT6_CC, CAR.CHEVROLET_TRAILBLAZER_CC, CAR.CADILLAC_XT5_CC, CAR.CHEVROLET_MALIBU_CC}
CC_REGEN_PADDLE_CAR = {CAR.CHEVROLET_BOLT_CC, CAR.CHEVROLET_BOLT_EUV}
# CC_ONLY_CAR = set(c for c in CAR if str(c).endswith('_CC'))
# We're integrated at the Safety Data Gateway Module on these cars
+5 -5
View File
@@ -286,11 +286,11 @@ class CarController(CarControllerBase):
self.gas = pcm_accel / self.params.NIDEC_GAS_MAX
new_actuators = actuators.as_builder()
new_actuators.speed = self.speed
new_actuators.accel = self.accel
new_actuators.gas = self.gas
new_actuators.brake = self.brake
new_actuators.steer = self.last_steer
new_actuators.speed = float(self.speed)
new_actuators.accel = float(self.accel)
new_actuators.gas = float(self.gas)
new_actuators.brake = float(self.brake)
new_actuators.steer = float(self.last_steer)
new_actuators.steerOutputCan = apply_steer
self.frame += 1
+3 -3
View File
@@ -76,14 +76,14 @@ def create_brake_command(packer, CAN, apply_brake, pump_on, pcm_override, pcm_ca
return packer.make_can_msg("BRAKE_COMMAND", CAN.pt, values)
def create_acc_commands(packer, CAN, enabled, active, accel, gas, stopping_counter, car_fingerprint):
def create_acc_commands(packer, CAN, enabled, active, accel, gas, stopping_counter, car_fingerprint, gas_force):
commands = []
min_gas_accel = CarControllerParams.BOSCH_GAS_LOOKUP_BP[0]
control_on = 5 if enabled else 0
gas_command = gas if active and accel > min_gas_accel else -30000
gas_command = gas if active and gas_force > min_gas_accel else -30000
accel_command = accel if active else 0
braking = 1 if active and accel < min_gas_accel else 0
braking = 1 if active and gas_force < min_gas_accel else 0
standstill = 1 if active and stopping_counter > 0 else 0
standstill_release = 1 if active and stopping_counter == 0 else 0
+7 -4
View File
@@ -85,10 +85,10 @@ class CarInterface(CarInterfaceBase):
ret.longitudinalActuatorDelay = 0.5 # s
if candidate in HONDA_BOSCH_RADARLESS:
ret.stopAccel = CarControllerParams.BOSCH_ACCEL_MIN # stock uses -4.0 m/s^2 once stopped but limited by safety model
else:
# default longitudinal tuning for all hondas
ret.longitudinalTuning.kiBP = [0., 5., 35.]
ret.longitudinalTuning.kiV = [1.2, 0.8, 0.5]
# default longitudinal tuning for all hondas
ret.longitudinalTuning.kiBP = [0., 5., 35.]
ret.longitudinalTuning.kiV = [1.2, 0.8, 0.5]
eps_modified = False
for fw in car_fw:
@@ -117,6 +117,9 @@ class CarInterface(CarInterfaceBase):
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]]
if candidate == CAR.HONDA_CIVIC_BOSCH:
CarControllerParams.BOSCH_GAS_LOOKUP_V = [0, 750]
elif candidate == CAR.HONDA_ACCORD:
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
+1 -1
View File
@@ -43,7 +43,7 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
"CADILLAC_ESCALADE" = [1.899999976158142, 1.842270016670227, 0.1120000034570694]
"CADILLAC_ESCALADE_ESV_2019" = [1.15, 1.3, 0.2]
"CADILLAC_XT4" = [1.45, 1.6, 0.2]
"CHEVROLET_BOLT_EUV" = [2.0, 2.0, 0.09]
"CHEVROLET_BOLT_EUV" = [2.0, 2.0, 0.05]
"CHEVROLET_MALIBU_CC" = [1.85, 1.85, 0.075]
"CHEVROLET_SILVERADO" = [1.9, 1.9, 0.112]
"CHEVROLET_TRAILBLAZER" = [1.33, 1.9, 0.16]
+1 -1
View File
@@ -982,7 +982,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
"",
AlertStatus.normal, AlertSize.full,
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2, creation_delay=0.5),
ET.USER_DISABLE: ImmediateDisableAlert("Wrong Gear"),
ET.USER_DISABLE: ImmediateDisableAlert("Reverse Gear"),
ET.NO_ENTRY: NoEntryAlert("Reverse Gear"),
},
@@ -17,9 +17,9 @@ from openpilot.selfdrive.controls.lib.drive_helpers import V_CRUISE_UNSET, CONTR
from openpilot.common.swaglog import cloudlog
LON_MPC_STEP = 0.2 # first step is 0.2s
A_CRUISE_MIN = -1.0
A_CRUISE_MAX_BP = [0.0, 5., 10., 15., 20., 25., 40.]
A_CRUISE_MAX_VALS = [1.125, 1.125, 1.125, 1.125, 1.25, 1.25, 1.5]
A_CRUISE_MIN = -1.2
A_CRUISE_MAX_VALS = [1.6, 1.2, 0.8, 0.6]
A_CRUISE_MAX_BP = [0., 10.0, 25., 40.]
CONTROL_N_T_IDX = ModelConstants.T_IDXS[:CONTROL_N]
ALLOW_THROTTLE_THRESHOLD = 0.5
MIN_ALLOW_THROTTLE_SPEED = 2.5
+1 -1
View File
@@ -151,7 +151,7 @@ def laplacian_pdf(x: float, mu: float, b: float):
def match_vision_to_track(v_ego: float, lead: capnp._DynamicStructReader, model_data: capnp._DynamicStructReader, tracks: dict[int, Track], frogpilot_toggles: SimpleNamespace):
if model_data.meta.laneChangeState == LaneChangeState.laneChangeStarting and frogpilot_toggles.human_lane_changes:
if model_data.meta.laneChangeState == LaneChangeState.laneChangeStarting and getattr(frogpilot_toggles, "human_lane_changes", False):
direction = model_data.meta.laneChangeDirection
if direction == LaneChangeDirection.left:
+1 -1
View File
@@ -135,7 +135,7 @@ def main():
CP = msg
cloudlog.info("paramsd got CarParams")
min_sr, max_sr = 0.25 * CP.steerRatio, 2.0 * CP.steerRatio
min_sr, max_sr = 0.5 * CP.steerRatio, 2.0 * CP.steerRatio
params = params_reader.get("LiveParameters")