Compare commits

..

108 Commits

Author SHA1 Message Date
firestar5683 259ac19499 Honda 2026-02-17 21:02:15 -06:00
firestar5683 1a77897c3a no sascm
Revert "no sascm"

This reverts commit 147e752007c6a4f80eec551934bc1cf86510e6dc.

Update interface.py
2026-02-17 20:49:33 -06:00
firestar5683 b5d39c4bc1 Truck Tuning 2026-02-17 19:57:35 -06:00
firestar5683 d4d78c9435 Update frogpilot_acceleration.py 2026-02-17 12:28:29 -06:00
firestar5683 2f29d7ee04 EV Tuning 2026-02-16 23:43:46 -06:00
firestar5683 338a07973b Truck Tuning 2026-02-16 23:39:45 -06:00
firestar5683 f4da6a3e3b silverado 2026-02-16 17:28:35 -06:00
firestar5683 5fbaebc91c brake mismatches 2026-02-16 13:25:23 -06:00
firestarsdog 7dbdb33ed1 Gen2ACC Distance Button Sync for CC_ONLY_CAR 2026-02-15 23:33:15 -06:00
firestar5683 a1cd4954b1 cancel acc bolt with pedal 2026-02-15 23:15:48 -06:00
firestar5683 2bbffc2a38 cruisestatus acc pedal 2026-02-14 22:44:33 -06:00
firestar5683 4d7aee4935 pedal 2026-02-14 15:58:32 -06:00
firestarsdog 41b055d140 Update values.py 2026-02-14 16:24:10 -05:00
firestarsdog bec0c04334 Evil +? 2026-02-14 13:02:22 -05:00
firestar5683 a8499d20fc Separate Non-ACC vs ACC + Pedal 2026-02-13 23:48:41 -06:00
firestar5683 6d0c17f43a Holiday 2026-02-13 22:45:30 -06:00
firestar5683 6dec58237b Fingerprinting 2026-02-13 22:35:10 -06:00
firestarsdog 6a47be1631 Hondadays 2026-02-13 21:38:01 -05:00
firestarsdog 8ea080b4cb Honda attempt from bugsink 2026-02-13 15:35:17 -05:00
firestarsdog a51503f2e4 BugSink Catch - human_lane_changes 2026-02-13 11:16:12 -05:00
firestar5683 07c722553d The Great Merge 2026-02-13 01:52:05 -06:00
firestar5683 14b1793c79 User adjustable offsets 2026-02-07 23:32:26 -06:00
firestar5683 055c223ded Integrator Smooth On Handoff 2026-02-06 15:46:56 -06:00
firestar5683 4d406112f7 Lights 2026-02-05 22:39:42 -06:00
firestar5683 e03f28bba0 New Models 2026-02-05 15:05:18 -06:00
firestar5683 f0cc963c0e Revert "merry christmas"
This reverts commit 8a9d0e5e6a.
2026-02-05 13:33:40 -06:00
firestar5683 cd39ce0305 Increase Fault Resilience 2026-02-05 13:15:39 -06:00
firestarsdog 749b5e06fb Stats 2026-02-02 01:04:19 -05:00
firestarsdog 23121cca0e Stats 2026-02-01 22:46:13 -06:00
firestar5683 6f0502e862 friction threshold 2026-01-29 11:28:30 -06:00
firestar5683 04c59fb18e Lat Updates 2026-01-28 23:51:36 -06:00
firestar5683 844dce2030 Update interface.py 2026-01-20 22:08:07 -06:00
firestar5683 aa77db1fc9 Update override.toml 2026-01-19 21:18:53 -06:00
firestar5683 bee9b2b046 Revert "Mac Update"
This reverts commit 1b5d776464.
2026-01-19 11:43:31 -06:00
firestarsdog 469cd5e528 Add SASCM to vehicle settings detection/stats 2026-01-19 10:32:21 -06:00
firestar5683 23f52644ae Update interface.py 2026-01-18 23:45:59 -06:00
firestar5683 e76b82603b Update interface.py 2026-01-18 23:44:42 -06:00
firestar5683 1b5d776464 Mac Update 2026-01-18 22:22:06 -06:00
firestarsdog 61f4e8b142 Stats 2026-01-18 22:17:42 -06:00
firestar5683 f0fefb6e13 Torque Controller Update 2026-01-18 21:58:43 -06:00
firestar5683 25a7090c3d Update redneck 2026-01-15 22:54:15 -06:00
firestar5683 b0de4d64b4 Split Tune 2026-01-15 19:17:55 -06:00
firestar5683 77ae5b176a fix redneck v2 2026-01-14 13:58:22 -06:00
firestar5683 89de28682c Remove lat smooth seconds 2026-01-14 13:49:35 -06:00
firestar5683 a1d4dcb9a0 frogpilot migration 2026-01-12 22:10:40 -06:00
firestar5683 c8deae75b7 More defaults 2026-01-12 22:04:19 -06:00
firestar5683 8653fb41f2 Update defaults 2026-01-12 22:00:04 -06:00
firestar5683 c064197fde Big Mac 2026-01-11 16:58:25 -06:00
firestar5683 7f878ec1dc Try Higher Friction 2026-01-10 14:04:32 -06:00
firestar5683 140bdd59fb Autotune Off 2026-01-09 22:40:45 -06:00
firestar5683 6f728f935a Revert "Pedal Braking Limits"
This reverts commit 568b72095f.
2025-12-31 20:55:13 -06:00
firestar5683 568b72095f Pedal Braking Limits 2025-12-30 20:17:59 -06:00
firestar5683 0aaf4d1336 merry christmas 2025-12-24 22:04:58 -06:00
firestar5683 bb3f0a3354 ds2 2025-12-24 21:28:40 -06:00
firestar5683 f2aba355b9 Try friction adjustment 2025-12-16 14:38:29 -06:00
firestar5683 e6513efb9b Update frogpilot_tracking.py 2025-12-15 00:55:51 -06:00
firestar5683 872a2c58aa minsteer speed 2025-12-14 14:46:27 -06:00
firestar5683 1630560715 Update Percentages 2025-12-13 19:13:44 -06:00
firestar5683 4cfd893837 Trailer Load Gas Tuning 2025-12-12 10:50:11 -06:00
firestar5683 0e93ceef00 Live Friction 2025-12-11 16:54:11 -06:00
firestar5683 d626f0fe49 Zero error 2025-12-11 15:12:29 -06:00
firestar5683 8dae3d375c Updates
Update latcontrol_torque.py

interp friction threshold
2025-12-09 19:58:46 -06:00
firestar5683 721d39ef1f Change NoEntryAlert message to 'Reverse Gear' 2025-12-06 16:44:30 -06:00
firestar5683 a97c5742b7 Update events.py 2025-12-05 20:13:49 -06:00
firestar5683 488f821983 LattyBoi2.0 2025-12-03 23:30:35 -06:00
firestar5683 190dc98180 Latty Boi
Revert "Latty Boi"

This reverts commit af687e501cc4bdcda7840453d06595d7ea674148.

Reapply "Latty Boi"

This reverts commit ff5566d4439f5e4997fe83f4f21d0be62b75d75d.
2025-12-02 20:29:48 -06:00
firestar5683 0b459d9f0b Recovery Power 2025-12-02 17:18:43 -06:00
firestar5683 3cd594bbe4 New planplus 2025-12-02 12:09:05 -06:00
Woohyun Rho f31082ce2b Update 2025-11-28 17:10:45 -06:00
firestar5683 b51d7ae35d Update interface.py 2025-11-18 20:48:48 -06:00
firestar5683 884fcb8315 New Lateral Changes 2025-11-18 20:48:21 -06:00
firestar5683 77597e60b2 Update 2025-11-15 14:44:07 -06:00
firestar5683 f2fbc8f30b Accel Tests 2025-11-14 20:32:47 -06:00
firestar5683 fffea614a4 Paddle Planner 2025-11-14 01:26:06 -06:00
firestar5683 e7e593cdb2 Revert "Upstream Lateral"
This reverts commit 97f8736605.
2025-11-10 23:07:02 -06:00
firestar5683 97f8736605 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:13:34 -06:00
firestar5683 48efc5b97a Update manager.py 2025-10-27 00:58:28 -05:00
firestar5683 4cca6553e4 Update 2025-10-25 15:35:55 -05:00
firestar5683 6eda52b562 Medium Fanta 2025-10-22 22:18:08 -05:00
firestar5683 de9cbc5de6 Update interfaces.py 2025-10-20 13:49:08 -05:00
firestar5683 fee241dc0b no nnff 2025-10-19 17:59:36 -05:00
firestar5683 2094be9a7a Scene Complexity 2025-10-18 14:24:48 -05:00
firestar5683 6ce476025d Update carcontroller.py 2025-10-17 19:10:41 -05:00
firestar5683 dd6c62dbf6 Update interface.py 2025-10-17 18:13:24 -05:00
firestar5683 2ab19dbd4c CEM 2025-10-17 17:39:06 -05:00
firestar5683 3241fbdd8c lite 2025-10-17 17:13:37 -05:00
firestar5683 1f0350e66a Redneck 2.0 2025-10-17 16:55:56 -05:00
firestar5683 ce46776439 Modify torque tuning parameters in interfaces.py
Adjusted torque tuning parameters for improved performance.
2025-10-17 16:53:54 -05:00
firestar5683 afb209a1a8 Hurts Donut 2025-10-16 23:57:08 -05:00
firestar5683 b4e29d4ed6 Smoothy Boi 2025-10-16 23:35:26 -05:00
firestar5683 dada0f2ae6 New change 2025-10-15 22:59:04 -05:00
firestar5683 4532e7f5d1 lat3 2025-10-15 22:20:35 -05:00
firestar5683 78de442ee1 New Lateral Changes 2025-10-10 20:59:23 -05:00
firestar5683 953b343e06 Fix Standard 2025-10-10 19:24:24 -05:00
firestar5683 5b26be2e3c error? 2025-10-08 23:13:32 -05:00
firestar5683 4abe50405c Update interface.py 2025-10-08 23:07:37 -05:00
firestar5683 f2e705413c Fix New Devices 2025-10-08 22:19:43 -05:00
firestar5683 da56f26105 No positive P-response for long control if user-selected parameter set 2025-10-08 07:42:32 -05:00
firestar5683 ab39266180 Automatic updates 2025-10-04 16:04:35 -05:00
firestar5683 dac85dfd3a Steer Alerts 2025-10-04 01:49:22 -05:00
firestar5683 7e539cde38 Update frogpilot_acceleration.py 2025-10-03 22:42:08 -05:00
firestar5683 16a79fbc3d SteerAlerts
Revert "SteerAlerts"

This reverts commit cbaba399c5b9caac5a8faf3917f0929d747a0acc.

Update controlsd.py
2025-10-03 22:14:25 -05:00
firestar5683 9cdf0120cf Donut DM 2025-10-03 20:50:00 -05:00
firestar5683 aa0f0aaac8 Update gm_global_a_powertrain_generated.dbc 2025-10-03 16:41:22 -05:00
firestar5683 aefaafb616 Update 2025-10-03 00:43:40 -05:00
firestar5683 388f63168f firehose 2025-09-30 20:45:47 -05:00
firestar5683 7fe40f6e7f Update 2025-09-30 14:30:04 -05:00
firestar5683 eb2218e733 Dom 2025-09-30 09:25:14 -05:00
78 changed files with 2998 additions and 416 deletions
+6
View File
@@ -247,6 +247,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"BlacklistedModels", PERSISTENT}, {"BlacklistedModels", PERSISTENT},
{"BlindSpotMetrics", PERSISTENT}, {"BlindSpotMetrics", PERSISTENT},
{"BlindSpotPath", PERSISTENT}, {"BlindSpotPath", PERSISTENT},
{"BootLogo", PERSISTENT},
{"BorderMetrics", PERSISTENT}, {"BorderMetrics", PERSISTENT},
{"CalibratedLateralAcceleration", PERSISTENT}, {"CalibratedLateralAcceleration", PERSISTENT},
{"CalibrationProgress", PERSISTENT}, {"CalibrationProgress", PERSISTENT},
@@ -272,6 +273,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"CEStatus", CLEAR_ON_OFFROAD_TRANSITION}, {"CEStatus", CLEAR_ON_OFFROAD_TRANSITION},
{"CEStoppedLead", PERSISTENT}, {"CEStoppedLead", PERSISTENT},
{"ClusterOffset", PERSISTENT}, {"ClusterOffset", PERSISTENT},
{"BootLogoToDownload", CLEAR_ON_MANAGER_START},
{"ColorToDownload", CLEAR_ON_MANAGER_START}, {"ColorToDownload", CLEAR_ON_MANAGER_START},
{"Compass", PERSISTENT}, {"Compass", PERSISTENT},
{"ConditionalExperimental", PERSISTENT}, {"ConditionalExperimental", PERSISTENT},
@@ -310,6 +312,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"DisengageVolume", PERSISTENT}, {"DisengageVolume", PERSISTENT},
{"DoToggleReset", PERSISTENT}, {"DoToggleReset", PERSISTENT},
{"DoToggleResetStock", PERSISTENT}, {"DoToggleResetStock", PERSISTENT},
{"DownloadableBootLogos", PERSISTENT},
{"DownloadableColors", PERSISTENT}, {"DownloadableColors", PERSISTENT},
{"DownloadableDistanceIcons", PERSISTENT}, {"DownloadableDistanceIcons", PERSISTENT},
{"DownloadableIcons", PERSISTENT}, {"DownloadableIcons", PERSISTENT},
@@ -323,6 +326,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"EngageVolume", PERSISTENT}, {"EngageVolume", PERSISTENT},
{"ExperimentalGMTune", PERSISTENT}, {"ExperimentalGMTune", PERSISTENT},
{"EVTuning", PERSISTENT}, {"EVTuning", PERSISTENT},
{"TruckTuning", PERSISTENT},
{"Fahrenheit", PERSISTENT}, {"Fahrenheit", PERSISTENT},
{"FavoriteDestinations", PERSISTENT | DONT_LOG}, {"FavoriteDestinations", PERSISTENT | DONT_LOG},
{"FlashPanda", CLEAR_ON_MANAGER_START}, {"FlashPanda", CLEAR_ON_MANAGER_START},
@@ -469,6 +473,8 @@ std::unordered_map<std::string, uint32_t> keys = {
{"RoadEdgesWidth", PERSISTENT}, {"RoadEdgesWidth", PERSISTENT},
{"RoadName", CLEAR_ON_MANAGER_START}, {"RoadName", CLEAR_ON_MANAGER_START},
{"RoadNameUI", PERSISTENT}, {"RoadNameUI", PERSISTENT},
{"RedPanda", PERSISTENT},
{"RemoteStartBootsComma", PERSISTENT},
{"RotatingWheel", PERSISTENT}, {"RotatingWheel", PERSISTENT},
{"ScreenBrightness", PERSISTENT}, {"ScreenBrightness", PERSISTENT},
{"ScreenBrightnessOnroad", PERSISTENT}, {"ScreenBrightnessOnroad", PERSISTENT},
Binary file not shown.
+28 -11
View File
@@ -29,13 +29,15 @@ def check_github_rate_limit():
print(f"Error checking GitHub rate limit: {error}") print(f"Error checking GitHub rate limit: {error}")
return False return False
def download_file(cancel_param, destination, progress_param, url, download_param, params_memory): def download_file(cancel_param, destination, progress_param, url, download_param, params_memory, allow_unknown_size=False, suppress_errors=False):
try: try:
destination.parent.mkdir(parents=True, exist_ok=True) destination.parent.mkdir(parents=True, exist_ok=True)
total_size = get_remote_file_size(url) total_size = get_remote_file_size(url, suppress_errors=suppress_errors or allow_unknown_size)
if total_size == 0: if total_size == 0 and not allow_unknown_size:
if not url.endswith(".gif"): if not url.endswith(".gif"):
if suppress_errors:
return
handle_error(None, "Download invalid...", "Download invalid...", download_param, progress_param, params_memory) handle_error(None, "Download invalid...", "Download invalid...", download_param, progress_param, params_memory)
return return
@@ -56,24 +58,30 @@ def download_file(cancel_param, destination, progress_param, url, download_param
temp_file.write(chunk) temp_file.write(chunk)
downloaded_size += len(chunk) downloaded_size += len(chunk)
progress = (downloaded_size / total_size) * 100 if total_size > 0:
if progress != 100: progress = (downloaded_size / total_size) * 100
params_memory.put(progress_param, f"{progress:.0f}%") if progress != 100:
else: params_memory.put(progress_param, f"{progress:.0f}%")
else:
params_memory.put(progress_param, "Verifying authenticity...")
elif downloaded_size > 0:
params_memory.put(progress_param, "Verifying authenticity...") params_memory.put(progress_param, "Verifying authenticity...")
temp_file_path.rename(destination) temp_file_path.rename(destination)
except Exception as error: except Exception as error:
if suppress_errors:
return
handle_request_error(error, destination, download_param, progress_param, params_memory) handle_request_error(error, destination, download_param, progress_param, params_memory)
def get_remote_file_size(url): def get_remote_file_size(url, suppress_errors=False):
try: try:
response = requests.head(url, headers={"Accept-Encoding": "identity"}, timeout=10) response = requests.head(url, headers={"Accept-Encoding": "identity"}, timeout=10)
response.raise_for_status() response.raise_for_status()
return int(response.headers.get("Content-Length", 0)) return int(response.headers.get("Content-Length", 0))
except Exception as error: except Exception as error:
handle_request_error(error, None, None, None, None) if not suppress_errors:
handle_request_error(error, None, None, None, None)
return 0 return 0
def get_repository_url(): def get_repository_url():
@@ -104,8 +112,17 @@ def handle_request_error(error, destination, download_param, progress_param, par
error_message = error_map.get(type(error), "Unexpected error") error_message = error_map.get(type(error), "Unexpected error")
handle_error(destination, f"Failed: {error_message}", error, download_param, progress_param, params_memory) handle_error(destination, f"Failed: {error_message}", error, download_param, progress_param, params_memory)
def verify_download(file_path, url): def verify_download(file_path, url, allow_unknown_size=False):
remote_file_size = get_remote_file_size(url) remote_file_size = get_remote_file_size(url, suppress_errors=allow_unknown_size)
if remote_file_size == 0 and allow_unknown_size:
if not file_path.is_file():
print(f"File not found: {file_path}")
return False
if file_path.stat().st_size == 0:
print(f"File is empty: {file_path}")
return False
return True
if remote_file_size == 0: if remote_file_size == 0:
print(f"Error fetching remote size for {file_path}") print(f"Error fetching remote size for {file_path}")
@@ -0,0 +1 @@
{"input_std":[[9.342214],[1.5915664],[0.60113484],[0.048193663],[1.5680411],[1.57577],[1.5836853],[1.5711677],[1.5445132],[1.5007596],[1.4529978],[0.047915205],[0.04800539],[0.04808892],[0.04822398],[0.04817677],[0.047881734],[0.047405947]],"model_test_loss":0.019342588260769844,"input_size":18,"current_date_and_time":"2023-08-05_06-09-11","input_mean":[[22.757933],[-0.016342578],[-0.001405228],[-0.014619173],[-0.018091483],[-0.018382493],[-0.019270267],[-0.018759886],[-0.019559544],[-0.017848592],[-0.020014366],[-0.014564899],[-0.01457757],[-0.014600966],[-0.014757987],[-0.014915743],[-0.015121007],[-0.015359475]],"input_vars":["v_ego","lateral_accel","lateral_jerk","roll","lateral_accel_m03","lateral_accel_m02","lateral_accel_m01","lateral_accel_p03","lateral_accel_p06","lateral_accel_p10","lateral_accel_p15","roll_m03","roll_m02","roll_m01","roll_p03","roll_p06","roll_p10","roll_p15"],"output_size":1,"layers":[{"dense_1_b":[[-0.045577038],[-2.8160777],[-0.21418032],[2.9552083],[-0.06852827],[0.029141279],[-0.053249933]],"dense_1_W":[[0.0010664682,1.3813498,-8.153277,-0.009101015,-0.1484779,1.0008405,-1.5930991,-1.195274,0.6136762,0.3560462,-0.30077773,0.93531257,0.14550218,-0.40074933,-0.21716364,0.13834935,-0.0658936,-0.49427196],[-0.7338253,-0.037501235,-0.49922377,-1.0526338,-0.46141604,-1.3649396,0.7309814,-0.91667104,0.044683233,-0.18628967,-0.20878822,-0.2678598,0.48446324,0.51164204,0.09547851,0.41491362,-0.4524314,0.16594785],[-0.0032175342,3.5451593,-0.11421584,-0.2511033,0.27893174,0.6384996,0.80790603,1.3835542,1.8000495,2.249461,1.4026878,0.7851167,-0.35052946,0.041820426,-0.39790183,0.45703772,-0.30459648,0.18287674],[0.72289664,-0.77138704,-0.5025135,-0.49323097,-0.39893976,-0.8779149,0.6848096,-0.58729875,-0.16643623,-0.14427555,-0.15013328,-0.11467142,-0.27280045,0.48508415,0.52080667,-0.0029569597,-0.28170735,0.06367212],[0.00014026981,-2.0353239,0.0060915067,0.4794941,1.1882906,-1.512865,0.80642134,-0.26044324,-0.56213886,-0.365122,0.55078083,-0.34897435,-0.32031298,0.46106994,0.37792024,-0.14116105,0.15597256,-0.32811671],[0.0011494387,1.9060265,8.3941965,-0.3078165,-0.9530427,0.6589645,-1.2487054,-0.541133,0.13451256,0.2805466,-0.33187166,0.9900705,0.2821258,-0.51270896,-0.5130031,-0.28222615,0.042734932,0.27233443],[-0.0014444552,-1.0933362,0.003359957,-0.15052961,0.37165833,1.7087307,-1.4971043,0.673802,-0.108465396,-0.088505454,0.21561684,0.6252258,-0.15019403,-0.34727478,0.08958758,-0.1723621,-0.25557828,0.29778987]],"activation":"σ"},{"dense_2_W":[[0.20810607,-0.13481373,-0.15003344,-0.6067625,-0.31937903,-0.37380016,0.4666911],[0.71834767,0.15669753,-0.11389502,0.27131546,-0.060118295,0.039282244,0.52961355],[-0.27200606,0.43380752,-0.106262706,-0.49363258,0.35659012,-0.01706296,-1.0807354],[-0.79583454,-0.66428274,-0.42157334,-0.52979547,-0.2803004,-0.57637554,0.084149174],[0.1230394,-0.57023287,0.28639448,-0.506744,-0.9920808,0.7510901,0.8584937],[-0.41256845,0.35423175,0.13009231,0.5198333,0.7576573,-0.7053181,-0.3390053],[-0.15090485,0.33375353,-0.64164793,0.57386595,0.25700107,-0.15245672,-0.49020413],[-0.50120676,0.5210849,-0.3282951,0.4276323,1.0257447,-1.0398436,-0.8911315],[0.11402861,-0.41491523,0.247507,-0.39776865,-0.6089287,0.20646147,0.6692102],[0.09411492,0.31819808,0.41330767,0.024243973,0.2314893,0.08529045,0.14911193],[0.5179265,0.20473345,-0.36762783,-0.009045922,-0.19436747,-0.548099,-0.08656279],[-0.69121784,-0.14201449,0.3887621,0.10787631,1.0371574,-0.64747447,-0.73437464],[-0.07860244,-0.597764,0.019551078,0.010199122,-0.7493642,0.66619915,0.121666186]],"activation":"σ","dense_2_b":[[-0.04259814],[-0.053309314],[-0.28045595],[-0.23801634],[0.00944943],[-0.109921046],[-0.037457183],[0.24627604],[-0.0069056284],[-0.04725389],[-0.03361769],[0.044101644],[-0.0009850285]]},{"dense_3_W":[[-0.19631335,-0.47722518,-0.019853225,-0.29363275,-0.625923,0.35145283,0.62401354,0.14337404,-0.25707108,-0.51310915,0.2565006,0.61742216,-0.07952821],[0.5868974,-0.36786363,-0.0177682,-0.45121866,0.68608487,-0.55178356,-0.35236016,-0.7226455,-0.015394288,-0.10650332,0.5391039,0.17791761,0.34196886],[0.16821232,-0.35580373,0.26906335,0.41736925,-0.6979869,0.41801625,0.34707317,0.7784011,-0.10002936,0.32485273,-0.3644285,0.49092358,-0.43872768]],"activation":"identity","dense_3_b":[[-0.019481273],[0.031026587],[-0.03595322]]},{"dense_4_W":[[-0.72340566,0.21244061,-0.67248434]],"dense_4_b":[[0.026229527]],"activation":"identity"}]}
@@ -0,0 +1 @@
{"input_std":[[9.342214],[1.5915664],[0.60113484],[0.048193663],[1.5680411],[1.57577],[1.5836853],[1.5711677],[1.5445132],[1.5007596],[1.4529978],[0.047915205],[0.04800539],[0.04808892],[0.04822398],[0.04817677],[0.047881734],[0.047405947]],"model_test_loss":0.019342588260769844,"input_size":18,"current_date_and_time":"2023-08-05_06-09-11","input_mean":[[22.757933],[-0.016342578],[-0.001405228],[-0.014619173],[-0.018091483],[-0.018382493],[-0.019270267],[-0.018759886],[-0.019559544],[-0.017848592],[-0.020014366],[-0.014564899],[-0.01457757],[-0.014600966],[-0.014757987],[-0.014915743],[-0.015121007],[-0.015359475]],"input_vars":["v_ego","lateral_accel","lateral_jerk","roll","lateral_accel_m03","lateral_accel_m02","lateral_accel_m01","lateral_accel_p03","lateral_accel_p06","lateral_accel_p10","lateral_accel_p15","roll_m03","roll_m02","roll_m01","roll_p03","roll_p06","roll_p10","roll_p15"],"output_size":1,"layers":[{"dense_1_b":[[-0.045577038],[-2.8160777],[-0.21418032],[2.9552083],[-0.06852827],[0.029141279],[-0.053249933]],"dense_1_W":[[0.0010664682,1.3813498,-8.153277,-0.009101015,-0.1484779,1.0008405,-1.5930991,-1.195274,0.6136762,0.3560462,-0.30077773,0.93531257,0.14550218,-0.40074933,-0.21716364,0.13834935,-0.0658936,-0.49427196],[-0.7338253,-0.037501235,-0.49922377,-1.0526338,-0.46141604,-1.3649396,0.7309814,-0.91667104,0.044683233,-0.18628967,-0.20878822,-0.2678598,0.48446324,0.51164204,0.09547851,0.41491362,-0.4524314,0.16594785],[-0.0032175342,3.5451593,-0.11421584,-0.2511033,0.27893174,0.6384996,0.80790603,1.3835542,1.8000495,2.249461,1.4026878,0.7851167,-0.35052946,0.041820426,-0.39790183,0.45703772,-0.30459648,0.18287674],[0.72289664,-0.77138704,-0.5025135,-0.49323097,-0.39893976,-0.8779149,0.6848096,-0.58729875,-0.16643623,-0.14427555,-0.15013328,-0.11467142,-0.27280045,0.48508415,0.52080667,-0.0029569597,-0.28170735,0.06367212],[0.00014026981,-2.0353239,0.0060915067,0.4794941,1.1882906,-1.512865,0.80642134,-0.26044324,-0.56213886,-0.365122,0.55078083,-0.34897435,-0.32031298,0.46106994,0.37792024,-0.14116105,0.15597256,-0.32811671],[0.0011494387,1.9060265,8.3941965,-0.3078165,-0.9530427,0.6589645,-1.2487054,-0.541133,0.13451256,0.2805466,-0.33187166,0.9900705,0.2821258,-0.51270896,-0.5130031,-0.28222615,0.042734932,0.27233443],[-0.0014444552,-1.0933362,0.003359957,-0.15052961,0.37165833,1.7087307,-1.4971043,0.673802,-0.108465396,-0.088505454,0.21561684,0.6252258,-0.15019403,-0.34727478,0.08958758,-0.1723621,-0.25557828,0.29778987]],"activation":"σ"},{"dense_2_W":[[0.20810607,-0.13481373,-0.15003344,-0.6067625,-0.31937903,-0.37380016,0.4666911],[0.71834767,0.15669753,-0.11389502,0.27131546,-0.060118295,0.039282244,0.52961355],[-0.27200606,0.43380752,-0.106262706,-0.49363258,0.35659012,-0.01706296,-1.0807354],[-0.79583454,-0.66428274,-0.42157334,-0.52979547,-0.2803004,-0.57637554,0.084149174],[0.1230394,-0.57023287,0.28639448,-0.506744,-0.9920808,0.7510901,0.8584937],[-0.41256845,0.35423175,0.13009231,0.5198333,0.7576573,-0.7053181,-0.3390053],[-0.15090485,0.33375353,-0.64164793,0.57386595,0.25700107,-0.15245672,-0.49020413],[-0.50120676,0.5210849,-0.3282951,0.4276323,1.0257447,-1.0398436,-0.8911315],[0.11402861,-0.41491523,0.247507,-0.39776865,-0.6089287,0.20646147,0.6692102],[0.09411492,0.31819808,0.41330767,0.024243973,0.2314893,0.08529045,0.14911193],[0.5179265,0.20473345,-0.36762783,-0.009045922,-0.19436747,-0.548099,-0.08656279],[-0.69121784,-0.14201449,0.3887621,0.10787631,1.0371574,-0.64747447,-0.73437464],[-0.07860244,-0.597764,0.019551078,0.010199122,-0.7493642,0.66619915,0.121666186]],"activation":"σ","dense_2_b":[[-0.04259814],[-0.053309314],[-0.28045595],[-0.23801634],[0.00944943],[-0.109921046],[-0.037457183],[0.24627604],[-0.0069056284],[-0.04725389],[-0.03361769],[0.044101644],[-0.0009850285]]},{"dense_3_W":[[-0.19631335,-0.47722518,-0.019853225,-0.29363275,-0.625923,0.35145283,0.62401354,0.14337404,-0.25707108,-0.51310915,0.2565006,0.61742216,-0.07952821],[0.5868974,-0.36786363,-0.0177682,-0.45121866,0.68608487,-0.55178356,-0.35236016,-0.7226455,-0.015394288,-0.10650332,0.5391039,0.17791761,0.34196886],[0.16821232,-0.35580373,0.26906335,0.41736925,-0.6979869,0.41801625,0.34707317,0.7784011,-0.10002936,0.32485273,-0.3644285,0.49092358,-0.43872768]],"activation":"identity","dense_3_b":[[-0.019481273],[0.031026587],[-0.03595322]]},{"dense_4_W":[[-0.72340566,0.21244061,-0.67248434]],"dense_4_b":[[0.026229527]],"activation":"identity"}]}
@@ -0,0 +1 @@
{"input_std":[[9.342214],[1.5915664],[0.60113484],[0.048193663],[1.5680411],[1.57577],[1.5836853],[1.5711677],[1.5445132],[1.5007596],[1.4529978],[0.047915205],[0.04800539],[0.04808892],[0.04822398],[0.04817677],[0.047881734],[0.047405947]],"model_test_loss":0.019342588260769844,"input_size":18,"current_date_and_time":"2023-08-05_06-09-11","input_mean":[[22.757933],[-0.016342578],[-0.001405228],[-0.014619173],[-0.018091483],[-0.018382493],[-0.019270267],[-0.018759886],[-0.019559544],[-0.017848592],[-0.020014366],[-0.014564899],[-0.01457757],[-0.014600966],[-0.014757987],[-0.014915743],[-0.015121007],[-0.015359475]],"input_vars":["v_ego","lateral_accel","lateral_jerk","roll","lateral_accel_m03","lateral_accel_m02","lateral_accel_m01","lateral_accel_p03","lateral_accel_p06","lateral_accel_p10","lateral_accel_p15","roll_m03","roll_m02","roll_m01","roll_p03","roll_p06","roll_p10","roll_p15"],"output_size":1,"layers":[{"dense_1_b":[[-0.045577038],[-2.8160777],[-0.21418032],[2.9552083],[-0.06852827],[0.029141279],[-0.053249933]],"dense_1_W":[[0.0010664682,1.3813498,-8.153277,-0.009101015,-0.1484779,1.0008405,-1.5930991,-1.195274,0.6136762,0.3560462,-0.30077773,0.93531257,0.14550218,-0.40074933,-0.21716364,0.13834935,-0.0658936,-0.49427196],[-0.7338253,-0.037501235,-0.49922377,-1.0526338,-0.46141604,-1.3649396,0.7309814,-0.91667104,0.044683233,-0.18628967,-0.20878822,-0.2678598,0.48446324,0.51164204,0.09547851,0.41491362,-0.4524314,0.16594785],[-0.0032175342,3.5451593,-0.11421584,-0.2511033,0.27893174,0.6384996,0.80790603,1.3835542,1.8000495,2.249461,1.4026878,0.7851167,-0.35052946,0.041820426,-0.39790183,0.45703772,-0.30459648,0.18287674],[0.72289664,-0.77138704,-0.5025135,-0.49323097,-0.39893976,-0.8779149,0.6848096,-0.58729875,-0.16643623,-0.14427555,-0.15013328,-0.11467142,-0.27280045,0.48508415,0.52080667,-0.0029569597,-0.28170735,0.06367212],[0.00014026981,-2.0353239,0.0060915067,0.4794941,1.1882906,-1.512865,0.80642134,-0.26044324,-0.56213886,-0.365122,0.55078083,-0.34897435,-0.32031298,0.46106994,0.37792024,-0.14116105,0.15597256,-0.32811671],[0.0011494387,1.9060265,8.3941965,-0.3078165,-0.9530427,0.6589645,-1.2487054,-0.541133,0.13451256,0.2805466,-0.33187166,0.9900705,0.2821258,-0.51270896,-0.5130031,-0.28222615,0.042734932,0.27233443],[-0.0014444552,-1.0933362,0.003359957,-0.15052961,0.37165833,1.7087307,-1.4971043,0.673802,-0.108465396,-0.088505454,0.21561684,0.6252258,-0.15019403,-0.34727478,0.08958758,-0.1723621,-0.25557828,0.29778987]],"activation":"σ"},{"dense_2_W":[[0.20810607,-0.13481373,-0.15003344,-0.6067625,-0.31937903,-0.37380016,0.4666911],[0.71834767,0.15669753,-0.11389502,0.27131546,-0.060118295,0.039282244,0.52961355],[-0.27200606,0.43380752,-0.106262706,-0.49363258,0.35659012,-0.01706296,-1.0807354],[-0.79583454,-0.66428274,-0.42157334,-0.52979547,-0.2803004,-0.57637554,0.084149174],[0.1230394,-0.57023287,0.28639448,-0.506744,-0.9920808,0.7510901,0.8584937],[-0.41256845,0.35423175,0.13009231,0.5198333,0.7576573,-0.7053181,-0.3390053],[-0.15090485,0.33375353,-0.64164793,0.57386595,0.25700107,-0.15245672,-0.49020413],[-0.50120676,0.5210849,-0.3282951,0.4276323,1.0257447,-1.0398436,-0.8911315],[0.11402861,-0.41491523,0.247507,-0.39776865,-0.6089287,0.20646147,0.6692102],[0.09411492,0.31819808,0.41330767,0.024243973,0.2314893,0.08529045,0.14911193],[0.5179265,0.20473345,-0.36762783,-0.009045922,-0.19436747,-0.548099,-0.08656279],[-0.69121784,-0.14201449,0.3887621,0.10787631,1.0371574,-0.64747447,-0.73437464],[-0.07860244,-0.597764,0.019551078,0.010199122,-0.7493642,0.66619915,0.121666186]],"activation":"σ","dense_2_b":[[-0.04259814],[-0.053309314],[-0.28045595],[-0.23801634],[0.00944943],[-0.109921046],[-0.037457183],[0.24627604],[-0.0069056284],[-0.04725389],[-0.03361769],[0.044101644],[-0.0009850285]]},{"dense_3_W":[[-0.19631335,-0.47722518,-0.019853225,-0.29363275,-0.625923,0.35145283,0.62401354,0.14337404,-0.25707108,-0.51310915,0.2565006,0.61742216,-0.07952821],[0.5868974,-0.36786363,-0.0177682,-0.45121866,0.68608487,-0.55178356,-0.35236016,-0.7226455,-0.015394288,-0.10650332,0.5391039,0.17791761,0.34196886],[0.16821232,-0.35580373,0.26906335,0.41736925,-0.6979869,0.41801625,0.34707317,0.7784011,-0.10002936,0.32485273,-0.3644285,0.49092358,-0.43872768]],"activation":"identity","dense_3_b":[[-0.019481273],[0.031026587],[-0.03595322]]},{"dense_4_W":[[-0.72340566,0.21244061,-0.67248434]],"dense_4_b":[[0.026229527]],"activation":"identity"}]}
@@ -0,0 +1 @@
{"input_std":[[9.342214],[1.5915664],[0.60113484],[0.048193663],[1.5680411],[1.57577],[1.5836853],[1.5711677],[1.5445132],[1.5007596],[1.4529978],[0.047915205],[0.04800539],[0.04808892],[0.04822398],[0.04817677],[0.047881734],[0.047405947]],"model_test_loss":0.019342588260769844,"input_size":18,"current_date_and_time":"2023-08-05_06-09-11","input_mean":[[22.757933],[-0.016342578],[-0.001405228],[-0.014619173],[-0.018091483],[-0.018382493],[-0.019270267],[-0.018759886],[-0.019559544],[-0.017848592],[-0.020014366],[-0.014564899],[-0.01457757],[-0.014600966],[-0.014757987],[-0.014915743],[-0.015121007],[-0.015359475]],"input_vars":["v_ego","lateral_accel","lateral_jerk","roll","lateral_accel_m03","lateral_accel_m02","lateral_accel_m01","lateral_accel_p03","lateral_accel_p06","lateral_accel_p10","lateral_accel_p15","roll_m03","roll_m02","roll_m01","roll_p03","roll_p06","roll_p10","roll_p15"],"output_size":1,"layers":[{"dense_1_b":[[-0.045577038],[-2.8160777],[-0.21418032],[2.9552083],[-0.06852827],[0.029141279],[-0.053249933]],"dense_1_W":[[0.0010664682,1.3813498,-8.153277,-0.009101015,-0.1484779,1.0008405,-1.5930991,-1.195274,0.6136762,0.3560462,-0.30077773,0.93531257,0.14550218,-0.40074933,-0.21716364,0.13834935,-0.0658936,-0.49427196],[-0.7338253,-0.037501235,-0.49922377,-1.0526338,-0.46141604,-1.3649396,0.7309814,-0.91667104,0.044683233,-0.18628967,-0.20878822,-0.2678598,0.48446324,0.51164204,0.09547851,0.41491362,-0.4524314,0.16594785],[-0.0032175342,3.5451593,-0.11421584,-0.2511033,0.27893174,0.6384996,0.80790603,1.3835542,1.8000495,2.249461,1.4026878,0.7851167,-0.35052946,0.041820426,-0.39790183,0.45703772,-0.30459648,0.18287674],[0.72289664,-0.77138704,-0.5025135,-0.49323097,-0.39893976,-0.8779149,0.6848096,-0.58729875,-0.16643623,-0.14427555,-0.15013328,-0.11467142,-0.27280045,0.48508415,0.52080667,-0.0029569597,-0.28170735,0.06367212],[0.00014026981,-2.0353239,0.0060915067,0.4794941,1.1882906,-1.512865,0.80642134,-0.26044324,-0.56213886,-0.365122,0.55078083,-0.34897435,-0.32031298,0.46106994,0.37792024,-0.14116105,0.15597256,-0.32811671],[0.0011494387,1.9060265,8.3941965,-0.3078165,-0.9530427,0.6589645,-1.2487054,-0.541133,0.13451256,0.2805466,-0.33187166,0.9900705,0.2821258,-0.51270896,-0.5130031,-0.28222615,0.042734932,0.27233443],[-0.0014444552,-1.0933362,0.003359957,-0.15052961,0.37165833,1.7087307,-1.4971043,0.673802,-0.108465396,-0.088505454,0.21561684,0.6252258,-0.15019403,-0.34727478,0.08958758,-0.1723621,-0.25557828,0.29778987]],"activation":"σ"},{"dense_2_W":[[0.20810607,-0.13481373,-0.15003344,-0.6067625,-0.31937903,-0.37380016,0.4666911],[0.71834767,0.15669753,-0.11389502,0.27131546,-0.060118295,0.039282244,0.52961355],[-0.27200606,0.43380752,-0.106262706,-0.49363258,0.35659012,-0.01706296,-1.0807354],[-0.79583454,-0.66428274,-0.42157334,-0.52979547,-0.2803004,-0.57637554,0.084149174],[0.1230394,-0.57023287,0.28639448,-0.506744,-0.9920808,0.7510901,0.8584937],[-0.41256845,0.35423175,0.13009231,0.5198333,0.7576573,-0.7053181,-0.3390053],[-0.15090485,0.33375353,-0.64164793,0.57386595,0.25700107,-0.15245672,-0.49020413],[-0.50120676,0.5210849,-0.3282951,0.4276323,1.0257447,-1.0398436,-0.8911315],[0.11402861,-0.41491523,0.247507,-0.39776865,-0.6089287,0.20646147,0.6692102],[0.09411492,0.31819808,0.41330767,0.024243973,0.2314893,0.08529045,0.14911193],[0.5179265,0.20473345,-0.36762783,-0.009045922,-0.19436747,-0.548099,-0.08656279],[-0.69121784,-0.14201449,0.3887621,0.10787631,1.0371574,-0.64747447,-0.73437464],[-0.07860244,-0.597764,0.019551078,0.010199122,-0.7493642,0.66619915,0.121666186]],"activation":"σ","dense_2_b":[[-0.04259814],[-0.053309314],[-0.28045595],[-0.23801634],[0.00944943],[-0.109921046],[-0.037457183],[0.24627604],[-0.0069056284],[-0.04725389],[-0.03361769],[0.044101644],[-0.0009850285]]},{"dense_3_W":[[-0.19631335,-0.47722518,-0.019853225,-0.29363275,-0.625923,0.35145283,0.62401354,0.14337404,-0.25707108,-0.51310915,0.2565006,0.61742216,-0.07952821],[0.5868974,-0.36786363,-0.0177682,-0.45121866,0.68608487,-0.55178356,-0.35236016,-0.7226455,-0.015394288,-0.10650332,0.5391039,0.17791761,0.34196886],[0.16821232,-0.35580373,0.26906335,0.41736925,-0.6979869,0.41801625,0.34707317,0.7784011,-0.10002936,0.32485273,-0.3644285,0.49092358,-0.43872768]],"activation":"identity","dense_3_b":[[-0.019481273],[0.031026587],[-0.03595322]]},{"dense_4_W":[[-0.72340566,0.21244061,-0.67248434]],"dense_4_b":[[0.026229527]],"activation":"identity"}]}
@@ -0,0 +1 @@
{"input_std":[[9.342214],[1.5915664],[0.60113484],[0.048193663],[1.5680411],[1.57577],[1.5836853],[1.5711677],[1.5445132],[1.5007596],[1.4529978],[0.047915205],[0.04800539],[0.04808892],[0.04822398],[0.04817677],[0.047881734],[0.047405947]],"model_test_loss":0.019342588260769844,"input_size":18,"current_date_and_time":"2023-08-05_06-09-11","input_mean":[[22.757933],[-0.016342578],[-0.001405228],[-0.014619173],[-0.018091483],[-0.018382493],[-0.019270267],[-0.018759886],[-0.019559544],[-0.017848592],[-0.020014366],[-0.014564899],[-0.01457757],[-0.014600966],[-0.014757987],[-0.014915743],[-0.015121007],[-0.015359475]],"input_vars":["v_ego","lateral_accel","lateral_jerk","roll","lateral_accel_m03","lateral_accel_m02","lateral_accel_m01","lateral_accel_p03","lateral_accel_p06","lateral_accel_p10","lateral_accel_p15","roll_m03","roll_m02","roll_m01","roll_p03","roll_p06","roll_p10","roll_p15"],"output_size":1,"layers":[{"dense_1_b":[[-0.045577038],[-2.8160777],[-0.21418032],[2.9552083],[-0.06852827],[0.029141279],[-0.053249933]],"dense_1_W":[[0.0010664682,1.3813498,-8.153277,-0.009101015,-0.1484779,1.0008405,-1.5930991,-1.195274,0.6136762,0.3560462,-0.30077773,0.93531257,0.14550218,-0.40074933,-0.21716364,0.13834935,-0.0658936,-0.49427196],[-0.7338253,-0.037501235,-0.49922377,-1.0526338,-0.46141604,-1.3649396,0.7309814,-0.91667104,0.044683233,-0.18628967,-0.20878822,-0.2678598,0.48446324,0.51164204,0.09547851,0.41491362,-0.4524314,0.16594785],[-0.0032175342,3.5451593,-0.11421584,-0.2511033,0.27893174,0.6384996,0.80790603,1.3835542,1.8000495,2.249461,1.4026878,0.7851167,-0.35052946,0.041820426,-0.39790183,0.45703772,-0.30459648,0.18287674],[0.72289664,-0.77138704,-0.5025135,-0.49323097,-0.39893976,-0.8779149,0.6848096,-0.58729875,-0.16643623,-0.14427555,-0.15013328,-0.11467142,-0.27280045,0.48508415,0.52080667,-0.0029569597,-0.28170735,0.06367212],[0.00014026981,-2.0353239,0.0060915067,0.4794941,1.1882906,-1.512865,0.80642134,-0.26044324,-0.56213886,-0.365122,0.55078083,-0.34897435,-0.32031298,0.46106994,0.37792024,-0.14116105,0.15597256,-0.32811671],[0.0011494387,1.9060265,8.3941965,-0.3078165,-0.9530427,0.6589645,-1.2487054,-0.541133,0.13451256,0.2805466,-0.33187166,0.9900705,0.2821258,-0.51270896,-0.5130031,-0.28222615,0.042734932,0.27233443],[-0.0014444552,-1.0933362,0.003359957,-0.15052961,0.37165833,1.7087307,-1.4971043,0.673802,-0.108465396,-0.088505454,0.21561684,0.6252258,-0.15019403,-0.34727478,0.08958758,-0.1723621,-0.25557828,0.29778987]],"activation":"σ"},{"dense_2_W":[[0.20810607,-0.13481373,-0.15003344,-0.6067625,-0.31937903,-0.37380016,0.4666911],[0.71834767,0.15669753,-0.11389502,0.27131546,-0.060118295,0.039282244,0.52961355],[-0.27200606,0.43380752,-0.106262706,-0.49363258,0.35659012,-0.01706296,-1.0807354],[-0.79583454,-0.66428274,-0.42157334,-0.52979547,-0.2803004,-0.57637554,0.084149174],[0.1230394,-0.57023287,0.28639448,-0.506744,-0.9920808,0.7510901,0.8584937],[-0.41256845,0.35423175,0.13009231,0.5198333,0.7576573,-0.7053181,-0.3390053],[-0.15090485,0.33375353,-0.64164793,0.57386595,0.25700107,-0.15245672,-0.49020413],[-0.50120676,0.5210849,-0.3282951,0.4276323,1.0257447,-1.0398436,-0.8911315],[0.11402861,-0.41491523,0.247507,-0.39776865,-0.6089287,0.20646147,0.6692102],[0.09411492,0.31819808,0.41330767,0.024243973,0.2314893,0.08529045,0.14911193],[0.5179265,0.20473345,-0.36762783,-0.009045922,-0.19436747,-0.548099,-0.08656279],[-0.69121784,-0.14201449,0.3887621,0.10787631,1.0371574,-0.64747447,-0.73437464],[-0.07860244,-0.597764,0.019551078,0.010199122,-0.7493642,0.66619915,0.121666186]],"activation":"σ","dense_2_b":[[-0.04259814],[-0.053309314],[-0.28045595],[-0.23801634],[0.00944943],[-0.109921046],[-0.037457183],[0.24627604],[-0.0069056284],[-0.04725389],[-0.03361769],[0.044101644],[-0.0009850285]]},{"dense_3_W":[[-0.19631335,-0.47722518,-0.019853225,-0.29363275,-0.625923,0.35145283,0.62401354,0.14337404,-0.25707108,-0.51310915,0.2565006,0.61742216,-0.07952821],[0.5868974,-0.36786363,-0.0177682,-0.45121866,0.68608487,-0.55178356,-0.35236016,-0.7226455,-0.015394288,-0.10650332,0.5391039,0.17791761,0.34196886],[0.16821232,-0.35580373,0.26906335,0.41736925,-0.6979869,0.41801625,0.34707317,0.7784011,-0.10002936,0.32485273,-0.3644285,0.49092358,-0.43872768]],"activation":"identity","dense_3_b":[[-0.019481273],[0.031026587],[-0.03595322]]},{"dense_4_W":[[-0.72340566,0.21244061,-0.67248434]],"dense_4_b":[[0.026229527]],"activation":"identity"}]}
@@ -0,0 +1 @@
{"input_std":[[9.342214],[1.5915664],[0.60113484],[0.048193663],[1.5680411],[1.57577],[1.5836853],[1.5711677],[1.5445132],[1.5007596],[1.4529978],[0.047915205],[0.04800539],[0.04808892],[0.04822398],[0.04817677],[0.047881734],[0.047405947]],"model_test_loss":0.019342588260769844,"input_size":18,"current_date_and_time":"2023-08-05_06-09-11","input_mean":[[22.757933],[-0.016342578],[-0.001405228],[-0.014619173],[-0.018091483],[-0.018382493],[-0.019270267],[-0.018759886],[-0.019559544],[-0.017848592],[-0.020014366],[-0.014564899],[-0.01457757],[-0.014600966],[-0.014757987],[-0.014915743],[-0.015121007],[-0.015359475]],"input_vars":["v_ego","lateral_accel","lateral_jerk","roll","lateral_accel_m03","lateral_accel_m02","lateral_accel_m01","lateral_accel_p03","lateral_accel_p06","lateral_accel_p10","lateral_accel_p15","roll_m03","roll_m02","roll_m01","roll_p03","roll_p06","roll_p10","roll_p15"],"output_size":1,"layers":[{"dense_1_b":[[-0.045577038],[-2.8160777],[-0.21418032],[2.9552083],[-0.06852827],[0.029141279],[-0.053249933]],"dense_1_W":[[0.0010664682,1.3813498,-8.153277,-0.009101015,-0.1484779,1.0008405,-1.5930991,-1.195274,0.6136762,0.3560462,-0.30077773,0.93531257,0.14550218,-0.40074933,-0.21716364,0.13834935,-0.0658936,-0.49427196],[-0.7338253,-0.037501235,-0.49922377,-1.0526338,-0.46141604,-1.3649396,0.7309814,-0.91667104,0.044683233,-0.18628967,-0.20878822,-0.2678598,0.48446324,0.51164204,0.09547851,0.41491362,-0.4524314,0.16594785],[-0.0032175342,3.5451593,-0.11421584,-0.2511033,0.27893174,0.6384996,0.80790603,1.3835542,1.8000495,2.249461,1.4026878,0.7851167,-0.35052946,0.041820426,-0.39790183,0.45703772,-0.30459648,0.18287674],[0.72289664,-0.77138704,-0.5025135,-0.49323097,-0.39893976,-0.8779149,0.6848096,-0.58729875,-0.16643623,-0.14427555,-0.15013328,-0.11467142,-0.27280045,0.48508415,0.52080667,-0.0029569597,-0.28170735,0.06367212],[0.00014026981,-2.0353239,0.0060915067,0.4794941,1.1882906,-1.512865,0.80642134,-0.26044324,-0.56213886,-0.365122,0.55078083,-0.34897435,-0.32031298,0.46106994,0.37792024,-0.14116105,0.15597256,-0.32811671],[0.0011494387,1.9060265,8.3941965,-0.3078165,-0.9530427,0.6589645,-1.2487054,-0.541133,0.13451256,0.2805466,-0.33187166,0.9900705,0.2821258,-0.51270896,-0.5130031,-0.28222615,0.042734932,0.27233443],[-0.0014444552,-1.0933362,0.003359957,-0.15052961,0.37165833,1.7087307,-1.4971043,0.673802,-0.108465396,-0.088505454,0.21561684,0.6252258,-0.15019403,-0.34727478,0.08958758,-0.1723621,-0.25557828,0.29778987]],"activation":"σ"},{"dense_2_W":[[0.20810607,-0.13481373,-0.15003344,-0.6067625,-0.31937903,-0.37380016,0.4666911],[0.71834767,0.15669753,-0.11389502,0.27131546,-0.060118295,0.039282244,0.52961355],[-0.27200606,0.43380752,-0.106262706,-0.49363258,0.35659012,-0.01706296,-1.0807354],[-0.79583454,-0.66428274,-0.42157334,-0.52979547,-0.2803004,-0.57637554,0.084149174],[0.1230394,-0.57023287,0.28639448,-0.506744,-0.9920808,0.7510901,0.8584937],[-0.41256845,0.35423175,0.13009231,0.5198333,0.7576573,-0.7053181,-0.3390053],[-0.15090485,0.33375353,-0.64164793,0.57386595,0.25700107,-0.15245672,-0.49020413],[-0.50120676,0.5210849,-0.3282951,0.4276323,1.0257447,-1.0398436,-0.8911315],[0.11402861,-0.41491523,0.247507,-0.39776865,-0.6089287,0.20646147,0.6692102],[0.09411492,0.31819808,0.41330767,0.024243973,0.2314893,0.08529045,0.14911193],[0.5179265,0.20473345,-0.36762783,-0.009045922,-0.19436747,-0.548099,-0.08656279],[-0.69121784,-0.14201449,0.3887621,0.10787631,1.0371574,-0.64747447,-0.73437464],[-0.07860244,-0.597764,0.019551078,0.010199122,-0.7493642,0.66619915,0.121666186]],"activation":"σ","dense_2_b":[[-0.04259814],[-0.053309314],[-0.28045595],[-0.23801634],[0.00944943],[-0.109921046],[-0.037457183],[0.24627604],[-0.0069056284],[-0.04725389],[-0.03361769],[0.044101644],[-0.0009850285]]},{"dense_3_W":[[-0.19631335,-0.47722518,-0.019853225,-0.29363275,-0.625923,0.35145283,0.62401354,0.14337404,-0.25707108,-0.51310915,0.2565006,0.61742216,-0.07952821],[0.5868974,-0.36786363,-0.0177682,-0.45121866,0.68608487,-0.55178356,-0.35236016,-0.7226455,-0.015394288,-0.10650332,0.5391039,0.17791761,0.34196886],[0.16821232,-0.35580373,0.26906335,0.41736925,-0.6979869,0.41801625,0.34707317,0.7784011,-0.10002936,0.32485273,-0.3644285,0.49092358,-0.43872768]],"activation":"identity","dense_3_b":[[-0.019481273],[0.031026587],[-0.03595322]]},{"dense_4_W":[[-0.72340566,0.21244061,-0.67248434]],"dense_4_b":[[0.026229527]],"activation":"identity"}]}
+140 -50
View File
@@ -37,6 +37,7 @@ HOLIDAY_SLUGS = {
} }
THEME_COMPONENT_PARAMS = { THEME_COMPONENT_PARAMS = {
"boot_logos": "BootLogoToDownload",
"colors": "ColorToDownload", "colors": "ColorToDownload",
"distance_icons": "DistanceIconToDownload", "distance_icons": "DistanceIconToDownload",
"icons": "IconToDownload", "icons": "IconToDownload",
@@ -93,8 +94,16 @@ class ThemeManager:
steering_wheel_save_path.parent.mkdir(parents=True, exist_ok=True) steering_wheel_save_path.parent.mkdir(parents=True, exist_ok=True)
shutil.copy2(steering_wheel_image_path, steering_wheel_save_path) shutil.copy2(steering_wheel_image_path, steering_wheel_save_path)
default_boot_logo_path = Path(__file__).parent / "other_images/frogpilot_boot_logo.png"
boot_logo_save_path = THEME_SAVE_PATH / "bootlogos/starpilot.png"
boot_logo_save_path.parent.mkdir(parents=True, exist_ok=True)
if not boot_logo_save_path.exists():
shutil.copy2(default_boot_logo_path, boot_logo_save_path)
def download_theme(self, theme_component, theme_name, asset_param, frogpilot_toggles): def download_theme(self, theme_component, theme_name, asset_param, frogpilot_toggles):
self.downloading_theme = True self.downloading_theme = True
allow_unknown_size = theme_component in {"boot_logos", "steering_wheels"}
name_candidates = [theme_name]
repo_url = get_repository_url() repo_url = get_repository_url()
if not repo_url: if not repo_url:
@@ -102,7 +111,12 @@ class ThemeManager:
self.downloading_theme = False self.downloading_theme = False
return return
if theme_component == "distance_icons": if theme_component == "boot_logos":
download_link = f"{repo_url}/Themes/bootlogo"
download_path = THEME_SAVE_PATH / "bootlogos" / theme_name
extensions = [".png", ".jpg", ".jpeg"]
name_candidates = list(dict.fromkeys([theme_name, theme_name.replace("_", "-"), theme_name.replace("-", "_")]))
elif theme_component == "distance_icons":
download_link = f"{repo_url}/Distance-Icons/{theme_name}" download_link = f"{repo_url}/Distance-Icons/{theme_name}"
download_path = THEME_SAVE_PATH / "theme_packs" / theme_name / theme_component download_path = THEME_SAVE_PATH / "theme_packs" / theme_name / theme_component
extensions = [".zip"] extensions = [".zip"]
@@ -117,37 +131,40 @@ class ThemeManager:
for extension in extensions: for extension in extensions:
theme_path = download_path.with_suffix(extension) theme_path = download_path.with_suffix(extension)
theme_url = download_link + extension theme_urls = [f"{download_link}/{candidate}{extension}" for candidate in name_candidates]
if theme_component != "boot_logos":
theme_urls = [download_link + extension]
delete_file(theme_path) for theme_url in theme_urls:
print(f"Downloading theme from GitHub: {theme_name}")
download_file(CANCEL_DOWNLOAD_PARAM, theme_path, DOWNLOAD_PROGRESS_PARAM, theme_url, asset_param, params_memory)
if params_memory.get_bool(CANCEL_DOWNLOAD_PARAM):
delete_file(theme_path) delete_file(theme_path)
handle_error(None, "Download cancelled...", "Download cancelled...", asset_param, DOWNLOAD_PROGRESS_PARAM, params_memory)
self.downloading_theme = False print(f"Downloading theme from GitHub: {theme_name}")
return download_file(CANCEL_DOWNLOAD_PARAM, theme_path, DOWNLOAD_PROGRESS_PARAM, theme_url, asset_param, params_memory, allow_unknown_size=allow_unknown_size, suppress_errors=allow_unknown_size)
if verify_download(theme_path, theme_url): if params_memory.get_bool(CANCEL_DOWNLOAD_PARAM):
print(f"Theme {theme_name} downloaded and verified successfully from GitHub!") delete_file(theme_path)
self.update_theme_size(theme_component, theme_name, theme_path.stat().st_size) handle_error(None, "Download cancelled...", "Download cancelled...", asset_param, DOWNLOAD_PROGRESS_PARAM, params_memory)
if extension == ".zip": self.downloading_theme = False
params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Unpacking theme...") return
extract_zip(theme_path, download_path)
params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Downloaded!") if verify_download(theme_path, theme_url, allow_unknown_size=allow_unknown_size):
params_memory.remove(asset_param) print(f"Theme {theme_name} downloaded and verified successfully from GitHub!")
self.update_theme_size(theme_component, theme_name, theme_path.stat().st_size)
self.downloading_theme = False if extension == ".zip":
params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Unpacking theme...")
extract_zip(theme_path, download_path)
self.update_themes(frogpilot_toggles) params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Downloaded!")
return params_memory.remove(asset_param)
elif self.handle_verification_failure(extension, theme_component, theme_name, asset_param, theme_path, download_path, frogpilot_toggles):
return self.downloading_theme = False
self.update_themes(frogpilot_toggles)
return
elif self.handle_verification_failure(extension, theme_component, theme_name, asset_param, theme_path, download_path, frogpilot_toggles):
return
handle_error(download_path, "Download failed...", "Download failed...", asset_param, DOWNLOAD_PROGRESS_PARAM, params_memory) handle_error(download_path, "Download failed...", "Download failed...", asset_param, DOWNLOAD_PROGRESS_PARAM, params_memory)
self.downloading_theme = False self.downloading_theme = False
@@ -158,7 +175,7 @@ class ThemeManager:
repo_encoded = quote_plus(RESOURCES_REPO) repo_encoded = quote_plus(RESOURCES_REPO)
assets = {"themes": {}, "wheels": []} assets = {"boot_logos": [], "themes": {}, "wheels": []}
try: try:
def list_files(branch): def list_files(branch):
if is_github: if is_github:
@@ -234,6 +251,20 @@ class ThemeManager:
theme_name, sub_path = item["path"].split("/", 1) theme_name, sub_path = item["path"].split("/", 1)
theme_path = sub_path.lower() theme_path = sub_path.lower()
if theme_name.lower() == "bootlogo":
if Path(sub_path).suffix.lower() not in (".png", ".jpg", ".jpeg"):
continue
assets["boot_logos"].append(sub_path)
logo_name = Path(sub_path).stem
local_files = list((THEME_SAVE_PATH / "bootlogos").glob(f"{logo_name}.*"))
if local_files and expected_size > 0:
local_size = self.theme_sizes.get("boot_logos", {}).get(logo_name)
if local_size != expected_size:
print(f"boot logo {logo_name} is outdated, redownloading...")
self.download_theme("boot_logos", logo_name, THEME_COMPONENT_PARAMS["boot_logos"], frogpilot_toggles)
continue
for key in ("colors", "icons", "signals", "sounds"): for key in ("colors", "icons", "signals", "sounds"):
if key in theme_path: if key in theme_path:
assets["themes"].setdefault(theme_name, set()).add(key) assets["themes"].setdefault(theme_name, set()).add(key)
@@ -246,6 +277,7 @@ class ThemeManager:
self.download_theme(key, theme_name, THEME_COMPONENT_PARAMS[key], frogpilot_toggles) self.download_theme(key, theme_name, THEME_COMPONENT_PARAMS[key], frogpilot_toggles)
break break
assets["boot_logos"].sort()
assets["themes"] = {key: sorted(list(value)) for key, value in assets["themes"].items()} assets["themes"] = {key: sorted(list(value)) for key, value in assets["themes"].items()}
assets["wheels"].sort() assets["wheels"].sort()
return assets return assets
@@ -265,7 +297,7 @@ class ThemeManager:
parts = base.replace("_", "-").split("-") parts = base.replace("_", "-").split("-")
capitalized_parts = [part.capitalize() for part in parts if part] capitalized_parts = [part.capitalize() for part in parts if part]
if len(capitalized_parts) > 1 and component != "steering_wheels": if len(capitalized_parts) > 1 and component not in {"boot_logos", "steering_wheels"}:
display = f"{capitalized_parts[0]} ({' '.join(capitalized_parts[1:])})" display = f"{capitalized_parts[0]} ({' '.join(capitalized_parts[1:])})"
else: else:
display = " ".join(capitalized_parts) display = " ".join(capitalized_parts)
@@ -321,37 +353,44 @@ class ThemeManager:
} }
def handle_verification_failure(self, extension, theme_component, theme_name, asset_param, theme_path, download_path, frogpilot_toggles): def handle_verification_failure(self, extension, theme_component, theme_name, asset_param, theme_path, download_path, frogpilot_toggles):
if theme_component == "distance_icons": allow_unknown_size = theme_component in {"boot_logos", "steering_wheels"}
if theme_component == "boot_logos":
download_link = f"{GITLAB_URL}/Themes/bootlogo"
name_candidates = list(dict.fromkeys([theme_name, theme_name.replace("_", "-"), theme_name.replace("-", "_")]))
elif theme_component == "distance_icons":
download_link = f"{GITLAB_URL}/Distance-Icons/{theme_name}" download_link = f"{GITLAB_URL}/Distance-Icons/{theme_name}"
name_candidates = [theme_name]
elif theme_component == "steering_wheels": elif theme_component == "steering_wheels":
download_link = f"{GITLAB_URL}/Steering-Wheels/{theme_name}" download_link = f"{GITLAB_URL}/Steering-Wheels/{theme_name}"
name_candidates = [theme_name]
else: else:
download_link = f"{GITLAB_URL}/Themes/{theme_name}/{theme_component}" download_link = f"{GITLAB_URL}/Themes/{theme_name}/{theme_component}"
name_candidates = [theme_name]
delete_file(theme_path) for candidate in name_candidates:
delete_file(theme_path)
theme_url = download_link + extension theme_url = f"{download_link}/{candidate}{extension}" if theme_component == "boot_logos" else download_link + extension
print(f"Downloading theme from GitLab: {theme_name}") print(f"Downloading theme from GitLab: {theme_name}")
download_file(CANCEL_DOWNLOAD_PARAM, theme_path, DOWNLOAD_PROGRESS_PARAM, theme_url, asset_param, params_memory) download_file(CANCEL_DOWNLOAD_PARAM, theme_path, DOWNLOAD_PROGRESS_PARAM, theme_url, asset_param, params_memory, allow_unknown_size=allow_unknown_size, suppress_errors=allow_unknown_size)
if verify_download(theme_path, theme_url): if verify_download(theme_path, theme_url, allow_unknown_size=allow_unknown_size):
print(f"Theme {theme_name} downloaded and verified successfully from GitLab!") print(f"Theme {theme_name} downloaded and verified successfully from GitLab!")
self.update_theme_size(theme_component, theme_name, theme_path.stat().st_size) self.update_theme_size(theme_component, theme_name, theme_path.stat().st_size)
if extension == ".zip": if extension == ".zip":
params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Unpacking theme...") params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Unpacking theme...")
extract_zip(theme_path, download_path) extract_zip(theme_path, download_path)
params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Downloaded!") params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Downloaded!")
params_memory.remove(asset_param) params_memory.remove(asset_param)
self.downloading_theme = False self.downloading_theme = False
self.update_themes(frogpilot_toggles) self.update_themes(frogpilot_toggles)
return True return True
handle_error(None, "Download failed...", "Download failed...", asset_param, DOWNLOAD_PROGRESS_PARAM, params_memory) # Let the caller continue trying alternate extensions before surfacing failure.
self.downloading_theme = False
return False return False
@staticmethod @staticmethod
@@ -415,6 +454,8 @@ class ThemeManager:
return random.choice(candidates) if candidates else "stock" return random.choice(candidates) if candidates else "stock"
def update_active_theme(self, time_validated, frogpilot_toggles, boot_run=False, randomize_theme=False): def update_active_theme(self, time_validated, frogpilot_toggles, boot_run=False, randomize_theme=False):
boot_logo = getattr(frogpilot_toggles, "boot_logo", "stock")
if time_validated and frogpilot_toggles.holiday_themes: if time_validated and frogpilot_toggles.holiday_themes:
self.holiday_theme = self.update_holiday() self.holiday_theme = self.update_holiday()
else: else:
@@ -422,6 +463,7 @@ class ThemeManager:
if self.holiday_theme != "stock": if self.holiday_theme != "stock":
asset_mappings = { asset_mappings = {
"boot_logo": ("boot_logo", boot_logo),
"color_scheme": ("colors", self.holiday_theme), "color_scheme": ("colors", self.holiday_theme),
"distance_icons": ("distance_icons", self.holiday_theme), "distance_icons": ("distance_icons", self.holiday_theme),
"icon_pack": ("icons", self.holiday_theme), "icon_pack": ("icons", self.holiday_theme),
@@ -434,6 +476,7 @@ class ThemeManager:
selected_theme = self.randomize_theme_asset(available_themes) selected_theme = self.randomize_theme_asset(available_themes)
asset_mappings = { asset_mappings = {
"boot_logo": ("boot_logo", boot_logo),
"color_scheme": ("colors", selected_theme.replace("-animated", "")), "color_scheme": ("colors", selected_theme.replace("-animated", "")),
"distance_icons": ("distance_icons", self.randomize_distance_icons(available_themes, selected_theme.replace("-animated", ""))), "distance_icons": ("distance_icons", self.randomize_distance_icons(available_themes, selected_theme.replace("-animated", ""))),
"icon_pack": ("icons", selected_theme), "icon_pack": ("icons", selected_theme),
@@ -444,6 +487,7 @@ class ThemeManager:
elif not frogpilot_toggles.random_themes: elif not frogpilot_toggles.random_themes:
asset_mappings = { asset_mappings = {
"boot_logo": ("boot_logo", boot_logo),
"color_scheme": ("colors", frogpilot_toggles.color_scheme), "color_scheme": ("colors", frogpilot_toggles.color_scheme),
"distance_icons": ("distance_icons", frogpilot_toggles.distance_icons), "distance_icons": ("distance_icons", frogpilot_toggles.distance_icons),
"icon_pack": ("icons", frogpilot_toggles.icon_pack), "icon_pack": ("icons", frogpilot_toggles.icon_pack),
@@ -458,7 +502,9 @@ class ThemeManager:
for asset, (asset_type, current_value) in asset_mappings.items(): for asset, (asset_type, current_value) in asset_mappings.items():
print(f"Updating {asset}: {asset_type} with value {current_value}") print(f"Updating {asset}: {asset_type} with value {current_value}")
if asset_type == "wheel_image": if asset_type == "boot_logo":
self.update_boot_logo(current_value)
elif asset_type == "wheel_image":
self.update_wheel_image(current_value, boot_run=boot_run) self.update_wheel_image(current_value, boot_run=boot_run)
else: else:
self.update_theme_asset(asset_type, current_value, boot_run=boot_run) self.update_theme_asset(asset_type, current_value, boot_run=boot_run)
@@ -499,9 +545,16 @@ class ThemeManager:
save_location.symlink_to(asset_location, target_is_directory=True) save_location.symlink_to(asset_location, target_is_directory=True)
print(f"Linked {save_location} to {asset_location}") print(f"Linked {save_location} to {asset_location}")
def update_theme_params(self, downloadable_colors, downloadable_distance_icons, downloadable_icons, downloadable_signals, downloadable_sounds, downloadable_wheels): def update_theme_params(self, downloadable_boot_logos, downloadable_colors, downloadable_distance_icons, downloadable_icons, downloadable_signals, downloadable_sounds, downloadable_wheels):
def update_param(key, assets, subfolder): def update_param(key, assets, subfolder):
if subfolder == "steering_wheels": if subfolder == "boot_logos":
themes_path = THEME_SAVE_PATH / "bootlogos"
existing_assets = {item.stem.lower() for item in themes_path.glob("*") if item.is_file()}
pending_assets = [asset for asset in assets if asset.lower() not in existing_assets]
params.put(key, ",".join(sorted(set(pending_assets))))
print(f"{key} updated successfully")
return
elif subfolder == "steering_wheels":
themes_path = THEME_SAVE_PATH / subfolder themes_path = THEME_SAVE_PATH / subfolder
existing_assets = {self.format_name(item.name, "steering_wheels") for item in themes_path.glob("*") if item.is_file()} existing_assets = {self.format_name(item.name, "steering_wheels") for item in themes_path.glob("*") if item.is_file()}
else: else:
@@ -511,6 +564,7 @@ class ThemeManager:
params.put(key, ",".join(sorted(set(assets) - existing_assets))) params.put(key, ",".join(sorted(set(assets) - existing_assets)))
print(f"{key} updated successfully") print(f"{key} updated successfully")
update_param("DownloadableBootLogos", downloadable_boot_logos, "boot_logos")
update_param("DownloadableColors", downloadable_colors, "colors") update_param("DownloadableColors", downloadable_colors, "colors")
update_param("DownloadableDistanceIcons", downloadable_distance_icons, "distance_icons") update_param("DownloadableDistanceIcons", downloadable_distance_icons, "distance_icons")
update_param("DownloadableIcons", downloadable_icons, "icons") update_param("DownloadableIcons", downloadable_icons, "icons")
@@ -529,12 +583,20 @@ class ThemeManager:
theme_name = self.format_name(theme_dir.name, "theme_packs") theme_name = self.format_name(theme_dir.name, "theme_packs")
downloaded_themes[theme_name] = sorted(components) downloaded_themes[theme_name] = sorted(components)
(THEME_SAVE_PATH / "bootlogos").mkdir(parents=True, exist_ok=True)
downloaded_boot_logos = []
for boot_logo_file in (THEME_SAVE_PATH / "bootlogos").iterdir():
if boot_logo_file.is_file():
downloaded_boot_logos.append(self.format_name(boot_logo_file.name, "boot_logos"))
downloaded_wheels = [] downloaded_wheels = []
for wheel_file in (THEME_SAVE_PATH / "steering_wheels").iterdir(): for wheel_file in (THEME_SAVE_PATH / "steering_wheels").iterdir():
if wheel_file.is_file(): if wheel_file.is_file():
downloaded_wheels.append(self.format_name(wheel_file.name, "steering_wheels")) downloaded_wheels.append(self.format_name(wheel_file.name, "steering_wheels"))
params.put("ThemesDownloaded", json.dumps({ params.put("ThemesDownloaded", json.dumps({
"boot_logos": sorted(downloaded_boot_logos),
"themes": {key: downloaded_themes[key] for key in sorted(downloaded_themes)}, "themes": {key: downloaded_themes[key] for key in sorted(downloaded_themes)},
"steering_wheels": sorted(downloaded_wheels) "steering_wheels": sorted(downloaded_wheels)
})) }))
@@ -542,7 +604,9 @@ class ThemeManager:
print("ThemesDownloaded updated successfully") print("ThemesDownloaded updated successfully")
def update_theme_size(self, theme_component, theme_name, file_size): def update_theme_size(self, theme_component, theme_name, file_size):
if theme_component == "steering_wheels": if theme_component == "boot_logos":
key = "boot_logos"
elif theme_component == "steering_wheels":
key = "wheels" key = "wheels"
else: else:
key = "themes" key = "themes"
@@ -550,7 +614,7 @@ class ThemeManager:
if key not in self.theme_sizes: if key not in self.theme_sizes:
self.theme_sizes[key] = {} self.theme_sizes[key] = {}
if key == "wheels": if key in {"boot_logos", "wheels"}:
self.theme_sizes[key][theme_name] = file_size self.theme_sizes[key][theme_name] = file_size
else: else:
if theme_name not in self.theme_sizes[key]: if theme_name not in self.theme_sizes[key]:
@@ -572,6 +636,7 @@ class ThemeManager:
if not assets: if not assets:
return return
downloadable_boot_logos = []
downloadable_colors = [] downloadable_colors = []
downloadable_distance_icons = [] downloadable_distance_icons = []
downloadable_icons = [] downloadable_icons = []
@@ -593,8 +658,10 @@ class ThemeManager:
if "sounds" in available_assets: if "sounds" in available_assets:
downloadable_sounds.append(theme_name) downloadable_sounds.append(theme_name)
downloadable_boot_logos = [Path(boot_logo).stem for boot_logo in assets["boot_logos"]]
downloadable_wheels = [self.format_name(wheel, "steering_wheels") for wheel in assets["wheels"]] downloadable_wheels = [self.format_name(wheel, "steering_wheels") for wheel in assets["wheels"]]
print(f"Downloadable Boot Logos: {downloadable_boot_logos}")
print(f"Downloadable Colors: {downloadable_colors}") print(f"Downloadable Colors: {downloadable_colors}")
print(f"Downloadable Icons: {downloadable_icons}") print(f"Downloadable Icons: {downloadable_icons}")
print(f"Downloadable Signals: {downloadable_signals}") print(f"Downloadable Signals: {downloadable_signals}")
@@ -605,7 +672,21 @@ class ThemeManager:
if boot_run: if boot_run:
self.validate_themes(downloadable_colors, downloadable_distance_icons, downloadable_icons, downloadable_signals, downloadable_sounds, downloadable_wheels, frogpilot_toggles) self.validate_themes(downloadable_colors, downloadable_distance_icons, downloadable_icons, downloadable_signals, downloadable_sounds, downloadable_wheels, frogpilot_toggles)
self.update_theme_params(downloadable_colors, downloadable_distance_icons, downloadable_icons, downloadable_signals, downloadable_sounds, downloadable_wheels) self.update_theme_params(downloadable_boot_logos, downloadable_colors, downloadable_distance_icons, downloadable_icons, downloadable_signals, downloadable_sounds, downloadable_wheels)
@staticmethod
def update_boot_logo(image):
boot_logo_location = Path(__file__).parent / "other_images/frogpilot_boot_logo.png"
image_name = image.replace(" ", "_").lower()
source_file = next((file for file in (THEME_SAVE_PATH / "bootlogos").glob("*") if file.is_file() and file.stem.lower() == image_name), boot_logo_location)
# Avoid SameFileError when the selected/fallback source is already the active boot logo.
if source_file.resolve() == boot_logo_location.resolve():
print(f"Boot logo unchanged: {boot_logo_location}")
return
shutil.copy2(source_file, boot_logo_location)
print(f"Copied {source_file} to {boot_logo_location}")
def update_wheel_image(self, image, boot_run=False, random_event=False): def update_wheel_image(self, image, boot_run=False, random_event=False):
wheel_save_location = ACTIVE_THEME_PATH / "steering_wheel" wheel_save_location = ACTIVE_THEME_PATH / "steering_wheel"
@@ -641,6 +722,15 @@ class ThemeManager:
def validate_themes(self, downloadable_colors, downloadable_distance_icons, downloadable_icons, downloadable_signals, downloadable_sounds, downloadable_wheels, frogpilot_toggles): def validate_themes(self, downloadable_colors, downloadable_distance_icons, downloadable_icons, downloadable_signals, downloadable_sounds, downloadable_wheels, frogpilot_toggles):
downloaded_data = json.loads(params.get("ThemesDownloaded") or "{}") downloaded_data = json.loads(params.get("ThemesDownloaded") or "{}")
boot_logos_path = THEME_SAVE_PATH / "bootlogos"
for display_name in downloaded_data.get("boot_logos", []):
file_stem = display_name.replace(" ", "_").lower()
matching_files = list(boot_logos_path.glob(f"{file_stem}.*"))
if not matching_files:
print(f"Missing boot logo '{display_name}'. Downloading...")
self.download_theme("boot_logos", file_stem, THEME_COMPONENT_PARAMS["boot_logos"], frogpilot_toggles)
self.update_active_theme(True, frogpilot_toggles)
for display_name, components in downloaded_data.get("themes", {}).items(): for display_name, components in downloaded_data.get("themes", {}).items():
raw_name = display_name.lower().replace(" ", "_").replace("(", "").replace(")", "") raw_name = display_name.lower().replace(" ", "_").replace("(", "").replace(")", "")
theme_folder_name = raw_name.replace("_animated", "-animated") theme_folder_name = raw_name.replace("_animated", "-animated")
+13 -2
View File
@@ -2,6 +2,7 @@
import json import json
import math import math
import numpy as np import numpy as np
import os
import requests import requests
import shutil import shutil
import subprocess import subprocess
@@ -22,7 +23,7 @@ from opendbc.can.parser import CANParser
from openpilot.common.realtime import DT_DMON, DT_HW from openpilot.common.realtime import DT_DMON, DT_HW
from openpilot.selfdrive.car.toyota.carcontroller import LOCK_CMD from openpilot.selfdrive.car.toyota.carcontroller import LOCK_CMD
from openpilot.system.hardware import HARDWARE from openpilot.system.hardware import HARDWARE
from panda import Panda from panda import Panda, FW_PATH
from openpilot.frogpilot.common.frogpilot_variables import EARTH_RADIUS, KONIK_PATH, MAPD_PATH, MAPS_PATH, params, params_cache, params_memory from openpilot.frogpilot.common.frogpilot_variables import EARTH_RADIUS, KONIK_PATH, MAPD_PATH, MAPS_PATH, params, params_cache, params_memory
@@ -151,11 +152,21 @@ def extract_zip(zip_file, extract_path):
print(f"Extraction completed: {zip_file} has been removed") print(f"Extraction completed: {zip_file} has been removed")
def flash_panda(): def flash_panda():
remote_start = params.get_bool("RemoteStartBootsComma")
for serial in Panda.list(): for serial in Panda.list():
try: try:
panda = Panda(serial) panda = Panda(serial)
flash_fn = None
if remote_start:
app_fn = panda.get_mcu_type().config.app_fn
remote_fn = "panda_h7_remote.bin.signed" if app_fn == "panda_h7.bin.signed" else "panda_remote.bin.signed"
candidate = os.path.join(FW_PATH, remote_fn)
if os.path.isfile(candidate):
flash_fn = candidate
else:
print(f"Remote-start panda firmware missing: {candidate}. Falling back to default firmware.")
panda.reset(enter_bootstub=True) panda.reset(enter_bootstub=True)
panda.flash() panda.flash(fn=flash_fn)
panda.close() panda.close()
except Exception as exception: except Exception as exception:
print(f"Error flashing Panda {serial}: {exception}") print(f"Error flashing Panda {serial}: {exception}")
+35 -5
View File
@@ -133,6 +133,7 @@ frogpilot_default_params: list[tuple[str, str | bytes, int, str]] = [
("AdvancedLateralTune", "1", 2, "0"), ("AdvancedLateralTune", "1", 2, "0"),
("AdvancedLongitudinalTune", "0", 3, "0"), ("AdvancedLongitudinalTune", "0", 3, "0"),
("EVTuning", "", 3, "0"), ("EVTuning", "", 3, "0"),
("TruckTuning", "0", 3, "0"),
("AggressiveFollow", "1.25", 2, "1.25"), ("AggressiveFollow", "1.25", 2, "1.25"),
("AggressiveFollowHigh", "1.25", 2, "1.25"), ("AggressiveFollowHigh", "1.25", 2, "1.25"),
("AggressiveJerkAcceleration", "50", 3, "50"), ("AggressiveJerkAcceleration", "50", 3, "50"),
@@ -159,6 +160,7 @@ frogpilot_default_params: list[tuple[str, str | bytes, int, str]] = [
("BlacklistedModels", "", 2, ""), ("BlacklistedModels", "", 2, ""),
("BlindSpotMetrics", "1", 3, "0"), ("BlindSpotMetrics", "1", 3, "0"),
("BlindSpotPath", "1", 1, "0"), ("BlindSpotPath", "1", 1, "0"),
("BootLogo", "starpilot", 0, "stock"),
("BorderMetrics", "1", 3, "0"), ("BorderMetrics", "1", 3, "0"),
("CalibratedLateralAcceleration", str(DEFAULT_LATERAL_ACCELERATION), 2, str(DEFAULT_LATERAL_ACCELERATION)), ("CalibratedLateralAcceleration", str(DEFAULT_LATERAL_ACCELERATION), 2, str(DEFAULT_LATERAL_ACCELERATION)),
("CalibrationProgress", "0", 3, "0"), ("CalibrationProgress", "0", 3, "0"),
@@ -237,6 +239,8 @@ frogpilot_default_params: list[tuple[str, str | bytes, int, str]] = [
("FullMap", "0", 2, "0"), ("FullMap", "0", 2, "0"),
("GasRegenCmd", "1", 2, "0"), ("GasRegenCmd", "1", 2, "0"),
("GMPedalLongitudinal", "1", 2, "1"), ("GMPedalLongitudinal", "1", 2, "1"),
("RedPanda", "0", 3, "0"),
("RemoteStartBootsComma", "0", 3, "0"),
("GithubSshKeys", "", 0, ""), ("GithubSshKeys", "", 0, ""),
("GithubUsername", "", 0, ""), ("GithubUsername", "", 0, ""),
("GoatScream", "0", 1, "0"), ("GoatScream", "0", 1, "0"),
@@ -620,19 +624,34 @@ 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.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.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.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.75, latAccelFactor * 1.25) if advanced_lateral_tuning and tuning_level >= level["SteerLatAccel"] else latAccelFactor 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.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.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.5, steerRatio * 1.5) if advanced_lateral_tuning and tuning_level >= level["SteerRatio"] else steerRatio 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.use_custom_steerRatio = bool(round(toggle.steerRatio, 2) != round(steerRatio, 2)) and not toggle.force_auto_tune or toggle.force_auto_tune_off 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") advanced_longitudinal_tuning = params.get_bool("AdvancedLongitudinalTune") if tuning_level >= level["AdvancedLongitudinalTune"] else default.get_bool("AdvancedLongitudinalTune")
ev_vehicle = toggle.car_make == "gm" and toggle.car_model != "CHEVROLET_VOLT" and CP.carFingerprint in GM_EV_CAR or toggle.car_make == "hyundai" and CP.carFingerprint in HYUNDAI_EV_CAR gm_ev_vehicle = toggle.car_make == "gm" and CP.carFingerprint in GM_EV_CAR
gm_ev_vehicle &= not (toggle.car_model.startswith("CHEVROLET_VOLT") and not toggle.car_model.endswith("_CC"))
gm_ev_vehicle &= toggle.car_model != "CHEVROLET_MALIBU_HYBRID_CC"
ev_vehicle = gm_ev_vehicle or (toggle.car_make == "hyundai" and CP.carFingerprint in HYUNDAI_EV_CAR)
ev_vehicle |= CP.transmissionType == TransmissionType.direct ev_vehicle |= CP.transmissionType == TransmissionType.direct
if params.get("EVTuning") == b"": if params.get("EVTuning") == b"":
params.put_bool("EVTuning", ev_vehicle) params.put_bool("EVTuning", ev_vehicle)
toggle.ev_tuning = params.get_bool("EVTuning") if advanced_longitudinal_tuning and tuning_level >= level["EVTuning"] else ev_vehicle if params.get("TruckTuning") == b"":
params.put_bool("TruckTuning", False)
ev_tuning_param = params.get_bool("EVTuning")
truck_tuning_param = params.get_bool("TruckTuning")
# Enforce exclusivity between EV and Truck tuning.
if truck_tuning_param and ev_tuning_param:
ev_tuning_param = False
params.put_bool("EVTuning", False)
toggle.ev_tuning = ev_tuning_param if advanced_longitudinal_tuning and tuning_level >= level["EVTuning"] else ev_vehicle
toggle.truck_tuning = truck_tuning_param if advanced_longitudinal_tuning and tuning_level >= level["TruckTuning"] else False
toggle.longitudinalActuatorDelay = np.clip(params.get_float("LongitudinalActuatorDelay"), 0, 1) if advanced_longitudinal_tuning and tuning_level >= level["LongitudinalActuatorDelay"] else longitudinalActuatorDelay toggle.longitudinalActuatorDelay = np.clip(params.get_float("LongitudinalActuatorDelay"), 0, 1) if advanced_longitudinal_tuning and tuning_level >= level["LongitudinalActuatorDelay"] else longitudinalActuatorDelay
toggle.startAccel = np.clip(params.get_float("StartAccel"), 0, 4) if advanced_longitudinal_tuning and tuning_level >= level["StartAccel"] else startAccel toggle.startAccel = np.clip(params.get_float("StartAccel"), 0, 4) if advanced_longitudinal_tuning and tuning_level >= level["StartAccel"] else startAccel
toggle.stopAccel = np.clip(params.get_float("StopAccel"), -4, 0) if advanced_longitudinal_tuning and tuning_level >= level["StopAccel"] else stopAccel toggle.stopAccel = np.clip(params.get_float("StopAccel"), -4, 0) if advanced_longitudinal_tuning and tuning_level >= level["StopAccel"] else stopAccel
@@ -808,6 +827,9 @@ class FrogPilotVariables:
toggle.vEgoStarting = 0.15 if toggle.experimental_gm_tune else toggle.vEgoStarting toggle.vEgoStarting = 0.15 if toggle.experimental_gm_tune else toggle.vEgoStarting
toggle.vEgoStopping = 0.15 if toggle.experimental_gm_tune else toggle.vEgoStopping toggle.vEgoStopping = 0.15 if toggle.experimental_gm_tune else toggle.vEgoStopping
toggle.red_panda = toggle.car_make == "gm" and (params.get_bool("RedPanda") if tuning_level >= level["RedPanda"] else default.get_bool("RedPanda"))
toggle.remote_start_boots_comma = toggle.car_make == "gm" and (params.get_bool("RemoteStartBootsComma") if tuning_level >= level["RemoteStartBootsComma"] else default.get_bool("RemoteStartBootsComma"))
toggle.force_fingerprint = (params.get_bool("ForceFingerprint") if tuning_level >= level["ForceFingerprint"] else default.get_bool("ForceFingerprint")) and toggle.car_model is not None toggle.force_fingerprint = (params.get_bool("ForceFingerprint") if tuning_level >= level["ForceFingerprint"] else default.get_bool("ForceFingerprint")) and toggle.car_model is not None
toggle.frogsgomoo_tweak = toggle.openpilot_longitudinal and toggle.car_make == "toyota" and (params.get_bool("FrogsGoMoosTweak") if tuning_level >= level["FrogsGoMoosTweak"] else default.get_bool("FrogsGoMoosTweak")) toggle.frogsgomoo_tweak = toggle.openpilot_longitudinal and toggle.car_make == "toyota" and (params.get_bool("FrogsGoMoosTweak") if tuning_level >= level["FrogsGoMoosTweak"] else default.get_bool("FrogsGoMoosTweak"))
@@ -917,6 +939,7 @@ class FrogPilotVariables:
toggle.old_long_api |= toggle.openpilot_longitudinal and toggle.car_make == "hyundai" and not (params.get_bool("NewLongAPI") if tuning_level >= level["NewLongAPI"] else default.get_bool("NewLongAPI")) toggle.old_long_api |= toggle.openpilot_longitudinal and toggle.car_make == "hyundai" and not (params.get_bool("NewLongAPI") if tuning_level >= level["NewLongAPI"] else default.get_bool("NewLongAPI"))
personalize_openpilot = params.get_bool("PersonalizeOpenpilot") if tuning_level >= level["PersonalizeOpenpilot"] else default.get_bool("PersonalizeOpenpilot") personalize_openpilot = params.get_bool("PersonalizeOpenpilot") if tuning_level >= level["PersonalizeOpenpilot"] else default.get_bool("PersonalizeOpenpilot")
toggle.boot_logo = params.get("BootLogo", encoding="utf-8") or "starpilot"
toggle.color_scheme = toggle.current_holiday_theme if toggle.current_holiday_theme != "stock" else params.get("CustomColors", encoding="utf-8") if personalize_openpilot else "stock" toggle.color_scheme = toggle.current_holiday_theme if toggle.current_holiday_theme != "stock" else params.get("CustomColors", encoding="utf-8") if personalize_openpilot else "stock"
toggle.distance_icons = toggle.current_holiday_theme if toggle.current_holiday_theme != "stock" else params.get("CustomDistanceIcons", encoding="utf-8") if personalize_openpilot else "stock" toggle.distance_icons = toggle.current_holiday_theme if toggle.current_holiday_theme != "stock" else params.get("CustomDistanceIcons", encoding="utf-8") if personalize_openpilot else "stock"
toggle.icon_pack = toggle.current_holiday_theme if toggle.current_holiday_theme != "stock" else params.get("CustomIcons", encoding="utf-8") if personalize_openpilot else "stock" toggle.icon_pack = toggle.current_holiday_theme if toggle.current_holiday_theme != "stock" else params.get("CustomIcons", encoding="utf-8") if personalize_openpilot else "stock"
@@ -1006,7 +1029,14 @@ class FrogPilotVariables:
toggle.lock_doors = toyota_doors and (params.get_bool("LockDoors") if tuning_level >= level["LockDoors"] else default.get_bool("LockDoors")) toggle.lock_doors = toyota_doors and (params.get_bool("LockDoors") if tuning_level >= level["LockDoors"] else default.get_bool("LockDoors"))
toggle.unlock_doors = toyota_doors and (params.get_bool("UnlockDoors") if tuning_level >= level["UnlockDoors"] else default.get_bool("UnlockDoors")) toggle.unlock_doors = toyota_doors and (params.get_bool("UnlockDoors") if tuning_level >= level["UnlockDoors"] else default.get_bool("UnlockDoors"))
toggle.volt_sng = toggle.car_model == "CHEVROLET_VOLT" and (params.get_bool("VoltSNG") if tuning_level >= level["VoltSNG"] else default.get_bool("VoltSNG")) volt_models = {
"CHEVROLET_VOLT",
"CHEVROLET_VOLT_2019",
"CHEVROLET_VOLT_ASCM",
"CHEVROLET_VOLT_CAMERA",
}
toggle.volt_sng = toggle.car_model in volt_models and (params.get_bool("VoltSNG") if tuning_level >= level["VoltSNG"] else default.get_bool("VoltSNG"))
toggle.gm_pedal_longitudinal = params.get_bool("GMPedalLongitudinal") if tuning_level >= level["GMPedalLongitudinal"] else default.get_bool("GMPedalLongitudinal") toggle.gm_pedal_longitudinal = params.get_bool("GMPedalLongitudinal") if tuning_level >= level["GMPedalLongitudinal"] else default.get_bool("GMPedalLongitudinal")
@@ -47,26 +47,53 @@ A_CRUISE_MIN_SPORT = A_CRUISE_MIN * 2
# MPH = [0.0, 11, 22, 34, 45, 56, 89] # MPH = [0.0, 11, 22, 34, 45, 56, 89]
A_CRUISE_MAX_BP_CUSTOM = [0.0, 5., 10., 15., 20., 25., 40.] A_CRUISE_MAX_BP_CUSTOM = [0.0, 5., 10., 15., 20., 25., 40.]
A_CRUISE_MAX_VALS_ECO_EV = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0] A_CRUISE_MAX_VALS_ECO_EV = [1.0, 1.0, 1.0, 1.0, 1.12, 1.12, 1.45]
A_CRUISE_MAX_VALS_SPORT_EV = [1.25, 1.25, 1.25, 1.25, 1.5, 1.5, 2.0] A_CRUISE_MAX_VALS_STANDARD_EV = [1.15, 1.15, 1.15, 1.15, 1.30, 1.30, 1.72]
A_CRUISE_MAX_VALS_SPORT_EV = [1.25, 1.25, 1.25, 1.25, 1.45, 1.5, 2.0]
A_CRUISE_MAX_VALS_SPORT_PLUS_EV = [1.35, 1.35, 1.35, 1.35, 1.60, 1.60, 2.10]
A_CRUISE_MAX_VALS_ECO_GAS = [2.0, 1.5, 1.0, 0.8, 0.6, 0.4, 0.2] A_CRUISE_MAX_VALS_ECO_GAS = [2.0, 1.5, 1.0, 0.8, 0.6, 0.4, 0.2]
A_CRUISE_MAX_VALS_SPORT_GAS = [3.0, 2.5, 2.0, 1.5, 1.0, 0.8, 0.6] A_CRUISE_MAX_VALS_SPORT_GAS = [3.0, 2.5, 2.0, 1.5, 1.0, 0.8, 0.6]
A_CRUISE_MAX_VALS_ECO_TRUCK = [3.00, 1.05, 0.60, 0.50, 0.50, 0.45, 0.35]
A_CRUISE_MAX_VALS_STANDARD_TRUCK = [6.00, 1.10, 0.70, 0.60, 0.55, 0.45, 0.35]
A_CRUISE_MAX_VALS_SPORT_TRUCK = [6.00, 1.15, 0.75, 0.70, 0.60, 0.50, 0.40]
A_CRUISE_MAX_VALS_SPORT_PLUS_TRUCK = [6.00, 1.30, 0.90, 0.80, 0.70, 0.60, 0.45]
def get_max_accel_eco(v_ego, ev_tuning=True): def get_max_accel_eco(v_ego, ev_tuning=True, truck_tuning=False):
cruise_vals = A_CRUISE_MAX_VALS_ECO_EV if ev_tuning else A_CRUISE_MAX_VALS_ECO_GAS if ev_tuning:
cruise_vals = A_CRUISE_MAX_VALS_ECO_EV
elif truck_tuning:
cruise_vals = A_CRUISE_MAX_VALS_ECO_TRUCK
else:
cruise_vals = A_CRUISE_MAX_VALS_ECO_GAS
return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, cruise_vals)) return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, cruise_vals))
def get_max_accel_sport(v_ego, ev_tuning=True): def get_max_accel_sport(v_ego, ev_tuning=True, truck_tuning=False):
cruise_vals = A_CRUISE_MAX_VALS_SPORT_EV if ev_tuning else A_CRUISE_MAX_VALS_SPORT_GAS if ev_tuning:
cruise_vals = A_CRUISE_MAX_VALS_SPORT_EV
elif truck_tuning:
cruise_vals = A_CRUISE_MAX_VALS_SPORT_TRUCK
else:
cruise_vals = A_CRUISE_MAX_VALS_SPORT_GAS
return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, cruise_vals)) return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, cruise_vals))
def get_max_accel_standard(v_ego, ev_tuning=True, truck_tuning=False):
if ev_tuning:
return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, A_CRUISE_MAX_VALS_STANDARD_EV))
if truck_tuning:
return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, A_CRUISE_MAX_VALS_STANDARD_TRUCK))
return get_max_accel(v_ego)
def get_max_accel_low_speeds(max_accel, v_cruise): def get_max_accel_low_speeds(max_accel, v_cruise):
return float(akima_interp(v_cruise, [0., CITY_SPEED_LIMIT / 2, CITY_SPEED_LIMIT], [max_accel / 4, max_accel / 2, max_accel])) return float(akima_interp(v_cruise, [0., CITY_SPEED_LIMIT / 2, CITY_SPEED_LIMIT], [max_accel / 4, max_accel / 2, max_accel]))
def get_max_accel_ramp_off(max_accel, v_cruise, v_ego): def get_max_accel_ramp_off(max_accel, v_cruise, v_ego):
return float(akima_interp(v_cruise - v_ego, [0., 1., 5., 10.], [0., 0.5, 1.0, max_accel])) return float(akima_interp(v_cruise - v_ego, [0., 1., 5., 10.], [0., 0.5, 1.0, max_accel]))
def get_max_allowed_accel(v_ego): def get_max_allowed_accel(v_ego, ev_tuning=True, truck_tuning=False):
if ev_tuning:
return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, A_CRUISE_MAX_VALS_SPORT_PLUS_EV))
if truck_tuning:
return float(akima_interp(v_ego, A_CRUISE_MAX_BP_CUSTOM, A_CRUISE_MAX_VALS_SPORT_PLUS_TRUCK))
return float(akima_interp(v_ego, [0., 5., 20.], [4.0, 4.0, 2.0])) # ISO 15622:2018 return float(akima_interp(v_ego, [0., 5., 20.], [4.0, 4.0, 2.0])) # ISO 15622:2018
class FrogPilotAcceleration: class FrogPilotAcceleration:
@@ -80,26 +107,27 @@ class FrogPilotAcceleration:
eco_gear = sm["frogpilotCarState"].ecoGear eco_gear = sm["frogpilotCarState"].ecoGear
sport_gear = sm["frogpilotCarState"].sportGear sport_gear = sm["frogpilotCarState"].sportGear
ev_tuning = frogpilot_toggles.ev_tuning ev_tuning = frogpilot_toggles.ev_tuning
truck_tuning = frogpilot_toggles.truck_tuning
if sm["frogpilotCarState"].trafficModeEnabled: if sm["frogpilotCarState"].trafficModeEnabled:
self.max_accel = get_max_accel(v_ego) self.max_accel = get_max_accel_standard(v_ego, ev_tuning, truck_tuning)
elif frogpilot_toggles.map_acceleration and (eco_gear or sport_gear): elif frogpilot_toggles.map_acceleration and (eco_gear or sport_gear):
if eco_gear: if eco_gear:
self.max_accel = get_max_accel_eco(v_ego, ev_tuning) self.max_accel = get_max_accel_eco(v_ego, ev_tuning, truck_tuning)
else: else:
if frogpilot_toggles.acceleration_profile == 2: if frogpilot_toggles.acceleration_profile == 2:
self.max_accel = get_max_accel_sport(v_ego, ev_tuning) self.max_accel = get_max_accel_sport(v_ego, ev_tuning, truck_tuning)
else: else:
self.max_accel = get_max_allowed_accel(v_ego) self.max_accel = get_max_allowed_accel(v_ego, ev_tuning, truck_tuning)
else: else:
if frogpilot_toggles.acceleration_profile == 1: if frogpilot_toggles.acceleration_profile == 1:
self.max_accel = get_max_accel_eco(v_ego, ev_tuning) self.max_accel = get_max_accel_eco(v_ego, ev_tuning, truck_tuning)
elif frogpilot_toggles.acceleration_profile == 2: elif frogpilot_toggles.acceleration_profile == 2:
self.max_accel = get_max_accel_sport(v_ego, ev_tuning) self.max_accel = get_max_accel_sport(v_ego, ev_tuning, truck_tuning)
elif frogpilot_toggles.acceleration_profile == 3: elif frogpilot_toggles.acceleration_profile == 3:
self.max_accel = get_max_allowed_accel(v_ego) self.max_accel = get_max_allowed_accel(v_ego, ev_tuning, truck_tuning)
else: else:
self.max_accel = get_max_accel(v_ego) self.max_accel = get_max_accel_standard(v_ego, ev_tuning, truck_tuning)
if frogpilot_toggles.human_acceleration: if frogpilot_toggles.human_acceleration:
self.max_accel = min(get_max_accel_low_speeds(self.max_accel, self.frogpilot_planner.v_cruise), self.max_accel) self.max_accel = min(get_max_accel_low_speeds(self.max_accel, self.frogpilot_planner.v_cruise), self.max_accel)
@@ -273,7 +273,10 @@ void FrogPilotSettingsWindow::updateVariables() {
hasSNG = hasOpenpilotLongitudinal && CP.getAutoResumeSng(); hasSNG = hasOpenpilotLongitudinal && CP.getAutoResumeSng();
hasZSS = frogpilot_toggles.value("has_zss").toBool(); hasZSS = frogpilot_toggles.value("has_zss").toBool();
isAngleCar = CP.getSteerControlType() == cereal::CarParams::SteerControlType::ANGLE; isAngleCar = CP.getSteerControlType() == cereal::CarParams::SteerControlType::ANGLE;
isBolt = carFingerprint == "CHEVROLET_BOLT_CC" || carFingerprint == "CHEVROLET_BOLT_EUV"; isBolt = carFingerprint == "CHEVROLET_BOLT_ACC_2022_2023" ||
carFingerprint == "CHEVROLET_BOLT_CC_2022_2023" ||
carFingerprint == "CHEVROLET_BOLT_CC_2019_2021" ||
carFingerprint == "CHEVROLET_BOLT_CC_2017";
isGM = carMake == "gm"; isGM = carMake == "gm";
isHKG = carMake == "hyundai"; isHKG = carMake == "hyundai";
isHKGCanFd = isHKG && safetyModel == cereal::CarParams::SafetyModel::HYUNDAI_CANFD; isHKGCanFd = isHKG && safetyModel == cereal::CarParams::SafetyModel::HYUNDAI_CANFD;
@@ -103,6 +103,10 @@ FrogPilotLongitudinalPanel::FrogPilotLongitudinalPanel(
"vehicle's detected powertrain type but can be overridden if the " "vehicle's detected powertrain type but can be overridden if the "
"automatic choice doesn't match."), "automatic choice doesn't match."),
""}, ""},
{"TruckTuning", tr("Truck Tuning"),
tr("<b>Use aggressive acceleration profiles tuned for trucks.</b> "
"Intended for heavy vehicles that need stronger throttle."),
""},
{"LongitudinalActuatorDelay", {"LongitudinalActuatorDelay",
longitudinalActuatorDelay != 0 longitudinalActuatorDelay != 0
? QString(tr("Actuator Delay (Default: %1)")) ? QString(tr("Actuator Delay (Default: %1)"))
@@ -1125,6 +1129,21 @@ FrogPilotLongitudinalPanel::FrogPilotLongitudinalPanel(
&FrogPilotLongitudinalPanel::updateToggles); &FrogPilotLongitudinalPanel::updateToggles);
} }
QObject::connect(static_cast<ToggleControl *>(toggles["EVTuning"]),
&ToggleControl::toggleFlipped, this, [this]() {
if (params.getBool("EVTuning")) {
params.putBool("TruckTuning", false);
}
updateToggles();
});
QObject::connect(static_cast<ToggleControl *>(toggles["TruckTuning"]),
&ToggleControl::toggleFlipped, this, [this]() {
if (params.getBool("TruckTuning")) {
params.putBool("EVTuning", false);
}
updateToggles();
});
FrogPilotParamValueControl *trafficFollowToggle = FrogPilotParamValueControl *trafficFollowToggle =
static_cast<FrogPilotParamValueControl *>(toggles["TrafficFollow"]); static_cast<FrogPilotParamValueControl *>(toggles["TrafficFollow"]);
FrogPilotParamValueControl *trafficAccelerationToggle = FrogPilotParamValueControl *trafficAccelerationToggle =
@@ -1636,6 +1655,12 @@ void FrogPilotLongitudinalPanel::updateToggles() {
setVisible &= !isToyota || !params.getBool("FrogsGoMoosTweak"); setVisible &= !isToyota || !params.getBool("FrogsGoMoosTweak");
} }
if (key == "EVTuning") {
toggle->setEnabled(!params.getBool("TruckTuning"));
} else if (key == "TruckTuning") {
toggle->setEnabled(!params.getBool("EVTuning"));
}
toggle->setVisible(setVisible); toggle->setVisible(setVisible);
if (setVisible) { if (setVisible) {
@@ -40,7 +40,7 @@ private:
std::map<QString, AbstractControl*> toggles; std::map<QString, AbstractControl*> toggles;
QSet<QString> advancedLongitudinalTuneKeys = {"EVTuning", "LongitudinalActuatorDelay", "StartAccel", "StopAccel", "StoppingDecelRate", "VEgoStarting", "VEgoStopping"}; QSet<QString> advancedLongitudinalTuneKeys = {"EVTuning", "TruckTuning", "LongitudinalActuatorDelay", "StartAccel", "StopAccel", "StoppingDecelRate", "VEgoStarting", "VEgoStopping"};
QSet<QString> aggressivePersonalityKeys = {"AggressiveFollow", "AggressiveFollowHigh", "AggressiveJerkAcceleration", "AggressiveJerkDeceleration", "AggressiveJerkDanger", "AggressiveJerkSpeed", "AggressiveJerkSpeedDecrease", "ResetAggressivePersonality"}; QSet<QString> aggressivePersonalityKeys = {"AggressiveFollow", "AggressiveFollowHigh", "AggressiveJerkAcceleration", "AggressiveJerkDeceleration", "AggressiveJerkDanger", "AggressiveJerkSpeed", "AggressiveJerkSpeedDecrease", "ResetAggressivePersonality"};
QSet<QString> conditionalExperimentalKeys = {"CESpeed", "CESpeedLead", "CECurves", "CELead", "CEModelStopTime", "CENavigation", "CESignalSpeed", "ShowCEMStatus"}; QSet<QString> conditionalExperimentalKeys = {"CESpeed", "CESpeedLead", "CECurves", "CELead", "CEModelStopTime", "CENavigation", "CESignalSpeed", "ShowCEMStatus"};
QSet<QString> curveSpeedKeys = {"CalibratedLateralAcceleration", "CalibrationProgress", "ResetCurveData", "ShowCSCStatus"}; QSet<QString> curveSpeedKeys = {"CalibratedLateralAcceleration", "CalibrationProgress", "ResetCurveData", "ShowCSCStatus"};
+65
View File
@@ -66,6 +66,11 @@ void deleteThemeAsset(QDir &directory, const QString &subFolder, const QString &
} }
void downloadThemeAsset(const QString &input, const std::string &paramKey, const QString &assetParam, Params &params, Params &params_memory) { void downloadThemeAsset(const QString &input, const std::string &paramKey, const QString &assetParam, Params &params, Params &params_memory) {
if (paramKey == "BootLogoToDownload") {
params_memory.put(paramKey, input.trimmed().toStdString());
return;
}
QString output = input; QString output = input;
int tilde = output.indexOf("~"); int tilde = output.indexOf("~");
if (tilde >= 0) { if (tilde >= 0) {
@@ -228,6 +233,7 @@ FrogPilotThemesPanel::FrogPilotThemesPanel(FrogPilotSettingsWindow *parent) : Fr
const std::vector<std::tuple<QString, QString, QString, QString>> themeToggles { const std::vector<std::tuple<QString, QString, QString, QString>> themeToggles {
{"PersonalizeOpenpilot", tr("Custom Themes"), tr("<b>The overall look and feel of openpilot.</b> Use the \"Theme Maker\" in \"The Pond\" to create and share your own themes!"), "../../frogpilot/assets/toggle_icons/icon_frog.png"}, {"PersonalizeOpenpilot", tr("Custom Themes"), tr("<b>The overall look and feel of openpilot.</b> Use the \"Theme Maker\" in \"The Pond\" to create and share your own themes!"), "../../frogpilot/assets/toggle_icons/icon_frog.png"},
{"BootLogo", tr("Boot Logo"), tr("<b>The boot logo shown while the device starts.</b>"), ""},
{"CustomColors", tr("Color Scheme"), tr("<b>The color scheme used throughout openpilot.</b> Use the \"Theme Maker\" in \"The Pond\" to create and share your own themes!"), ""}, {"CustomColors", tr("Color Scheme"), tr("<b>The color scheme used throughout openpilot.</b> Use the \"Theme Maker\" in \"The Pond\" to create and share your own themes!"), ""},
{"CustomDistanceIcons", tr("Distance Button"), tr("<b>The distance button icons shown on the driving screen.</b> Use the \"Theme Maker\" in \"The Pond\" to create and share your own themes!"), ""}, {"CustomDistanceIcons", tr("Distance Button"), tr("<b>The distance button icons shown on the driving screen.</b> Use the \"Theme Maker\" in \"The Pond\" to create and share your own themes!"), ""},
{"CustomIcons", tr("Icon Pack"), tr("<b>The icon style used across openpilot.</b> Use the \"Theme Maker\" in \"The Pond\" to create and share your own themes!"), ""}, {"CustomIcons", tr("Icon Pack"), tr("<b>The icon style used across openpilot.</b> Use the \"Theme Maker\" in \"The Pond\" to create and share your own themes!"), ""},
@@ -252,6 +258,57 @@ FrogPilotThemesPanel::FrogPilotThemesPanel(FrogPilotSettingsWindow *parent) : Fr
themesLayout->setCurrentWidget(customThemesPanel); themesLayout->setCurrentWidget(customThemesPanel);
}); });
themeToggle = personalizeOpenpilotToggle; themeToggle = personalizeOpenpilotToggle;
} else if (param == "BootLogo") {
manageBootLogosButton = new FrogPilotButtonsControl(title, desc, icon, {tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")});
QObject::connect(manageBootLogosButton, &FrogPilotButtonsControl::buttonClicked, [this](int id) {
// Show all downloaded boot logos, including the currently selected one.
QStringList bootLogos = getThemeList(true, QDir(bootLogosDirectory.path()), "", "BootLogo", params);
if (id == 0) {
QString bootLogoToDelete = MultiOptionDialog::getSelection(tr("Select a boot logo to delete"), bootLogos, "", this);
if (!bootLogoToDelete.isEmpty() && ConfirmationDialog::confirm(tr("Delete the \"%1\" boot logo?").arg(bootLogoToDelete), tr("Delete"), this)) {
bootLogosDownloaded = false;
deleteThemeAsset(bootLogosDirectory, "", "DownloadableBootLogos", bootLogoToDelete, params);
}
} else if (id == 1) {
if (bootLogoDownloading) {
cancellingDownload = true;
params_memory.putBool("CancelThemeDownload", true);
QTimer::singleShot(2500, [this]() {
bootLogoDownloading = false;
cancellingDownload = false;
themeDownloading = false;
params_memory.putBool("CancelThemeDownload", false);
});
} else {
QStringList downloadableBootLogos = QString::fromStdString(params.get("DownloadableBootLogos")).split(",");
bootLogoToDownload = MultiOptionDialog::getSelection(tr("Select a boot logo to download"), downloadableBootLogos, "", this);
if (!bootLogoToDownload.isEmpty()) {
manageBootLogosButton->setValue(storeThemeName(bootLogoToDownload, "BootLogo", params));
bootLogoDownloading = true;
themeDownloading = true;
params_memory.put("ThemeDownloadProgress", "Downloading...");
downloadThemeAsset(bootLogoToDownload, "BootLogoToDownload", "DownloadableBootLogos", params, params_memory);
downloadStatusLabel->setText("Downloading...");
}
}
} else if (id == 2) {
QString bootLogoToSelect = MultiOptionDialog::getSelection(tr("Select a boot logo"), bootLogos, getThemeName("BootLogo", params), this);
if (!bootLogoToSelect.isEmpty()) {
manageBootLogosButton->setValue(storeThemeName(bootLogoToSelect, "BootLogo", params));
}
}
});
manageBootLogosButton->setValue(getThemeName(param.toStdString(), params));
themeToggle = manageBootLogosButton;
} else if (param == "CustomColors") { } else if (param == "CustomColors") {
manageCustomColorsButton = new FrogPilotButtonsControl(title, desc, icon, {tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")}); manageCustomColorsButton = new FrogPilotButtonsControl(title, desc, icon, {tr("DELETE"), tr("DOWNLOAD"), tr("SELECT")});
QObject::connect(manageCustomColorsButton, &FrogPilotButtonsControl::buttonClicked, [this](int id) { QObject::connect(manageCustomColorsButton, &FrogPilotButtonsControl::buttonClicked, [this](int id) {
@@ -704,6 +761,7 @@ FrogPilotThemesPanel::FrogPilotThemesPanel(FrogPilotSettingsWindow *parent) : Fr
} }
void FrogPilotThemesPanel::showEvent(QShowEvent *event) { void FrogPilotThemesPanel::showEvent(QShowEvent *event) {
bootLogosDownloaded = params.get("DownloadableBootLogos").empty();
colorsDownloaded = params.get("DownloadableColors").empty(); colorsDownloaded = params.get("DownloadableColors").empty();
distanceIconsDownloaded = params.get("DownloadableDistanceIcons").empty(); distanceIconsDownloaded = params.get("DownloadableDistanceIcons").empty();
iconsDownloaded = params.get("DownloadableIcons").empty(); iconsDownloaded = params.get("DownloadableIcons").empty();
@@ -756,6 +814,7 @@ void FrogPilotThemesPanel::updateState(const UIState &s, const FrogPilotUIState
finalizingDownload = true; finalizingDownload = true;
QTimer::singleShot(2500, [this]() { QTimer::singleShot(2500, [this]() {
bootLogoDownloading = false;
colorDownloading = false; colorDownloading = false;
distanceIconDownloading = false; distanceIconDownloading = false;
finalizingDownload = false; finalizingDownload = false;
@@ -765,6 +824,7 @@ void FrogPilotThemesPanel::updateState(const UIState &s, const FrogPilotUIState
themeDownloading = false; themeDownloading = false;
wheelDownloading = false; wheelDownloading = false;
bootLogosDownloaded = params.get("DownloadableBootLogos").empty();
colorsDownloaded = params.get("DownloadableColors").empty(); colorsDownloaded = params.get("DownloadableColors").empty();
distanceIconsDownloaded = params.get("DownloadableDistanceIcons").empty(); distanceIconsDownloaded = params.get("DownloadableDistanceIcons").empty();
iconsDownloaded = params.get("DownloadableIcons").empty(); iconsDownloaded = params.get("DownloadableIcons").empty();
@@ -782,6 +842,11 @@ void FrogPilotThemesPanel::updateState(const UIState &s, const FrogPilotUIState
bool parked = !s.scene.started || fs.frogpilot_scene.parked || fs.frogpilot_toggles.value("frogs_go_moo").toBool(); bool parked = !s.scene.started || fs.frogpilot_scene.parked || fs.frogpilot_toggles.value("frogs_go_moo").toBool();
manageBootLogosButton->setText(1, bootLogoDownloading ? tr("CANCEL") : tr("DOWNLOAD"));
manageBootLogosButton->setEnabledButtons(0, !themeDownloading);
manageBootLogosButton->setEnabledButtons(1, fs.frogpilot_scene.online && (!themeDownloading || bootLogoDownloading) && !cancellingDownload && !finalizingDownload && !bootLogosDownloaded && parked);
manageBootLogosButton->setEnabledButtons(2, !themeDownloading);
manageCustomColorsButton->setText(1, colorDownloading ? tr("CANCEL") : tr("DOWNLOAD")); manageCustomColorsButton->setText(1, colorDownloading ? tr("CANCEL") : tr("DOWNLOAD"));
manageCustomColorsButton->setEnabledButtons(0, !themeDownloading); manageCustomColorsButton->setEnabledButtons(0, !themeDownloading);
manageCustomColorsButton->setEnabledButtons(1, fs.frogpilot_scene.online && (!themeDownloading || colorDownloading) && !cancellingDownload && !finalizingDownload && !colorsDownloaded && parked); manageCustomColorsButton->setEnabledButtons(1, fs.frogpilot_scene.online && (!themeDownloading || colorDownloading) && !cancellingDownload && !finalizingDownload && !colorsDownloaded && parked);
+6 -1
View File
@@ -19,6 +19,8 @@ private:
void updateToggles(); void updateToggles();
bool cancellingDownload; bool cancellingDownload;
bool bootLogoDownloading = false;
bool bootLogosDownloaded = false;
bool colorDownloading; bool colorDownloading;
bool colorsDownloaded; bool colorsDownloaded;
bool distanceIconDownloading; bool distanceIconDownloading;
@@ -40,10 +42,11 @@ private:
std::map<QString, AbstractControl*> toggles; std::map<QString, AbstractControl*> toggles;
QSet<QString> customThemeKeys = {"CustomColors", "CustomDistanceIcons", "CustomIcons", "CustomSignals", "CustomSounds", "DownloadStatusLabel", "WheelIcon"}; QSet<QString> customThemeKeys = {"BootLogo", "CustomColors", "CustomDistanceIcons", "CustomIcons", "CustomSignals", "CustomSounds", "DownloadStatusLabel", "WheelIcon"};
QSet<QString> parentKeys; QSet<QString> parentKeys;
FrogPilotButtonsControl *manageBootLogosButton;
FrogPilotButtonsControl *manageCustomColorsButton; FrogPilotButtonsControl *manageCustomColorsButton;
FrogPilotButtonsControl *manageCustomIconsButton; FrogPilotButtonsControl *manageCustomIconsButton;
FrogPilotButtonsControl *manageCustomSignalsButton; FrogPilotButtonsControl *manageCustomSignalsButton;
@@ -55,11 +58,13 @@ private:
LabelControl *downloadStatusLabel; LabelControl *downloadStatusLabel;
QDir bootLogosDirectory{"/data/themes/bootlogos/"};
QDir themePacksDirectory{"/data/themes/theme_packs/"}; QDir themePacksDirectory{"/data/themes/theme_packs/"};
QDir wheelsDirectory{"/data/themes/steering_wheels/"}; QDir wheelsDirectory{"/data/themes/steering_wheels/"};
QJsonObject frogpilotToggleLevels; QJsonObject frogpilotToggleLevels;
QString bootLogoToDownload;
QString colorSchemeToDownload; QString colorSchemeToDownload;
QString distanceIconPackToDownload; QString distanceIconPackToDownload;
QString iconPackToDownload; QString iconPackToDownload;
@@ -1,6 +1,9 @@
#include <QRegularExpression> #include <QRegularExpression>
#include <QTextStream> #include <QTextStream>
#include <chrono>
#include <thread>
#include "frogpilot/ui/qt/offroad/vehicle_settings.h" #include "frogpilot/ui/qt/offroad/vehicle_settings.h"
QStringList getCarNames(const QString &carMake, QMap<QString, QString> &carModels) { QStringList getCarNames(const QString &carMake, QMap<QString, QString> &carModels) {
@@ -170,6 +173,8 @@ FrogPilotVehiclesPanel::FrogPilotVehiclesPanel(FrogPilotSettingsWindow *parent)
{"ExperimentalGMTune", tr("FrogsGoMoo's Experimental Tune"), tr("<b>Experimental GM tune by FrogsGoMoo</b> that attempts to smoothen stopping and takeoff control. Use at your own risk!"), ""}, {"ExperimentalGMTune", tr("FrogsGoMoo's Experimental Tune"), tr("<b>Experimental GM tune by FrogsGoMoo</b> that attempts to smoothen stopping and takeoff control. Use at your own risk!"), ""},
{"GMPedalLongitudinal", tr("Use Pedal for Longitudinal Control"), tr("<b>Use the pedal interceptor for longitudinal control</b> instead of camera ACC/Redneck when available."), ""}, {"GMPedalLongitudinal", tr("Use Pedal for Longitudinal Control"), tr("<b>Use the pedal interceptor for longitudinal control</b> instead of camera ACC/Redneck when available."), ""},
{"LongPitch", tr("Smooth Pedal Response on Hills"), tr("<b>Smoothen acceleration and braking</b> when driving downhill/uphill."), ""}, {"LongPitch", tr("Smooth Pedal Response on Hills"), tr("<b>Smoothen acceleration and braking</b> when driving downhill/uphill."), ""},
{"RedPanda", tr("Red Panda"), tr("<b>Enable Red Panda behavior</b> for GM (alternate safety config and bus numbering). Requires a reboot to take effect."), ""},
{"RemoteStartBootsComma", tr("Remote Start Boots Comma"), tr("<b>Use GM C9 SystemPowerMode</b> for ignition detection. Toggle requires a panda firmware update and a reboot to take effect."), ""},
{"VoltSNG", tr("Stop-and-Go Hack"), tr("<b>Force stop-and-go</b> on the 2017 Chevy Volt."), ""}, {"VoltSNG", tr("Stop-and-Go Hack"), tr("<b>Force stop-and-go</b> on the 2017 Chevy Volt."), ""},
{"HKGToggles", tr("Hyundai/Kia/Genesis Settings"), tr("<b>FrogPilot features for Genesis, Hyundai, and Kia vehicles.</b>"), ""}, {"HKGToggles", tr("Hyundai/Kia/Genesis Settings"), tr("<b>FrogPilot features for Genesis, Hyundai, and Kia vehicles.</b>"), ""},
@@ -300,6 +305,25 @@ FrogPilotVehiclesPanel::FrogPilotVehiclesPanel(FrogPilotSettingsWindow *parent)
}); });
} }
ParamControl *remoteStartToggle = static_cast<ParamControl*>(toggles["RemoteStartBootsComma"]);
QObject::connect(remoteStartToggle, &ToggleControl::toggleFlipped, [parent, remoteStartToggle, this](bool state) {
const QString prompt = tr("Remote Start requires a Panda firmware update. Flash the Panda now?");
if (!FrogPilotConfirmationDialog::yesorno(prompt, this)) {
params.putBool("RemoteStartBootsComma", !state);
remoteStartToggle->refresh();
return;
}
std::thread([parent, this]() {
parent->keepScreenOn = true;
params_memory.putBool("FlashPanda", true);
while (params_memory.getBool("FlashPanda")) {
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
Hardware::reboot();
}).detach();
});
openDescriptions(forceOpenDescriptions, toggles); openDescriptions(forceOpenDescriptions, toggles);
QObject::connect(uiState(), &UIState::offroadTransition, [selectMakeButton, selectModelButton, this]() { QObject::connect(uiState(), &UIState::offroadTransition, [selectMakeButton, selectModelButton, this]() {
+2 -1
View File
@@ -36,7 +36,7 @@ private:
std::map<QString, AbstractControl*> toggles; std::map<QString, AbstractControl*> toggles;
QSet<QString> gmKeys = {"ExperimentalGMTune", "GMPedalLongitudinal", "LongPitch", "VoltSNG"}; QSet<QString> gmKeys = {"ExperimentalGMTune", "GMPedalLongitudinal", "LongPitch", "RedPanda", "RemoteStartBootsComma", "VoltSNG"};
QSet<QString> hkgKeys = {"NewLongAPI", "TacoTuneHacks"}; QSet<QString> hkgKeys = {"NewLongAPI", "TacoTuneHacks"};
QSet<QString> longitudinalKeys = {"ExperimentalGMTune", "FrogsGoMoosTweak", "LongPitch", "NewLongAPI", "SNGHack", "VoltSNG"}; QSet<QString> longitudinalKeys = {"ExperimentalGMTune", "FrogsGoMoosTweak", "LongPitch", "NewLongAPI", "SNGHack", "VoltSNG"};
QSet<QString> toyotaKeys = {"ClusterOffset", "FrogsGoMoosTweak", "LockDoorsTimer", "SNGHack", "ToyotaDoors"}; QSet<QString> toyotaKeys = {"ClusterOffset", "FrogsGoMoosTweak", "LockDoorsTimer", "SNGHack", "ToyotaDoors"};
@@ -50,6 +50,7 @@ private:
ParamControl *forceFingerprint; ParamControl *forceFingerprint;
Params params; Params params;
Params params_memory{"/dev/shm/params"};
Params params_default{"/dev/shm/params_default"}; Params params_default{"/dev/shm/params_default"};
QJsonObject frogpilotToggleLevels; QJsonObject frogpilotToggleLevels;
+15 -3
View File
@@ -82,6 +82,12 @@ VAL_TABLE_ HandsOffSWDetectionMode 2 "Failed" 1 "Enabled" 0 "Disabled" ;
BO_ 189 EBCMRegenPaddle: 7 K17_EBCM BO_ 189 EBCMRegenPaddle: 7 K17_EBCM
SG_ RegenPaddle : 7|4@0+ (1,0) [0|0] "" NEO 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 BO_ 190 ECMAcceleratorPos: 6 K20_ECM
SG_ BrakePedalPos : 15|8@0+ (1,0) [0|0] "sticky" NEO SG_ BrakePedalPos : 15|8@0+ (1,0) [0|0] "sticky" NEO
@@ -165,6 +171,7 @@ BO_ 481 ASCMSteeringButton: 7 K124_ASCM
SG_ DistanceButton : 22|1@0+ (1,0) [0|0] "" NEO SG_ DistanceButton : 22|1@0+ (1,0) [0|0] "" NEO
SG_ LKAButton : 23|1@0+ (1,0) [0|0] "" NEO SG_ LKAButton : 23|1@0+ (1,0) [0|0] "" NEO
SG_ ACCAlwaysOne : 24|1@0+ (1,0) [0|1] "" XXX SG_ ACCAlwaysOne : 24|1@0+ (1,0) [0|1] "" XXX
SG_ ACCHiddenBit : 30|1@0+ (1,0) [0|1] "" XXX
SG_ ACCButtons : 46|3@0+ (1,0) [0|0] "" NEO SG_ ACCButtons : 46|3@0+ (1,0) [0|0] "" NEO
SG_ DriveModeButton : 39|1@0+ (1,0) [0|1] "" XXX SG_ DriveModeButton : 39|1@0+ (1,0) [0|1] "" XXX
SG_ RollingCounter : 33|2@0+ (1,0) [0|3] "" NEO SG_ RollingCounter : 33|2@0+ (1,0) [0|3] "" NEO
@@ -192,10 +199,15 @@ BO_ 500 SportMode: 6 XXX
SG_ SportMode : 15|1@0+ (1,0) [0|1] "" XXX SG_ SportMode : 15|1@0+ (1,0) [0|1] "" XXX
BO_ 501 ECMPRDNL2: 8 K20_ECM BO_ 501 ECMPRDNL2: 8 K20_ECM
SG_ TransmissionState : 48|4@1+ (1,0) [0|7] "" NEO 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_ 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_ 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
BO_ 532 BRAKE_RELATED: 6 XXX BO_ 532 BRAKE_RELATED: 6 XXX
SG_ UserBrakePressure : 0|9@0+ (1,0) [0|511] "" XXX SG_ UserBrakePressure : 0|9@0+ (1,0) [0|511] "" XXX
@@ -370,6 +382,6 @@ VAL_ 715 GasRegenCmdActive 1 "Active" 0 "Inactive" ;
VAL_ 320 Intellibeam 1 "Active" 0 "Inactive" ; VAL_ 320 Intellibeam 1 "Active" 0 "Inactive" ;
VAL_ 320 HighBeamsActive 1 "Active" 0 "Inactive" ; VAL_ 320 HighBeamsActive 1 "Active" 0 "Inactive" ;
VAL_ 320 HighBeamsTemporary 1 "Active" 0 "Inactive" ; VAL_ 320 HighBeamsTemporary 1 "Active" 0 "Inactive" ;
VAL_ 501 PRNDL2 6 "L" 4 "D" 3 "N" 2 "R" 1 "P" 0 "Shifting"; VAL_ 501 PRNDL2 7 "L2" 6 "L" 5 "L3" 4 "D" 3 "N" 2 "R" 1 "P" 0 "Shifting";
VAL_ 501 TransmissionState 11 "Shifting" 10 "Reverse" 9 "Forward" 8 "Disengaged"; VAL_ 501 TransmissionState 11 "Shifting" 10 "Reverse" 9 "Forward" 8 "Disengaged";
VAL_ 501 ManualMode 1 "Active" 0 "Inactive" VAL_ 501 ManualMode 1 "Active" 0 "Inactive"
+5
View File
@@ -13,6 +13,11 @@ a.out
dist/ dist/
pandacan.egg-info/ pandacan.egg-info/
obj/ obj/
!board/obj/
!board/obj/bootstub.panda_remote.bin
!board/obj/bootstub.panda_h7_remote.bin
!board/obj/panda_remote.bin.signed
!board/obj/panda_h7_remote.bin.signed
examples/output.csv examples/output.csv
.DS_Store .DS_Store
.vscode* .vscode*
+17 -4
View File
@@ -33,6 +33,7 @@ extern bool can_loopback;
// Ignition detected from CAN meessages // Ignition detected from CAN meessages
bool ignition_can = false; bool ignition_can = false;
uint32_t ignition_can_cnt = 0U; uint32_t ignition_can_cnt = 0U;
extern bool gm_remote_start_boots_comma;
#define ALL_CAN_SILENT 0xFF #define ALL_CAN_SILENT 0xFF
#define ALL_CAN_LIVE 0 #define ALL_CAN_LIVE 0
@@ -202,10 +203,22 @@ void ignition_can_hook(CANPacket_t *to_push) {
int len = GET_LEN(to_push); int len = GET_LEN(to_push);
// GM exception // GM exception
if ((addr == 0x1F1) && (len == 8)) { #ifdef PANDA_GM_REMOTE_START_C9
// SystemPowerMode (2=Run, 3=Crank Request) if (true) {
ignition_can = (GET_BYTE(to_push, 0) & 0x2U) != 0U; #else
ignition_can_cnt = 0U; if (gm_remote_start_boots_comma) {
#endif
if ((addr == 0xC9) && (len == 8)) {
// Matches SystemPowerMode (1=Run, 0=Off)
ignition_can = (GET_BYTE(to_push, 6) & 0x10U) != 0U;
ignition_can_cnt = 0U;
}
} else {
if ((addr == 0x1F1) && (len == 8)) {
// SystemPowerMode (2=Run, 3=Crank Request)
ignition_can = (GET_BYTE(to_push, 0) & 0x2U) != 0U;
ignition_can_cnt = 0U;
}
} }
// Tesla exception // Tesla exception
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
const uint8_t gitversion[] = "DEV-87d2f6ab-DEBUG"; const uint8_t gitversion[] = "DEV-4d1efbb2-DEBUG";
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) { bool get_longitudinal_allowed(void) {
return controls_allowed && !gas_pressed_prev; return controls_allowed && !gas_pressed;
} }
// Given a CRC-8 poly, generate a static lookup table to use with a fast CRC-8 // Given a CRC-8 poly, generate a static lookup table to use with a fast CRC-8
+130 -66
View File
@@ -9,43 +9,55 @@ const SteeringLimits GM_STEERING_LIMITS = {
.type = TorqueDriverLimited, .type = TorqueDriverLimited,
}; };
const SteeringLimits GM_BOLT_2017_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,
.type = TorqueDriverLimited,
};
const LongitudinalLimits GM_ASCM_LONG_LIMITS = { const LongitudinalLimits GM_ASCM_LONG_LIMITS = {
.max_gas = 3072, .max_gas = 8191,
.min_gas = 1404, .min_gas = 5500,
.inactive_gas = 1404, .inactive_gas = 5500,
.max_brake = 400, .max_brake = 400,
}; };
const LongitudinalLimits GM_CAM_LONG_LIMITS = { const LongitudinalLimits GM_CAM_LONG_LIMITS = {
.max_gas = 3400, .max_gas = 8848,
.min_gas = 1514, .min_gas = 5610,
.inactive_gas = 1554, .inactive_gas = 5650,
.max_brake = 400, .max_brake = 400,
}; };
const SteeringLimits *gm_steer_limits;
const LongitudinalLimits *gm_long_limits; const LongitudinalLimits *gm_long_limits;
const int GM_STANDSTILL_THRSLD = 10; // 0.311kph const int GM_STANDSTILL_THRSLD = 10; // 0.311kph
// panda interceptor threshold needs to be equivalent to openpilot threshold to avoid controls mismatches // 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 // 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 = 515; // (675 + 355) / 2 ratio between offset and gain from dbc file const int GM_GAS_INTERCEPTOR_THRESHOLD = 595; // (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 #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}, // 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}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus
{0xA1, 1, 7}, {0x306, 1, 8}, {0x308, 1, 7}, {0x310, 1, 2}, // obs bus {0xA1, 1, 7}, {0x306, 1, 8}, {0x308, 1, 7}, {0x310, 1, 2}, // obs bus
{0x315, 2, 5}}; // ch bus {0x315, 2, 5}}; // ch bus
const CanMsg GM_CAM_TX_MSGS[] = {{0x180, 0, 4}, {0x200, 0, 6}, {0x1E1, 0, 7}, // pt bus const CanMsg GM_CAM_TX_MSGS[] = {{0x180, 0, 4}, {0x200, 0, 6}, {0x1E1, 0, 7}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus
{0x1E1, 2, 7}, {0x184, 2, 8}}; // camera 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}, // pt 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
{0x1E1, 2, 7}, {0x184, 2, 8}}; // camera bus {0x315, 2, 5}, {0x1E1, 2, 7}, {0x184, 2, 8}}; // camera bus
const CanMsg GM_SDGM_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, // pt bus const CanMsg GM_SDGM_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus
{0x184, 2, 8}}; // camera bus {0x184, 2, 8}}; // camera bus
const CanMsg GM_CC_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, // pt bus const CanMsg GM_CC_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus
{0x184, 2, 8}, {0x1E1, 2, 7}}; // camera bus {0x184, 2, 8}, {0x1E1, 2, 7}}; // camera bus
// TODO: do checksum and counter checks. Add correct timestep, 0.1s for now. // TODO: do checksum and counter checks. Add correct timestep, 0.1s for now.
@@ -62,13 +74,18 @@ RxCheck gm_rx_checks[] = {
const uint16_t GM_PARAM_HW_CAM = 1; const uint16_t GM_PARAM_HW_CAM = 1;
const uint16_t GM_PARAM_HW_CAM_LONG = 2; const uint16_t GM_PARAM_HW_CAM_LONG = 2;
const uint16_t GM_PARAM_HW_SDGM = 4; const uint16_t GM_PARAM_CC_LONG = 4;
const uint16_t GM_PARAM_CC_LONG = 8; const uint16_t GM_PARAM_HW_ASCM_LONG = 8;
const uint16_t GM_PARAM_HW_ASCM_LONG = 16; const uint16_t GM_PARAM_NO_CAMERA = 16;
const uint16_t GM_PARAM_NO_CAMERA = 32; const uint16_t GM_PARAM_NO_ACC = 32;
const uint16_t GM_PARAM_NO_ACC = 64; const uint16_t GM_PARAM_PEDAL_LONG = 64; // TODO: this can be inferred
const uint16_t GM_PARAM_PEDAL_LONG = 128; // TODO: this can be inferred const uint16_t GM_PARAM_PEDAL_INTERCEPTOR = 128;
const uint16_t GM_PARAM_PEDAL_INTERCEPTOR = 256; const uint16_t GM_PARAM_ASCM_INT = 256;
const uint16_t GM_PARAM_FORCE_BRAKE_C9 = 512;
const uint16_t GM_PARAM_HW_SDGM = 1024;
const uint16_t GM_PARAM_BOLT_2017 = 2048;
const uint16_t GM_PARAM_BOLT_2022_PEDAL = 4096;
const uint16_t GM_PARAM_REMOTE_START_BOOTS_COMMA = 8192;
enum { enum {
GM_BTN_UNPRESS = 1, GM_BTN_UNPRESS = 1,
@@ -90,30 +107,12 @@ bool gm_pedal_long = false;
bool gm_cc_long = false; bool gm_cc_long = false;
bool gm_skip_relay_check = false; bool gm_skip_relay_check = false;
bool gm_force_ascm = false; bool gm_force_ascm = false;
bool gm_bolt_2022_pedal = false;
static void handle_gm_wheel_buttons(const CANPacket_t *to_push) { bool gm_ascm_int = false;
int button = (GET_BYTE(to_push, 5) & 0x70U) >> 4; bool gm_force_brake_c9 = false;
bool gm_remote_start_boots_comma = false;
// enter controls on falling edge of set or rising edge of resume (avoids fault)
bool set = (button != GM_BTN_SET) && (cruise_button_prev == GM_BTN_SET);
bool res = (button == GM_BTN_RESUME) && (cruise_button_prev != GM_BTN_RESUME);
if (set || res) {
controls_allowed = true;
}
// exit controls on cancel press
if (button == GM_BTN_CANCEL) {
controls_allowed = false;
}
cruise_button_prev = button;
}
static void gm_rx_hook(const CANPacket_t *to_push) { static void gm_rx_hook(const CANPacket_t *to_push) {
if ((GET_BUS(to_push) == 2U) && (GET_ADDR(to_push) == 0x1E1) && (gm_hw == GM_SDGM)) {
// SDGM buttons are on bus 2
handle_gm_wheel_buttons(to_push);
}
if (GET_BUS(to_push) == 0U) { if (GET_BUS(to_push) == 0U) {
int addr = GET_ADDR(to_push); int addr = GET_ADDR(to_push);
@@ -131,19 +130,34 @@ static void gm_rx_hook(const CANPacket_t *to_push) {
vehicle_moving = (left_rear_speed > GM_STANDSTILL_THRSLD) || (right_rear_speed > GM_STANDSTILL_THRSLD); vehicle_moving = (left_rear_speed > GM_STANDSTILL_THRSLD) || (right_rear_speed > GM_STANDSTILL_THRSLD);
} }
// ACC steering wheel buttons (GM_CAM and GM_SDGM are tied to the PCM) // ACC steering wheel buttons (GM_CAM is tied to the PCM)
if ((addr == 0x1E1) && (!gm_pcm_cruise || gm_cc_long) && (gm_hw != GM_SDGM)) { if ((addr == 0x1E1) && (!gm_pcm_cruise || gm_cc_long)) {
handle_gm_wheel_buttons(to_push); int button = (GET_BYTE(to_push, 5) & 0x70U) >> 4;
// enter controls on falling edge of set or rising edge of resume (avoids fault)
bool set = (button != GM_BTN_SET) && (cruise_button_prev == GM_BTN_SET);
bool res = (button == GM_BTN_RESUME) && (cruise_button_prev != GM_BTN_RESUME);
if (set || res) {
controls_allowed = true;
}
// exit controls on cancel press
if (button == GM_BTN_CANCEL) {
controls_allowed = false;
}
cruise_button_prev = button;
} }
// Reference for brake pressed signals: // Reference for brake pressed signals:
// https://github.com/commaai/openpilot/blob/master/selfdrive/car/gm/carstate.py // https://github.com/commaai/openpilot/blob/master/selfdrive/car/gm/carstate.py
if ((addr == 0xBE) && (gm_hw == GM_ASCM)) { // Prefer 0xC9 (ECMEngineStatus) when gm_force_brake_c9 is set, otherwise keep legacy behavior.
if ((addr == 0xC9) && gm_force_brake_c9) {
brake_pressed = GET_BIT(to_push, 40U) != 0U;
} else if ((addr == 0xBE) && ((gm_hw == GM_ASCM) || (gm_hw == GM_SDGM))) {
brake_pressed = GET_BYTE(to_push, 1) >= 8U; brake_pressed = GET_BYTE(to_push, 1) >= 8U;
} } else if ((addr == 0xC9) && (gm_hw == GM_CAM)) {
brake_pressed = GET_BIT(to_push, 40U) != 0U;
if ((addr == 0xC9) && ((gm_hw == GM_CAM) || (gm_hw == GM_SDGM))) {
brake_pressed = GET_BIT(to_push, 40U);
} }
if (addr == 0xC9) { if (addr == 0xC9) {
@@ -162,6 +176,11 @@ 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 && gm_bolt_2022_pedal) {
cruise_engaged_prev = false;
}
// Cruise check for CC only cars // Cruise check for CC only cars
if ((addr == 0x3D1) && !gm_has_acc) { if ((addr == 0x3D1) && !gm_has_acc) {
bool cruise_engaged = (GET_BYTE(to_push, 4) >> 7) != 0U; bool cruise_engaged = (GET_BYTE(to_push, 4) >> 7) != 0U;
@@ -192,6 +211,19 @@ static void gm_rx_hook(const CANPacket_t *to_push) {
} }
generic_rx_checks(stock_ecu_detected); generic_rx_checks(stock_ecu_detected);
} }
// Cruise check for ASCMActiveCruiseControlStatus on bus 2.
// Keep kaofui behavior for non-Bolt paths; Bolt pedal path keeps local tracking.
if ((GET_ADDR(to_push) == 0x370) && (GET_BUS(to_push) == 2U)) {
bool cruise_engaged = (GET_BYTE(to_push, 2) >> 7) != 0U; // ACCCmdActive
if (gm_bolt_2022_pedal) {
cruise_engaged_prev = cruise_engaged;
} else if (gm_pcm_cruise && gm_has_acc) {
pcm_cruise_check(cruise_engaged);
} else {
cruise_engaged_prev = cruise_engaged;
}
}
} }
static bool gm_tx_hook(const CANPacket_t *to_send) { static bool gm_tx_hook(const CANPacket_t *to_send) {
@@ -214,7 +246,7 @@ static bool gm_tx_hook(const CANPacket_t *to_send) {
bool steer_req = GET_BIT(to_send, 3U); bool steer_req = GET_BIT(to_send, 3U);
if (steer_torque_cmd_checks(desired_torque, steer_req, GM_STEERING_LIMITS)) { if (steer_torque_cmd_checks(desired_torque, steer_req, *gm_steer_limits)) {
tx = false; tx = false;
} }
} }
@@ -229,7 +261,7 @@ static bool gm_tx_hook(const CANPacket_t *to_send) {
// GAS/REGEN: safety check // GAS/REGEN: safety check
if (addr == 0x2CB) { if (addr == 0x2CB) {
bool apply = GET_BIT(to_send, 0U); bool apply = GET_BIT(to_send, 0U);
int gas_regen = ((GET_BYTE(to_send, 2) & 0x7FU) << 5) + ((GET_BYTE(to_send, 3) & 0xF8U) >> 3); int gas_regen = ((GET_BYTE(to_send, 1) & 0x1U) << 13) + ((GET_BYTE(to_send, 2) & 0xFFU) << 5) + ((GET_BYTE(to_send, 3) & 0xF8U) >> 3);
bool violation = false; bool violation = false;
// Allow apply bit in pre-enabled and overriding states // Allow apply bit in pre-enabled and overriding states
@@ -246,8 +278,11 @@ static bool gm_tx_hook(const CANPacket_t *to_send) {
int button = (GET_BYTE(to_send, 5) >> 4) & 0x7U; int button = (GET_BYTE(to_send, 5) >> 4) & 0x7U;
bool allowed_btn = (button == GM_BTN_CANCEL) && cruise_engaged_prev; bool allowed_btn = (button == GM_BTN_CANCEL) && cruise_engaged_prev;
// For standard CC, allow spamming of SET / RESUME if (gm_hw == GM_CAM && enable_gas_interceptor && gm_bolt_2022_pedal && button == GM_BTN_CANCEL) {
if (gm_cc_long) { allowed_btn = true;
}
// For CC_LONG or PCM cruise vehicles, allow SET/RESUME when cruise is engaged
if (gm_cc_long || gm_pcm_cruise) {
allowed_btn |= cruise_engaged_prev && (button == GM_BTN_SET || button == GM_BTN_RESUME || button == GM_BTN_UNPRESS); allowed_btn |= cruise_engaged_prev && (button == GM_BTN_SET || button == GM_BTN_RESUME || button == GM_BTN_UNPRESS);
} }
@@ -256,6 +291,22 @@ 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; return tx;
} }
@@ -272,10 +323,20 @@ static int gm_fwd_hook(int bus_num, int addr) {
} }
if (bus_num == 2) { if (bus_num == 2) {
// block lkas message and acc messages if gm_cam_long, forward all others
bool is_lkas_msg = (addr == 0x180); bool is_lkas_msg = (addr == 0x180);
bool is_acc_msg = (addr == 0x315) || (addr == 0x2CB) || (addr == 0x370); bool block_msg = false;
bool block_msg = is_lkas_msg || (is_acc_msg && gm_cam_long); if (gm_bolt_2022_pedal) {
// Block 0x370 only for experimental long without pedal interceptor
bool is_acc_msg = (addr == 0x315) || (addr == 0x2CB);
if (gm_cam_long && !enable_gas_interceptor) {
is_acc_msg = is_acc_msg || (addr == 0x370);
}
block_msg = is_lkas_msg || (is_acc_msg && gm_cam_long);
} else {
// block lkas message and acc messages if gm_cam_long, forward all others
bool is_acc_msg = (addr == 0x315) || (addr == 0x2CB) || (addr == 0x370);
block_msg = is_lkas_msg || (is_acc_msg && gm_cam_long);
}
if (!block_msg) { if (!block_msg) {
bus_fwd = 0; bus_fwd = 0;
} }
@@ -286,30 +347,35 @@ static int gm_fwd_hook(int bus_num, int addr) {
} }
static safety_config gm_init(uint16_t param) { static safety_config gm_init(uint16_t param) {
if GET_FLAG(param, GM_PARAM_HW_CAM) { gm_ascm_int = GET_FLAG(param, GM_PARAM_ASCM_INT);
if (GET_FLAG(param, GM_PARAM_HW_CAM)) {
gm_hw = GM_CAM; gm_hw = GM_CAM;
} else if GET_FLAG(param, GM_PARAM_HW_SDGM) { } else if (GET_FLAG(param, GM_PARAM_HW_SDGM)) {
gm_hw = GM_SDGM; gm_hw = GM_SDGM;
} else { } else {
gm_hw = GM_ASCM; gm_hw = GM_ASCM;
} }
gm_force_ascm = GET_FLAG(param, GM_PARAM_HW_ASCM_LONG); gm_force_ascm = GET_FLAG(param, GM_PARAM_HW_ASCM_LONG);
gm_steer_limits = GET_FLAG(param, GM_PARAM_BOLT_2017) ? &GM_BOLT_2017_STEERING_LIMITS : &GM_STEERING_LIMITS;
if (gm_hw == GM_ASCM || gm_force_ascm) { if (gm_hw == GM_ASCM || gm_force_ascm || gm_ascm_int) {
gm_long_limits = &GM_ASCM_LONG_LIMITS; gm_long_limits = &GM_ASCM_LONG_LIMITS;
} else if ((gm_hw == GM_CAM) || (gm_hw == GM_SDGM)) { } else if ((gm_hw == GM_CAM) || (gm_hw == GM_SDGM)) {
gm_long_limits = &GM_CAM_LONG_LIMITS; gm_long_limits = &GM_CAM_LONG_LIMITS;
} else { } else {
} }
gm_pedal_long = GET_FLAG(param, GM_PARAM_PEDAL_LONG); gm_pedal_long = GET_FLAG(param, GM_PARAM_PEDAL_LONG);
gm_cc_long = GET_FLAG(param, GM_PARAM_CC_LONG); gm_cc_long = GET_FLAG(param, GM_PARAM_CC_LONG);
enable_gas_interceptor = GET_FLAG(param, GM_PARAM_PEDAL_INTERCEPTOR);
gm_cam_long = GET_FLAG(param, GM_PARAM_HW_CAM_LONG) && !gm_cc_long; gm_cam_long = GET_FLAG(param, GM_PARAM_HW_CAM_LONG) && !gm_cc_long;
gm_pcm_cruise = ((gm_hw == GM_CAM) && (!gm_cam_long || gm_cc_long) && !gm_force_ascm && !gm_pedal_long) || (gm_hw == GM_SDGM); gm_bolt_2022_pedal = GET_FLAG(param, GM_PARAM_BOLT_2022_PEDAL);
gm_pcm_cruise = (((gm_hw == GM_CAM) || (gm_hw == GM_SDGM)) && (!gm_cam_long || gm_cc_long) && !gm_force_ascm && !gm_pedal_long);
gm_skip_relay_check = GET_FLAG(param, GM_PARAM_NO_CAMERA); gm_skip_relay_check = GET_FLAG(param, GM_PARAM_NO_CAMERA);
gm_has_acc = !GET_FLAG(param, GM_PARAM_NO_ACC); gm_has_acc = !GET_FLAG(param, GM_PARAM_NO_ACC);
enable_gas_interceptor = GET_FLAG(param, GM_PARAM_PEDAL_INTERCEPTOR); gm_force_brake_c9 = GET_FLAG(param, GM_PARAM_FORCE_BRAKE_C9);
gm_remote_start_boots_comma = GET_FLAG(param, GM_PARAM_REMOTE_START_BOOTS_COMMA);
safety_config ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_ASCM_TX_MSGS); safety_config ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_ASCM_TX_MSGS);
if (gm_hw == GM_CAM) { if (gm_hw == GM_CAM) {
@@ -320,8 +386,6 @@ static safety_config gm_init(uint16_t param) {
} else { } else {
ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_CAM_TX_MSGS); ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_CAM_TX_MSGS);
} }
} else if (gm_hw == GM_SDGM) {
ret = BUILD_SAFETY_CFG(gm_rx_checks, GM_SDGM_TX_MSGS);
} }
return ret; return ret;
} }
+12 -7
View File
@@ -231,13 +231,18 @@ class Panda:
FLAG_GM_HW_CAM = 1 FLAG_GM_HW_CAM = 1
FLAG_GM_HW_CAM_LONG = 2 FLAG_GM_HW_CAM_LONG = 2
FLAG_GM_HW_SDGM = 4 FLAG_GM_CC_LONG = 4
FLAG_GM_CC_LONG = 8 FLAG_GM_HW_ASCM_LONG = 8
FLAG_GM_HW_ASCM_LONG = 16 FLAG_GM_NO_CAMERA = 16
FLAG_GM_NO_CAMERA = 32 FLAG_GM_NO_ACC = 32
FLAG_GM_NO_ACC = 64 FLAG_GM_PEDAL_LONG = 64 # TODO: This can be inferred
FLAG_GM_PEDAL_LONG = 128 # TODO: This can be inferred FLAG_GM_GAS_INTERCEPTOR = 128
FLAG_GM_GAS_INTERCEPTOR = 256 FLAG_GM_ASCM_INT = 256
FLAG_GM_FORCE_BRAKE_C9 = 512
FLAG_GM_HW_SDGM = 1024
FLAG_GM_BOLT_2017 = 2048
FLAG_GM_BOLT_2022_PEDAL = 4096
FLAG_GM_REMOTE_START_BOOTS_COMMA = 8192
FLAG_FORD_LONG_CONTROL = 1 FLAG_FORD_LONG_CONTROL = 1
FLAG_FORD_CANFD = 2 FLAG_FORD_CANFD = 2
+130
View File
@@ -11,12 +11,14 @@ from openpilot.selfdrive.car.fingerprints import eliminate_incompatible_cars, al
from openpilot.selfdrive.car.vin import get_vin, is_valid_vin, VIN_UNKNOWN from openpilot.selfdrive.car.vin import get_vin, is_valid_vin, VIN_UNKNOWN
from openpilot.selfdrive.car.fw_versions import get_fw_versions_ordered, get_present_ecus, match_fw_to_car, set_obd_multiplexing from openpilot.selfdrive.car.fw_versions import get_fw_versions_ordered, get_present_ecus, match_fw_to_car, set_obd_multiplexing
from openpilot.selfdrive.car.mock.values import CAR as MOCK from openpilot.selfdrive.car.mock.values import CAR as MOCK
from openpilot.selfdrive.car.gm.values import CAR as GM_CAR, CanBus as GMCanBus
from openpilot.common.swaglog import cloudlog from openpilot.common.swaglog import cloudlog
import cereal.messaging as messaging import cereal.messaging as messaging
from openpilot.selfdrive.car import gen_empty_fingerprint from openpilot.selfdrive.car import gen_empty_fingerprint
from openpilot.system.version import get_build_metadata from openpilot.system.version import get_build_metadata
FRAME_FINGERPRINT = 100 # 1s FRAME_FINGERPRINT = 100 # 1s
SOURCE_BRANCH_FILE = "/data/media/0/starpilot_source_branch"
EventName = car.CarEvent.EventName EventName = car.CarEvent.EventName
FrogPilotEventName = custom.FrogPilotCarEvent.EventName FrogPilotEventName = custom.FrogPilotCarEvent.EventName
@@ -188,6 +190,64 @@ def get_car_interface(CP, FPCP):
CarInterface, CarController, CarState = interfaces[CP.carFingerprint] CarInterface, CarController, CarState = interfaces[CP.carFingerprint]
return CarInterface(CP, FPCP, CarController, CarState) return CarInterface(CP, FPCP, CarController, CarState)
def get_cached_car_fingerprint(params: Params) -> str | None:
for key in ("CarParamsPersistent", "CarParamsCache", "CarParams"):
cp_bytes = params.get(key)
if cp_bytes is None:
continue
try:
with car.CarParams.from_bytes(cp_bytes) as cached_cp:
if cached_cp.carFingerprint:
return cached_cp.carFingerprint
except Exception:
continue
return None
def clear_stale_car_params(params: Params, candidate: str) -> None:
cached_fingerprint = get_cached_car_fingerprint(params)
if cached_fingerprint is None or cached_fingerprint == candidate:
return
stale_keys = (
"CarParams",
"CarParamsCache",
"CarParamsPersistent",
"FrogPilotCarParams",
"FrogPilotCarParamsPersistent",
"CarModelName",
)
for key in stale_keys:
params.remove(key)
cloudlog.warning("cleared stale car params after fingerprint change: %s -> %s", cached_fingerprint, candidate)
def migrate_legacy_bolt_candidate(candidate: str) -> str:
source_branch = ""
try:
with open(SOURCE_BRANCH_FILE, encoding="utf-8") as f:
source_branch = f.read().strip()
except OSError:
pass
migration_branch = source_branch or get_build_metadata().channel
replacements = {}
if migration_branch in {"TorqueTune", "TorquePedal"}:
replacements = {
"CHEVROLET_BOLT_EUV": GM_CAR.CHEVROLET_BOLT_ACC_2022_2023,
"CHEVROLET_BOLT_CC": GM_CAR.CHEVROLET_BOLT_CC_2022_2023,
}
elif migration_branch in {"TotallyTune", "StarPilot-2017", "StarPilot 2017"}:
replacements = {
"CHEVROLET_BOLT_CC": GM_CAR.CHEVROLET_BOLT_CC_2017,
}
elif migration_branch in {"StarPilot"}:
replacements = {
"CHEVROLET_BOLT_CC": GM_CAR.CHEVROLET_BOLT_CC_2019_2021,
}
normalized_candidate = candidate[4:] if candidate.startswith("CAR.") else candidate
return replacements.get(normalized_candidate, normalized_candidate)
def get_car(logcan, sendcan, experimental_long_allowed, params, num_pandas=1, frogpilot_toggles=None): def get_car(logcan, sendcan, experimental_long_allowed, params, num_pandas=1, frogpilot_toggles=None):
candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(logcan, sendcan, num_pandas) candidate, fingerprints, vin, car_fw, source, exact_match = fingerprint(logcan, sendcan, num_pandas)
@@ -202,10 +262,80 @@ def get_car(logcan, sendcan, experimental_long_allowed, params, num_pandas=1, fr
params.put_nonblocking("CarMake", candidate.split('_')[0].title()) params.put_nonblocking("CarMake", candidate.split('_')[0].title())
params.put_nonblocking("CarModel", candidate) params.put_nonblocking("CarModel", candidate)
# Branch migration can leave legacy Bolt candidate names active in params/cache.
# Remap the selected candidate itself so fingerprint selection and params stay in sync.
migrated_candidate = migrate_legacy_bolt_candidate(candidate)
if candidate != migrated_candidate:
cloudlog.warning("legacy Bolt candidate migration: %s -> %s", candidate, migrated_candidate)
candidate = migrated_candidate
params.put_nonblocking("CarMake", candidate.split('_')[0].title())
params.put_nonblocking("CarModel", candidate)
params.remove("CarModelName")
# VIN-based Bolt year mapping (selfdrive-only, bolt variants only)
if not frogpilot_toggles.force_fingerprint and is_valid_vin(vin):
bolt_variants = {
"CHEVROLET_BOLT_EUV",
"CHEVROLET_BOLT_CC",
"CAR.CHEVROLET_BOLT_EUV",
"CAR.CHEVROLET_BOLT_CC",
GM_CAR.CHEVROLET_BOLT_ACC_2022_2023,
GM_CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL,
GM_CAR.CHEVROLET_BOLT_CC_2022_2023,
GM_CAR.CHEVROLET_BOLT_CC_2019_2021,
GM_CAR.CHEVROLET_BOLT_CC_2017,
}
if candidate in bolt_variants:
year_code = vin[9:10]
year_map = {
"H": GM_CAR.CHEVROLET_BOLT_CC_2017, # 2017
"J": GM_CAR.CHEVROLET_BOLT_CC_2019_2021, # 2018
"K": GM_CAR.CHEVROLET_BOLT_CC_2019_2021, # 2019
"L": GM_CAR.CHEVROLET_BOLT_CC_2019_2021, # 2020
"M": GM_CAR.CHEVROLET_BOLT_CC_2019_2021, # 2021
"N": GM_CAR.CHEVROLET_BOLT_ACC_2022_2023, # 2022
"P": GM_CAR.CHEVROLET_BOLT_ACC_2022_2023, # 2023
}
if year_code in year_map:
vin_candidate = year_map[year_code]
if vin_candidate == GM_CAR.CHEVROLET_BOLT_ACC_2022_2023:
has_acc_msg = (
0x370 in fingerprints.get(GMCanBus.CAMERA, {}) or
0x370 in fingerprints.get(GMCanBus.POWERTRAIN, {})
)
has_pedal_msg = 0x201 in fingerprints.get(GMCanBus.POWERTRAIN, {})
if has_acc_msg:
vin_candidate = GM_CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL if has_pedal_msg else GM_CAR.CHEVROLET_BOLT_ACC_2022_2023
else:
vin_candidate = GM_CAR.CHEVROLET_BOLT_CC_2022_2023
if candidate != vin_candidate:
prev_candidate = candidate
candidate = vin_candidate
params.put_nonblocking("CarMake", candidate.split('_')[0].title())
params.put_nonblocking("CarModel", candidate)
params.remove("CarModelName")
cloudlog.warning("VIN Bolt override: %s -> %s", prev_candidate, candidate)
# Always prefer live fingerprint naming for Bolt variants to avoid stale manual labels.
if candidate in {
GM_CAR.CHEVROLET_BOLT_ACC_2022_2023,
GM_CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL,
GM_CAR.CHEVROLET_BOLT_CC_2022_2023,
GM_CAR.CHEVROLET_BOLT_CC_2019_2021,
GM_CAR.CHEVROLET_BOLT_CC_2017,
"CHEVROLET_BOLT_EUV",
"CHEVROLET_BOLT_CC",
"CAR.CHEVROLET_BOLT_EUV",
"CAR.CHEVROLET_BOLT_CC",
}:
params.remove("CarModelName")
if frogpilot_toggles.block_user: if frogpilot_toggles.block_user:
candidate = MOCK.MOCK candidate = MOCK.MOCK
sentry.capture_block() sentry.capture_block()
clear_stale_car_params(params, candidate)
CarInterface, _, _ = interfaces[candidate] CarInterface, _, _ = interfaces[candidate]
CP = CarInterface.get_params(candidate, fingerprints, car_fw, experimental_long_allowed, frogpilot_toggles, docs=False) CP = CarInterface.get_params(candidate, fingerprints, car_fw, experimental_long_allowed, frogpilot_toggles, docs=False)
FPCP = CarInterface.get_frogpilot_params(candidate, fingerprints, car_fw, CP, frogpilot_toggles) FPCP = CarInterface.get_frogpilot_params(candidate, fingerprints, car_fw, CP, frogpilot_toggles)
+1 -1
View File
@@ -158,7 +158,7 @@ MIGRATION = {
"CADILLAC ESCALADE 2017": GM.CADILLAC_ESCALADE, "CADILLAC ESCALADE 2017": GM.CADILLAC_ESCALADE,
"CADILLAC ESCALADE ESV 2016": GM.CADILLAC_ESCALADE_ESV, "CADILLAC ESCALADE ESV 2016": GM.CADILLAC_ESCALADE_ESV,
"CADILLAC ESCALADE ESV 2019": GM.CADILLAC_ESCALADE_ESV_2019, "CADILLAC ESCALADE ESV 2019": GM.CADILLAC_ESCALADE_ESV_2019,
"CHEVROLET BOLT EUV 2022": GM.CHEVROLET_BOLT_EUV, "CHEVROLET BOLT EUV 2022": GM.CHEVROLET_BOLT_ACC_2022_2023,
"CHEVROLET SILVERADO 1500 2020": GM.CHEVROLET_SILVERADO, "CHEVROLET SILVERADO 1500 2020": GM.CHEVROLET_SILVERADO,
"CHEVROLET EQUINOX 2019": GM.CHEVROLET_EQUINOX, "CHEVROLET EQUINOX 2019": GM.CHEVROLET_EQUINOX,
"CHEVROLET TRAILBLAZER 2021": GM.CHEVROLET_TRAILBLAZER, "CHEVROLET TRAILBLAZER 2021": GM.CHEVROLET_TRAILBLAZER,
+376 -50
View File
@@ -1,3 +1,7 @@
from typing import Tuple
import time
import math
from openpilot.common.swaglog import cloudlog
from cereal import car from cereal import car
from openpilot.common.conversions import Conversions as CV from openpilot.common.conversions import Conversions as CV
from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.filter_simple import FirstOrderFilter
@@ -7,10 +11,11 @@ from openpilot.common.params_pyx import Params
from opendbc.can.packer import CANPacker from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import apply_driver_steer_torque_limits, create_gas_interceptor_command 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 import gmcan
from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, CarControllerParams, CruiseButtons, GMFlags, CC_ONLY_CAR, SDGM_CAR, EV_CAR from openpilot.selfdrive.car.gm.values import CAR, DBC, AccState, CanBus, CarControllerParams, CruiseButtons, GMFlags, CC_ONLY_CAR, SDGM_CAR, ASCM_INT, EV_CAR, CC_REGEN_PADDLE_CAR
from openpilot.selfdrive.car.interfaces import CarControllerBase from openpilot.selfdrive.car.interfaces import CarControllerBase
from openpilot.selfdrive.controls.lib.drive_helpers import apply_deadzone from openpilot.selfdrive.controls.lib.drive_helpers import apply_deadzone
from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY
from openpilot.common.swaglog import cloudlog
VisualAlert = car.CarControl.HUDControl.VisualAlert VisualAlert = car.CarControl.HUDControl.VisualAlert
NetworkLocation = car.CarParams.NetworkLocation NetworkLocation = car.CarParams.NetworkLocation
@@ -22,7 +27,15 @@ TransmissionType = car.CarParams.TransmissionType
CAMERA_CANCEL_DELAY_FRAMES = 10 CAMERA_CANCEL_DELAY_FRAMES = 10
# Enforce a minimum interval between steering messages to avoid a fault # Enforce a minimum interval between steering messages to avoid a fault
MIN_STEER_MSG_INTERVAL_MS = 15 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 # Constants for pitch compensation
BRAKE_PITCH_FACTOR_BP = [5., 10.] # [m/s] smoothly revert to planned accel at low speeds 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 BRAKE_PITCH_FACTOR_V = [0., 1.] # [unitless in [0,1]]; don't touch
@@ -38,6 +51,11 @@ class CarController(CarControllerBase):
self.apply_speed = 0 self.apply_speed = 0
self.frame = 0 self.frame = 0
self.last_steer_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.last_button_frame = 0
self.cancel_counter = 0 self.cancel_counter = 0
self.pedal_steady = 0. self.pedal_steady = 0.
@@ -46,35 +64,126 @@ class CarController(CarControllerBase):
self.lka_icon_status_last = (False, False) self.lka_icon_status_last = (False, False)
self.params = CarControllerParams(self.CP) self.params = CarControllerParams(self.CP)
self.is_volt = self.CP.carFingerprint in (CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_2019, CAR.CHEVROLET_VOLT_ASCM, CAR.CHEVROLET_VOLT_CAMERA, CAR.CHEVROLET_VOLT_CC)
self.pedal_scale = 1.0
self.params_ = Params() self.params_ = Params()
self.mass = CP.mass
self.tireRadius = 0.075 * CP.wheelbase + 0.1453
self.frontalArea = 1.05 * CP.wheelbase + 0.0679
self.coeffDrag = 0.30
self.airDensity = 1.225
self.malibu_cancel_phase = 0
self.malibu_cancel_last_ts = 0.0
self.malibu_cancel_frame = 0
self.malibu_button_phase = 0
self.packer_pt = CANPacker(DBC[self.CP.carFingerprint]['pt']) self.packer_pt = CANPacker(DBC[self.CP.carFingerprint]['pt'])
self.packer_obj = CANPacker(DBC[self.CP.carFingerprint]['radar']) self.packer_obj = CANPacker(DBC[self.CP.carFingerprint]['radar'])
self.packer_ch = CANPacker(DBC[self.CP.carFingerprint]['chassis']) self.packer_ch = CANPacker(DBC[self.CP.carFingerprint]['chassis'])
# FrogPilot variables # FrogPilot variables
self.accel_g = 0.0 self.accel_g = 0.0
self.pitch = FirstOrderFilter(0., 0.09 * 4, DT_CTRL * 4) # runs at 25 Hz 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
return pedal_gas # 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
def update(self, CC, CS, now_nanos, frogpilot_toggles): def update(self, CC, CS, now_nanos, frogpilot_toggles):
self.CS = CS
self.aego = CS.out.aEgo
actuators = CC.actuators actuators = CC.actuators
accel = brake_accel = actuators.accel accel = brake_accel = actuators.accel
press_regen_paddle = False
kaofui_cars = SDGM_CAR | ASCM_INT | {
CAR.CHEVROLET_VOLT,
CAR.CHEVROLET_VOLT_2019,
CAR.CHEVROLET_VOLT_ASCM,
CAR.CHEVROLET_VOLT_CAMERA,
CAR.CHEVROLET_VOLT_CC,
CAR.CHEVROLET_MALIBU_CC,
CAR.CHEVROLET_MALIBU_HYBRID_CC,
}
volt_like = {
CAR.CHEVROLET_VOLT,
CAR.CHEVROLET_VOLT_2019,
CAR.CHEVROLET_VOLT_ASCM,
CAR.CHEVROLET_VOLT_CAMERA,
CAR.CHEVROLET_VOLT_CC,
}
# 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_control = CC.hudControl
hud_alert = hud_control.visualAlert hud_alert = hud_control.visualAlert
hud_v_cruise = hud_control.setSpeed hud_v_cruise = hud_control.setSpeed
@@ -83,6 +192,129 @@ class CarController(CarControllerBase):
# Send CAN commands. # Send CAN commands.
can_sends = [] can_sends = []
paddle_sends = []
if self.CP.carFingerprint == CAR.CHEVROLET_MALIBU_HYBRID_CC:
phase_map = gmcan.malibu_phase_map_for_acc(CS.cruise_buttons)
if phase_map and CS.steering_button_checksum in phase_map:
phase = (phase_map[CS.steering_button_checksum] + 1) % 4
self.malibu_cancel_phase = phase
self.malibu_button_phase = phase
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
# 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, self.CP))
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
# 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, self.CP))
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):
# 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, self.CP))
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) # Steering (Active: 50Hz, inactive: 10Hz)
steer_step = self.params.STEER_STEP if CC.latActive else self.params.INACTIVE_STEER_STEP steer_step = self.params.STEER_STEP if CC.latActive else self.params.INACTIVE_STEER_STEP
@@ -112,24 +344,35 @@ class CarController(CarControllerBase):
else: else:
apply_steer = 0 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.last_steer_frame = self.frame
self.apply_steer_last = apply_steer self.apply_steer_last = apply_steer
idx = self.lka_steering_cmd_counter % 4 idx = self.lka_steering_cmd_counter % 4
can_sends.append(gmcan.create_steering_control(self.packer_pt, CanBus.POWERTRAIN, apply_steer, idx, CC.latActive)) 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: if self.CP.openpilotLongitudinalControl:
# Gas/regen, brakes, and UI commands - all at 25Hz # Gas/regen, brakes, and UI commands - all at 25Hz
if self.frame % 4 == 0: if self.frame % 4 == 0:
stopping = actuators.longControlState == LongCtrlState.stopping stopping = actuators.longControlState == LongCtrlState.stopping
# Pitch compensated acceleration;
# TODO: include future pitch (sm['modelDataV2'].orientation.y) to account for long actuator delay
if frogpilot_toggles.long_pitch and len(CC.orientationNED) > 1:
self.pitch.update(CC.orientationNED[1])
self.accel_g = ACCELERATION_DUE_TO_GRAVITY * apply_deadzone(self.pitch.x, PITCH_DEADZONE) # driving uphill is positive pitch
accel += self.accel_g
brake_accel = actuators.accel + self.accel_g * interp(CS.out.vEgo, BRAKE_PITCH_FACTOR_BP, BRAKE_PITCH_FACTOR_V)
at_full_stop = CC.longActive and CS.out.standstill at_full_stop = CC.longActive and CS.out.standstill
near_stop = CC.longActive and (CS.out.vEgo < self.params.NEAR_STOP_BRAKE_PHASE) near_stop = CC.longActive and (CS.out.vEgo < self.params.NEAR_STOP_BRAKE_PHASE)
interceptor_gas_cmd = 0 interceptor_gas_cmd = 0
@@ -141,21 +384,61 @@ class CarController(CarControllerBase):
self.apply_gas = self.params.INACTIVE_REGEN self.apply_gas = self.params.INACTIVE_REGEN
self.apply_brake = int(min(-100 * frogpilot_toggles.stopAccel, self.params.MAX_BRAKE)) self.apply_brake = int(min(-100 * frogpilot_toggles.stopAccel, self.params.MAX_BRAKE))
else: else:
# Normal operation if self.is_volt:
if self.CP.carFingerprint in EV_CAR: if len(CC.orientationNED) == 3 and CS.out.vEgo > self.CP.vEgoStopping:
self.params.update_ev_gas_brake_threshold(CS.out.vEgo) volt_pitch_accel = math.sin(CC.orientationNED[1]) * ACCELERATION_DUE_TO_GRAVITY
self.apply_gas = int(round(interp(accel, self.params.EV_GAS_LOOKUP_BP, self.params.GAS_LOOKUP_V))) else:
self.apply_brake = int(round(interp(brake_accel, self.params.EV_BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V))) volt_pitch_accel = 0.0
aero_drag_accel = (0.5 * self.coeffDrag * self.frontalArea * self.airDensity * CS.out.vEgo ** 2) / self.mass
accel += aero_drag_accel + volt_pitch_accel
brake_accel = actuators.accel + aero_drag_accel + volt_pitch_accel * interp(CS.out.vEgo, BRAKE_PITCH_FACTOR_BP, BRAKE_PITCH_FACTOR_V)
accel = clip(accel, self.params.ACCEL_MIN, self.params.ACCEL_MAX)
brake_accel = clip(brake_accel, self.params.ACCEL_MIN, self.params.ACCEL_MAX)
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)))
# Clamp within message-valid ranges to avoid ASCM faults from overshoot or rounding
self.apply_gas = int(round(clip(self.apply_gas, self.params.MAX_ACC_REGEN, self.params.MAX_GAS)))
self.apply_brake = int(round(clip(self.apply_brake, 0, self.params.MAX_BRAKE)))
if self.apply_brake > 0:
# Volt should never present positive torque alongside friction braking
self.apply_gas = self.params.INACTIVE_REGEN
else: else:
self.apply_gas = int(round(interp(accel, self.params.GAS_LOOKUP_BP, self.params.GAS_LOOKUP_V))) if len(CC.orientationNED) == 3 and CS.out.vEgo > self.CP.vEgoStopping:
accel_due_to_pitch = math.sin(CC.orientationNED[1]) * ACCELERATION_DUE_TO_GRAVITY
else:
accel_due_to_pitch = 0.0
gas_max = self.params.MAX_GAS
accel_max = self.params.ACCEL_MAX
accel = clip(actuators.accel + accel_due_to_pitch, self.params.ACCEL_MIN, accel_max)
torque = self.tireRadius * ((self.mass*accel) + (0.5*self.coeffDrag*self.frontalArea*self.airDensity*CS.out.vEgo**2))
scaled_torque = torque + self.params.ZERO_GAS
apply_gas_torque = clip(scaled_torque, self.params.MAX_ACC_REGEN, gas_max)
BRAKE_SWITCH = int(round(interp(CS.out.vEgo, self.params.BRAKE_SWITCH_LOOKUP_BP, self.params.BRAKE_SWITCH_LOOKUP_V)))
brake_accel = min((scaled_torque - BRAKE_SWITCH)/(self.tireRadius*self.mass), 0)
self.apply_gas = int(round(apply_gas_torque))
self.apply_brake = int(round(interp(brake_accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V))) self.apply_brake = int(round(interp(brake_accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V)))
if self.apply_brake > 0:
self.apply_gas = self.params.INACTIVE_REGEN
# Don't allow any gas above inactive regen while stopping # Don't allow any gas above inactive regen while stopping
# FIXME: brakes aren't applied immediately when enabling at a stop # FIXME: brakes aren't applied immediately when enabling at a stop
if stopping: if stopping:
self.apply_gas = self.params.INACTIVE_REGEN self.apply_gas = self.params.INACTIVE_REGEN
if self.CP.carFingerprint in CC_ONLY_CAR: if self.CP.carFingerprint in CC_ONLY_CAR:
# gas interceptor only used for full long control on cars without ACC # gas interceptor only used for full long control on cars without ACC
interceptor_gas_cmd = self.calc_pedal_command(actuators.accel, CC.longActive) interceptor_gas_cmd, press_regen_paddle = self.calc_pedal_command(actuators.accel, CC.longActive, CS.out.vEgo)
if self.CP.enableGasInterceptor and self.apply_gas > self.params.INACTIVE_REGEN and CS.out.cruiseState.standstill: 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 # "Tap" the accelerator pedal to re-engage ACC
@@ -168,7 +451,16 @@ class CarController(CarControllerBase):
if self.CP.flags & GMFlags.CC_LONG.value: if self.CP.flags & GMFlags.CC_LONG.value:
if CC.longActive and CS.out.cruiseState.enabled and CS.out.vEgo > self.CP.minEnableSpeed: 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 # 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)) 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):
if self.CP.carFingerprint == CAR.CHEVROLET_MALIBU_HYBRID_CC:
can_sends.append(gmcan.create_buttons_malibu(
self.packer_pt, CanBus.POWERTRAIN, CruiseButtons.DECEL_SET,
self.malibu_button_phase, CS.steering_button_prefix))
self.malibu_button_phase = (self.malibu_button_phase + 1) % 4
else:
can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, (CS.buttons_counter + 1) % 4, CruiseButtons.DECEL_SET))
if self.CP.enableGasInterceptor: if self.CP.enableGasInterceptor:
can_sends.append(create_gas_interceptor_command(self.packer_pt, interceptor_gas_cmd, idx)) can_sends.append(create_gas_interceptor_command(self.packer_pt, interceptor_gas_cmd, idx))
if self.CP.carFingerprint not in CC_ONLY_CAR: if self.CP.carFingerprint not in CC_ONLY_CAR:
@@ -178,6 +470,8 @@ class CarController(CarControllerBase):
if self.CP.networkLocation == NetworkLocation.fwdCamera and self.CP.carFingerprint not in CC_ONLY_CAR: if self.CP.networkLocation == NetworkLocation.fwdCamera and self.CP.carFingerprint not in CC_ONLY_CAR:
at_full_stop = at_full_stop and stopping at_full_stop = at_full_stop and stopping
friction_brake_bus = CanBus.POWERTRAIN friction_brake_bus = CanBus.POWERTRAIN
if self.CP.carFingerprint in SDGM_CAR:
friction_brake_bus = CanBus.CAMERA
if self.CP.autoResumeSng: if self.CP.autoResumeSng:
resume = actuators.longControlState != LongCtrlState.starting or CC.cruiseControl.resume resume = actuators.longControlState != LongCtrlState.starting or CC.cruiseControl.resume
@@ -189,9 +483,10 @@ class CarController(CarControllerBase):
acc_engaged = CC.enabled acc_engaged = CC.enabled
# GasRegenCmdActive needs to be 1 to avoid cruise faults. It describes the ACC state, not actuation # 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_gas_regen_command(self.packer_pt, CanBus.POWERTRAIN, self.apply_gas, idx, acc_engaged, at_full_stop,
include_always_one3=self.CP.carFingerprint in kaofui_cars))
can_sends.append(gmcan.create_friction_brake_command(self.packer_ch, friction_brake_bus, self.apply_brake, 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 dashboard UI commands (ACC status)
send_fcw = hud_alert == VisualAlert.fcw send_fcw = hud_alert == VisualAlert.fcw
@@ -202,32 +497,57 @@ class CarController(CarControllerBase):
accel += self.accel_g accel += self.accel_g
# Radar needs to know current speed and yaw rate (50hz), # Radar needs to know current speed and yaw rate (50hz),
# and that ADAS is alive (10hz) # and that ADAS is alive (5hz, previously 10hz)
if not self.CP.radarUnavailable: if not self.CP.radarUnavailable:
tt = self.frame * DT_CTRL send_adas = True
time_and_headlights_step = 10 if self.CP.carFingerprint in kaofui_cars:
if self.frame % time_and_headlights_step == 0: send_adas = (self.CP.networkLocation != NetworkLocation.fwdCamera) and (self.CP.carFingerprint not in SDGM_CAR)
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 send_adas:
if self.frame % speed_and_accelerometer_step == 0: tt = self.frame * DT_CTRL
idx = (self.frame // speed_and_accelerometer_step) % 4 if self.CP.carFingerprint in kaofui_cars:
can_sends.append(gmcan.create_adas_steering_status(CanBus.OBSTACLE, idx)) time_and_headlights_step = 10
can_sends.append(gmcan.create_adas_accelerometer_speed_status(CanBus.OBSTACLE, CS.out.vEgo, idx)) speed_and_accelerometer_step = 2
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))
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))
else:
time_and_headlights_step = 20
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))
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 == 0: if self.CP.networkLocation == NetworkLocation.gateway and (self.frame % (self.params.ADAS_KEEPALIVE_STEP if self.CP.carFingerprint in kaofui_cars else self.params.ADAS_KEEPALIVE_STEP * 2)) == 0:
can_sends += gmcan.create_adas_keepalive(CanBus.POWERTRAIN) can_sends += gmcan.create_adas_keepalive(CanBus.POWERTRAIN)
# TODO: integrate this with the code block below? # TODO: integrate this with the code block below?
stock_cc_active = CS.out.cruiseState.enabled or CS.pcm_acc_status != AccState.OFF
if self.CP.carFingerprint == CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL:
stock_cc_active = CS.out.cruiseState.enabled
if ( if (
(self.CP.flags & GMFlags.PEDAL_LONG.value) # Always cancel stock CC when using pedal interceptor (self.CP.flags & GMFlags.PEDAL_LONG.value) # Always cancel stock CC when using pedal interceptor
or (self.CP.flags & GMFlags.CC_LONG.value and not CC.enabled) # Cancel stock CC if OP is not active or (self.CP.flags & GMFlags.CC_LONG.value and not CC.enabled) # Cancel stock CC if OP is not active
) and CS.out.cruiseState.enabled: ) and stock_cc_active:
if (self.frame - self.last_button_frame) * DT_CTRL > 0.04: if self.CP.carFingerprint == CAR.CHEVROLET_MALIBU_HYBRID_CC:
self.last_button_frame = self.frame # Match 33 Hz cadence (every 3 frames) and align phase to the last seen checksum.
can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, (CS.buttons_counter + 1) % 4, CruiseButtons.CANCEL)) if self.malibu_cancel_frame % 3 == 0:
can_sends.append(gmcan.create_buttons_malibu_cancel(
CanBus.POWERTRAIN, self.malibu_cancel_phase, CS.steering_button_prefix))
self.malibu_cancel_phase = (self.malibu_cancel_phase + 1) % 4
self.malibu_cancel_frame += 1
else:
if (self.frame - self.last_button_frame) * DT_CTRL > 0.04:
self.last_button_frame = self.frame
cancel_bus = CanBus.CAMERA if self.CP.carFingerprint == CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL else CanBus.POWERTRAIN
can_sends.append(gmcan.create_buttons(self.packer_pt, cancel_bus, (CS.buttons_counter + 1) % 4, CruiseButtons.CANCEL))
else: else:
# While car is braking, cancel button causes ECM to enter a soft disable state with a fault status. # While car is braking, cancel button causes ECM to enter a soft disable state with a fault status.
@@ -238,7 +558,13 @@ class CarController(CarControllerBase):
if (self.frame - self.last_button_frame) * DT_CTRL > 0.04: if (self.frame - self.last_button_frame) * DT_CTRL > 0.04:
if self.cancel_counter > CAMERA_CANCEL_DELAY_FRAMES: if self.cancel_counter > CAMERA_CANCEL_DELAY_FRAMES:
self.last_button_frame = self.frame self.last_button_frame = self.frame
if self.CP.carFingerprint in SDGM_CAR: if self.CP.carFingerprint == CAR.CHEVROLET_MALIBU_HYBRID_CC:
if self.malibu_cancel_frame % 3 == 0:
can_sends.append(gmcan.create_buttons_malibu_cancel(
CanBus.POWERTRAIN, self.malibu_cancel_phase, CS.steering_button_prefix))
self.malibu_cancel_phase = (self.malibu_cancel_phase + 1) % 4
self.malibu_cancel_frame += 1
elif self.CP.carFingerprint in SDGM_CAR and self.CP.carFingerprint not in (volt_like | {CAR.CHEVROLET_BLAZER, CAR.CHEVROLET_MALIBU_SDGM, CAR.CHEVROLET_TRAVERSE}):
can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, CS.buttons_counter, CruiseButtons.CANCEL)) can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, CS.buttons_counter, CruiseButtons.CANCEL))
else: else:
can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.CAMERA, CS.buttons_counter, CruiseButtons.CANCEL)) can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.CAMERA, CS.buttons_counter, CruiseButtons.CANCEL))
+86 -21
View File
@@ -5,7 +5,7 @@ from openpilot.common.numpy_fast import mean
from opendbc.can.can_define import CANDefine from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser from opendbc.can.parser import CANParser
from openpilot.selfdrive.car.interfaces import CarStateBase 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 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, ASCM_INT, CAR
TransmissionType = car.CarParams.TransmissionType TransmissionType = car.CarParams.TransmissionType
NetworkLocation = car.CarParams.NetworkLocation NetworkLocation = car.CarParams.NetworkLocation
@@ -26,6 +26,8 @@ class CarState(CarStateBase):
self.pt_lka_steering_cmd_counter = 0 self.pt_lka_steering_cmd_counter = 0
self.cam_lka_steering_cmd_counter = 0 self.cam_lka_steering_cmd_counter = 0
self.buttons_counter = 0 self.buttons_counter = 0
self.steering_button_checksum = 0
self.steering_button_prefix = 0x01
self.prev_distance_button = 0 self.prev_distance_button = 0
self.distance_button = 0 self.distance_button = 0
@@ -36,13 +38,25 @@ class CarState(CarStateBase):
def update(self, pt_cp, cam_cp, loopback_cp, frogpilot_toggles): def update(self, pt_cp, cam_cp, loopback_cp, frogpilot_toggles):
ret = car.CarState.new_message() ret = car.CarState.new_message()
fp_ret = custom.FrogPilotCarState.new_message() fp_ret = custom.FrogPilotCarState.new_message()
volt_like = {CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_2019, CAR.CHEVROLET_VOLT_ASCM, CAR.CHEVROLET_VOLT_CAMERA, CAR.CHEVROLET_VOLT_CC}
kaofui_state_cars = volt_like | SDGM_CAR | ASCM_INT | {
CAR.CHEVROLET_BLAZER,
CAR.CHEVROLET_MALIBU_SDGM,
CAR.CHEVROLET_MALIBU_HYBRID_CC,
}
sdgm_non_volt = self.CP.carFingerprint in SDGM_CAR and \
self.CP.carFingerprint not in kaofui_state_cars
self.prev_cruise_buttons = self.cruise_buttons self.prev_cruise_buttons = self.cruise_buttons
self.prev_distance_button = self.distance_button self.prev_distance_button = self.distance_button
if self.CP.carFingerprint not in SDGM_CAR: if not sdgm_non_volt:
self.cruise_buttons = pt_cp.vl["ASCMSteeringButton"]["ACCButtons"] self.cruise_buttons = pt_cp.vl["ASCMSteeringButton"]["ACCButtons"]
self.distance_button = pt_cp.vl["ASCMSteeringButton"]["DistanceButton"] self.distance_button = pt_cp.vl["ASCMSteeringButton"]["DistanceButton"]
self.buttons_counter = pt_cp.vl["ASCMSteeringButton"]["RollingCounter"] self.buttons_counter = pt_cp.vl["ASCMSteeringButton"]["RollingCounter"]
self.steering_button_checksum = pt_cp.vl["ASCMSteeringButton"]["SteeringButtonChecksum"]
acc_always_one = pt_cp.vl["ASCMSteeringButton"]["ACCAlwaysOne"]
acc_hidden_bit = pt_cp.vl["ASCMSteeringButton"].get("ACCHiddenBit", 0)
self.steering_button_prefix = (int(acc_always_one) & 1) | ((int(acc_hidden_bit) & 1) << 6)
else: else:
self.cruise_buttons = cam_cp.vl["ASCMSteeringButton"]["ACCButtons"] self.cruise_buttons = cam_cp.vl["ASCMSteeringButton"]["ACCButtons"]
self.distance_button = cam_cp.vl["ASCMSteeringButton"]["DistanceButton"] self.distance_button = cam_cp.vl["ASCMSteeringButton"]["DistanceButton"]
@@ -56,6 +70,13 @@ class CarState(CarStateBase):
self.loopback_lka_steering_cmd_updated = len(loopback_cp.vl_all["ASCMLKASteeringCmd"]["RollingCounter"]) > 0 self.loopback_lka_steering_cmd_updated = len(loopback_cp.vl_all["ASCMLKASteeringCmd"]["RollingCounter"]) > 0
if self.loopback_lka_steering_cmd_updated: if self.loopback_lka_steering_cmd_updated:
self.loopback_lka_steering_cmd_ts_nanos = loopback_cp.ts_nanos["ASCMLKASteeringCmd"]["RollingCounter"] 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: 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.pt_lka_steering_cmd_counter = pt_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"]
self.cam_lka_steering_cmd_counter = cam_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"] self.cam_lka_steering_cmd_counter = cam_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"]
@@ -77,26 +98,42 @@ class CarState(CarStateBase):
ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(pt_cp.vl["ECMPRDNL2"]["PRNDL2"], None)) 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: if self.CP.flags & GMFlags.NO_ACCELERATOR_POS_MSG.value:
ret.brake = pt_cp.vl["EBCMBrakePedalPosition"]["BrakePedalPosition"] / 0xd0 if self.CP.carFingerprint in kaofui_state_cars:
ret.brake = pt_cp.vl.get("EBCMBrakePedalPosition", {}).get("BrakePedalPosition", 0) / 0xd0
else:
ret.brake = pt_cp.vl["EBCMBrakePedalPosition"]["BrakePedalPosition"] / 0xd0
else: else:
ret.brake = pt_cp.vl["ECMAcceleratorPos"]["BrakePedalPos"] if self.CP.carFingerprint in kaofui_state_cars:
if self.CP.networkLocation == NetworkLocation.fwdCamera: ret.brake = pt_cp.vl.get("ECMAcceleratorPos", {}).get("BrakePedalPos", 0)
else:
ret.brake = pt_cp.vl["ECMAcceleratorPos"]["BrakePedalPos"]
if self.CP.carFingerprint == CAR.CHEVROLET_BLAZER:
# Blazer can miss light taps on analog threshold; include digital brake switch.
ret.brakePressed = (pt_cp.vl["ECMEngineStatus"]["BrakePressed"] != 0) or (ret.brake >= 0.7)
elif self.CP.carFingerprint == CAR.CHEVROLET_MALIBU_CC:
# Malibu CC: keep strict opgm behavior using BrakePedalPos >= 8.
ret.brakePressed = ret.brake >= 8
elif (self.CP.flags & GMFlags.FORCE_BRAKE_C9.value) or (self.CP.networkLocation == NetworkLocation.fwdCamera):
ret.brakePressed = pt_cp.vl["ECMEngineStatus"]["BrakePressed"] != 0 ret.brakePressed = pt_cp.vl["ECMEngineStatus"]["BrakePressed"] != 0
else: else:
# Some Volt 2016-17 have loose brake pedal push rod retainers which causes the ECM to believe # Some Volt 2016-17 have loose brake pedal push rod retainers which causes the ECM to believe
# that the brake is being intermittently pressed without user interaction. # that the brake is being intermittently pressed without user interaction.
# To avoid a cruise fault we need to use a conservative brake position threshold # To avoid a cruise fault we need to use a conservative brake position threshold
# https://static.nhtsa.gov/odi/tsbs/2017/MC-10137629-9999.pdf # https://static.nhtsa.gov/odi/tsbs/2017/MC-10137629-9999.pdf
ret.brakePressed = ret.brake >= 8 analog_thresh = 0.15 if (self.CP.flags & GMFlags.NO_ACCELERATOR_POS_MSG.value) else 8
ret.brakePressed = ret.brake >= analog_thresh
# Regen braking is braking # Regen braking is braking
if self.CP.transmissionType == TransmissionType.direct: if self.CP.transmissionType == TransmissionType.direct:
ret.regenBraking = pt_cp.vl["EBCMRegenPaddle"]["RegenPaddle"] != 0 ret.regenBraking = pt_cp.vl["EBCMRegenPaddle"]["RegenPaddle"] != 0
self.single_pedal_mode = ret.gearShifter == GearShifter.low or pt_cp.vl["EVDriveMode"]["SinglePedalModeActive"] == 1 or (ret.regenBraking and GearShifter.manumatic) self.single_pedal_mode = (ret.gearShifter == GearShifter.low or
pt_cp.vl["EVDriveMode"]["SinglePedalModeActive"] == 1 or
(ret.regenBraking and GearShifter.manumatic) or
(self.CP.carFingerprint in (CAR.CHEVROLET_BOLT_ACC_2022_2023, CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL, CAR.CHEVROLET_BOLT_CC_2022_2023) and self.CP.enableGasInterceptor))
if self.CP.enableGasInterceptor: if self.CP.enableGasInterceptor:
ret.gas = (pt_cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS"] + pt_cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS2"]) / 2. ret.gas = (pt_cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS"] + pt_cp.vl["GAS_SENSOR"]["INTERCEPTOR_GAS2"]) / 2.
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. 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.
ret.gasPressed = ret.gas > threshold ret.gasPressed = ret.gas > threshold
else: else:
ret.gas = pt_cp.vl["AcceleratorPedal2"]["AcceleratorPedal2"] / 254. ret.gas = pt_cp.vl["AcceleratorPedal2"]["AcceleratorPedal2"] / 254.
@@ -113,7 +150,7 @@ class CarState(CarStateBase):
ret.steerFaultTemporary = self.lkas_status == 2 ret.steerFaultTemporary = self.lkas_status == 2
ret.steerFaultPermanent = self.lkas_status == 3 ret.steerFaultPermanent = self.lkas_status == 3
if self.CP.carFingerprint not in SDGM_CAR: if not sdgm_non_volt:
# 1 - open, 0 - closed # 1 - open, 0 - closed
ret.doorOpen = (pt_cp.vl["BCMDoorBeltStatus"]["FrontLeftDoor"] == 1 or ret.doorOpen = (pt_cp.vl["BCMDoorBeltStatus"]["FrontLeftDoor"] == 1 or
pt_cp.vl["BCMDoorBeltStatus"]["FrontRightDoor"] == 1 or pt_cp.vl["BCMDoorBeltStatus"]["FrontRightDoor"] == 1 or
@@ -149,20 +186,30 @@ class CarState(CarStateBase):
if self.CP.networkLocation == NetworkLocation.fwdCamera and not self.CP.flags & GMFlags.NO_CAMERA.value: if self.CP.networkLocation == NetworkLocation.fwdCamera and not self.CP.flags & GMFlags.NO_CAMERA.value:
if self.CP.carFingerprint not in CC_ONLY_CAR: if self.CP.carFingerprint not in CC_ONLY_CAR:
ret.cruiseState.speed = cam_cp.vl["ASCMActiveCruiseControlStatus"]["ACCSpeedSetpoint"] * CV.KPH_TO_MS ret.cruiseState.speed = cam_cp.vl["ASCMActiveCruiseControlStatus"]["ACCSpeedSetpoint"] * CV.KPH_TO_MS
if self.CP.carFingerprint not in SDGM_CAR: if self.CP.carFingerprint not in (SDGM_CAR | ASCM_INT):
ret.stockAeb = cam_cp.vl["AEBCmd"]["AEBCmdActive"] != 0 ret.stockAeb = cam_cp.vl["AEBCmd"]["AEBCmdActive"] != 0
else: else:
ret.stockAeb = False ret.stockAeb = False
# openpilot controls nonAdaptive when not pcmCruise # openpilot controls nonAdaptive when not pcmCruise
if self.CP.pcmCruise: if self.CP.pcmCruise and self.CP.carFingerprint not in ASCM_INT:
ret.cruiseState.nonAdaptive = cam_cp.vl["ASCMActiveCruiseControlStatus"]["ACCCruiseState"] not in (2, 3) ret.cruiseState.nonAdaptive = cam_cp.vl["ASCMActiveCruiseControlStatus"]["ACCCruiseState"] not in (2, 3)
if self.CP.carFingerprint in CC_ONLY_CAR: if self.CP.carFingerprint in CC_ONLY_CAR:
ret.accFaulted = False ret.accFaulted = False
ret.cruiseState.speed = pt_cp.vl["ECMCruiseControl"]["CruiseSetSpeed"] * CV.KPH_TO_MS ret.cruiseState.speed = pt_cp.vl["ECMCruiseControl"]["CruiseSetSpeed"] * CV.KPH_TO_MS
ret.cruiseState.enabled = pt_cp.vl["ECMCruiseControl"]["CruiseActive"] != 0 if self.CP.carFingerprint == CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL:
try:
ret.cruiseState.enabled = cam_cp.vl["ASCMActiveCruiseControlStatus"]["ACCCmdActive"] != 0
except:
ret.cruiseState.enabled = pt_cp.vl["ECMCruiseControl"]["CruiseActive"] != 0
else:
# Most CC paths use ECM first.
try:
ret.cruiseState.enabled = pt_cp.vl["ECMCruiseControl"]["CruiseActive"] != 0
except:
ret.cruiseState.enabled = cam_cp.vl["ASCMActiveCruiseControlStatus"]["ACCCmdActive"] != 0
if self.CP.enableBsm: if self.CP.enableBsm:
if self.CP.carFingerprint not in SDGM_CAR: if not sdgm_non_volt:
ret.leftBlindspot = pt_cp.vl["BCMBlindSpotMonitor"]["LeftBSM"] == 1 ret.leftBlindspot = pt_cp.vl["BCMBlindSpotMonitor"]["LeftBSM"] == 1
ret.rightBlindspot = pt_cp.vl["BCMBlindSpotMonitor"]["RightBSM"] == 1 ret.rightBlindspot = pt_cp.vl["BCMBlindSpotMonitor"]["RightBSM"] == 1
else: else:
@@ -171,7 +218,7 @@ class CarState(CarStateBase):
# FrogPilot CarState functions # FrogPilot CarState functions
self.lkas_previously_enabled = self.lkas_enabled self.lkas_previously_enabled = self.lkas_enabled
if self.CP.carFingerprint in SDGM_CAR: if sdgm_non_volt:
self.lkas_enabled = cam_cp.vl["ASCMSteeringButton"]["LKAButton"] self.lkas_enabled = cam_cp.vl["ASCMSteeringButton"]["LKAButton"]
else: else:
self.lkas_enabled = pt_cp.vl["ASCMSteeringButton"]["LKAButton"] self.lkas_enabled = pt_cp.vl["ASCMSteeringButton"]["LKAButton"]
@@ -186,10 +233,18 @@ class CarState(CarStateBase):
def get_cam_can_parser(CP, FPCP): def get_cam_can_parser(CP, FPCP):
messages = [] messages = []
if CP.networkLocation == NetworkLocation.fwdCamera and not CP.flags & GMFlags.NO_CAMERA.value: if CP.networkLocation == NetworkLocation.fwdCamera and not CP.flags & GMFlags.NO_CAMERA.value:
volt_like = {CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_2019, CAR.CHEVROLET_VOLT_ASCM, CAR.CHEVROLET_VOLT_CAMERA, CAR.CHEVROLET_VOLT_CC}
kaofui_state_cars = volt_like | SDGM_CAR | ASCM_INT | {
CAR.CHEVROLET_BLAZER,
CAR.CHEVROLET_MALIBU_SDGM,
CAR.CHEVROLET_MALIBU_HYBRID_CC,
}
sdgm_non_volt = CP.carFingerprint in SDGM_CAR and \
CP.carFingerprint not in kaofui_state_cars
messages += [ messages += [
("ASCMLKASteeringCmd", 10), ("ASCMLKASteeringCmd", 10),
] ]
if CP.carFingerprint in SDGM_CAR: if sdgm_non_volt:
messages += [ messages += [
("BCMTurnSignals", 1), ("BCMTurnSignals", 1),
("BCMDoorBeltStatus", 10), ("BCMDoorBeltStatus", 10),
@@ -198,11 +253,11 @@ class CarState(CarStateBase):
] ]
if CP.enableBsm: if CP.enableBsm:
messages.append(("BCMBlindSpotMonitor", 10)) messages.append(("BCMBlindSpotMonitor", 10))
else: elif CP.carFingerprint not in (SDGM_CAR | ASCM_INT):
messages += [ messages += [
("AEBCmd", 10), ("AEBCmd", 10),
] ]
if CP.carFingerprint not in CC_ONLY_CAR: if CP.carFingerprint not in CC_ONLY_CAR or CP.carFingerprint == CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL:
messages += [ messages += [
("ASCMActiveCruiseControlStatus", 25), ("ASCMActiveCruiseControlStatus", 25),
] ]
@@ -222,15 +277,24 @@ class CarState(CarStateBase):
("SportMode", 0), ("SportMode", 0),
] ]
if CP.carFingerprint in SDGM_CAR: volt_like = {CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_2019, CAR.CHEVROLET_VOLT_ASCM, CAR.CHEVROLET_VOLT_CAMERA, CAR.CHEVROLET_VOLT_CC}
kaofui_state_cars = volt_like | SDGM_CAR | ASCM_INT | {
CAR.CHEVROLET_BLAZER,
CAR.CHEVROLET_MALIBU_SDGM,
CAR.CHEVROLET_MALIBU_HYBRID_CC,
}
prndl2_rate = 10 if CP.carFingerprint in kaofui_state_cars else 40
sdgm_non_volt = CP.carFingerprint in SDGM_CAR and \
CP.carFingerprint not in kaofui_state_cars
if sdgm_non_volt:
messages += [ messages += [
("ECMPRDNL2", 40), ("ECMPRDNL2", prndl2_rate),
("AcceleratorPedal2", 40), ("AcceleratorPedal2", 40),
("ECMEngineStatus", 80), ("ECMEngineStatus", 80),
] ]
else: else:
messages += [ messages += [
("ECMPRDNL2", 10), ("ECMPRDNL2", prndl2_rate),
("AcceleratorPedal2", 33), ("AcceleratorPedal2", 33),
("ECMEngineStatus", 100), ("ECMEngineStatus", 100),
("BCMTurnSignals", 1), ("BCMTurnSignals", 1),
@@ -251,8 +315,9 @@ class CarState(CarStateBase):
messages.append(("EBCMBrakePedalPosition", 100)) messages.append(("EBCMBrakePedalPosition", 100))
if CP.transmissionType == TransmissionType.direct: if CP.transmissionType == TransmissionType.direct:
regen_paddle_rate = 50 if CP.carFingerprint in kaofui_state_cars else 40
messages += [ messages += [
("EBCMRegenPaddle", 50), ("EBCMRegenPaddle", regen_paddle_rate),
("EVDriveMode", 0), ("EVDriveMode", 0),
] ]
+62 -17
View File
@@ -26,6 +26,20 @@ FINGERPRINTS = {
{ {
170: 8, 171: 8, 189: 7, 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 288: 5, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 389: 2, 390: 7, 417: 7, 419: 1, 426: 7, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 528: 4, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 5, 567: 3, 568: 1, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 717: 5, 761: 7, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1273: 3, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1905: 7, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1922: 7, 1927: 7, 1930: 7, 2017: 8, 2020: 8, 2025: 8, 2028: 8 170: 8, 171: 8, 189: 7, 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 288: 5, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 389: 2, 390: 7, 417: 7, 419: 1, 426: 7, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 528: 4, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 5, 567: 3, 568: 1, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 717: 5, 761: 7, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1273: 3, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1905: 7, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1922: 7, 1927: 7, 1930: 7, 2017: 8, 2020: 8, 2025: 8, 2028: 8
}], }],
CAR.CHEVROLET_VOLT_ASCM: [
# Causes errors with normal OBD install
# {
# 189: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 288: 5, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 451: 8, 452: 8, 453: 6, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 497: 8, 500: 6, 501: 8, 528: 4, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 566: 5, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 761: 7, 767: 4, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4, 880: 6, 977: 8, 1001: 8, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1265: 8, 1267: 1, 1280: 4, 1296: 4, 1300: 8, 1922: 7, 1930: 7
# }
],
CAR.CHEVROLET_VOLT_CAMERA: [
# Volt Premier 2017 w/ flashed firmware, cam harness + pedal (no 0x170/0x171 on PT bus)
{
# 189: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 386: 8, 388: 8, 451: 8, 452: 8, 453: 6, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 497: 8, 500: 6, 501: 8, 513: 6, 528: 4, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 566: 5, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 977: 8, 1001: 8, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1265: 8, 1267: 1, 1280: 4, 1300: 8, 1922: 7
}],
CAR.GMC_ACADIA_ASCM: [
# Causes errors with normal OBD install
],
CAR.BUICK_LACROSSE: [{ CAR.BUICK_LACROSSE: [{
190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 353: 3, 381: 6, 386: 8, 388: 8, 393: 7, 398: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 455: 7, 456: 8, 463: 3, 479: 3, 481: 7, 485: 8, 487: 8, 489: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 510: 8, 528: 5, 532: 6, 534: 2, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 5, 707: 8, 753: 5, 761: 7, 801: 8, 804: 3, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 872: 1, 882: 8, 890: 1, 892: 2, 893: 1, 894: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1217: 8, 1221: 5, 1223: 2, 1225: 7, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1417: 8, 1609: 8, 1613: 8, 1649: 8, 1792: 8, 1798: 8, 1824: 8, 1825: 8, 1840: 8, 1842: 8, 1858: 8, 1860: 8, 1863: 8, 1872: 8, 1875: 8, 1882: 8, 1888: 8, 1889: 8, 1892: 8, 1904: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1914: 7, 1916: 7, 1918: 7, 1919: 7, 1937: 8, 1953: 8, 1968: 8, 2001: 8, 2017: 8, 2018: 8, 2020: 8, 2026: 8 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 353: 3, 381: 6, 386: 8, 388: 8, 393: 7, 398: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 455: 7, 456: 8, 463: 3, 479: 3, 481: 7, 485: 8, 487: 8, 489: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 510: 8, 528: 5, 532: 6, 534: 2, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 5, 707: 8, 753: 5, 761: 7, 801: 8, 804: 3, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 872: 1, 882: 8, 890: 1, 892: 2, 893: 1, 894: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1217: 8, 1221: 5, 1223: 2, 1225: 7, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1417: 8, 1609: 8, 1613: 8, 1649: 8, 1792: 8, 1798: 8, 1824: 8, 1825: 8, 1840: 8, 1842: 8, 1858: 8, 1860: 8, 1863: 8, 1872: 8, 1875: 8, 1882: 8, 1888: 8, 1889: 8, 1892: 8, 1904: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1914: 7, 1916: 7, 1918: 7, 1919: 7, 1937: 8, 1953: 8, 1968: 8, 2001: 8, 2017: 8, 2018: 8, 2020: 8, 2026: 8
}], }],
@@ -52,6 +66,9 @@ FINGERPRINTS = {
CAR.CHEVROLET_MALIBU: [{ CAR.CHEVROLET_MALIBU: [{
190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 455: 7, 456: 8, 479: 3, 481: 7, 485: 8, 487: 8, 489: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 510: 8, 528: 5, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1217: 8, 1221: 5, 1223: 2, 1225: 7, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1906: 7, 1907: 7, 1912: 7, 1919: 7, 1930: 7, 2016: 8, 2024: 8 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 455: 7, 456: 8, 479: 3, 481: 7, 485: 8, 487: 8, 489: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 510: 8, 528: 5, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1217: 8, 1221: 5, 1223: 2, 1225: 7, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1906: 7, 1907: 7, 1912: 7, 1919: 7, 1930: 7, 2016: 8, 2024: 8
}], }],
CAR.CHEVROLET_MALIBU_ASCM: [{
190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 6, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 455: 7, 456: 8, 479: 3, 481: 7, 485: 8, 487: 8, 489: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 510: 8, 528: 5, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1217: 8, 1221: 5, 1223: 2, 1225: 7, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1906: 7, 1907: 7, 1912: 7, 1919: 7, 1930: 7, 2016: 8, 2024: 8
}],
CAR.GMC_ACADIA: [{ CAR.GMC_ACADIA: [{
190: 6, 192: 5, 193: 8, 197: 8, 199: 4, 201: 6, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 289: 1, 290: 1, 298: 8, 304: 8, 309: 8, 313: 8, 320: 8, 322: 7, 328: 1, 352: 7, 368: 8, 381: 8, 384: 8, 386: 8, 388: 8, 393: 8, 398: 8, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 454: 8, 455: 7, 458: 8, 460: 4, 462: 4, 463: 3, 479: 3, 481: 7, 485: 8, 489: 5, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 510: 8, 512: 3, 530: 8, 532: 6, 534: 2, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 567: 5, 568: 2, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 801: 8, 803: 8, 804: 3, 805: 8, 832: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1003: 5, 1005: 6, 1009: 8, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1217: 8, 1221: 5, 1225: 8, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1328: 4, 1417: 8, 1906: 7, 1907: 7, 1912: 7, 1914: 7, 1918: 7, 1919: 7, 1920: 7, 1930: 7 190: 6, 192: 5, 193: 8, 197: 8, 199: 4, 201: 6, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 289: 1, 290: 1, 298: 8, 304: 8, 309: 8, 313: 8, 320: 8, 322: 7, 328: 1, 352: 7, 368: 8, 381: 8, 384: 8, 386: 8, 388: 8, 393: 8, 398: 8, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 454: 8, 455: 7, 458: 8, 460: 4, 462: 4, 463: 3, 479: 3, 481: 7, 485: 8, 489: 5, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 510: 8, 512: 3, 530: 8, 532: 6, 534: 2, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 567: 5, 568: 2, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 801: 8, 803: 8, 804: 3, 805: 8, 832: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1003: 5, 1005: 6, 1009: 8, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1105: 6, 1217: 8, 1221: 5, 1225: 8, 1233: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1328: 4, 1417: 8, 1906: 7, 1907: 7, 1912: 7, 1914: 7, 1918: 7, 1919: 7, 1920: 7, 1930: 7
}, },
@@ -67,14 +84,34 @@ FINGERPRINTS = {
CAR.CADILLAC_ESCALADE_ESV_2019: [{ CAR.CADILLAC_ESCALADE_ESV_2019: [{
715: 8, 840: 5, 717: 5, 869: 4, 880: 6, 289: 8, 454: 8, 842: 5, 460: 5, 463: 3, 801: 8, 170: 8, 190: 6, 241: 6, 201: 8, 417: 7, 211: 2, 419: 1, 398: 8, 426: 7, 487: 8, 442: 8, 451: 8, 452: 8, 453: 6, 479: 3, 311: 8, 500: 6, 647: 6, 193: 8, 707: 8, 197: 8, 209: 7, 199: 4, 455: 7, 313: 8, 481: 7, 485: 8, 489: 8, 249: 8, 393: 7, 407: 7, 413: 8, 422: 4, 431: 8, 501: 8, 499: 3, 810: 8, 508: 8, 381: 8, 462: 4, 532: 6, 562: 8, 386: 8, 761: 7, 573: 1, 554: 3, 719: 5, 560: 8, 1279: 4, 388: 8, 288: 5, 1005: 6, 497: 8, 844: 8, 961: 8, 967: 4, 977: 8, 979: 8, 985: 5, 1001: 8, 1017: 8, 1019: 2, 1020: 8, 1217: 8, 510: 8, 866: 4, 304: 1, 969: 8, 384: 4, 1033: 7, 1009: 8, 1034: 7, 1296: 4, 1930: 7, 1105: 5, 1013: 5, 1225: 7, 1919: 7, 320: 3, 534: 2, 352: 5, 298: 8, 1223: 2, 1233: 8, 608: 8, 1265: 8, 609: 6, 1267: 1, 1417: 8, 610: 6, 1906: 7, 611: 6, 612: 8, 613: 8, 208: 8, 564: 5, 309: 8, 1221: 5, 1280: 4, 1249: 8, 1907: 7, 1257: 6, 1300: 8, 1920: 7, 563: 5, 1322: 6, 1323: 4, 1328: 4, 1917: 7, 328: 1, 1912: 7, 1914: 7, 804: 3, 1918: 7 715: 8, 840: 5, 717: 5, 869: 4, 880: 6, 289: 8, 454: 8, 842: 5, 460: 5, 463: 3, 801: 8, 170: 8, 190: 6, 241: 6, 201: 8, 417: 7, 211: 2, 419: 1, 398: 8, 426: 7, 487: 8, 442: 8, 451: 8, 452: 8, 453: 6, 479: 3, 311: 8, 500: 6, 647: 6, 193: 8, 707: 8, 197: 8, 209: 7, 199: 4, 455: 7, 313: 8, 481: 7, 485: 8, 489: 8, 249: 8, 393: 7, 407: 7, 413: 8, 422: 4, 431: 8, 501: 8, 499: 3, 810: 8, 508: 8, 381: 8, 462: 4, 532: 6, 562: 8, 386: 8, 761: 7, 573: 1, 554: 3, 719: 5, 560: 8, 1279: 4, 388: 8, 288: 5, 1005: 6, 497: 8, 844: 8, 961: 8, 967: 4, 977: 8, 979: 8, 985: 5, 1001: 8, 1017: 8, 1019: 2, 1020: 8, 1217: 8, 510: 8, 866: 4, 304: 1, 969: 8, 384: 4, 1033: 7, 1009: 8, 1034: 7, 1296: 4, 1930: 7, 1105: 5, 1013: 5, 1225: 7, 1919: 7, 320: 3, 534: 2, 352: 5, 298: 8, 1223: 2, 1233: 8, 608: 8, 1265: 8, 609: 6, 1267: 1, 1417: 8, 610: 6, 1906: 7, 611: 6, 612: 8, 613: 8, 208: 8, 564: 5, 309: 8, 1221: 5, 1280: 4, 1249: 8, 1907: 7, 1257: 6, 1300: 8, 1920: 7, 563: 5, 1322: 6, 1323: 4, 1328: 4, 1917: 7, 328: 1, 1912: 7, 1914: 7, 804: 3, 1918: 7
}], }],
CAR.CHEVROLET_BOLT_EUV: [{ CAR.CHEVROLET_BOLT_ACC_2022_2023: [{
189: 7, 190: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 3, 241: 6, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 451: 8, 452: 8, 453: 6, 458: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 566: 8, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1265: 8, 1280: 4, 1296: 4, 1300: 8, 1611: 8, 1930: 7 189: 7, 190: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 3, 241: 6, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 451: 8, 452: 8, 453: 6, 458: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 566: 8, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1265: 8, 1280: 4, 1296: 4, 1300: 8, 1611: 8, 1930: 7
}], }],
CAR.CHEVROLET_BOLT_CC: [ CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL: [{
189: 7, 190: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 3, 241: 6, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 451: 8, 452: 8, 453: 6, 458: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 566: 8, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1265: 8, 1280: 4, 1296: 4, 1300: 8, 1611: 8, 1930: 7
}],
CAR.CHEVROLET_BOLT_CC_2022_2023: [{
189: 7, 190: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 3, 241: 6, 257: 8, 288: 5, 289: 8, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 451: 8, 452: 8, 453: 6, 458: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 528: 5, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 566: 8, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 869: 4, 880: 6, 977: 8, 1001: 8, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1265: 8, 1280: 4, 1296: 4, 1300: 8, 1611: 8, 1930: 7
}],
CAR.CHEVROLET_BOLT_CC_2017: [
# Bolt Premier w/o ACC 2017 # Bolt Premier w/o ACC 2017
{ {
170: 8, 188: 8, 189: 7, 190: 6, 192: 5, 193: 8, 197: 8, 201: 6, 209: 7, 211: 2, 241: 6, 289: 1, 290: 1, 298: 8, 304: 8, 309: 8, 311: 8, 313: 8, 320: 8, 322: 7, 328: 1, 352: 5, 353: 3, 368: 8, 381: 6, 384: 8, 386: 8, 388: 8, 390: 7, 407: 7, 417: 7, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 458: 8, 463: 3, 479: 3, 481: 7, 485: 8, 489: 5, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 512: 3, 514: 2, 516: 4, 519: 2, 521: 3, 528: 5, 530: 8, 532: 7, 537: 5, 539: 8, 542: 7, 546: 7, 550: 8, 554: 3, 558: 8, 560: 6, 562: 4, 563: 5, 564: 5, 565: 8, 566: 6, 567: 5, 568: 1, 569: 3, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 717: 5, 753: 5, 761: 7, 800: 6, 810: 8, 832: 8, 840: 6, 842: 6, 844: 8, 866: 4, 869: 4, 872: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 5, 1003: 5, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1601: 8, 1904: 7, 1905: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1927: 7, 2016: 8, 2020: 8, 2024: 8, 2028: 8 170: 8, 188: 8, 189: 7, 190: 6, 192: 5, 193: 8, 197: 8, 201: 6, 209: 7, 211: 2, 241: 6, 289: 1, 290: 1, 298: 8, 304: 8, 309: 8, 311: 8, 313: 8, 320: 8, 322: 7, 328: 1, 352: 5, 353: 3, 368: 8, 381: 6, 384: 8, 386: 8, 388: 8, 390: 7, 407: 7, 417: 7, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 458: 8, 463: 3, 479: 3, 481: 7, 485: 8, 489: 5, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 512: 3, 514: 2, 516: 4, 519: 2, 521: 3, 528: 5, 530: 8, 532: 7, 537: 5, 539: 8, 542: 7, 546: 7, 550: 8, 554: 3, 558: 8, 560: 6, 562: 4, 563: 5, 564: 5, 565: 8, 566: 6, 567: 5, 568: 1, 569: 3, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 717: 5, 753: 5, 761: 7, 800: 6, 810: 8, 832: 8, 840: 6, 842: 6, 844: 8, 866: 4, 869: 4, 872: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 5, 1003: 5, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1601: 8, 1904: 7, 1905: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1927: 7, 2016: 8, 2020: 8, 2024: 8, 2028: 8
}, },
# Bolt EV Premier 2017
{
170: 8, 188: 8, 189: 7, 190: 6, 192: 5, 193: 8, 197: 8, 201: 6, 209: 7, 211: 2, 241: 6, 289: 1, 290: 1, 298: 8, 304: 8, 309: 8, 311: 8, 313: 8, 320: 8, 322: 7, 328: 1, 352: 5, 353: 3, 368: 8, 381: 6, 384: 8, 386: 8, 388: 8, 390: 7, 407: 7, 417: 7, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 458: 8, 463: 3, 479: 3, 481: 7, 485: 8, 489: 5, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 512: 3, 514: 2, 516: 4, 519: 2, 521: 3, 528: 5, 530: 8, 532: 7, 537: 5, 539: 8, 542: 7, 546: 7, 550: 8, 554: 3, 558: 8, 560: 6, 562: 4, 563: 5, 564: 5, 565: 8, 566: 6, 567: 5, 568: 1, 569: 3, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 717: 5, 753: 5, 761: 7, 800: 6, 810: 8, 832: 8, 840: 6, 842: 6, 844: 8, 866: 4, 869: 4, 872: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 5, 1003: 5, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1601: 8, 1904: 7, 1905: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1927: 7, 2016: 8, 2020: 8, 2024: 8, 2028: 8
},
# Bolt EV Premier 2017 w Pedal
{ # pylint: disable=duplicate-key
170: 8, 188: 8, 189: 7, 190: 6, 192: 5, 193: 8, 197: 8, 201: 6, 209: 7, 211: 2, 241: 6, 289: 1, 290: 1, 298: 8, 304: 8, 309: 8, 311: 8, 313: 8, 320: 8, 322: 7, 328: 1, 352: 5, 353: 3, 368: 8, 381: 6, 384: 8, 386: 8, 388: 8, 390: 7, 407: 7, 417: 7, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 458: 8, 463: 3, 479: 3, 481: 7, 485: 8, 489: 5, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 512: 3, 512: 6, 513: 6, 514: 2, 516: 4, 519: 2, 521: 3, 528: 5, 530: 8, 532: 7, 537: 5, 539: 8, 542: 7, 546: 7, 550: 8, 554: 3, 558: 8, 560: 6, 562: 4, 563: 5, 564: 5, 565: 8, 566: 6, 567: 5, 568: 1, 569: 3, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 717: 5, 753: 5, 761: 7, 800: 6, 810: 8, 832: 8, 840: 6, 842: 6, 844: 8, 866: 4, 869: 4, 872: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 5, 1003: 5, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1601: 8, 1904: 7, 1905: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1927: 7, 2016: 8, 2020: 8, 2024: 8, 2028: 8 # pylint: disable=duplicate-key # noqa: F601
},
# Bolt EV Premier 2017 2 w Pedal
{
170: 8, 188: 8, 189: 7, 190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 353: 3, 381: 6, 384: 4, 386: 8, 388: 8, 390: 7, 407: 7, 417: 7, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 513: 6, 528: 5, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 6, 567: 5, 568: 1, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 717: 5, 753: 5, 761: 7, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 872: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1904: 7, 1905: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1922: 7, 1927: 7
}],
CAR.CHEVROLET_BOLT_CC_2019_2021: [
# Chevy Bolt EV 2019-2021
# Bolt Premier no ACC 2018 + Pedal # Bolt Premier no ACC 2018 + Pedal
{ {
170: 8, 188: 8, 189: 7, 190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 353: 3, 381: 6, 384: 4, 386: 8, 388: 8, 390: 7, 407: 7, 417: 7, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 2, 508: 8, 513: 6, 528: 5, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 6, 567: 5, 568: 1, 573: 1, 577: 8, 592: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 717: 5, 753: 5, 761: 7, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 872: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1601: 8, 1616: 8, 1904: 7, 1905: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1922: 7, 1927: 7, 2020: 8, 2023: 8, 2028: 8, 2031: 8 170: 8, 188: 8, 189: 7, 190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 353: 3, 381: 6, 384: 4, 386: 8, 388: 8, 390: 7, 407: 7, 417: 7, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 2, 508: 8, 513: 6, 528: 5, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 6, 567: 5, 568: 1, 573: 1, 577: 8, 592: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 717: 5, 753: 5, 761: 7, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 872: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1601: 8, 1616: 8, 1904: 7, 1905: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1922: 7, 1927: 7, 2020: 8, 2023: 8, 2028: 8, 2031: 8
@@ -95,18 +132,6 @@ FINGERPRINTS = {
{ {
170: 8, 188: 8, 189: 7, 190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 288: 5, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 353: 3, 368: 3, 381: 8, 386: 8, 388: 8, 390: 7, 407: 7, 417: 7, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 2, 508: 8, 512: 6, 513: 6, 528: 5, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 7, 567: 5, 568: 2, 569: 3, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 753: 5, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 866: 4, 872: 1, 961: 8, 967: 4, 969: 8, 975: 2, 977: 8, 979: 7, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1037: 5, 1105: 5, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1236: 8, 1243: 3, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1279: 4, 1280: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1904: 7, 1905: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1922: 7, 1927: 7 170: 8, 188: 8, 189: 7, 190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 288: 5, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 353: 3, 368: 3, 381: 8, 386: 8, 388: 8, 390: 7, 407: 7, 417: 7, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 2, 508: 8, 512: 6, 513: 6, 528: 5, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 7, 567: 5, 568: 2, 569: 3, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 753: 5, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 866: 4, 872: 1, 961: 8, 967: 4, 969: 8, 975: 2, 977: 8, 979: 7, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1037: 5, 1105: 5, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1236: 8, 1243: 3, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1279: 4, 1280: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1904: 7, 1905: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1922: 7, 1927: 7
}, },
# Bolt EV Premier 2017
{
170: 8, 188: 8, 189: 7, 190: 6, 192: 5, 193: 8, 197: 8, 201: 6, 209: 7, 211: 2, 241: 6, 289: 1, 290: 1, 298: 8, 304: 8, 309: 8, 311: 8, 313: 8, 320: 8, 322: 7, 328: 1, 352: 5, 353: 3, 368: 8, 381: 6, 384: 8, 386: 8, 388: 8, 390: 7, 407: 7, 417: 7, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 458: 8, 463: 3, 479: 3, 481: 7, 485: 8, 489: 5, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 512: 3, 514: 2, 516: 4, 519: 2, 521: 3, 528: 5, 530: 8, 532: 7, 537: 5, 539: 8, 542: 7, 546: 7, 550: 8, 554: 3, 558: 8, 560: 6, 562: 4, 563: 5, 564: 5, 565: 8, 566: 6, 567: 5, 568: 1, 569: 3, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 717: 5, 753: 5, 761: 7, 800: 6, 810: 8, 832: 8, 840: 6, 842: 6, 844: 8, 866: 4, 869: 4, 872: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 5, 1003: 5, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1601: 8, 1904: 7, 1905: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1927: 7, 2016: 8, 2020: 8, 2024: 8, 2028: 8
},
# Bolt EV Premier 2017 w Pedal
{ # pylint: disable=duplicate-key
170: 8, 188: 8, 189: 7, 190: 6, 192: 5, 193: 8, 197: 8, 201: 6, 209: 7, 211: 2, 241: 6, 289: 1, 290: 1, 298: 8, 304: 8, 309: 8, 311: 8, 313: 8, 320: 8, 322: 7, 328: 1, 352: 5, 353: 3, 368: 8, 381: 6, 384: 8, 386: 8, 388: 8, 390: 7, 407: 7, 417: 7, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 458: 8, 463: 3, 479: 3, 481: 7, 485: 8, 489: 5, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 512: 3, 512: 6, 513: 6, 514: 2, 516: 4, 519: 2, 521: 3, 528: 5, 530: 8, 532: 7, 537: 5, 539: 8, 542: 7, 546: 7, 550: 8, 554: 3, 558: 8, 560: 6, 562: 4, 563: 5, 564: 5, 565: 8, 566: 6, 567: 5, 568: 1, 569: 3, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 717: 5, 753: 5, 761: 7, 800: 6, 810: 8, 832: 8, 840: 6, 842: 6, 844: 8, 866: 4, 869: 4, 872: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 5, 1003: 5, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1601: 8, 1904: 7, 1905: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1927: 7, 2016: 8, 2020: 8, 2024: 8, 2028: 8 # pylint: disable=duplicate-key # noqa: F601
},
# Bolt EV Premier 2017 2 w Pedal
{
170: 8, 188: 8, 189: 7, 190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 353: 3, 381: 6, 384: 4, 386: 8, 388: 8, 390: 7, 407: 7, 417: 7, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 513: 6, 528: 5, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 6, 567: 5, 568: 1, 573: 1, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 717: 5, 753: 5, 761: 7, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 872: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 7, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1904: 7, 1905: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1922: 7, 1927: 7
},
# Bolt EV Premier no ACC 2023 # Bolt EV Premier no ACC 2023
{ {
170: 8, 188: 8, 189: 7, 190: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 3, 241: 6, 257: 8, 288: 5, 289: 8, 292: 2, 298: 8, 304: 3, 308: 4, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 331: 3, 352: 5, 353: 3, 368: 3, 381: 8, 384: 4, 386: 8, 388: 8, 390: 7, 398: 8, 407: 7, 417: 8, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 458: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 2, 508: 8, 528: 5, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 8, 567: 5, 568: 2, 569: 3, 573: 1, 577: 8, 592: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 711: 6, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 866: 4, 869: 4, 872: 1, 880: 6, 961: 8, 967: 4, 969: 8, 975: 2, 977: 8, 979: 8, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1010: 8, 1013: 6, 1015: 1, 1017: 8, 1019: 2, 1020: 8, 1037: 5, 1105: 5, 1187: 5, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1236: 8, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1279: 4, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1601: 8, 1616: 8, 1618: 8, 1905: 7, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1913: 7, 1922: 7, 1927: 7, 1930: 7, 2016: 8, 2020: 8, 2023: 8, 2024: 8, 2028: 8, 2031: 8 170: 8, 188: 8, 189: 7, 190: 7, 193: 8, 197: 8, 201: 8, 209: 7, 211: 3, 241: 6, 257: 8, 288: 5, 289: 8, 292: 2, 298: 8, 304: 3, 308: 4, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 331: 3, 352: 5, 353: 3, 368: 3, 381: 8, 384: 4, 386: 8, 388: 8, 390: 7, 398: 8, 407: 7, 417: 8, 419: 1, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 458: 5, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 2, 508: 8, 528: 5, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 8, 567: 5, 568: 2, 569: 3, 573: 1, 577: 8, 592: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 711: 6, 715: 8, 717: 5, 753: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 848: 4, 866: 4, 869: 4, 872: 1, 880: 6, 961: 8, 967: 4, 969: 8, 975: 2, 977: 8, 979: 8, 985: 5, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1010: 8, 1013: 6, 1015: 1, 1017: 8, 1019: 2, 1020: 8, 1037: 5, 1105: 5, 1187: 5, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1236: 8, 1249: 8, 1257: 6, 1265: 8, 1275: 3, 1279: 4, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1601: 8, 1616: 8, 1618: 8, 1905: 7, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1913: 7, 1922: 7, 1927: 7, 1930: 7, 2016: 8, 2020: 8, 2023: 8, 2024: 8, 2028: 8, 2031: 8
@@ -178,31 +203,51 @@ FINGERPRINTS = {
CAR.CADILLAC_XT4: [ CAR.CADILLAC_XT4: [
# Cadillac XT4 w/ ACC 2023 # Cadillac XT4 w/ ACC 2023
{ {
190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 292: 2, 298: 8, 304: 3, 309: 8, 313: 8, 320: 4, 322: 7, 328: 1, 331: 3, 352: 5, 353: 3, 368: 3, 381: 8, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 401: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 455: 7, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 499: 3, 500: 6, 501: 8, 503: 2, 508: 8, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 719: 5, 761: 7, 806: 1, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 872: 1, 880: 6, 961: 8, 969: 8, 975: 2, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 5, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1037: 5, 1105: 5, 1187: 5, 1195: 3, 1217: 8, 1221: 5, 1223: 2, 1225: 7, 1233: 8, 1236: 8, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1268: 2, 1271: 8, 1273: 3, 1276: 2, 1277: 7, 1278: 4, 1279: 4, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1345: 8, 1417: 8, 1512: 8, 1517: 8, 1601: 8, 1609: 8, 1613: 8, 1649: 8, 1792: 8, 1793: 8, 1798: 8, 1824: 8, 1825: 8, 1840: 8, 1842: 8, 1858: 8, 1860: 8, 1863: 8, 1872: 8, 1875: 8, 1882: 8, 1888: 8, 1889: 8, 1892: 8, 1906: 7, 1907: 7, 1912: 7, 1919: 7, 1920: 8, 1924: 8, 1930: 7, 1937: 8, 1953: 8, 1968: 8, 1969: 8, 1971: 8, 1975: 8, 1984: 8, 1988: 8, 2000: 8, 2001: 8, 2002: 8, 2016: 8, 2017: 8, 2018: 8, 2020: 8, 2021: 8, 2024: 8, 2026: 8 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 292: 2, 298: 8, 304: 3, 309: 8, 313: 8, 320: 4, 322: 7, 328: 1, 331: 3, 352: 5, 353: 3, 368: 3, 381: 8, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 401: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 455: 7, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 499: 3, 500: 6, 501: 8, 503: 2, 508: 8, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 719: 5, 761: 7, 767: 4, 806: 1, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 872: 1, 880: 6, 961: 8, 969: 8, 975: 2, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 5, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1037: 5, 1105: 5, 1187: 5, 1195: 3, 1217: 8, 1221: 5, 1223: 2, 1225: 7, 1233: 8, 1236: 8, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1268: 2, 1271: 8, 1273: 3, 1276: 2, 1277: 7, 1278: 4, 1279: 4, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1345: 8, 1417: 8, 1512: 8, 1517: 8, 1601: 8, 1609: 8, 1613: 8, 1649: 8, 1792: 8, 1793: 8, 1798: 8, 1824: 8, 1825: 8, 1840: 8, 1842: 8, 1858: 8, 1860: 8, 1863: 8, 1872: 8, 1875: 8, 1882: 8, 1888: 8, 1889: 8, 1892: 8, 1906: 7, 1907: 7, 1912: 7, 1919: 7, 1920: 8, 1924: 8, 1930: 7, 1937: 8, 1953: 8, 1968: 8, 1969: 8, 1971: 8, 1975: 8, 1984: 8, 1988: 8, 2000: 8, 2001: 8, 2002: 8, 2016: 8, 2017: 8, 2018: 8, 2020: 8, 2021: 8, 2024: 8, 2026: 8
}], }],
CAR.CADILLAC_XT5_CC: [ CAR.CADILLAC_XT5_CC: [
# TRain's 2017 XT5 # TRain's 2017 XT5
{ {
190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 353: 3, 381: 6, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 454: 8, 455: 7, 462: 4, 463: 3, 479: 3, 481: 7, 485: 8, 487: 8, 489: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 510: 8, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 567: 5, 647: 3, 707: 8, 717: 5, 723: 2, 753: 5, 761: 7, 800: 6, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 872: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1417: 8, 1904: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1914: 7, 1919: 7, 1920: 7 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 1, 309: 8, 313: 8, 320: 3, 322: 7, 328: 1, 352: 5, 353: 3, 381: 6, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 454: 8, 455: 7, 462: 4, 463: 3, 479: 3, 481: 7, 485: 8, 487: 8, 489: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 503: 1, 508: 8, 510: 8, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 567: 5, 647: 3, 707: 8, 717: 5, 723: 2, 753: 5, 761: 7, 800: 6, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 872: 1, 961: 8, 967: 4, 969: 8, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 3, 1017: 8, 1019: 2, 1020: 8, 1022: 1, 1105: 6, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1233: 8, 1243: 3, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1280: 4, 1300: 8, 1322: 6, 1328: 4, 1417: 8, 1904: 7, 1906: 7, 1907: 7, 1912: 7, 1913: 7, 1914: 7, 1919: 7, 1920: 7
}], }],
CAR.CADILLAC_XT6: [
#{}
],
CAR.CHEVROLET_BLAZER: [{
190: 6, 193: 8, 197: 8, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 289: 8, 298: 8, 304: 3, 309: 8, 313: 8, 322: 7, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 510: 8, 532: 6, 560: 8, 562: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 753: 5, 761: 7, 767: 4, 840: 5, 842: 5, 844: 8, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1217: 8, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1296: 4
}],
CAR.CHEVROLET_TRAVERSE: [ CAR.CHEVROLET_TRAVERSE: [
# Chevy Traverse w/ ACC 2023 # Chevy Traverse w/ ACC 2023
{ {
190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 292: 2, 298: 8, 304: 3, 309: 8, 313: 8, 320: 4, 322: 7, 328: 1, 331: 3, 352: 5, 368: 3, 381: 8, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 401: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 454: 8, 455: 7, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 510: 8, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 567: 5, 573: 1, 577: 8, 578: 8, 579: 8, 587: 8, 603: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 723: 4, 730: 4, 753: 5, 761: 7, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 969: 8, 975: 2, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 5, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1105: 5, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1233: 8, 1236: 8, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1268: 2, 1271: 8, 1279: 4, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1345: 8, 1346: 8, 1347: 8, 1355: 8, 1362: 8, 1417: 8, 1512: 8, 1514: 8, 1601: 8, 1602: 8, 1603: 7, 1609: 8, 1611: 8, 1613: 8, 1618: 8, 1649: 8, 1792: 8, 1793: 8, 1798: 8, 1799: 8, 1810: 8, 1813: 8, 1824: 8, 1825: 8, 1840: 8, 1842: 8, 1856: 8, 1858: 8, 1859: 8, 1860: 8, 1862: 8, 1863: 8, 1871: 8, 1872: 8, 1875: 8, 1879: 8, 1882: 8, 1888: 8, 1889: 8, 1892: 8, 1906: 7, 1907: 7, 1912: 7, 1919: 7, 1920: 7, 1927: 8, 1930: 7, 1937: 8, 1953: 8, 1954: 8, 1955: 8, 1968: 8, 1969: 8, 1971: 8, 1975: 8, 1988: 8, 1990: 8, 2000: 8, 2001: 8, 2004: 8, 2016: 8, 2017: 8, 2018: 8, 2019: 8, 2020: 8, 2024: 8, 2026: 8 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 292: 2, 298: 8, 304: 3, 309: 8, 313: 8, 320: 4, 322: 7, 328: 1, 331: 3, 352: 5, 368: 3, 381: 8, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 401: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 454: 8, 455: 7, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 510: 8, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 567: 5, 573: 1, 577: 8, 578: 8, 579: 8, 587: 8, 603: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 723: 4, 730: 4, 753: 5, 761: 7, 767: 4, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 969: 8, 975: 2, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 5, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1105: 5, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1233: 8, 1236: 8, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1268: 2, 1271: 8, 1279: 4, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1345: 8, 1346: 8, 1347: 8, 1355: 8, 1362: 8, 1417: 8, 1512: 8, 1514: 8, 1601: 8, 1602: 8, 1603: 7, 1609: 8, 1611: 8, 1613: 8, 1618: 8, 1649: 8, 1792: 8, 1793: 8, 1798: 8, 1799: 8, 1810: 8, 1813: 8, 1824: 8, 1825: 8, 1840: 8, 1842: 8, 1856: 8, 1858: 8, 1859: 8, 1860: 8, 1862: 8, 1863: 8, 1871: 8, 1872: 8, 1875: 8, 1879: 8, 1882: 8, 1888: 8, 1889: 8, 1892: 8, 1906: 7, 1907: 7, 1912: 7, 1919: 7, 1920: 7, 1927: 8, 1930: 7, 1937: 8, 1953: 8, 1954: 8, 1955: 8, 1968: 8, 1969: 8, 1971: 8, 1975: 8, 1988: 8, 1990: 8, 2000: 8, 2001: 8, 2004: 8, 2016: 8, 2017: 8, 2018: 8, 2019: 8, 2020: 8, 2024: 8, 2026: 8
}],
CAR.CHEVROLET_MALIBU_SDGM: [
# Chevy Malibu w/ SDGM Harness 2019
{
190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 5, 288: 5, 289: 8, 298: 8, 304: 1, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 587: 8, 707: 8, 715: 8, 717: 5, 761: 7, 767: 4, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4, 880: 6, 882: 8, 890: 1, 892: 2, 893: 2, 894: 1, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1353: 8, 1355: 8, 1611: 8, 1792: 8, 1793: 8, 1798: 8, 1799: 8, 1810: 8, 1813: 8, 1824: 8, 1825: 8, 1840: 8, 1842: 8, 1843: 8, 1856: 8, 1858: 8, 1859: 8, 1860: 8, 1862: 8, 1863: 8, 1871: 8, 1872: 8, 1875: 8, 1879: 8, 1882: 8, 1888: 8, 1889: 8, 1892: 8, 1916: 7, 1920: 8, 1927: 8, 1930: 7, 1937: 8, 1953: 8, 1954: 8, 1955: 8, 1968: 8, 1969: 8, 1971: 8, 1975: 8, 1988: 8, 1990: 8, 2000: 8, 2001: 8, 2002: 8, 2004: 8, 2017: 8, 2018: 8, 2020: 8
}], }],
CAR.BUICK_BABYENCLAVE: [ CAR.BUICK_BABYENCLAVE: [
# Buick Baby Enclave w/ ACC 2020-23 # Buick Baby Enclave w/ ACC 2020-23
{ {
190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 292: 2, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 331: 3, 352: 5, 353: 3, 368: 3, 381: 8, 384: 4, 386: 8, 388: 8, 394: 7, 398: 8, 401: 8, 405: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 450: 4, 451: 8, 452: 8, 453: 6, 454: 8, 455: 7, 456: 8, 457: 6, 462: 4, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 499: 3, 500: 6, 501: 8, 503: 2, 508: 8, 528: 5, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 569: 3, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 723: 4, 730: 4, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4, 872: 1, 880: 6, 882: 8, 890: 1, 892: 2, 893: 2, 894: 1, 961: 8, 969: 8, 975: 2, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1037: 5, 1105: 5, 1187: 5, 1195: 3, 1201: 3, 1217: 8, 1218: 3, 1221: 5, 1223: 3, 1225: 7, 1233: 8, 1236: 8, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1268: 2, 1271: 8, 1273: 3, 1276: 2, 1277: 7, 1278: 4, 1279: 4, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1345: 8, 1417: 8, 1512: 8, 1514: 8, 1517: 8, 1601: 8, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1914: 7, 1916: 7, 1919: 7, 1927: 7, 1930: 7, 2018: 8, 2020: 8, 2021: 8, 2028: 8 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 208: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 289: 8, 292: 2, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 331: 3, 352: 5, 353: 3, 368: 3, 381: 8, 384: 4, 386: 8, 388: 8, 394: 7, 398: 8, 401: 8, 405: 8, 407: 7, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 450: 4, 451: 8, 452: 8, 453: 6, 454: 8, 455: 7, 456: 8, 457: 6, 462: 4, 463: 3, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 499: 3, 500: 6, 501: 8, 503: 2, 508: 8, 528: 5, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 569: 3, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 715: 8, 717: 5, 723: 4, 730: 4, 761: 7, 767: 4, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4, 872: 1, 880: 6, 882: 8, 890: 1, 892: 2, 893: 2, 894: 1, 961: 8, 969: 8, 975: 2, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 6, 1017: 8, 1020: 8, 1033: 7, 1034: 7, 1037: 5, 1105: 5, 1187: 5, 1195: 3, 1201: 3, 1217: 8, 1218: 3, 1221: 5, 1223: 3, 1225: 7, 1233: 8, 1236: 8, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1268: 2, 1271: 8, 1273: 3, 1276: 2, 1277: 7, 1278: 4, 1279: 4, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1345: 8, 1417: 8, 1512: 8, 1514: 8, 1517: 8, 1601: 8, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1914: 7, 1916: 7, 1919: 7, 1927: 7, 1930: 7, 2018: 8, 2020: 8, 2021: 8, 2028: 8
}], }],
CAR.CHEVROLET_MALIBU_CC: [ CAR.CHEVROLET_MALIBU_CC: [
{ {
190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 328: 1, 352: 5, 368: 3, 381: 8, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 401: 8, 407: 7, 409: 8, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 455: 7, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 717: 5, 730: 4, 761: 7, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 961: 8, 969: 8, 975: 2, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 6, 1017: 8, 1020: 8, 1037: 5, 1105: 5, 1187: 6, 1189: 1, 1195: 3, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1233: 8, 1236: 8, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1268: 2, 1271: 8, 1273: 3, 1279: 4, 1280: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1906: 7, 1907: 7, 1912: 7, 1919: 7 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 257: 8, 288: 5, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 328: 1, 352: 5, 368: 3, 381: 8, 384: 4, 386: 8, 388: 8, 393: 7, 398: 8, 401: 8, 407: 7, 409: 8, 413: 8, 417: 7, 419: 1, 422: 4, 426: 7, 431: 8, 442: 8, 451: 8, 452: 8, 453: 6, 455: 7, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 532: 6, 554: 3, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 567: 5, 573: 1, 577: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 6, 707: 8, 717: 5, 730: 4, 761: 7, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 961: 8, 969: 8, 975: 2, 977: 8, 979: 8, 985: 5, 1001: 8, 1005: 6, 1009: 8, 1011: 6, 1013: 6, 1017: 8, 1020: 8, 1037: 5, 1105: 5, 1187: 6, 1189: 1, 1195: 3, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1233: 8, 1236: 8, 1249: 8, 1257: 6, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1268: 2, 1271: 8, 1273: 3, 1279: 4, 1280: 4, 1300: 8, 1322: 6, 1323: 4, 1328: 4, 1417: 8, 1601: 8, 1906: 7, 1907: 7, 1912: 7, 1919: 7
}], }],
CAR.CHEVROLET_MALIBU_HYBRID_CC: [
{
193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 352: 5, 386: 8, 451: 8, 452: 8, 453: 6, 481: 7, 485: 8, 489: 8, 493: 8, 500: 6, 560: 8, 562: 8, 566: 6, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 717: 5, 761: 7, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4
}],
CAR.CHEVROLET_TRAX: [ CAR.CHEVROLET_TRAX: [
{ {
190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1930: 7 190: 6, 193: 8, 197: 8, 201: 8, 209: 7, 211: 2, 241: 6, 249: 8, 288: 5, 298: 8, 304: 3, 309: 8, 311: 8, 313: 8, 320: 4, 322: 7, 328: 1, 352: 5, 381: 8, 384: 4, 386: 8, 388: 8, 413: 8, 451: 8, 452: 8, 453: 6, 455: 7, 479: 3, 481: 7, 485: 8, 489: 8, 497: 8, 500: 6, 501: 8, 532: 6, 560: 8, 562: 8, 563: 5, 565: 5, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 707: 8, 715: 8, 717: 5, 761: 7, 789: 5, 800: 6, 810: 8, 840: 5, 842: 5, 844: 8, 869: 4, 880: 6, 977: 8, 1001: 8, 1011: 6, 1017: 8, 1020: 8, 1217: 8, 1221: 5, 1233: 8, 1249: 8, 1259: 8, 1261: 7, 1263: 4, 1265: 8, 1267: 1, 1271: 8, 1280: 4, 1296: 4, 1300: 8, 1930: 7
}], }],
CAR.CHEVROLET_VOLT_2019: [
# Chevy Volt w/ ACC 2019
{
170: 8, 189: 7, 190: 6, 193: 8, 197: 8, 199: 4, 201: 8, 209: 7, 211: 2, 241: 6, 257: 8, 288: 5, 289: 8, 292: 2, 298: 8, 304: 1, 308: 4, 309: 8, 311: 8, 313: 8, 320: 3, 328: 1, 331: 3, 352: 5, 368: 3, 381: 8, 384: 4, 386: 8, 388: 8, 390: 7, 417: 7, 419: 1, 426: 7, 451: 8, 452: 8, 453: 6, 454: 8, 456: 8, 479: 3, 481: 7, 485: 8, 489: 8, 493: 8, 495: 4, 497: 8, 499: 3, 500: 6, 501: 8, 508: 8, 528: 5, 532: 6, 546: 7, 550: 8, 554: 3, 558: 8, 560: 8, 562: 8, 563: 5, 564: 5, 565: 5, 566: 7, 567: 5, 573: 1, 577: 8, 587: 8, 608: 8, 609: 6, 610: 6, 611: 6, 612: 8, 613: 8, 647: 3, 707: 8, 711: 6, 715: 8, 717: 5, 761: 7, 767: 4, 810: 8, 840: 5, 842: 5, 844: 8, 866: 4, 869: 4, 880: 6, 961: 8, 967: 4, 969: 8, 975: 2, 977: 8, 979: 7, 988: 6, 989: 8, 995: 7, 1001: 8, 1005: 6, 1009: 8, 1017: 8, 1019: 2, 1020: 8, 1033: 7, 1034: 7, 1105: 5, 1187: 4, 1217: 8, 1221: 5, 1223: 3, 1225: 7, 1227: 4, 1233: 8, 1236: 8, 1249: 8, 1257: 6, 1265: 8, 1267: 1, 1268: 2, 1273: 3, 1275: 3, 1279: 4, 1280: 4, 1296: 4, 1300: 8, 1322: 6, 1328: 4, 1345: 8, 1417: 8, 1512: 8, 1513: 8, 1516: 8, 1517: 8, 1601: 8, 1609: 8, 1611: 8, 1618: 8, 1613: 8, 1649: 8, 1792: 8, 1793: 8, 1798: 8, 1799: 8, 1810: 8, 1813: 8, 1824: 8, 1825: 8, 1840: 8, 1842: 8, 1856: 8, 1858: 8, 1859: 8, 1860: 8, 1862: 8, 1863: 8, 1871: 8, 1872: 8, 1875: 8, 1879: 8, 1882: 8, 1888: 8, 1889: 8, 1892: 8, 1905: 7, 1906: 7, 1907: 7, 1910: 7, 1912: 7, 1920: 8, 1922: 7, 1927: 7, 1930: 7, 1937: 8, 1953: 8, 1954: 8, 1955: 8, 1968: 8, 1969: 8, 1971: 8, 1975: 8, 1988: 8, 1990: 8, 2000: 8, 2001: 8, 2004: 8, 2017: 8, 2018: 8, 2020: 8, 2021: 8, 2023: 8, 2025: 8, 2028: 8, 2031: 8
}],
} }
FW_VERSIONS: dict[str, dict[tuple, list[bytes]]] = { FW_VERSIONS: dict[str, dict[tuple, list[bytes]]] = {
+123 -27
View File
@@ -6,6 +6,56 @@ from openpilot.common.realtime import DT_CTRL
from openpilot.selfdrive.car import make_can_msg from openpilot.selfdrive.car import make_can_msg
from openpilot.selfdrive.car.gm.values import CAR, CruiseButtons, CanBus from openpilot.selfdrive.car.gm.values import CAR, CruiseButtons, CanBus
MALIBU_BUTTON_TABLE = {
0: [0x2FBC, 0x25DE, 0x15EE, 0x1FCC],
1: [0x55AE, 0x5F8C, 0x6F7C, 0x659E],
4: [0x2ACD, 0x20EF, 0x1ADD, 0x10FF],
5: [0x50BF, 0x5A9D, 0x60AF, 0x6A8D],
}
MALIBU_BUTTON_MAP = {
CruiseButtons.UNPRESS: 0,
CruiseButtons.RES_ACCEL: 1,
CruiseButtons.MAIN: 4,
CruiseButtons.CANCEL: 5,
}
def malibu_phase_map_for_button(button):
key = MALIBU_BUTTON_MAP.get(button, None)
if key is None or key not in MALIBU_BUTTON_TABLE:
return None
return {v: i for i, v in enumerate(MALIBU_BUTTON_TABLE[key])}
def malibu_phase_map_for_acc(acc_value):
seq = MALIBU_BUTTON_TABLE.get(acc_value)
if not seq:
return None
return {v: i for i, v in enumerate(seq)}
def create_buttons_malibu(packer, bus, button, phase, prefix=0x41):
key = MALIBU_BUTTON_MAP.get(button, None)
if key is None or key not in MALIBU_BUTTON_TABLE:
# fallback to standard checksum for unsupported buttons
return create_buttons(packer, bus, 0, button)
values = {
"ACCButtons": button,
"RollingCounter": 0,
"ACCAlwaysOne": 1,
"DistanceButton": 0,
}
dat = packer.make_can_msg("ASCMSteeringButton", bus, values)[2]
data = bytearray(dat)
data[3] = prefix & 0xFF
seq = MALIBU_BUTTON_TABLE[key]
val = seq[phase % len(seq)]
data[5] = (val >> 8) & 0xFF
data[6] = val & 0xFF
return make_can_msg(0x1e1, bytes(data), bus)
def create_buttons(packer, bus, idx, button): def create_buttons(packer, bus, idx, button):
values = { values = {
@@ -23,6 +73,17 @@ def create_buttons(packer, bus, idx, button):
values["SteeringButtonChecksum"] = checksum values["SteeringButtonChecksum"] = checksum
return packer.make_can_msg("ASCMSteeringButton", bus, values) return packer.make_can_msg("ASCMSteeringButton", bus, values)
def create_buttons_malibu_cancel(bus, phase, prefix=0x41):
# Malibu Hybrid CC cancel frames use a 4-value pattern in the last 2 bytes.
data = bytearray(7)
data[3] = prefix & 0xFF
data[4] = 0x00
cancel_bytes = (0x60, 0xAF, 0x65, 0x9E, 0x6A, 0x8D, 0x6F, 0x7C)
idx = ((phase + 2) % 4) * 2
data[5] = cancel_bytes[idx]
data[6] = cancel_bytes[idx + 1]
return make_can_msg(0x1e1, bytes(data), bus)
def create_pscm_status(packer, bus, pscm_status): def create_pscm_status(packer, bus, pscm_status):
values = {s: pscm_status[s] for s in [ values = {s: pscm_status[s] for s in [
@@ -57,7 +118,7 @@ def create_adas_keepalive(bus):
return [make_can_msg(0x409, dat, bus), make_can_msg(0x40a, dat, bus)] return [make_can_msg(0x409, dat, bus), make_can_msg(0x40a, dat, bus)]
def create_gas_regen_command(packer, bus, throttle, idx, enabled, at_full_stop): def create_gas_regen_command(packer, bus, throttle, idx, enabled, at_full_stop, include_always_one3=False):
values = { values = {
"GasRegenCmdActive": enabled, "GasRegenCmdActive": enabled,
"RollingCounter": idx, "RollingCounter": idx,
@@ -66,8 +127,9 @@ def create_gas_regen_command(packer, bus, throttle, idx, enabled, at_full_stop):
"GasRegenFullStopActive": at_full_stop, "GasRegenFullStopActive": at_full_stop,
"GasRegenAlwaysOne": 1, "GasRegenAlwaysOne": 1,
"GasRegenAlwaysOne2": 1, "GasRegenAlwaysOne2": 1,
"GasRegenAlwaysOne3": 1,
} }
if include_always_one3:
values["GasRegenAlwaysOne3"] = 1
dat = packer.make_can_msg("ASCMGasRegenCmd", bus, values)[2] dat = packer.make_can_msg("ASCMGasRegenCmd", bus, values)[2]
values["GasRegenChecksum"] = (((0xff - dat[1]) & 0xff) << 16) | \ values["GasRegenChecksum"] = (((0xff - dat[1]) & 0xff) << 16) | \
@@ -81,7 +143,7 @@ def create_friction_brake_command(packer, bus, apply_brake, idx, enabled, near_s
mode = 0x1 mode = 0x1
# TODO: Understand this better. Volts and ICE Camera ACC cars are 0x1 when enabled with no brake # TODO: Understand this better. Volts and ICE Camera ACC cars are 0x1 when enabled with no brake
if enabled and CP.carFingerprint in (CAR.CHEVROLET_BOLT_EUV,): if enabled and CP.carFingerprint in (CAR.CHEVROLET_BOLT_ACC_2022_2023,):
mode = 0x9 mode = 0x9
if apply_brake > 0: if apply_brake > 0:
@@ -177,47 +239,81 @@ def create_lka_icon_command(bus, active, critical, steer):
dat = b"\x00\x00\x00" dat = b"\x00\x00\x00"
return make_can_msg(0x104c006c, dat, bus) return make_can_msg(0x104c006c, dat, bus)
def create_prndl2_command(packer, bus, press_regen_paddle, CP):
def create_gm_cc_spam_command(packer, controller, CS, actuators): if CP.carFingerprint in (CAR.CHEVROLET_BOLT_ACC_2022_2023, CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL, CAR.CHEVROLET_BOLT_CC_2022_2023):
if controller.params_.get_bool("IsMetric"): prndl2_value = 5 if press_regen_paddle else 6
_CV = CV.MS_TO_KPH
RATE_UP_MAX = 0.04
RATE_DOWN_MAX = 0.04
else: else:
_CV = CV.MS_TO_MPH prndl2_value = 7 if press_regen_paddle else 6
RATE_UP_MAX = 0.2 manual_mode = 1 if press_regen_paddle else 0
RATE_DOWN_MAX = 0.2 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)
accel = actuators.accel * _CV # m/s/s to mph/s def create_regen_paddle_command(packer, bus, press_regen_paddle):
speedSetPoint = int(round(CS.out.cruiseState.speed * _CV)) 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, frogpilot_toggles):
accel = actuators.accel
Vego = CS.out.vEgo
cruiseBtn = CruiseButtons.INIT cruiseBtn = CruiseButtons.INIT
if speedSetPoint == CS.CP.minEnableSpeed and accel < -1: 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:
cruiseBtn = CruiseButtons.CANCEL cruiseBtn = CruiseButtons.CANCEL
controller.apply_speed = 0 controller.apply_speed = 0
rate = 0.04 elif DesiredSetPoint < speedSetPoint and speedSetPoint > CS.CP.minEnableSpeed * MS_CONVERT + 1:
elif accel < 0:
cruiseBtn = CruiseButtons.DECEL_SET 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 controller.apply_speed = speedSetPoint - 1
elif accel > 0: elif DesiredSetPoint > speedSetPoint:
cruiseBtn = CruiseButtons.RES_ACCEL 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 controller.apply_speed = speedSetPoint + 1
else: else:
cruiseBtn = CruiseButtons.INIT
controller.apply_speed = speedSetPoint controller.apply_speed = speedSetPoint
rate = float('inf')
# Check rlogs closely - our message shouldn't show up on the pt bus for us # 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 # 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): if (cruiseBtn != CruiseButtons.INIT) and ((controller.frame - controller.last_button_frame) * DT_CTRL > rate):
controller.last_button_frame = controller.frame controller.last_button_frame = controller.frame
if CS.CP.carFingerprint == CAR.CHEVROLET_MALIBU_HYBRID_CC:
phase_map = malibu_phase_map_for_button(cruiseBtn)
if phase_map:
msgs = [create_buttons_malibu(packer, CanBus.POWERTRAIN, cruiseBtn, controller.malibu_button_phase,
CS.steering_button_prefix)]
controller.malibu_button_phase = (controller.malibu_button_phase + 1) % 4
return msgs
idx = (CS.buttons_counter + 1) % 4 # Need to predict the next idx for '22-23 EUV idx = (CS.buttons_counter + 1) % 4 # Need to predict the next idx for '22-23 EUV
return [create_buttons(packer, CanBus.POWERTRAIN, idx, cruiseBtn)] return [create_buttons(packer, CanBus.POWERTRAIN, idx, cruiseBtn)]
else: else:
+280 -71
View File
@@ -7,7 +7,7 @@ from panda import Panda
from openpilot.common.conversions import Conversions as CV from openpilot.common.conversions import Conversions as CV
from openpilot.selfdrive.car import create_button_events, get_safety_config from openpilot.selfdrive.car import create_button_events, get_safety_config
from openpilot.selfdrive.car.gm.radar_interface import RADAR_HEADER_MSG from openpilot.selfdrive.car.gm.radar_interface import RADAR_HEADER_MSG
from openpilot.selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus, GMFlags, CC_ONLY_CAR, SDGM_CAR from openpilot.selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus, GMFlags, CC_ONLY_CAR, SDGM_CAR, ASCM_INT, set_red_panda_canbus
from openpilot.selfdrive.car.interfaces import CarInterfaceBase, TorqueFromLateralAccelCallbackType, FRICTION_THRESHOLD, LateralAccelFromTorqueCallbackType, get_friction_threshold from openpilot.selfdrive.car.interfaces import CarInterfaceBase, TorqueFromLateralAccelCallbackType, FRICTION_THRESHOLD, LateralAccelFromTorqueCallbackType, get_friction_threshold
from openpilot.selfdrive.controls.lib.drive_helpers import get_friction from openpilot.selfdrive.controls.lib.drive_helpers import get_friction
@@ -26,11 +26,48 @@ CAM_MSG = 0x320 # AEBCmd
# TODO: Is this always linked to camera presence? # TODO: Is this always linked to camera presence?
ACCELERATOR_POS_MSG = 0xbe ACCELERATOR_POS_MSG = 0xbe
VOLT_LIKE_CARS = {
CAR.CHEVROLET_VOLT,
CAR.CHEVROLET_VOLT_2019,
CAR.CHEVROLET_VOLT_CC,
CAR.CHEVROLET_VOLT_CAMERA,
CAR.CHEVROLET_VOLT_ASCM,
CAR.CHEVROLET_MALIBU,
CAR.CHEVROLET_MALIBU_ASCM,
CAR.CHEVROLET_MALIBU_SDGM,
CAR.CHEVROLET_MALIBU_CC,
CAR.CHEVROLET_MALIBU_HYBRID_CC,
}
NON_LINEAR_TORQUE_PARAMS = { NON_LINEAR_TORQUE_PARAMS = {
CAR.CHEVROLET_BOLT_EUV: [2.6531724862969748, 1.0, 0.1919764879840985, 0.009054123646805178], CAR.CHEVROLET_BOLT_ACC_2022_2023: {
CAR.CHEVROLET_BOLT_CC: [2.6531724862969748, 1.0, 0.1919764879840985, 0.009054123646805178], "left": [2.6531724862969748, 1.1, 0.1919764879840985, 0.0],
CAR.GMC_ACADIA: [4.78003305, 1.0, 0.3122, 0.05591772], "right": [2.7031724862969748, 1.0, 0.1469764879840985, 0.0],
CAR.CHEVROLET_SILVERADO: [3.29974374, 1.0, 0.25571356, 0.0465122] },
CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL: {
"left": [2.6531724862969748, 1.1, 0.1919764879840985, 0.0],
"right": [2.7031724862969748, 1.0, 0.1469764879840985, 0.0],
},
CAR.CHEVROLET_BOLT_CC_2022_2023: {
"left": [2.6531724862969748, 1.1, 0.1919764879840985, 0.0],
"right": [2.7031724862969748, 1.0, 0.1469764879840985, 0.0],
},
CAR.CHEVROLET_BOLT_CC_2019_2021: {
"left": [1.8, 1.1, 0.27, 0.0],
"right": [2.0, 1.0, 0.205, 0.0],
},
CAR.CHEVROLET_BOLT_CC_2017: {
"left": [2.15, 1.0, 0.21, 0.0],
"right": [2.15, 1.0, 0.21, 0.0],
},
CAR.GMC_ACADIA: {
"left": [4.78003305, 1.0, 0.3122, 0.05591772],
"right": [4.78003305, 1.0, 0.3122, 0.05591772],
},
CAR.CHEVROLET_SILVERADO: {
"left": [3.8, 0.81, 0.24, 0.0465122],
"right": [3.8, 0.81, 0.24, 0.0465122],
},
} }
@@ -51,7 +88,7 @@ class CarInterface(CarInterfaceBase):
return 0.10006696 * sigmoid * (v_ego + 3.12485927) return 0.10006696 * sigmoid * (v_ego + 3.12485927)
def get_steer_feedforward_function(self): def get_steer_feedforward_function(self):
if self.CP.carFingerprint in (CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_CC): if self.CP.carFingerprint in VOLT_LIKE_CARS:
return self.get_steer_feedforward_volt return self.get_steer_feedforward_volt
else: else:
return CarInterfaceBase.get_steer_feedforward_default return CarInterfaceBase.get_steer_feedforward_default
@@ -64,10 +101,12 @@ class CarInterface(CarInterfaceBase):
# This has big effect on the stability about 0 (noise when going straight) # 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) non_linear_torque_params = NON_LINEAR_TORQUE_PARAMS.get(self.CP.carFingerprint)
assert non_linear_torque_params, "The params are not defined" assert non_linear_torque_params, "The params are not defined"
a, b, c, _ = non_linear_torque_params # Left is positive
side_key = "left" if lateral_acceleration >= 0 else "right"
a, b, c, d = non_linear_torque_params[side_key]
sig_input = a * lateral_acceleration sig_input = a * lateral_acceleration
sig = np.sign(sig_input) * (1 / (1 + exp(-fabs(sig_input))) - 0.5) sig = np.sign(sig_input) * (1 / (1 + exp(-fabs(sig_input))) - 0.5)
steer_torque = (sig * b) + (lateral_acceleration * c) steer_torque = (sig * b) + (lateral_acceleration * c) + d
return float(steer_torque) return float(steer_torque)
lataccel_values = np.arange(-5.0, 5.0, 0.01) lataccel_values = np.arange(-5.0, 5.0, 0.01)
@@ -106,73 +145,184 @@ class CarInterface(CarInterfaceBase):
@staticmethod @staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs, frogpilot_toggles): def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs, frogpilot_toggles):
ret.carName = "gm" ret.carName = "gm"
red_panda = getattr(frogpilot_toggles, "red_panda", False)
set_red_panda_canbus(red_panda)
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.gm)] ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.gm)]
if red_panda:
ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.noOutput), ret.safetyConfigs[0]]
gm_safety_cfg = ret.safetyConfigs[-1] if red_panda else ret.safetyConfigs[0]
ret.autoResumeSng = False ret.autoResumeSng = False
ret.enableBsm = 0x142 in fingerprint[CanBus.POWERTRAIN] ret.enableBsm = 0x142 in fingerprint.get(CanBus.POWERTRAIN, {})
def has_sascm(fingerprint):
return 0x2FF in fingerprint.get(CanBus.POWERTRAIN, {})
# Detect Beartech SASCM allows openpilot longitudinal control on SDGM and ASCM_INT vehicles # Detect Beartech SASCM allows openpilot longitudinal control on SDGM and ASCM_INT vehicles
if 0x2FF in fingerprint[0]: if has_sascm(fingerprint):
ret.flags |= GMFlags.SASCM.value ret.flags |= GMFlags.SASCM.value
if PEDAL_MSG in fingerprint[0]: if PEDAL_MSG in fingerprint.get(CanBus.POWERTRAIN, {}):
ret.enableGasInterceptor = True ret.enableGasInterceptor = True
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_GAS_INTERCEPTOR gm_safety_cfg.safetyParam |= Panda.FLAG_GM_GAS_INTERCEPTOR
if candidate == CAR.CHEVROLET_BOLT_ACC_2022_2023:
# Hard-block pedal interceptor for ACC fingerprinted Bolts
ret.enableGasInterceptor = False
gm_safety_cfg.safetyParam &= ~Panda.FLAG_GM_GAS_INTERCEPTOR
else:
# When a pedal interceptor is present, always use normal longitudinal (block stock cruise)
experimental_long = False
if candidate in EV_CAR: if candidate in EV_CAR:
ret.transmissionType = TransmissionType.direct ret.transmissionType = TransmissionType.direct
else: else:
ret.transmissionType = TransmissionType.automatic ret.transmissionType = TransmissionType.automatic
ret.longitudinalTuning.kiBP = [5., 35.] kaofui_cars = SDGM_CAR | ASCM_INT | VOLT_LIKE_CARS | {CAR.CHEVROLET_MALIBU_HYBRID_CC}
ret.longitudinalTuning.kiBP = [5., 35.] if candidate in kaofui_cars else [5., 35., 60.]
if candidate in CAMERA_ACC_CAR: is_bolt_2022_2023_pedal = candidate == CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL and ret.enableGasInterceptor
ret.experimentalLongitudinalAvailable = candidate not in CC_ONLY_CAR
kaofui_camera_cars = {
CAR.CHEVROLET_VOLT_CAMERA,
CAR.CHEVROLET_VOLT_CC,
CAR.CHEVROLET_MALIBU_HYBRID_CC,
}
bolt_cc_camera_cars = {
CAR.CHEVROLET_BOLT_CC_2017,
CAR.CHEVROLET_BOLT_CC_2019_2021,
CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL,
CAR.CHEVROLET_BOLT_CC_2022_2023,
}
is_camera_acc = candidate in CAMERA_ACC_CAR and candidate not in kaofui_cars and \
(candidate not in CC_ONLY_CAR or candidate in bolt_cc_camera_cars)
if candidate in kaofui_camera_cars:
# Keep Volt/Malibu camera path functionally aligned with kaofui.
ret.experimentalLongitudinalAvailable = candidate not in (CC_ONLY_CAR | ASCM_INT | SDGM_CAR) or has_sascm(fingerprint)
ret.networkLocation = NetworkLocation.fwdCamera ret.networkLocation = NetworkLocation.fwdCamera
ret.radarUnavailable = True # no radar ret.radarUnavailable = 0x460 not in fingerprint.get(CanBus.OBSTACLE, {})
ret.pcmCruise = True ret.pcmCruise = True
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM
ret.minEnableSpeed = 5 * CV.KPH_TO_MS ret.minEnableSpeed = 5 * CV.KPH_TO_MS
ret.minSteerSpeed = 10 * CV.KPH_TO_MS ret.minSteerSpeed = 10 * CV.KPH_TO_MS
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM
# Tuning for experimental long # Tuning for experimental long
ret.longitudinalTuning.kiV = [2.0, 1.5] ret.longitudinalTuning.kiV = [0.5, 0.5]
ret.vEgoStopping = 0.1 ret.stoppingDecelRate = 1.0 # reach brake quickly after enabling
ret.vEgoStarting = 0.1
ret.stoppingDecelRate = 2.0 # reach brake quickly after enabling
ret.vEgoStopping = 0.25 ret.vEgoStopping = 0.25
ret.vEgoStarting = 0.25 ret.vEgoStarting = 0.25
ret.stopAccel = -0.25
if ret.experimentalLongitudinalAvailable and experimental_long: if ret.experimentalLongitudinalAvailable and experimental_long:
ret.pcmCruise = False ret.pcmCruise = False
ret.openpilotLongitudinalControl = True ret.openpilotLongitudinalControl = True
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM_LONG gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM_LONG
elif is_camera_acc:
elif candidate in SDGM_CAR: # TorqueTune camera-ACC behavior
ret.longitudinalTuning.kiV = [0., 0.] # TODO: tuning ret.experimentalLongitudinalAvailable = (candidate not in CC_ONLY_CAR) and not ret.enableGasInterceptor
ret.experimentalLongitudinalAvailable = False
ret.networkLocation = NetworkLocation.fwdCamera ret.networkLocation = NetworkLocation.fwdCamera
ret.pcmCruise = True ret.radarUnavailable = True # no radar
ret.radarUnavailable = True ret.pcmCruise = not ret.enableGasInterceptor
ret.minEnableSpeed = -1. # engage speed is decided by ASCM gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM
ret.minSteerSpeed = 30 * CV.MPH_TO_MS ret.minEnableSpeed = 5 * CV.KPH_TO_MS
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_SDGM ret.minSteerSpeed = 10 * CV.KPH_TO_MS
# Tuning for experimental long
ret.longitudinalTuning.kiV = [0.5, 0.5, 0.5]
ret.vEgoStopping = 0.1
ret.vEgoStarting = 0.1
ret.stoppingDecelRate = 1.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
ret.openpilotLongitudinalControl = True
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM_LONG
elif candidate in SDGM_CAR:
# kaofui parity: SDGM cars require SASCM for experimental long
ret.experimentalLongitudinalAvailable = candidate not in (CC_ONLY_CAR | ASCM_INT | SDGM_CAR) or has_sascm(fingerprint)
ret.networkLocation = NetworkLocation.fwdCamera
ret.radarUnavailable = 0x460 not in fingerprint.get(CanBus.OBSTACLE, {})
ret.pcmCruise = True
ret.minEnableSpeed = -1. # engage speed is decided by pcm
ret.minSteerSpeed = 7 * CV.MPH_TO_MS
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_SDGM
# Use C9 brake bit on Blazer and SDGM variants that lack 0xBE (ECMAcceleratorPos),
# so panda brake_pressed source matches carstate on light taps.
if candidate == CAR.CHEVROLET_BLAZER or ACCELERATOR_POS_MSG not in fingerprint.get(CanBus.POWERTRAIN, {}):
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_FORCE_BRAKE_C9
ret.flags |= GMFlags.FORCE_BRAKE_C9.value
# Tuning for experimental long
ret.longitudinalTuning.kiV = [0.5, 0.5] if candidate in kaofui_cars else [0.5, 0.5, 0.5]
ret.vEgoStopping = 0.1
ret.vEgoStarting = 0.1
ret.stoppingDecelRate = 1.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
ret.openpilotLongitudinalControl = True
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM_LONG
if is_bolt_2022_2023_pedal:
ret.experimentalLongitudinalAvailable = False
ret.pcmCruise = False
elif candidate in ASCM_INT and has_sascm(fingerprint):
ret.experimentalLongitudinalAvailable = True
ret.networkLocation = NetworkLocation.fwdCamera
ret.radarUnavailable = 0x460 not in fingerprint.get(CanBus.OBSTACLE, {})
ret.pcmCruise = True
ret.minEnableSpeed = 5 * CV.KPH_TO_MS
ret.minSteerSpeed = 7 * CV.MPH_TO_MS
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_ASCM_INT
# Tuning for experimental long
ret.longitudinalTuning.kiV = [0.5, 0.5] if candidate in kaofui_cars else [0.5, 0.5, 0.5]
ret.vEgoStopping = 0.1
ret.vEgoStarting = 0.1
ret.stoppingDecelRate = 1.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
ret.openpilotLongitudinalControl = True
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM_LONG
if is_bolt_2022_2023_pedal:
ret.experimentalLongitudinalAvailable = False
ret.pcmCruise = False
else: # ASCM, OBD-II harness else: # ASCM, OBD-II harness
ret.openpilotLongitudinalControl = not frogpilot_toggles.disable_openpilot_long ret.openpilotLongitudinalControl = not frogpilot_toggles.disable_openpilot_long
ret.networkLocation = NetworkLocation.gateway ret.networkLocation = NetworkLocation.gateway
ret.radarUnavailable = RADAR_HEADER_MSG not in fingerprint[CanBus.OBSTACLE] and not docs ret.radarUnavailable = RADAR_HEADER_MSG not in fingerprint.get(CanBus.OBSTACLE, {}) and not docs
ret.pcmCruise = False # stock non-adaptive cruise control is kept off ret.pcmCruise = False # stock non-adaptive cruise control is kept off
# supports stop and go, but initial engage must (conservatively) be above 18mph # supports stop and go, but initial engage must (conservatively) be above 18mph
ret.minEnableSpeed = 18 * CV.MPH_TO_MS ret.minEnableSpeed = 18 * CV.MPH_TO_MS
ret.minSteerSpeed = 7 * CV.MPH_TO_MS ret.minSteerSpeed = 7 * CV.MPH_TO_MS
# Tuning # Tuning
ret.longitudinalTuning.kiV = [2.4, 1.5] ret.longitudinalTuning.kiV = [0.5, 0.5] if candidate in kaofui_cars else [0.5, 0.5, 0.5]
if candidate in kaofui_cars:
ret.stoppingDecelRate = 3
ret.vEgoStopping = 0.75
ret.vEgoStarting = 0.75
ret.stopAccel = -1.5
if ret.enableGasInterceptor: if ret.enableGasInterceptor:
# Need to set ASCM long limits when using pedal interceptor, instead of camera ACC long limits # Need to set ASCM long limits when using pedal interceptor, instead of camera ACC long limits
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_ASCM_LONG gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_ASCM_LONG
if getattr(frogpilot_toggles, "remote_start_boots_comma", False):
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_REMOTE_START_BOOTS_COMMA
# Start with a baseline tuning for all GM vehicles. Override tuning as needed in each model section below. # Start with a baseline tuning for all GM vehicles. Override tuning as needed in each model section below.
ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]] ret.lateralTuning.pid.kiBP, ret.lateralTuning.pid.kpBP = [[0.], [0.]]
@@ -186,14 +336,17 @@ class CarInterface(CarInterfaceBase):
ret.radarTimeStep = 0.0667 # GM radar runs at 15Hz instead of standard 20Hz ret.radarTimeStep = 0.0667 # GM radar runs at 15Hz instead of standard 20Hz
ret.longitudinalActuatorDelay = 0.5 # large delay to initially start braking ret.longitudinalActuatorDelay = 0.5 # large delay to initially start braking
if candidate in (CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_CC): if candidate in (CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_CC, CAR.CHEVROLET_VOLT_CAMERA):
ret.minEnableSpeed = -1 ret.minEnableSpeed = -1
ret.lateralTuning.pid.kpBP = [0., 40.]
ret.lateralTuning.pid.kpV = [0., 0.17] if candidate == CAR.CHEVROLET_VOLT_2019 and not ret.openpilotLongitudinalControl:
ret.lateralTuning.pid.kiBP = [0.] ret.minEnableSpeed = -1
ret.lateralTuning.pid.kiV = [0.]
ret.lateralTuning.pid.kf = 1. # get_steer_feedforward_volt() if candidate in VOLT_LIKE_CARS:
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
ret.steerActuatorDelay = 0.2 ret.steerActuatorDelay = 0.2
if candidate == CAR.CHEVROLET_MALIBU_HYBRID_CC and ret.enableGasInterceptor:
ret.flags |= GMFlags.PEDAL_LONG.value
elif candidate == CAR.GMC_ACADIA: elif candidate == CAR.GMC_ACADIA:
ret.minEnableSpeed = -1. # engage speed is decided by pcm ret.minEnableSpeed = -1. # engage speed is decided by pcm
@@ -218,15 +371,30 @@ class CarInterface(CarInterfaceBase):
ret.steerActuatorDelay = 0.2 ret.steerActuatorDelay = 0.2
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate in (CAR.CHEVROLET_BOLT_EUV, CAR.CHEVROLET_BOLT_CC): elif candidate in (CAR.CHEVROLET_BOLT_ACC_2022_2023, CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL, CAR.CHEVROLET_BOLT_CC_2022_2023, CAR.CHEVROLET_BOLT_CC_2019_2021, CAR.CHEVROLET_BOLT_CC_2017):
ret.steerActuatorDelay = 0.2 ret.steerActuatorDelay = 0.2
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
# Bolt-only lateral tuning overrides
ret.lateralTuning.torque.kp = 1.03
ret.lateralTuning.torque.ki = 1.07
ret.lateralTuning.torque.kd = 0.93
ret.lateralTuning.torque.kfDEPRECATED = 0.02
if candidate == CAR.CHEVROLET_BOLT_CC_2017:
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_BOLT_2017
if ret.enableGasInterceptor: if ret.enableGasInterceptor:
# ACC Bolts use pedal for full longitudinal control, not just sng # ACC Bolts use pedal for full longitudinal control, not just sng
ret.flags |= GMFlags.PEDAL_LONG.value ret.flags |= GMFlags.PEDAL_LONG.value
elif candidate == CAR.CHEVROLET_SILVERADO: # Enable pedal interceptor for ACC models when detected
if is_bolt_2022_2023_pedal:
ret.flags |= GMFlags.PEDAL_LONG.value
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_NO_ACC
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_BOLT_2022_PEDAL
if candidate == CAR.CHEVROLET_SILVERADO:
# On the Bolt, the ECM and camera independently check that you are either above 5 kph or at a stop # On the Bolt, the ECM and camera independently check that you are either above 5 kph or at a stop
# with foot on brake to allow engagement, but this platform only has that check in the camera. # with foot on brake to allow engagement, but this platform only has that check in the camera.
# TODO: check if this is split by EV/ICE with more platforms in the future # TODO: check if this is split by EV/ICE with more platforms in the future
@@ -249,22 +417,34 @@ class CarInterface(CarInterfaceBase):
ret.steerActuatorDelay = 0.2 ret.steerActuatorDelay = 0.2
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate == CAR.CADILLAC_XT6:
ret.steerActuatorDelay = 0.2
ret.minSteerSpeed = 7 * CV.MPH_TO_MS
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate == CAR.CADILLAC_XT4: elif candidate == CAR.CADILLAC_XT4:
ret.steerActuatorDelay = 0.2 ret.steerActuatorDelay = 0.2
if not ret.openpilotLongitudinalControl:
ret.minEnableSpeed = -1. # engage speed is decided by pcm
ret.minSteerSpeed = 30 * CV.MPH_TO_MS
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate == CAR.CADILLAC_XT5_CC: elif candidate == CAR.CADILLAC_XT5_CC:
ret.steerActuatorDelay = 0.2 ret.steerActuatorDelay = 0.2
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate == CAR.CHEVROLET_TRAVERSE: elif candidate in (CAR.CHEVROLET_TRAVERSE, CAR.CHEVROLET_BLAZER):
ret.steerActuatorDelay = 0.2 ret.steerActuatorDelay = 0.2
ret.minSteerSpeed = 10 * CV.KPH_TO_MS if not ret.openpilotLongitudinalControl:
ret.minEnableSpeed = -1. # engage speed is decided by pcm
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
if candidate == CAR.CHEVROLET_BLAZER:
ret.minEnableSpeed = 5 * CV.KPH_TO_MS
elif candidate == CAR.BUICK_BABYENCLAVE: elif candidate == CAR.BUICK_BABYENCLAVE:
ret.steerActuatorDelay = 0.2 ret.steerActuatorDelay = 0.2
ret.minSteerSpeed = 10 * CV.KPH_TO_MS if not ret.openpilotLongitudinalControl:
ret.minEnableSpeed = -1. # engage speed is decided by pcm
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate == CAR.CADILLAC_CT6_CC: elif candidate == CAR.CADILLAC_CT6_CC:
@@ -279,56 +459,80 @@ class CarInterface(CarInterfaceBase):
if ret.enableGasInterceptor and frogpilot_toggles.gm_pedal_longitudinal: if ret.enableGasInterceptor and frogpilot_toggles.gm_pedal_longitudinal:
ret.networkLocation = NetworkLocation.fwdCamera ret.networkLocation = NetworkLocation.fwdCamera
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM
ret.minEnableSpeed = -1 ret.minEnableSpeed = -1
ret.pcmCruise = False ret.pcmCruise = False
ret.openpilotLongitudinalControl = not frogpilot_toggles.disable_openpilot_long ret.openpilotLongitudinalControl = not frogpilot_toggles.disable_openpilot_long
ret.stoppingControl = True ret.stoppingControl = True
ret.autoResumeSng = True ret.autoResumeSng = True
if candidate in CC_ONLY_CAR: if candidate in CC_ONLY_CAR or (candidate in CAMERA_ACC_CAR and ret.enableGasInterceptor): #pedal interceptor tuning
ret.flags |= GMFlags.PEDAL_LONG.value ret.flags |= GMFlags.PEDAL_LONG.value
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_PEDAL_LONG gm_safety_cfg.safetyParam |= Panda.FLAG_GM_PEDAL_LONG
# Note: Low speed, stop and go not tested. Should be fairly smooth on highway # Note: Low speed, stop and go not tested. Should be fairly smooth on highway
ret.longitudinalTuning.kiBP = [0.0, 5., 35.] if candidate in (CAR.CHEVROLET_MALIBU_CC, CAR.CHEVROLET_MALIBU_HYBRID_CC):
ret.longitudinalTuning.kiV = [0.0, 0.35, 0.5] ret.longitudinalTuning.kiBP = [0.0, 5., 35.]
ret.longitudinalTuning.kfDEPRECATED = 0.15 ret.longitudinalTuning.kiV = [0.0, 0.35, 0.5]
ret.stoppingDecelRate = 0.8 ret.longitudinalTuning.kfDEPRECATED = 0.15
ret.stoppingDecelRate = 0.8
ret.minEnableSpeed = -1
ret.pcmCruise = False
ret.openpilotLongitudinalControl = not frogpilot_toggles.disable_openpilot_long
else:
ret.longitudinalTuning.kiBP = [0., 3., 6., 35.]
ret.longitudinalTuning.kiV = [0.125, 0.175, 0.225, 0.33]
ret.longitudinalTuning.kfDEPRECATED = 0.25
ret.stoppingDecelRate = 0.8
else: # Pedal used for SNG, ACC for longitudinal control otherwise else: # Pedal used for SNG, ACC for longitudinal control otherwise
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM_LONG gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM_LONG
ret.startingState = True ret.startingState = True
ret.vEgoStopping = 0.25 ret.vEgoStopping = 0.25
ret.vEgoStarting = 0.25 ret.vEgoStarting = 0.25
elif candidate in CC_ONLY_CAR: if ret.enableGasInterceptor and candidate == CAR.CHEVROLET_MALIBU_HYBRID_CC:
ret.flags |= GMFlags.PEDAL_LONG.value
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_PEDAL_LONG
ret.longitudinalTuning.kiBP = [0.0, 5., 35.]
ret.longitudinalTuning.kiV = [0.0, 0.18, 0.25]
ret.longitudinalTuning.kfDEPRECATED = 0.15
ret.stoppingDecelRate = 0.8
ret.minEnableSpeed = -1
ret.pcmCruise = False
ret.openpilotLongitudinalControl = not frogpilot_toggles.disable_openpilot_long
elif candidate in CC_ONLY_CAR and not ret.enableGasInterceptor:
ret.flags |= GMFlags.CC_LONG.value ret.flags |= GMFlags.CC_LONG.value
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_CC_LONG gm_safety_cfg.safetyParam |= Panda.FLAG_GM_CC_LONG
ret.radarUnavailable = True ret.radarUnavailable = True
ret.experimentalLongitudinalAvailable = False ret.experimentalLongitudinalAvailable = False
ret.minEnableSpeed = 24 * CV.MPH_TO_MS ret.minEnableSpeed = 24 * CV.MPH_TO_MS
ret.openpilotLongitudinalControl = not frogpilot_toggles.disable_openpilot_long ret.openpilotLongitudinalControl = not frogpilot_toggles.disable_openpilot_long
ret.pcmCruise = False ret.pcmCruise = False
ret.stoppingDecelRate = 11.18 # == 25 mph/s (.04 rate) if not ret.enableGasInterceptor and candidate in CC_ONLY_CAR: #redneck tuning
if candidate == CAR.CHEVROLET_MALIBU_HYBRID_CC:
ret.longitudinalTuning.deadzoneBP = [0.] pass
ret.longitudinalTuning.deadzoneV = [0.56] # == 2 km/h/s, 1.25 mph/s else:
ret.longitudinalActuatorDelay = 1. # TODO: measure this 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.kpBP = [10.7, 10.8, 28.] # 10.7 m/s == 24 mph ret.longitudinalTuning.deadzoneBP = [0., 1.]
ret.longitudinalTuning.kpV = [0., 20., 20.] # set lower end to 0 since we can't drive below that speed ret.longitudinalTuning.deadzoneV = [0.9, 0.9] # == 2 km/h/s, 1.25 mph/s
ret.longitudinalTuning.kiBP = [0.] ret.longitudinalActuatorDelay = 1. # TODO: measure this
ret.longitudinalTuning.kiV = [0.1] if candidate == CAR.CHEVROLET_MALIBU_CC:
ret.longitudinalTuning.kpV = [0., 20., 20.]
ret.longitudinalTuning.kiBP = [0.]
ret.longitudinalTuning.kiV = [0.1]
ret.stoppingDecelRate = 11.18 # == 25 mph/s (.04 rate)
if candidate in CC_ONLY_CAR: if candidate in CC_ONLY_CAR:
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_NO_ACC gm_safety_cfg.safetyParam |= Panda.FLAG_GM_NO_ACC
# Exception for flashed cars, or cars whose camera was removed # Exception for flashed cars, or cars whose camera was removed
if (ret.networkLocation == NetworkLocation.fwdCamera or candidate in CC_ONLY_CAR) and CAM_MSG not in fingerprint[CanBus.CAMERA] and not candidate in SDGM_CAR: if (ret.networkLocation == NetworkLocation.fwdCamera or candidate in CC_ONLY_CAR) and CAM_MSG not in fingerprint.get(CanBus.CAMERA, {}) and not candidate in (SDGM_CAR | ASCM_INT):
ret.flags |= GMFlags.NO_CAMERA.value ret.flags |= GMFlags.NO_CAMERA.value
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_NO_CAMERA gm_safety_cfg.safetyParam |= Panda.FLAG_GM_NO_CAMERA
if ACCELERATOR_POS_MSG not in fingerprint[CanBus.POWERTRAIN]: if ACCELERATOR_POS_MSG not in fingerprint.get(CanBus.POWERTRAIN, {}):
ret.flags |= GMFlags.NO_ACCELERATOR_POS_MSG.value ret.flags |= GMFlags.NO_ACCELERATOR_POS_MSG.value
return ret return ret
@@ -360,7 +564,8 @@ class CarInterface(CarInterfaceBase):
# TODO: verify 17 Volt can enable for the first time at a stop and allow for all GMs # TODO: verify 17 Volt can enable for the first time at a stop and allow for all GMs
below_min_enable_speed = ret.vEgo < self.CP.minEnableSpeed or self.CS.moving_backward below_min_enable_speed = ret.vEgo < self.CP.minEnableSpeed or self.CS.moving_backward
if below_min_enable_speed and not (ret.standstill and ret.brake >= 20 and if below_min_enable_speed and not (ret.standstill and ret.brake >= 20 and
(self.CP.networkLocation == NetworkLocation.fwdCamera and not self.CP.carFingerprint in SDGM_CAR)): (self.CP.networkLocation == NetworkLocation.fwdCamera and
(self.CP.carFingerprint in VOLT_LIKE_CARS or self.CP.carFingerprint in {CAR.CHEVROLET_BLAZER, CAR.CHEVROLET_MALIBU_SDGM, CAR.CHEVROLET_TRAVERSE} or self.CP.carFingerprint not in SDGM_CAR))):
events.add(EventName.belowEngageSpeed) events.add(EventName.belowEngageSpeed)
if ret.cruiseState.standstill and not self.CP.autoResumeSng: if ret.cruiseState.standstill and not self.CP.autoResumeSng:
events.add(EventName.resumeRequired) events.add(EventName.resumeRequired)
@@ -373,10 +578,14 @@ class CarInterface(CarInterfaceBase):
if (self.CP.flags & GMFlags.PEDAL_LONG.value) and \ if (self.CP.flags & GMFlags.PEDAL_LONG.value) and \
self.CP.transmissionType == TransmissionType.direct and \ self.CP.transmissionType == TransmissionType.direct and \
self.CP.carFingerprint != CAR.CHEVROLET_MALIBU_HYBRID_CC and \
not self.CS.single_pedal_mode and \ not self.CS.single_pedal_mode and \
c.longActive: c.longActive:
events.add(FrogPilotEventName.pedalInterceptorNoBrake) events.add(FrogPilotEventName.pedalInterceptorNoBrake)
if self.CS.lkas_status == 3:
events.add(EventName.steerUnavailable)
ret.events = events.to_msg() ret.events = events.to_msg()
return ret, fp_ret return ret, fp_ret
+226 -36
View File
@@ -33,41 +33,115 @@ class CarControllerParams:
# Our controller should still keep the 2 second average above # Our controller should still keep the 2 second average above
# -3.5 m/s^2 as per planner limits # -3.5 m/s^2 as per planner limits
ACCEL_MAX = 2. # m/s^2 ACCEL_MAX = 2. # m/s^2
ACCEL_MAX_PLUS = 4. # m/s^2
ACCEL_MIN = -4. # m/s^2 ACCEL_MIN = -4. # m/s^2
def __init__(self, CP): def __init__(self, CP):
self.STEER_MAX = CarControllerParams.STEER_MAX
self.STEER_STEP = CarControllerParams.STEER_STEP
self.INACTIVE_STEER_STEP = CarControllerParams.INACTIVE_STEER_STEP
self.STEER_DELTA_UP = CarControllerParams.STEER_DELTA_UP
self.STEER_DELTA_DOWN = CarControllerParams.STEER_DELTA_DOWN
self.STEER_DRIVER_ALLOWANCE = CarControllerParams.STEER_DRIVER_ALLOWANCE
self.STEER_DRIVER_MULTIPLIER = CarControllerParams.STEER_DRIVER_MULTIPLIER
self.STEER_DRIVER_FACTOR = CarControllerParams.STEER_DRIVER_FACTOR
if CP.carFingerprint == CAR.CHEVROLET_BOLT_CC_2017:
self.STEER_MAX = 450
self.STEER_DELTA_UP = 15
self.STEER_DELTA_DOWN = 34
self.STEER_DRIVER_ALLOWANCE = 78
self.STEER_DRIVER_MULTIPLIER = 6
self.STEER_DRIVER_FACTOR = 100
# Gas/brake lookups # Gas/brake lookups
self.ZERO_GAS = 2048 # Coasting self.ZERO_GAS = 6150 # Coasting
self.MAX_BRAKE = 400 # ~ -4.0 m/s^2 with regen 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: kaofui_cars = SDGM_CAR | ASCM_INT | {
self.MAX_GAS = 3400 CAR.CHEVROLET_VOLT,
self.MAX_ACC_REGEN = 1514 CAR.CHEVROLET_VOLT_2019,
self.INACTIVE_REGEN = 1554 CAR.CHEVROLET_VOLT_ASCM,
# Camera ACC vehicles have no regen while enabled. CAR.CHEVROLET_VOLT_CAMERA,
# Camera transitions to MAX_ACC_REGEN from ZERO_GAS and uses friction brakes instantly CAR.CHEVROLET_VOLT_CC,
max_regen_acceleration = 0. CAR.CHEVROLET_MALIBU_CC,
CAR.CHEVROLET_MALIBU_HYBRID_CC,
}
volt_like = {
CAR.CHEVROLET_VOLT,
CAR.CHEVROLET_VOLT_ASCM,
CAR.CHEVROLET_VOLT_CAMERA,
CAR.CHEVROLET_VOLT_CC,
}
elif CP.carFingerprint in SDGM_CAR: if CP.carFingerprint in kaofui_cars:
self.MAX_GAS = 3400 if (CP.carFingerprint in (CAMERA_ACC_CAR | SDGM_CAR) and
self.MAX_ACC_REGEN = 1514 CP.carFingerprint not in CC_ONLY_CAR and
self.INACTIVE_REGEN = 1554 CP.carFingerprint != CAR.CHEVROLET_BOLT_ACC_2022_2023):
max_regen_acceleration = 0. self.MAX_GAS = 8848
self.MAX_GAS_PLUS = 8848
self.MAX_ACC_REGEN = 5610
self.INACTIVE_REGEN = 5650
# Camera ACC vehicles have no regen while enabled.
# Camera transitions to MAX_ACC_REGEN from ZERO_GAS and uses friction brakes instantly
max_regen_acceleration = 0.
else:
self.MAX_GAS = 8191 # Safety limit, not ACC max. Stock ACC >8192 from standstill.
self.MAX_GAS_PLUS = 8191
self.MAX_ACC_REGEN = 5500 # Max ACC regen is slightly less than max paddle regen
self.INACTIVE_REGEN = 5500
# ICE has much less engine braking force compared to regen in EVs,
# lower threshold removes some braking deadzone
max_regen_acceleration = -1. if CP.carFingerprint in EV_CAR else -0.1
self.BRAKE_SWITCH_MAX = self.MAX_ACC_REGEN if CP.carFingerprint in EV_CAR else self.ZERO_GAS
if CP.carFingerprint in volt_like:
self.BRAKE_LOOKUP_BP = [self.ACCEL_MIN, 0.]
else:
self.BRAKE_LOOKUP_BP = [self.ACCEL_MIN, max_regen_acceleration]
else: else:
self.MAX_GAS = 3072 # Safety limit, not ACC max. Stock ACC >4096 from standstill. if CP.carFingerprint in CAMERA_ACC_CAR and CP.carFingerprint not in CC_ONLY_CAR:
self.MAX_ACC_REGEN = 1404 # Max ACC regen is slightly less than max paddle regen self.MAX_GAS = 8848
self.INACTIVE_REGEN = 1404 self.MAX_GAS_PLUS = 8848
# ICE has much less engine braking force compared to regen in EVs, self.MAX_ACC_REGEN = 5610
# lower threshold removes some braking deadzone self.INACTIVE_REGEN = 5650
max_regen_acceleration = -1. if CP.carFingerprint in EV_CAR else -0.1 # Camera ACC vehicles have no regen while enabled.
# Camera transitions to MAX_ACC_REGEN from ZERO_GAS and uses friction brakes instantly
max_regen_acceleration = 0.
self.BRAKE_SWITCH_MAX = self.MAX_ACC_REGEN if CP.carFingerprint in EV_CAR else self.ZERO_GAS
self.GAS_LOOKUP_BP = [max_regen_acceleration, 0., self.ACCEL_MAX] elif CP.carFingerprint in SDGM_CAR:
self.MAX_GAS = 8191
self.MAX_GAS_PLUS = 8191
self.MAX_ACC_REGEN = 5500
self.INACTIVE_REGEN = 5500
max_regen_acceleration = 0.
self.BRAKE_SWITCH_MAX = self.ZERO_GAS
else:
self.MAX_GAS = 7168 # Safety limit, not ACC max. Stock ACC >8192 from standstill.
self.MAX_GAS_PLUS = 7168 # 8292 uses new bit, possible but not tested. Matches Twilsonco tw-main max
self.MAX_ACC_REGEN = 5500 # Max ACC regen is slightly less than max paddle regen
self.INACTIVE_REGEN = 5500
# ICE has much less engine braking force compared to regen in EVs,
# lower threshold removes some braking deadzone
max_regen_acceleration = -3. if CP.carFingerprint in EV_CAR else -0.1
self.BRAKE_SWITCH_MAX = self.MAX_ACC_REGEN if CP.carFingerprint in EV_CAR else self.ZERO_GAS
self.BRAKE_LOOKUP_BP = [self.ACCEL_MIN, 0.]
self.max_regen_acceleration = max_regen_acceleration
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_V = [self.MAX_ACC_REGEN, self.ZERO_GAS, self.MAX_GAS] 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, max_regen_acceleration]
self.BRAKE_LOOKUP_V = [self.MAX_BRAKE, 0.] self.BRAKE_LOOKUP_V = [self.MAX_BRAKE, 0.]
self.BRAKE_SWITCH_LOOKUP_BP = [0.5, 10]
self.BRAKE_SWITCH_LOOKUP_V = [self.ZERO_GAS, self.BRAKE_SWITCH_MAX]
# determined by letting Volt regen to a stop in L gear from 89mph, # 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 # and by letting off gas and allowing car to creep, for determining
# the positive threshold values at very low speed # the positive threshold values at very low speed
@@ -76,10 +150,11 @@ class CarControllerParams:
def update_ev_gas_brake_threshold(self, v_ego): 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) gas_brake_threshold = interp(v_ego, self.EV_GAS_BRAKE_THRESHOLD_BP, self.EV_GAS_BRAKE_THRESHOLD_V)
self.GAS_LOOKUP_BP_PLUS = [self.max_regen_acceleration, 0., self.ACCEL_MAX_PLUS]
self.EV_GAS_LOOKUP_BP = [gas_brake_threshold, max(0., gas_brake_threshold), self.ACCEL_MAX] self.EV_GAS_LOOKUP_BP = [gas_brake_threshold, max(0., gas_brake_threshold), self.ACCEL_MAX]
self.EV_GAS_LOOKUP_BP_PLUS = [gas_brake_threshold, max(0., gas_brake_threshold), self.ACCEL_MAX_PLUS]
self.EV_BRAKE_LOOKUP_BP = [self.ACCEL_MIN, gas_brake_threshold] self.EV_BRAKE_LOOKUP_BP = [self.ACCEL_MIN, gas_brake_threshold]
@dataclass @dataclass
class GMCarDocs(CarDocs): class GMCarDocs(CarDocs):
package: str = "Adaptive Cruise Control (ACC)" package: str = "Adaptive Cruise Control (ACC)"
@@ -118,6 +193,16 @@ class CAR(Platforms):
GMCarSpecs(mass=1607, wheelbase=2.69, steerRatio=17.7, centerToFrontRatio=0.45, tireStiffnessFactor=0.469, minEnableSpeed=-1), GMCarSpecs(mass=1607, wheelbase=2.69, steerRatio=17.7, centerToFrontRatio=0.45, tireStiffnessFactor=0.469, minEnableSpeed=-1),
dbc_dict=dbc_dict('gm_global_a_powertrain_volt', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis') dbc_dict=dbc_dict('gm_global_a_powertrain_volt', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis')
) )
CHEVROLET_VOLT_ASCM = GMPlatformConfig(
[GMCarDocs("Chevrolet Volt 2017-18 ASCM Harness", min_enable_speed=0, video_link="https://youtu.be/QeMCN_4TFfQ")],
GMCarSpecs(mass=1607, wheelbase=2.69, steerRatio=17.7, centerToFrontRatio=0.45, tireStiffnessFactor=0.469, minEnableSpeed=-1),
dbc_dict=dbc_dict('gm_global_a_powertrain_volt', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis')
)
CHEVROLET_VOLT_CAMERA = GMPlatformConfig(
[GMCarDocs("Chevrolet Volt 2017-18 Camera Harness", "Flashed camera-forward integration with ACC")],
CHEVROLET_VOLT.specs,
dbc_dict=dbc_dict('gm_global_a_powertrain_volt', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis')
)
CADILLAC_ATS = GMASCMPlatformConfig( CADILLAC_ATS = GMASCMPlatformConfig(
[GMCarDocs("Cadillac ATS Premium Performance 2018")], [GMCarDocs("Cadillac ATS Premium Performance 2018")],
GMCarSpecs(mass=1601, wheelbase=2.78, steerRatio=15.3), GMCarSpecs(mass=1601, wheelbase=2.78, steerRatio=15.3),
@@ -126,10 +211,19 @@ class CAR(Platforms):
[GMCarDocs("Chevrolet Malibu Premier 2017")], [GMCarDocs("Chevrolet Malibu Premier 2017")],
GMCarSpecs(mass=1496, wheelbase=2.83, steerRatio=15.8, centerToFrontRatio=0.4), GMCarSpecs(mass=1496, wheelbase=2.83, steerRatio=15.8, centerToFrontRatio=0.4),
) )
CHEVROLET_MALIBU_ASCM = GMPlatformConfig(
[GMCarDocs("Chevrolet Malibu 2017-19 ASCM Harness")],
CHEVROLET_MALIBU.specs,
)
GMC_ACADIA = GMASCMPlatformConfig( GMC_ACADIA = GMASCMPlatformConfig(
[GMCarDocs("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo")], [GMCarDocs("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo")],
GMCarSpecs(mass=1975, wheelbase=2.86, steerRatio=14.4, centerToFrontRatio=0.4), GMCarSpecs(mass=1975, wheelbase=2.86, steerRatio=14.4, centerToFrontRatio=0.4),
) )
GMC_ACADIA_ASCM = GMPlatformConfig(
[GMCarDocs("GMC Acadia 2018 ASCM Harness", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo")],
GMCarSpecs(mass=1975, wheelbase=2.86, steerRatio=14.4, centerToFrontRatio=0.4),
dbc_dict=dbc_dict('gm_global_a_powertrain_generated', 'gm_global_a_object', chassis_dbc='gm_global_a_chassis')
)
BUICK_LACROSSE = GMASCMPlatformConfig( BUICK_LACROSSE = GMASCMPlatformConfig(
[GMCarDocs("Buick LaCrosse 2017-19", "Driver Confidence Package 2")], [GMCarDocs("Buick LaCrosse 2017-19", "Driver Confidence Package 2")],
GMCarSpecs(mass=1712, wheelbase=2.91, steerRatio=15.8, centerToFrontRatio=0.4), GMCarSpecs(mass=1712, wheelbase=2.91, steerRatio=15.8, centerToFrontRatio=0.4),
@@ -150,10 +244,10 @@ class CAR(Platforms):
[GMCarDocs("Cadillac Escalade ESV 2019", "Adaptive Cruise Control (ACC) & LKAS")], [GMCarDocs("Cadillac Escalade ESV 2019", "Adaptive Cruise Control (ACC) & LKAS")],
CADILLAC_ESCALADE_ESV.specs, CADILLAC_ESCALADE_ESV.specs,
) )
CHEVROLET_BOLT_EUV = GMPlatformConfig( CHEVROLET_BOLT_ACC_2022_2023 = GMPlatformConfig(
[ [
GMCarDocs("Chevrolet Bolt EUV 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", video_link="https://youtu.be/xvwzGMUA210"), GMCarDocs("Chevrolet Bolt ACC 2022-2023", "Premier or Premier Redline Trim without Super Cruise Package", video_link="https://youtu.be/xvwzGMUA210"),
GMCarDocs("Chevrolet Bolt EV 2022-23", "2LT Trim with Adaptive Cruise Control Package"), GMCarDocs("Chevrolet Bolt EV ACC 2022-2023", "2LT Trim with Adaptive Cruise Control Package"),
], ],
GMCarSpecs(mass=1669, wheelbase=2.63779, steerRatio=16.8, centerToFrontRatio=0.4, tireStiffnessFactor=1.0), GMCarSpecs(mass=1669, wheelbase=2.63779, steerRatio=16.8, centerToFrontRatio=0.4, tireStiffnessFactor=1.0),
) )
@@ -162,7 +256,7 @@ class CAR(Platforms):
GMCarDocs("Chevrolet Silverado 1500 2020-21", "Safety Package II"), GMCarDocs("Chevrolet Silverado 1500 2020-21", "Safety Package II"),
GMCarDocs("GMC Sierra 1500 2020-21", "Driver Alert Package II", video_link="https://youtu.be/5HbNoBLzRwE"), GMCarDocs("GMC Sierra 1500 2020-21", "Driver Alert Package II", video_link="https://youtu.be/5HbNoBLzRwE"),
], ],
GMCarSpecs(mass=2450, wheelbase=3.75, steerRatio=16.3, tireStiffnessFactor=1.0), GMCarSpecs(mass=2994, wheelbase=3.75, steerRatio=16.3, tireStiffnessFactor=1.0),
) )
CHEVROLET_EQUINOX = GMPlatformConfig( CHEVROLET_EQUINOX = GMPlatformConfig(
[GMCarDocs("Chevrolet Equinox 2019-22")], [GMCarDocs("Chevrolet Equinox 2019-22")],
@@ -178,12 +272,26 @@ class CAR(Platforms):
[GMCarDocs("Chevrolet Volt 2017-18 - No-ACC", min_enable_speed=0)], [GMCarDocs("Chevrolet Volt 2017-18 - No-ACC", min_enable_speed=0)],
CHEVROLET_VOLT.specs, CHEVROLET_VOLT.specs,
) )
CHEVROLET_BOLT_CC = GMPlatformConfig( CHEVROLET_BOLT_CC_2019_2021 = GMPlatformConfig(
[GMCarDocs("Chevrolet Bolt EV 2019-2021 - No-ACC")],
CHEVROLET_BOLT_ACC_2022_2023.specs,
)
CHEVROLET_BOLT_ACC_2022_2023_PEDAL = GMPlatformConfig(
[ [
GMCarDocs("Chevrolet Bolt EUV 2022-23 - No-ACC"), GMCarDocs("Chevrolet Bolt EV 2022-2023 ACC w Pedal"),
GMCarDocs("Chevrolet Bolt EV 2017-23 - No-ACC"),
], ],
CHEVROLET_BOLT_EUV.specs, CHEVROLET_BOLT_ACC_2022_2023.specs,
)
CHEVROLET_BOLT_CC_2022_2023 = GMPlatformConfig(
[
GMCarDocs("Chevrolet Bolt EV 2022-2023 - No-ACC"),
GMCarDocs("Chevrolet Bolt EV 2022-2023 - No-ACC"),
],
CHEVROLET_BOLT_ACC_2022_2023.specs,
)
CHEVROLET_BOLT_CC_2017 = GMPlatformConfig(
[GMCarDocs("Chevrolet Bolt EV 2017 - No-ACC")],
CHEVROLET_BOLT_ACC_2022_2023.specs,
) )
CHEVROLET_EQUINOX_CC = GMPlatformConfig( CHEVROLET_EQUINOX_CC = GMPlatformConfig(
[GMCarDocs("Chevrolet Equinox 2019-22 - No-ACC")], [GMCarDocs("Chevrolet Equinox 2019-22 - No-ACC")],
@@ -217,22 +325,42 @@ class CAR(Platforms):
[GMCarDocs("Cadillac XT5 - No-ACC")], [GMCarDocs("Cadillac XT5 - No-ACC")],
CarSpecs(mass=1810, wheelbase=2.86, steerRatio=16.34, centerToFrontRatio=0.5), CarSpecs(mass=1810, wheelbase=2.86, steerRatio=16.34, centerToFrontRatio=0.5),
) )
CHEVROLET_BLAZER = GMPlatformConfig(
[GMCarDocs("Chevrolet Blazer 2019-2025", "Driver Assist Package")],
CarSpecs(mass=1850, wheelbase=3.10, steerRatio=17.9, centerToFrontRatio=0.4),
)
CHEVROLET_TRAVERSE = GMPlatformConfig( CHEVROLET_TRAVERSE = GMPlatformConfig(
[GMCarDocs("Chevrolet Traverse 2023", "Driver Assist Package")], [GMCarDocs("Chevrolet Traverse 2023", "Driver Assist Package")],
CarSpecs(mass=1955, wheelbase=3.07, steerRatio=17.9, centerToFrontRatio=0.4), CarSpecs(mass=1955, wheelbase=3.07, steerRatio=17.9, centerToFrontRatio=0.4),
) )
CHEVROLET_MALIBU_SDGM = GMPlatformConfig(
[GMCarDocs("Chevrolet Malibu 2019", "SDGM Harness (Optional SASCM)")],
CHEVROLET_MALIBU.specs,
)
BUICK_BABYENCLAVE = GMPlatformConfig( BUICK_BABYENCLAVE = GMPlatformConfig(
[GMCarDocs("Buick Baby Enclave 2020-23", "Driver Assist Package")], [GMCarDocs("Buick Baby Enclave 2020-23", "Driver Assist Package")],
CarSpecs(mass=2050, wheelbase=2.86, steerRatio=16.0, centerToFrontRatio=0.5), CarSpecs(mass=2050, wheelbase=2.86, steerRatio=16.0, centerToFrontRatio=0.5),
) )
CHEVROLET_MALIBU_CC = GMPlatformConfig( CHEVROLET_MALIBU_CC = GMPlatformConfig(
[GMCarDocs("Chevrolet Malibu 2023 - No-ACC")], [GMCarDocs("Chevrolet Malibu 2023 - No-ACC")],
CarSpecs(mass=1450, wheelbase=2.8, steerRatio=18.25, centerToFrontRatio=0.4, tireStiffnessFactor=0.997),
)
CHEVROLET_MALIBU_HYBRID_CC = GMPlatformConfig(
[GMCarDocs("Chevrolet Malibu Hybrid 2017 - No-ACC")],
CarSpecs(mass=1450, wheelbase=2.8, steerRatio=15.8, centerToFrontRatio=0.4), CarSpecs(mass=1450, wheelbase=2.8, steerRatio=15.8, centerToFrontRatio=0.4),
) )
CHEVROLET_TRAX = GMPlatformConfig( CHEVROLET_TRAX = GMPlatformConfig(
[GMCarDocs("Chevrolet TRAX 2024")], [GMCarDocs("Chevrolet TRAX 2024")],
CarSpecs(mass=1365, wheelbase=2.7, steerRatio=16.4, centerToFrontRatio=0.4), CarSpecs(mass=1365, wheelbase=2.7, steerRatio=16.4, centerToFrontRatio=0.4),
) )
CHEVROLET_VOLT_2019 = GMPlatformConfig(
[GMCarDocs("Chevrolet Volt 2019")],
GMCarSpecs(mass=1607, wheelbase=2.69, steerRatio=15.7, centerToFrontRatio=0.45),
)
CADILLAC_XT6 = GMPlatformConfig(
[GMCarDocs("Cadillac XT6 2020", "Driver Assist Package")],
GMCarSpecs(mass=2050, wheelbase=2.86, steerRatio=16.5, centerToFrontRatio=0.4),
)
class CruiseButtons: class CruiseButtons:
@@ -257,6 +385,22 @@ class CanBus:
LOOPBACK = 128 LOOPBACK = 128
DROPPED = 192 DROPPED = 192
def set_red_panda_canbus(enabled: bool) -> None:
if enabled:
CanBus.POWERTRAIN = 4
CanBus.OBSTACLE = 5
CanBus.CAMERA = 6
CanBus.CHASSIS = 6
CanBus.LOOPBACK = 132
CanBus.DROPPED = 196
else:
CanBus.POWERTRAIN = 0
CanBus.OBSTACLE = 1
CanBus.CAMERA = 2
CanBus.CHASSIS = 2
CanBus.LOOPBACK = 128
CanBus.DROPPED = 192
class GMFlags(IntFlag): class GMFlags(IntFlag):
PEDAL_LONG = 1 PEDAL_LONG = 1
CC_LONG = 2 CC_LONG = 2
@@ -315,16 +459,62 @@ FW_QUERY_CONFIG = FwQueryConfig(
extra_ecus=[(Ecu.fwdCamera, 0x24b, None)], extra_ecus=[(Ecu.fwdCamera, 0x24b, None)],
) )
EV_CAR = {CAR.CHEVROLET_VOLT, CAR.CHEVROLET_BOLT_EUV, CAR.CHEVROLET_VOLT_CC, CAR.CHEVROLET_BOLT_CC} EV_CAR = {
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} CAR.CHEVROLET_VOLT,
# CC_ONLY_CAR = set(c for c in CAR if str(c).endswith('_CC')) CAR.CHEVROLET_VOLT_2019,
CAR.CHEVROLET_VOLT_ASCM,
CAR.CHEVROLET_VOLT_CAMERA,
CAR.CHEVROLET_VOLT_CC,
CAR.CHEVROLET_BOLT_ACC_2022_2023,
CAR.CHEVROLET_BOLT_CC_2019_2021,
CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL,
CAR.CHEVROLET_BOLT_CC_2022_2023,
CAR.CHEVROLET_BOLT_CC_2017,
CAR.CHEVROLET_MALIBU_HYBRID_CC,
}
CC_ONLY_CAR = {
CAR.CHEVROLET_VOLT_CC,
CAR.CHEVROLET_BOLT_CC_2019_2021,
CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL,
CAR.CHEVROLET_BOLT_CC_2022_2023,
CAR.CHEVROLET_BOLT_CC_2017,
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,
CAR.CHEVROLET_MALIBU_HYBRID_CC,
}
CC_REGEN_PADDLE_CAR = {
CAR.CHEVROLET_BOLT_CC_2019_2021,
CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL,
CAR.CHEVROLET_BOLT_CC_2022_2023,
CAR.CHEVROLET_BOLT_CC_2017,
}
# We're integrated at the Safety Data Gateway Module on these cars # We're integrated at the Safety Data Gateway Module on these cars
SDGM_CAR = {CAR.CADILLAC_XT4, CAR.CHEVROLET_TRAVERSE, CAR.BUICK_BABYENCLAVE} SDGM_CAR = {CAR.CADILLAC_XT4, CAR.CADILLAC_XT6, CAR.CHEVROLET_TRAVERSE, CAR.CHEVROLET_BLAZER, CAR.CHEVROLET_MALIBU_SDGM, CAR.BUICK_BABYENCLAVE, CAR.CHEVROLET_VOLT_2019}
ASCM_INT = {CAR.CHEVROLET_VOLT_ASCM, CAR.GMC_ACADIA_ASCM, CAR.CHEVROLET_MALIBU_ASCM}
# We're integrated at the camera with VOACC on these cars (instead of ASCM w/ OBD-II harness) # We're integrated at the camera with VOACC on these cars (instead of ASCM w/ OBD-II harness)
CAMERA_ACC_CAR = {CAR.CHEVROLET_BOLT_EUV, CAR.CHEVROLET_SILVERADO, CAR.CHEVROLET_EQUINOX, CAR.CHEVROLET_TRAILBLAZER, CAR.CHEVROLET_TRAX} CAMERA_ACC_CAR = {CAR.CHEVROLET_BOLT_ACC_2022_2023, CAR.CHEVROLET_SILVERADO, CAR.CHEVROLET_EQUINOX, CAR.CHEVROLET_TRAILBLAZER, CAR.CHEVROLET_TRAX, CAR.CHEVROLET_VOLT_CAMERA, CAR.CHEVROLET_BLAZER}
CAMERA_ACC_CAR.update({CAR.CHEVROLET_VOLT_CC, CAR.CHEVROLET_BOLT_CC, CAR.CHEVROLET_EQUINOX_CC, CAR.GMC_YUKON_CC, CAR.CADILLAC_CT6_CC, CAR.CHEVROLET_TRAILBLAZER_CC, CAR.CADILLAC_XT5_CC, CAR.CHEVROLET_MALIBU_CC}) CAMERA_ACC_CAR.update({
CAR.CHEVROLET_VOLT_CC,
CAR.CHEVROLET_BOLT_CC_2019_2021,
CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL,
CAR.CHEVROLET_BOLT_CC_2022_2023,
CAR.CHEVROLET_BOLT_CC_2017,
CAR.CHEVROLET_EQUINOX_CC,
CAR.GMC_YUKON_CC,
CAR.CADILLAC_CT6_CC,
CAR.CHEVROLET_TRAILBLAZER_CC,
CAR.CADILLAC_XT5_CC,
CAR.CHEVROLET_MALIBU_CC,
CAR.CHEVROLET_MALIBU_HYBRID_CC,
})
# CAMERA_ACC_CAR.update(CC_ONLY_CAR) # CAMERA_ACC_CAR.update(CC_ONLY_CAR)
STEER_THRESHOLD = 1.0 STEER_THRESHOLD = 1.0
+3 -3
View File
@@ -37,12 +37,12 @@ EventName = car.CarEvent.EventName
MAX_CTRL_SPEED = (V_CRUISE_MAX + 4) * CV.KPH_TO_MS MAX_CTRL_SPEED = (V_CRUISE_MAX + 4) * CV.KPH_TO_MS
ACCEL_MAX = 2.0 ACCEL_MAX = 2.0
ACCEL_MIN = -3.5 ACCEL_MIN = -3.5
FRICTION_THRESHOLD = 0.09 FRICTION_THRESHOLD = 0.12
def get_friction_threshold(v_ego): def get_friction_threshold(v_ego):
# Interpolate friction threshold from 0.09 at 50 mph to 0.15 at 75 mph # Interpolate friction threshold
from openpilot.common.numpy_fast import interp from openpilot.common.numpy_fast import interp
return interp(v_ego, [1 * CV.MPH_TO_MS, 75 * CV.MPH_TO_MS], [0.12, 0.25]) return interp(v_ego, [1 * CV.MPH_TO_MS, 75 * CV.MPH_TO_MS], [0.12, 0.3])
TORQUE_PARAMS_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/params.toml') TORQUE_PARAMS_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/params.toml')
TORQUE_OVERRIDE_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/override.toml') TORQUE_OVERRIDE_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/override.toml')
+4 -2
View File
@@ -43,8 +43,10 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
"CADILLAC_ESCALADE" = [1.899999976158142, 1.842270016670227, 0.1120000034570694] "CADILLAC_ESCALADE" = [1.899999976158142, 1.842270016670227, 0.1120000034570694]
"CADILLAC_ESCALADE_ESV_2019" = [1.15, 1.3, 0.2] "CADILLAC_ESCALADE_ESV_2019" = [1.15, 1.3, 0.2]
"CADILLAC_XT4" = [1.45, 1.6, 0.2] "CADILLAC_XT4" = [1.45, 1.6, 0.2]
"CHEVROLET_BOLT_EUV" = [2.0, 2.0, 0.05] "CADILLAC_XT6" = [1.33, 1.9, 0.16]
"CHEVROLET_MALIBU_CC" = [1.85, 1.85, 0.075] "CHEVROLET_BOLT_ACC_2022_2023" = [2.0, 2.0, 0.09]
"CHEVROLET_BLAZER" = [1.33, 1.33, 0.18]
"CHEVROLET_MALIBU_CC" = [1.58, 1.8422651988094612, 0.205]
"CHEVROLET_SILVERADO" = [1.9, 1.9, 0.112] "CHEVROLET_SILVERADO" = [1.9, 1.9, 0.112]
"CHEVROLET_TRAILBLAZER" = [1.33, 1.9, 0.16] "CHEVROLET_TRAILBLAZER" = [1.33, 1.9, 0.16]
"CHEVROLET_TRAVERSE" = [1.33, 1.33, 0.18] "CHEVROLET_TRAVERSE" = [1.33, 1.33, 0.18]
+1
View File
@@ -5,6 +5,7 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
"AUDI_A3_MK3" = [1.5122414863077502, 1.7443517531719404, 0.15194151892450905] "AUDI_A3_MK3" = [1.5122414863077502, 1.7443517531719404, 0.15194151892450905]
"AUDI_Q3_MK2" = [1.4439223359448605, 1.2254955789112076, 0.1413798895978097] "AUDI_Q3_MK2" = [1.4439223359448605, 1.2254955789112076, 0.1413798895978097]
"CHEVROLET_VOLT" = [1.5961527626411784, 1.8422651988094612, 0.1572393918005158] "CHEVROLET_VOLT" = [1.5961527626411784, 1.8422651988094612, 0.1572393918005158]
"CHEVROLET_MALIBU_HYBRID_CC" = [1.5961527626411784, 1.8422651988094612, 0.1572393918005158]
"CHRYSLER_PACIFICA_2018" = [2.07140, 1.3366521181047952, 0.13776367250652022] "CHRYSLER_PACIFICA_2018" = [2.07140, 1.3366521181047952, 0.13776367250652022]
"CHRYSLER_PACIFICA_2020" = [1.86206, 1.509076559398423, 0.14328246159386085] "CHRYSLER_PACIFICA_2020" = [1.86206, 1.509076559398423, 0.14328246159386085]
"CHRYSLER_PACIFICA_2017_HYBRID" = [1.79422, 1.06831764583744, 0.116237] "CHRYSLER_PACIFICA_2017_HYBRID" = [1.79422, 1.06831764583744, 0.116237]
+10 -1
View File
@@ -56,9 +56,18 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
"CADILLAC_ESCALADE_ESV" = "CHEVROLET_VOLT" "CADILLAC_ESCALADE_ESV" = "CHEVROLET_VOLT"
"CADILLAC_ATS" = "CHEVROLET_VOLT" "CADILLAC_ATS" = "CHEVROLET_VOLT"
"CHEVROLET_MALIBU" = "CHEVROLET_VOLT" "CHEVROLET_MALIBU" = "CHEVROLET_VOLT"
"CHEVROLET_MALIBU_ASCM" = "CHEVROLET_VOLT"
"CHEVROLET_MALIBU_SDGM" = "CHEVROLET_VOLT"
"HOLDEN_ASTRA" = "CHEVROLET_VOLT" "HOLDEN_ASTRA" = "CHEVROLET_VOLT"
"CHEVROLET_VOLT_CC" = "CHEVROLET_VOLT" "CHEVROLET_VOLT_CC" = "CHEVROLET_VOLT"
"CHEVROLET_BOLT_CC" = "CHEVROLET_BOLT_EUV" "CHEVROLET_VOLT_CAMERA" = "CHEVROLET_VOLT"
"CHEVROLET_VOLT_ASCM" = "CHEVROLET_VOLT"
"GMC_ACADIA_ASCM" = "GMC_ACADIA"
"CHEVROLET_VOLT_2019" = "CHEVROLET_VOLT"
"CHEVROLET_BOLT_CC_2019_2021" = "CHEVROLET_BOLT_ACC_2022_2023"
"CHEVROLET_BOLT_ACC_2022_2023_PEDAL" = "CHEVROLET_BOLT_ACC_2022_2023"
"CHEVROLET_BOLT_CC_2022_2023" = "CHEVROLET_BOLT_ACC_2022_2023"
"CHEVROLET_BOLT_CC_2017" = "CHEVROLET_BOLT_ACC_2022_2023"
"CHEVROLET_EQUINOX_CC" = "CHEVROLET_EQUINOX" "CHEVROLET_EQUINOX_CC" = "CHEVROLET_EQUINOX"
"CHEVROLET_SUBURBAN" = "CHEVROLET_SILVERADO" "CHEVROLET_SUBURBAN" = "CHEVROLET_SILVERADO"
"CHEVROLET_SUBURBAN_CC" = "CHEVROLET_SILVERADO" "CHEVROLET_SUBURBAN_CC" = "CHEVROLET_SILVERADO"
+1 -1
View File
@@ -199,7 +199,7 @@ class Controls:
self.event_names_to_clear = set() self.event_names_to_clear = set()
self.has_menu = self.CP.carName == "gm" and not (self.CP.flags & GMFlags.NO_CAMERA.value or self.CP.carFingerprint in CC_ONLY_CAR) self.has_menu = self.CP.carName == "gm" and not (self.CP.flags & GMFlags.NO_CAMERA.value)
self.frogpilot_AM = AlertManager() self.frogpilot_AM = AlertManager()
self.frogpilot_events = Events(frogpilot=True) self.frogpilot_events = Events(frogpilot=True)
+4 -4
View File
@@ -357,8 +357,8 @@ def forcing_stop_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMas
def holiday_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, frogpilot_toggles: SimpleNamespace) -> Alert: def holiday_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, frogpilot_toggles: SimpleNamespace) -> Alert:
holiday_messages = { holiday_messages = {
"new_years": "Happy New Year! 🎉", "new_years": "Happy New Year! 🎉",
"valentines": "Happy Valentine's Day! ❤️", "valentines_day": "Happy Valentine's Day! ❤️",
"st_patricks": "Happy St. Patrick's Day! 🍀", "st_patricks_day": "Happy St. Patrick's Day! 🍀",
"world_frog_day": "Happy World Frog Day! 🐸", "world_frog_day": "Happy World Frog Day! 🐸",
"april_fools": "Happy April Fool's Day! 🤡", "april_fools": "Happy April Fool's Day! 🤡",
"easter_week": "Happy Easter! 🐰", "easter_week": "Happy Easter! 🐰",
@@ -372,7 +372,7 @@ def holiday_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster,
} }
return Alert( return Alert(
holiday_messages.get(frogpilot_toggles.current_holiday_theme), holiday_messages.get(frogpilot_toggles.current_holiday_theme, "Happy Holidays!"),
"", "",
AlertStatus.normal, AlertSize.small, AlertStatus.normal, AlertSize.small,
Priority.LOWEST, VisualAlert.none, FrogPilotAudibleAlert.startup, 5.) Priority.LOWEST, VisualAlert.none, FrogPilotAudibleAlert.startup, 5.)
@@ -982,7 +982,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
"", "",
AlertStatus.normal, AlertSize.full, AlertStatus.normal, AlertSize.full,
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2, creation_delay=0.5), Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2, creation_delay=0.5),
ET.USER_DISABLE: ImmediateDisableAlert("Reverse Gear"), ET.USER_DISABLE: ImmediateDisableAlert("Wrong Gear"),
ET.NO_ENTRY: NoEntryAlert("Reverse Gear"), ET.NO_ENTRY: NoEntryAlert("Reverse Gear"),
}, },
+53 -3
View File
@@ -7,6 +7,7 @@ from openpilot.selfdrive.car.interfaces import FRICTION_THRESHOLD, get_friction_
from openpilot.selfdrive.controls.lib.drive_helpers import MIN_SPEED, get_friction from openpilot.selfdrive.controls.lib.drive_helpers import MIN_SPEED, get_friction
from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.filter_simple import FirstOrderFilter
from openpilot.selfdrive.controls.lib.latcontrol import LatControl, MIN_LATERAL_CONTROL_SPEED from openpilot.selfdrive.controls.lib.latcontrol import LatControl, MIN_LATERAL_CONTROL_SPEED
from openpilot.selfdrive.car.gm.values import CAR as GM_CAR
from openpilot.selfdrive.controls.lib.pid import PIDController from openpilot.selfdrive.controls.lib.pid import PIDController
from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY
@@ -21,8 +22,8 @@ from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_G
# Additionally, there is friction in the steering wheel that needs # Additionally, there is friction in the steering wheel that needs
# to be overcome to move it at all, this is compensated for too. # to be overcome to move it at all, this is compensated for too.
KP = 0.6 KP = 0.7
KI = 0.3 KI = 0.35
INTERP_SPEEDS = [1, 1.5, 2.0, 3.0, 5, 7.5, 10, 15, 30] INTERP_SPEEDS = [1, 1.5, 2.0, 3.0, 5, 7.5, 10, 15, 30]
KP_INTERP = [250, 120, 65, 30, 11.5, 5.5, 3.5, 2.0, KP] KP_INTERP = [250, 120, 65, 30, 11.5, 5.5, 3.5, 2.0, KP]
@@ -36,6 +37,17 @@ JERK_LOOKAHEAD_SECONDS = 0.19
JERK_GAIN = 0.22 JERK_GAIN = 0.22
LAT_ACCEL_REQUEST_BUFFER_SECONDS = 1.0 LAT_ACCEL_REQUEST_BUFFER_SECONDS = 1.0
VERSION = 2 VERSION = 2
DEBUG_TORQUE_TUNE = False
FF_SCALE_BLEND_LAT_ACCEL = 0.05
DEADZONE_BOOST_LAT_ACCEL = 0.08
UNWIND_D_DES_THRESHOLD = -1.0
UNWIND_LAT_ACCEL_NEAR_ZERO = 0.3
BOLT_CARS = (
GM_CAR.CHEVROLET_BOLT_ACC_2022_2023,
GM_CAR.CHEVROLET_BOLT_CC_2022_2023,
GM_CAR.CHEVROLET_BOLT_CC_2019_2021,
)
class LatControlTorque(LatControl): class LatControlTorque(LatControl):
def __init__(self, CP, CI, dt): def __init__(self, CP, CI, dt):
@@ -55,6 +67,21 @@ class LatControlTorque(LatControl):
self.previous_measurement = 0.0 self.previous_measurement = 0.0
self.measurement_rate_filter = FirstOrderFilter(0.0, 1 / (2 * np.pi * (MAX_LAT_JERK_UP - 0.5)), self.dt) self.measurement_rate_filter = FirstOrderFilter(0.0, 1 / (2 * np.pi * (MAX_LAT_JERK_UP - 0.5)), self.dt)
self.low_speed_reset_threshold = max(CP.minSteerSpeed, MIN_LATERAL_CONTROL_SPEED) self.low_speed_reset_threshold = max(CP.minSteerSpeed, MIN_LATERAL_CONTROL_SPEED)
self.debug_counter = 0
self.prev_desired_lateral_accel = 0.0
self.is_bolt = CP.carFingerprint in BOLT_CARS
self.torque_ff_scale_pos = 1.0
self.torque_ff_scale_neg = 1.0
self.torque_deadzone_boost_neg = 0.0
self.torque_ki_mult = 1.0
if self.is_bolt:
self.torque_ff_scale_pos = float(self.torque_params.kp)
self.torque_ff_scale_neg = float(self.torque_params.ki)
self.torque_ki_mult = float(self.torque_params.kd)
self.torque_deadzone_boost_neg = float(getattr(self.torque_params, "kfDEPRECATED", 0.0))
if self.torque_ki_mult > 0.0 and self.torque_ki_mult != 1.0:
self.pid._k_i = [self.pid._k_i[0], [k * self.torque_ki_mult for k in self.pid._k_i[1]]]
def update_live_torque_params(self, latAccelFactor, latAccelOffset, friction): def update_live_torque_params(self, latAccelFactor, latAccelOffset, friction):
self.torque_params.latAccelFactor = latAccelFactor self.torque_params.latAccelFactor = latAccelFactor
@@ -76,6 +103,7 @@ class LatControlTorque(LatControl):
self.previous_measurement = 0.0 self.previous_measurement = 0.0
self.measurement_rate_filter.x = 0.0 self.measurement_rate_filter.x = 0.0
self.lat_accel_request_buffer = deque([0.] * self.lat_accel_request_buffer_len , maxlen=self.lat_accel_request_buffer_len) self.lat_accel_request_buffer = deque([0.] * self.lat_accel_request_buffer_len , maxlen=self.lat_accel_request_buffer_len)
self.prev_desired_lateral_accel = 0.0
else: else:
if self.prev_steering_pressed and not CS.steeringPressed: if self.prev_steering_pressed and not CS.steeringPressed:
self.pid.i *= self.steer_release_i_decay self.pid.i *= self.steer_release_i_decay
@@ -94,6 +122,10 @@ class LatControlTorque(LatControl):
desired_lateral_jerk = np.clip(self.jerk_filter.update(raw_lateral_jerk), -MAX_LAT_JERK_UP, MAX_LAT_JERK_UP) desired_lateral_jerk = np.clip(self.jerk_filter.update(raw_lateral_jerk), -MAX_LAT_JERK_UP, MAX_LAT_JERK_UP)
gravity_adjusted_future_lateral_accel = future_desired_lateral_accel - roll_compensation gravity_adjusted_future_lateral_accel = future_desired_lateral_accel - roll_compensation
setpoint = expected_lateral_accel + desired_lateral_jerk * lat_delay setpoint = expected_lateral_accel + desired_lateral_jerk * lat_delay
desired_lateral_accel_rate = (setpoint - self.prev_desired_lateral_accel) / self.dt
unwind_detected = (desired_lateral_accel_rate < UNWIND_D_DES_THRESHOLD and
abs(setpoint) < UNWIND_LAT_ACCEL_NEAR_ZERO)
self.prev_desired_lateral_accel = setpoint
measurement = measured_curvature * CS.vEgo ** 2 measurement = measured_curvature * CS.vEgo ** 2
measurement_rate = self.measurement_rate_filter.update((measurement - self.previous_measurement) / self.dt) measurement_rate = self.measurement_rate_filter.update((measurement - self.previous_measurement) / self.dt)
@@ -110,11 +142,23 @@ class LatControlTorque(LatControl):
ff = gravity_adjusted_future_lateral_accel ff = gravity_adjusted_future_lateral_accel
# latAccelOffset corrects roll compensation bias from device roll misalignment relative to car roll # latAccelOffset corrects roll compensation bias from device roll misalignment relative to car roll
ff -= self.torque_params.latAccelOffset ff -= self.torque_params.latAccelOffset
ff_scale = 1.0
if self.is_bolt:
ff_scale = np.interp(ff, [-FF_SCALE_BLEND_LAT_ACCEL, 0.0, FF_SCALE_BLEND_LAT_ACCEL],
[self.torque_ff_scale_neg, 1.0, self.torque_ff_scale_pos])
ff *= ff_scale
ff += get_friction(error_with_lsf + JERK_GAIN * desired_lateral_jerk, lateral_accel_deadzone, get_friction_threshold(CS.vEgo), self.torque_params) ff += get_friction(error_with_lsf + JERK_GAIN * desired_lateral_jerk, lateral_accel_deadzone, get_friction_threshold(CS.vEgo), self.torque_params)
deadzone_boost_active = False
if self.is_bolt and self.torque_deadzone_boost_neg > 0.0 and gravity_adjusted_future_lateral_accel < 0.0:
if abs(gravity_adjusted_future_lateral_accel) < DEADZONE_BOOST_LAT_ACCEL:
boost_scale = np.interp(abs(gravity_adjusted_future_lateral_accel), [0.0, DEADZONE_BOOST_LAT_ACCEL], [1.0, 0.0])
ff -= self.torque_deadzone_boost_neg * boost_scale
deadzone_boost_active = True
if CS.vEgo < self.low_speed_reset_threshold: if CS.vEgo < self.low_speed_reset_threshold:
self.pid.reset() self.pid.reset()
freeze_integrator = steer_limited_by_safety or CS.steeringPressed or CS.vEgo < self.low_speed_reset_threshold freeze_integrator = (steer_limited_by_safety or CS.steeringPressed or
CS.vEgo < self.low_speed_reset_threshold or unwind_detected)
output_lataccel = self.pid.update(pid_log.error, error_rate=-measurement_rate, speed=CS.vEgo, feedforward=ff, freeze_integrator=freeze_integrator) output_lataccel = self.pid.update(pid_log.error, error_rate=-measurement_rate, speed=CS.vEgo, feedforward=ff, freeze_integrator=freeze_integrator)
output_torque = self.torque_from_lateral_accel(output_lataccel, self.torque_params) output_torque = self.torque_from_lateral_accel(output_lataccel, self.torque_params)
@@ -129,6 +173,12 @@ class LatControlTorque(LatControl):
pid_log.desiredLateralJerk = float(desired_lateral_jerk) pid_log.desiredLateralJerk = float(desired_lateral_jerk)
pid_log.saturated = bool(self._check_saturation(self.steer_max - abs(output_torque) < 1e-3, CS, steer_limited_by_safety, curvature_limited)) pid_log.saturated = bool(self._check_saturation(self.steer_max - abs(output_torque) < 1e-3, CS, steer_limited_by_safety, curvature_limited))
if DEBUG_TORQUE_TUNE and self.is_bolt:
self.debug_counter += 1
if self.debug_counter % 50 == 0:
print(f"bolt_torque ff_scale={ff_scale:.3f} pos={self.torque_ff_scale_pos:.3f} "
f"neg={self.torque_ff_scale_neg:.3f} deadzone_boost_active={deadzone_boost_active}")
self.prev_steering_pressed = CS.steeringPressed self.prev_steering_pressed = CS.steeringPressed
# TODO left is positive in this convention # TODO left is positive in this convention
@@ -17,9 +17,9 @@ from openpilot.selfdrive.controls.lib.drive_helpers import V_CRUISE_UNSET, CONTR
from openpilot.common.swaglog import cloudlog from openpilot.common.swaglog import cloudlog
LON_MPC_STEP = 0.2 # first step is 0.2s LON_MPC_STEP = 0.2 # first step is 0.2s
A_CRUISE_MIN = -1.2 A_CRUISE_MIN = -1.0
A_CRUISE_MAX_VALS = [1.6, 1.2, 0.8, 0.6] A_CRUISE_MAX_BP = [0.0, 5., 10., 15., 20., 25., 40.]
A_CRUISE_MAX_BP = [0., 10.0, 25., 40.] A_CRUISE_MAX_VALS = [1.125, 1.125, 1.125, 1.125, 1.25, 1.25, 1.5]
CONTROL_N_T_IDX = ModelConstants.T_IDXS[:CONTROL_N] CONTROL_N_T_IDX = ModelConstants.T_IDXS[:CONTROL_N]
ALLOW_THROTTLE_THRESHOLD = 0.5 ALLOW_THROTTLE_THRESHOLD = 0.5
MIN_ALLOW_THROTTLE_SPEED = 2.5 MIN_ALLOW_THROTTLE_SPEED = 2.5
+1 -1
View File
@@ -118,7 +118,7 @@ std::optional<std::string> Panda::get_serial() {
bool Panda::up_to_date() { bool Panda::up_to_date() {
if (auto fw_sig = get_firmware_version()) { if (auto fw_sig = get_firmware_version()) {
for (auto fn : { "panda.bin.signed", "panda_h7.bin.signed" }) { for (auto fn : { "panda.bin.signed", "panda_h7.bin.signed", "panda_remote.bin.signed", "panda_h7_remote.bin.signed" }) {
auto content = util::read_file(std::string("../../panda/board/obj/") + fn); auto content = util::read_file(std::string("../../panda/board/obj/") + fn);
if (content.size() >= fw_sig->size() && if (content.size() >= fw_sig->size() &&
memcmp(content.data() + content.size() - fw_sig->size(), fw_sig->data(), fw_sig->size()) == 0) { memcmp(content.data() + content.size() - fw_sig->size(), fw_sig->data(), fw_sig->size()) == 0) {
Binary file not shown.
+24 -6
View File
@@ -13,15 +13,25 @@ from openpilot.system.hardware import HARDWARE
from openpilot.common.swaglog import cloudlog from openpilot.common.swaglog import cloudlog
def get_expected_signature(panda: Panda) -> bytes: def get_expected_firmware_path(panda: Panda, remote_start: bool) -> str:
app_fn = panda.get_mcu_type().config.app_fn
if remote_start:
remote_fn = "panda_h7_remote.bin.signed" if app_fn == "panda_h7.bin.signed" else "panda_remote.bin.signed"
remote_path = os.path.join(FW_PATH, remote_fn)
if os.path.isfile(remote_path):
return remote_path
cloudlog.warning(f"Remote-start panda firmware not found: {remote_path}, falling back to default")
return os.path.join(FW_PATH, app_fn)
def get_expected_signature(panda: Panda, remote_start: bool) -> bytes:
try: try:
fn = os.path.join(FW_PATH, panda.get_mcu_type().config.app_fn) fn = get_expected_firmware_path(panda, remote_start)
return Panda.get_signature_from_firmware(fn) return Panda.get_signature_from_firmware(fn)
except Exception: except Exception:
cloudlog.exception("Error computing expected signature") cloudlog.exception("Error computing expected signature")
return b"" return b""
def flash_panda(panda_serial: str) -> Panda: def flash_panda(panda_serial: str, remote_start: bool) -> Panda:
try: try:
panda = Panda(panda_serial) panda = Panda(panda_serial)
except PandaProtocolMismatch: except PandaProtocolMismatch:
@@ -29,7 +39,8 @@ def flash_panda(panda_serial: str) -> Panda:
HARDWARE.recover_internal_panda() HARDWARE.recover_internal_panda()
raise raise
fw_signature = get_expected_signature(panda) fw_path = get_expected_firmware_path(panda, remote_start)
fw_signature = get_expected_signature(panda, remote_start)
internal_panda = panda.is_internal() internal_panda = panda.is_internal()
panda_version = "bootstub" if panda.bootstub else panda.get_version() panda_version = "bootstub" if panda.bootstub else panda.get_version()
@@ -38,7 +49,7 @@ def flash_panda(panda_serial: str) -> Panda:
if panda.bootstub or panda_signature != fw_signature: if panda.bootstub or panda_signature != fw_signature:
cloudlog.info("Panda firmware out of date, update required") cloudlog.info("Panda firmware out of date, update required")
panda.flash() panda.flash(fn=fw_path)
cloudlog.info("Done flashing") cloudlog.info("Done flashing")
if panda.bootstub: if panda.bootstub:
@@ -105,8 +116,9 @@ def main() -> NoReturn:
# Flash pandas # Flash pandas
pandas: list[Panda] = [] pandas: list[Panda] = []
remote_start = params.get_bool("RemoteStartBootsComma")
for serial in panda_serials: for serial in panda_serials:
pandas.append(flash_panda(serial)) pandas.append(flash_panda(serial, remote_start))
# Ensure internal panda is present if expected # Ensure internal panda is present if expected
internal_pandas = [panda for panda in pandas if panda.is_internal()] internal_pandas = [panda for panda in pandas if panda.is_internal()]
@@ -158,6 +170,12 @@ def main() -> NoReturn:
first_run = False first_run = False
# run pandad with all connected serials as arguments # run pandad with all connected serials as arguments
# BOARDD_SKIP_FW_CHECK is needed for remote-start alternate panda firmware on
# precompiled builds where native pandad may not include updated allowlist entries yet.
if params.get_bool("RemoteStartBootsComma"):
os.environ["BOARDD_SKIP_FW_CHECK"] = "1"
else:
os.environ.pop("BOARDD_SKIP_FW_CHECK", None)
os.environ['MANAGER_DAEMON'] = 'pandad' os.environ['MANAGER_DAEMON'] = 'pandad'
os.chdir(os.path.join(BASEDIR, "selfdrive/pandad")) os.chdir(os.path.join(BASEDIR, "selfdrive/pandad"))
subprocess.run(["./pandad", *panda_serials], check=True) subprocess.run(["./pandad", *panda_serials], check=True)
Binary file not shown.
Binary file not shown.
Binary file not shown.
+28
View File
@@ -2,6 +2,7 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QMouseEvent> #include <QMouseEvent>
#include <QSet>
#include <QStackedWidget> #include <QStackedWidget>
#include <QVBoxLayout> #include <QVBoxLayout>
@@ -172,6 +173,22 @@ OffroadHome::OffroadHome(QWidget* parent) : QFrame(parent) {
main_layout->addLayout(header_layout); main_layout->addLayout(header_layout);
branch_merge_banner = new QLabel(this);
branch_merge_banner->setAlignment(Qt::AlignCenter);
branch_merge_banner->setWordWrap(true);
branch_merge_banner->setAttribute(Qt::WA_TransparentForMouseEvents, true);
branch_merge_banner->setVisible(false);
branch_merge_banner->setStyleSheet(R"(
background-color: #E22C2C;
color: white;
border-radius: 16px;
padding: 24px;
font-size: 44px;
font-weight: 700;
)");
branch_merge_banner->setText(tr("Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch."));
main_layout->addWidget(branch_merge_banner);
// main content // main content
main_layout->addSpacing(25); main_layout->addSpacing(25);
center_layout = new QStackedLayout(); center_layout = new QStackedLayout();
@@ -268,10 +285,21 @@ void OffroadHome::hideEvent(QHideEvent *event) {
} }
void OffroadHome::refresh() { void OffroadHome::refresh() {
static const QSet<QString> deprecated_branches = {
"TorqueTune",
"TorquePedal",
"Kaofui",
"Red-Kao",
"TotallyTune",
"StarPilot-2017",
"TRX",
};
date->setText(QLocale(uiState()->language.mid(5)).toString(QDateTime::currentDateTime(), "dddd, MMMM d")); date->setText(QLocale(uiState()->language.mid(5)).toString(QDateTime::currentDateTime(), "dddd, MMMM d"));
date->setVisible(util::system_time_valid()); date->setVisible(util::system_time_valid());
version->setText(getBrand() + " v" + getVersion().left(14).trimmed() + " - " + processModelName(frogpilotUIState()->frogpilot_toggles.value("model_name").toString())); version->setText(getBrand() + " v" + getVersion().left(14).trimmed() + " - " + processModelName(frogpilotUIState()->frogpilot_toggles.value("model_name").toString()));
branch_merge_banner->setVisible(deprecated_branches.contains(QString::fromStdString(params.get("GitBranch"))));
bool updateAvailable = update_widget->refresh(); bool updateAvailable = update_widget->refresh();
int alerts = alerts_widget->refresh(); int alerts = alerts_widget->refresh();
+1
View File
@@ -41,6 +41,7 @@ private:
OffroadAlert* alerts_widget; OffroadAlert* alerts_widget;
QPushButton* alert_notif; QPushButton* alert_notif;
QPushButton* update_notif; QPushButton* update_notif;
QLabel* branch_merge_banner;
// FrogPilot variables // FrogPilot variables
ElidedLabel* date; ElidedLabel* date;
+56
View File
@@ -2134,6 +2134,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3364,6 +3372,30 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated">إلغاء</translation> <translation type="gpt-5-generated">إلغاء</translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3814,6 +3846,22 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3822,6 +3870,10 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4756,6 +4808,10 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source> ALERT</source> <source> ALERT</source>
<translation> تنبيه</translation> <translation> تنبيه</translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2136,6 +2136,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3368,6 +3376,30 @@ Developer - Many custom setting for seasoned enthusiast</translation>
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated">CANCEL</translation> <translation type="gpt-5-generated">CANCEL</translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3818,6 +3850,22 @@ Developer - Many custom setting for seasoned enthusiast</translation>
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3826,6 +3874,10 @@ Developer - Many custom setting for seasoned enthusiast</translation>
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4758,6 +4810,10 @@ Developer - Many custom setting for seasoned enthusiast</translation>
<source> ALERT</source> <source> ALERT</source>
<translation type="gpt-5-generated">ALERT</translation> <translation type="gpt-5-generated">ALERT</translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2134,6 +2134,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3364,6 +3372,30 @@ Entwickler Hochgradig anpassbare Einstellungen für versierte Enthusiasten</
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated">ABBRECHEN</translation> <translation type="gpt-5-generated">ABBRECHEN</translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3814,6 +3846,22 @@ Entwickler Hochgradig anpassbare Einstellungen für versierte Enthusiasten</
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3822,6 +3870,10 @@ Entwickler Hochgradig anpassbare Einstellungen für versierte Enthusiasten</
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4752,6 +4804,10 @@ Entwickler Hochgradig anpassbare Einstellungen für versierte Enthusiasten</
<source> ALERT</source> <source> ALERT</source>
<translation> HINWEIS</translation> <translation> HINWEIS</translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2136,6 +2136,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3366,6 +3374,30 @@ Developer - Ultra-custom settings for seasoned duckthusiasts</translation>
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated">QUACK-CANCEL</translation> <translation type="gpt-5-generated">QUACK-CANCEL</translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3816,6 +3848,22 @@ Developer - Ultra-custom settings for seasoned duckthusiasts</translation>
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3824,6 +3872,10 @@ Developer - Ultra-custom settings for seasoned duckthusiasts</translation>
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4754,6 +4806,10 @@ Developer - Ultra-custom settings for seasoned duckthusiasts</translation>
<source> ALERT</source> <source> ALERT</source>
<translation type="gpt-5-generated">QUACK ALERT</translation> <translation type="gpt-5-generated">QUACK ALERT</translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2134,6 +2134,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3363,6 +3371,30 @@ Desarrollador: configuración altamente personalizable para entusiastas veterano
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated">CANCELAR</translation> <translation type="gpt-5-generated">CANCELAR</translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3813,6 +3845,22 @@ Desarrollador: configuración altamente personalizable para entusiastas veterano
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3821,6 +3869,10 @@ Desarrollador: configuración altamente personalizable para entusiastas veterano
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4751,6 +4803,10 @@ Desarrollador: configuración altamente personalizable para entusiastas veterano
<source> ALERT</source> <source> ALERT</source>
<translation> ALERTA</translation> <translation> ALERTA</translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2134,6 +2134,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3363,6 +3371,30 @@ Développeur Paramètres hautement personnalisables pour passionnés chevron
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated">ANNULER</translation> <translation type="gpt-5-generated">ANNULER</translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3813,6 +3845,22 @@ Développeur Paramètres hautement personnalisables pour passionnés chevron
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3821,6 +3869,10 @@ Développeur Paramètres hautement personnalisables pour passionnés chevron
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4751,6 +4803,10 @@ Développeur Paramètres hautement personnalisables pour passionnés chevron
<source> ALERT</source> <source> ALERT</source>
<translation> ALERTE</translation> <translation> ALERTE</translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2134,6 +2134,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3364,6 +3372,30 @@ Developer - Highly customizable settings for seasoned swamp pros</translation>
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated">Ribbit! CANCEL croak!</translation> <translation type="gpt-5-generated">Ribbit! CANCEL croak!</translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3814,6 +3846,22 @@ Developer - Highly customizable settings for seasoned swamp pros</translation>
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3822,6 +3870,10 @@ Developer - Highly customizable settings for seasoned swamp pros</translation>
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4752,6 +4804,10 @@ Developer - Highly customizable settings for seasoned swamp pros</translation>
<source> ALERT</source> <source> ALERT</source>
<translation type="gpt-5-generated">Ribbit! ALERT!</translation> <translation type="gpt-5-generated">Ribbit! ALERT!</translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2134,6 +2134,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3362,6 +3370,30 @@ Developer - こだわりのある上級者向けの高度にカスタマイズ
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated"></translation> <translation type="gpt-5-generated"></translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3812,6 +3844,22 @@ Developer - こだわりのある上級者向けの高度にカスタマイズ
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3820,6 +3868,10 @@ Developer - こだわりのある上級者向けの高度にカスタマイズ
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4749,6 +4801,10 @@ Developer - こだわりのある上級者向けの高度にカスタマイズ
<source> ALERT</source> <source> ALERT</source>
<translation> </translation> <translation> </translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2134,6 +2134,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3363,6 +3371,30 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated"></translation> <translation type="gpt-5-generated"></translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3813,6 +3845,22 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3821,6 +3869,10 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4750,6 +4802,10 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source> ALERT</source> <source> ALERT</source>
<translation> </translation> <translation> </translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2134,6 +2134,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3364,6 +3372,30 @@ Developer - Highly customizable riggins fer seasoned enthusiasts</translation
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated">AVAST</translation> <translation type="gpt-5-generated">AVAST</translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3814,6 +3846,22 @@ Developer - Highly customizable riggins fer seasoned enthusiasts</translation
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3822,6 +3870,10 @@ Developer - Highly customizable riggins fer seasoned enthusiasts</translation
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4752,6 +4804,10 @@ Developer - Highly customizable riggins fer seasoned enthusiasts</translation
<source> ALERT</source> <source> ALERT</source>
<translation type="gpt-5-generated">ALERT, arrr!</translation> <translation type="gpt-5-generated">ALERT, arrr!</translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2134,6 +2134,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3364,6 +3372,30 @@ Desenvolvedor - Configurações altamente personalizáveis para entusiastas expe
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated">CANCELAR</translation> <translation type="gpt-5-generated">CANCELAR</translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3814,6 +3846,22 @@ Desenvolvedor - Configurações altamente personalizáveis para entusiastas expe
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3822,6 +3870,10 @@ Desenvolvedor - Configurações altamente personalizáveis para entusiastas expe
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4752,6 +4804,10 @@ Desenvolvedor - Configurações altamente personalizáveis para entusiastas expe
<source> ALERT</source> <source> ALERT</source>
<translation> ALERTA</translation> <translation> ALERTA</translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
@@ -2140,6 +2140,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3372,6 +3380,30 @@ Developer - Most customizable settings for well-tried enthusiasts</translation>
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated">CANCEL</translation> <translation type="gpt-5-generated">CANCEL</translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3824,6 +3856,22 @@ Developer - Most customizable settings for well-tried enthusiasts</translation>
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3832,6 +3880,10 @@ Developer - Most customizable settings for well-tried enthusiasts</translation>
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4764,6 +4816,10 @@ Developer - Most customizable settings for well-tried enthusiasts</translation>
<source> ALERT</source> <source> ALERT</source>
<translation type="gpt-5-generated">ALERT</translation> <translation type="gpt-5-generated">ALERT</translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2134,6 +2134,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3364,6 +3372,30 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated"></translation> <translation type="gpt-5-generated"></translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3814,6 +3846,22 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3822,6 +3870,10 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4751,6 +4803,10 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source> ALERT</source> <source> ALERT</source>
<translation> </translation> <translation> </translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2134,6 +2134,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3363,6 +3371,30 @@ Geliştirici - Tecrübeli meraklılar için yüksek özelleştirilebilir ayarlar
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated">İPTAL</translation> <translation type="gpt-5-generated">İPTAL</translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3813,6 +3845,22 @@ Geliştirici - Tecrübeli meraklılar için yüksek özelleştirilebilir ayarlar
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3821,6 +3869,10 @@ Geliştirici - Tecrübeli meraklılar için yüksek özelleştirilebilir ayarlar
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4750,6 +4802,10 @@ Geliştirici - Tecrübeli meraklılar için yüksek özelleştirilebilir ayarlar
<source> ALERT</source> <source> ALERT</source>
<translation> UYARI</translation> <translation> UYARI</translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2134,6 +2134,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3364,6 +3372,30 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated"></translation> <translation type="gpt-5-generated"></translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3814,6 +3846,22 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3822,6 +3870,10 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4751,6 +4803,10 @@ Developer - Highly customizable settings for seasoned enthusiasts</source>
<source> ALERT</source> <source> ALERT</source>
<translation> </translation> <translation> </translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
+56
View File
@@ -2134,6 +2134,14 @@
<source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source> <source>&lt;b&gt;Use acceleration profiles tuned for EVs.&lt;/b&gt; Defaults to the vehicle's detected powertrain type but can be overridden if the automatic choice doesn't match.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Truck Tuning</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use aggressive acceleration profiles tuned for trucks.&lt;/b&gt; Intended for heavy vehicles that need stronger throttle.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>High Speed Following Distance</source> <source>High Speed Following Distance</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3364,6 +3372,30 @@ Developer - 為資深愛好者提供高度自訂的設定</translation>
<source>CANCEL</source> <source>CANCEL</source>
<translation type="gpt-5-generated"></translation> <translation type="gpt-5-generated"></translation>
</message> </message>
<message>
<source>Boot Logo</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;The boot logo shown while the device starts.&lt;/b&gt;</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to delete</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Delete the "%1" boot logo?</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo to download</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Select a boot logo</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotUtilitiesPanel</name> <name>FrogPilotUtilitiesPanel</name>
@@ -3814,6 +3846,22 @@ Developer - 為資深愛好者提供高度自訂的設定</translation>
<source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source> <source>&lt;b&gt;Use the pedal interceptor for longitudinal control&lt;/b&gt; instead of camera ACC/Redneck when available.</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Red Panda</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Enable Red Panda behavior&lt;/b&gt; for GM (alternate safety config and bus numbering). Requires a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>Remote Start Boots Comma</source>
<translation type="unfinished"></translation>
</message>
<message>
<source>&lt;b&gt;Use GM C9 SystemPowerMode&lt;/b&gt; for ignition detection. Toggle requires a panda firmware update and a reboot to take effect.</source>
<translation type="unfinished"></translation>
</message>
<message> <message>
<source>SASCM Support</source> <source>SASCM Support</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
@@ -3822,6 +3870,10 @@ Developer - 為資深愛好者提供高度自訂的設定</translation>
<source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source> <source>&lt;b&gt;Does your vehicle support "SASCMs"?&lt;/b&gt;</source>
<translation type="unfinished"></translation> <translation type="unfinished"></translation>
</message> </message>
<message>
<source>Remote Start requires a Panda firmware update. Flash the Panda now?</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>FrogPilotVisualsPanel</name> <name>FrogPilotVisualsPanel</name>
@@ -4751,6 +4803,10 @@ Developer - 為資深愛好者提供高度自訂的設定</translation>
<source> ALERT</source> <source> ALERT</source>
<translation> </translation> <translation> </translation>
</message> </message>
<message>
<source>Branch Merge Notice: This branch is deprecated and has been merged into StarPilot. Please switch to the StarPilot branch.</source>
<translation type="unfinished"></translation>
</message>
</context> </context>
<context> <context>
<name>OnroadAlerts</name> <name>OnroadAlerts</name>
BIN
View File
Binary file not shown.
+67
View File
@@ -92,6 +92,65 @@ def manager_init() -> None:
params.put_bool("IsTestedBranch", build_metadata.tested_channel) params.put_bool("IsTestedBranch", build_metadata.tested_channel)
params.put_bool("IsReleaseBranch", build_metadata.release_channel) params.put_bool("IsReleaseBranch", build_metadata.release_channel)
# Legacy Bolt fingerprint migration after branch consolidation
bolt_source_branch_file = "/data/media/0/starpilot_source_branch"
bolt_fingerprint_migration_flag_file = "/data/media/0/frogpilot_bolt_fingerprint_migrated.flag"
if not os.path.exists(bolt_fingerprint_migration_flag_file):
source_branch = ""
try:
if os.path.exists(bolt_source_branch_file):
with open(bolt_source_branch_file, encoding="utf-8") as f:
source_branch = f.read().strip()
except OSError:
cloudlog.exception("failed reading StarPilot source branch file")
migration_branch = source_branch or build_metadata.channel
replacements = {}
if migration_branch in {"TorqueTune", "TorquePedal"}:
replacements = {
"CHEVROLET_BOLT_EUV": "CHEVROLET_BOLT_ACC_2022_2023",
"CHEVROLET_BOLT_CC": "CHEVROLET_BOLT_CC_2022_2023",
}
elif migration_branch in {"TotallyTune", "StarPilot-2017", "StarPilot 2017"}:
replacements = {
"CHEVROLET_BOLT_CC": "CHEVROLET_BOLT_CC_2017",
}
elif migration_branch in {"StarPilot"}:
replacements = {
"CHEVROLET_BOLT_CC": "CHEVROLET_BOLT_CC_2019_2021",
}
migrated_values = []
if replacements:
for param_key in ("CarModel", "CarModelName"):
current_value = params.get(param_key, encoding='utf-8')
normalized_value = current_value[4:] if current_value is not None and current_value.startswith("CAR.") else current_value
if normalized_value in replacements:
new_value = replacements[normalized_value]
params.put(param_key, new_value)
params_cache.put(param_key, new_value)
migrated_values.append(f"{param_key}: {current_value} -> {new_value}")
if migrated_values:
cloudlog.info(f"migrated legacy bolt fingerprint values from branch '{migration_branch}' (source='{source_branch}'): {', '.join(migrated_values)}")
# Keep Bolt display label aligned with live fingerprint selection
bolt_models = {
"CHEVROLET_BOLT_EUV",
"CHEVROLET_BOLT_CC",
"CHEVROLET_BOLT_ACC_2022_2023",
"CHEVROLET_BOLT_ACC_2022_2023_PEDAL",
"CHEVROLET_BOLT_CC_2022_2023",
"CHEVROLET_BOLT_CC_2019_2021",
"CHEVROLET_BOLT_CC_2017",
}
if (params.get("CarModel", encoding='utf-8') or "") in bolt_models:
params.remove("CarModelName")
params_cache.remove("CarModelName")
with open(bolt_fingerprint_migration_flag_file, "w") as f:
f.write(migration_branch or "unknown")
# One-time migration to align FrogPilot defaults after install # One-time migration to align FrogPilot defaults after install
frogpilot_migration_flag_file = "/data/media/0/frogpilot_migrated.flag" frogpilot_migration_flag_file = "/data/media/0/frogpilot_migrated.flag"
if not os.path.exists(frogpilot_migration_flag_file): if not os.path.exists(frogpilot_migration_flag_file):
@@ -180,6 +239,14 @@ def manager_init() -> None:
with open(lateral_tuning_migration_flag_file, "w") as f: with open(lateral_tuning_migration_flag_file, "w") as f:
f.write("migrated") f.write("migrated")
# One-time migration for MaxDesiredAcceleration to 4
max_desired_acceleration_migration_flag_file = "/data/media/0/frogpilot_max_desired_acceleration_migrated.flag"
if not os.path.exists(max_desired_acceleration_migration_flag_file):
if params.get_float("MaxDesiredAcceleration") != 4.0:
params.put_float("MaxDesiredAcceleration", 4.0)
with open(max_desired_acceleration_migration_flag_file, "w") as f:
f.write("migrated")
# set dongle id # set dongle id
reg_res = register(show_spinner=True) reg_res = register(show_spinner=True)
if reg_res: if reg_res:
+39
View File
@@ -36,6 +36,19 @@ OVERLAY_INIT = Path(os.path.join(BASEDIR, ".overlay_init"))
DAYS_NO_CONNECTIVITY_MAX = 14 # do not allow to engage after this many days DAYS_NO_CONNECTIVITY_MAX = 14 # do not allow to engage after this many days
DAYS_NO_CONNECTIVITY_PROMPT = 10 # send an offroad prompt after this many days DAYS_NO_CONNECTIVITY_PROMPT = 10 # send an offroad prompt after this many days
MIGRATED_TARGET_BRANCH = "StarPilot"
MIGRATION_DONE_FILE = "/data/starpilot_branch_migrated"
MIGRATION_SOURCE_BRANCH_FILE = "/data/media/0/starpilot_source_branch"
MIGRATION_EXCLUDED_BRANCHES = {"Dom"}
MIGRATION_SOURCE_BRANCHES = {
"TorqueTune",
"TorquePedal",
"Kaofui",
"Red-Kao",
"TotallyTune",
"StarPilot-2017",
"TRX",
}
class UserRequest: class UserRequest:
NONE = 0 NONE = 0
@@ -280,6 +293,7 @@ class Updater:
self.params = Params() self.params = Params()
self.branches = defaultdict(str) self.branches = defaultdict(str)
self._has_internet: bool = False self._has_internet: bool = False
self._migrate_target_branch()
@property @property
def has_internet(self) -> bool: def has_internet(self) -> bool:
@@ -292,6 +306,31 @@ class Updater:
b = self.get_branch(BASEDIR) b = self.get_branch(BASEDIR)
return b return b
def _migrate_target_branch(self) -> None:
target_branch: str | None = self.params.get("UpdaterTargetBranch", encoding='utf-8')
current_branch = self.get_branch(BASEDIR)
if current_branch in MIGRATION_EXCLUDED_BRANCHES or target_branch in MIGRATION_EXCLUDED_BRANCHES:
cloudlog.info(f"skipping StarPilot branch migration on excluded branch: current={current_branch}, target={target_branch}")
return
if current_branch not in MIGRATION_SOURCE_BRANCHES and target_branch not in MIGRATION_SOURCE_BRANCHES:
cloudlog.info(f"skipping StarPilot branch migration on unmanaged branch: current={current_branch}, target={target_branch}")
return
if current_branch != MIGRATED_TARGET_BRANCH:
try:
Path(MIGRATION_SOURCE_BRANCH_FILE).write_text(current_branch, encoding='utf-8')
except OSError:
cloudlog.exception(f"failed to persist source branch for migration: {MIGRATION_SOURCE_BRANCH_FILE}")
if target_branch != MIGRATED_TARGET_BRANCH or current_branch != MIGRATED_TARGET_BRANCH:
self.params.put("UpdaterTargetBranch", MIGRATED_TARGET_BRANCH)
cloudlog.info(f"migrated updater target branch to {MIGRATED_TARGET_BRANCH} from target={target_branch}, current={current_branch}")
try:
Path(MIGRATION_DONE_FILE).touch()
except OSError:
cloudlog.exception(f"failed to write migration flag file: {MIGRATION_DONE_FILE}")
@property @property
def update_ready(self) -> bool: def update_ready(self) -> bool:
consistent_file = Path(os.path.join(FINALIZED, ".overlay_consistent")) consistent_file = Path(os.path.join(FINALIZED, ".overlay_consistent"))