Compare commits

...

21 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
79 changed files with 2619 additions and 410 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;
@@ -171,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
+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 == 0xC9) && (len == 8)) { #ifdef PANDA_GM_REMOTE_START_C9
// Matches SystemPowerMode (1=Run, 0=Off) if (true) {
ignition_can = (GET_BYTE(to_push, 6) & 0x10U) != 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.
+104 -82
View File
@@ -9,20 +9,32 @@ 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
@@ -40,7 +52,7 @@ const CanMsg GM_CAM_TX_MSGS[] = {{0x180, 0, 4}, {0x200, 0, 6}, {0x1E1, 0, 7}, {0
{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}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus const CanMsg GM_CAM_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x315, 0, 5}, {0x2CB, 0, 8}, {0x370, 0, 6}, {0x200, 0, 6}, {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}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // 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
@@ -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;
@@ -172,13 +191,6 @@ static void gm_rx_hook(const CANPacket_t *to_push) {
} }
} }
// Cruise check for ACC models with pedal interceptor - block stock ACC
if ((addr == 0x1C4) && gm_has_acc && enable_gas_interceptor) {
// When pedal interceptor is active on ACC models, ignore stock cruise state
// to prevent conflicts between pedal interceptor and stock ACC
cruise_engaged_prev = false;
}
if (addr == 0xBD) { if (addr == 0xBD) {
regen_braking = (GET_BYTE(to_push, 0) >> 4) != 0U; regen_braking = (GET_BYTE(to_push, 0) >> 4) != 0U;
} }
@@ -199,11 +211,18 @@ 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 Gen2 Bolt (ASCMActiveCruiseControlStatus on bus 2)
int addr = GET_ADDR(to_push); // Cruise check for ASCMActiveCruiseControlStatus on bus 2.
if ((addr == 0x370) && (GET_BUS(to_push) == 2U)) { // 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 bool cruise_engaged = (GET_BYTE(to_push, 2) >> 7) != 0U; // ACCCmdActive
cruise_engaged_prev = cruise_engaged; 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;
}
} }
} }
@@ -227,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;
} }
} }
@@ -242,10 +261,10 @@ 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, except for inactive gas // Allow apply bit in pre-enabled and overriding states // Allow apply bit in pre-enabled and overriding states
violation |= !controls_allowed && apply; violation |= !controls_allowed && apply;
violation |= longitudinal_gas_checks(gas_regen, *gm_long_limits); violation |= longitudinal_gas_checks(gas_regen, *gm_long_limits);
@@ -259,13 +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 ACC cars with pedal interceptor, allow cancel even if cruise_engaged_prev is false if (gm_hw == GM_CAM && enable_gas_interceptor && gm_bolt_2022_pedal && button == GM_BTN_CANCEL) {
// (since we set it to false to prevent conflicts, but still need to cancel cruise)
if (gm_hw == GM_CAM && enable_gas_interceptor && button == GM_BTN_CANCEL) {
allowed_btn = true; allowed_btn = true;
} }
// For standard CC, allow spamming of SET / RESUME // For CC_LONG or PCM cruise vehicles, allow SET/RESUME when cruise is engaged
if (gm_cc_long) { 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);
} }
@@ -306,14 +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
// Block 0x370 only for experimental long without pedal interceptor
bool is_lkas_msg = (addr == 0x180); bool is_lkas_msg = (addr == 0x180);
bool is_acc_msg = (addr == 0x315) || (addr == 0x2CB); bool block_msg = false;
if (gm_cam_long && !enable_gas_interceptor) { if (gm_bolt_2022_pedal) {
is_acc_msg = is_acc_msg || (addr == 0x370); // 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);
} }
bool block_msg = is_lkas_msg || (is_acc_msg && gm_cam_long);
if (!block_msg) { if (!block_msg) {
bus_fwd = 0; bus_fwd = 0;
} }
@@ -324,34 +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;
// Block ACC messages when pedal interceptor is active on ACC models gm_bolt_2022_pedal = GET_FLAG(param, GM_PARAM_BOLT_2022_PEDAL);
if (gm_hw == GM_CAM && enable_gas_interceptor) { gm_pcm_cruise = (((gm_hw == GM_CAM) || (gm_hw == GM_SDGM)) && (!gm_cam_long || gm_cc_long) && !gm_force_ascm && !gm_pedal_long);
gm_cam_long = true;
}
gm_pcm_cruise = ((gm_hw == GM_CAM) && (!gm_cam_long || gm_cc_long) && !gm_force_ascm && !gm_pedal_long) || (gm_hw == GM_SDGM);
gm_skip_relay_check = GET_FLAG(param, GM_PARAM_NO_CAMERA); gm_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) {
@@ -362,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,
+153 -49
View File
@@ -1,5 +1,7 @@
from typing import Tuple from typing import Tuple
import time 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
@@ -9,7 +11,7 @@ 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, CC_REGEN_PADDLE_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
@@ -62,15 +64,29 @@ 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.accel_g = 0.0
self.regen_paddle_pressed = False self.regen_paddle_pressed = False
@@ -137,6 +153,22 @@ class CarController(CarControllerBase):
actuators = CC.actuators actuators = CC.actuators
accel = brake_accel = actuators.accel accel = brake_accel = actuators.accel
press_regen_paddle = False 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 # 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 if (self.CP.enableGasInterceptor and self.CP.carFingerprint in CC_REGEN_PADDLE_CAR
@@ -162,6 +194,13 @@ class CarController(CarControllerBase):
can_sends = [] can_sends = []
paddle_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 = ( raw_regen_active = (
self.CP.carFingerprint in CC_REGEN_PADDLE_CAR and self.CP.carFingerprint in CC_REGEN_PADDLE_CAR and
self.CP.openpilotLongitudinalControl and self.CP.openpilotLongitudinalControl and
@@ -204,11 +243,6 @@ class CarController(CarControllerBase):
# Midpoint spoof: one per interval # Midpoint spoof: one per interval
if not self.spoof_mid_sent and interval_ns > 0: if not self.spoof_mid_sent and interval_ns > 0:
midpoint_ns = self.prev_steer_ts_ns + interval_ns // 2 midpoint_ns = self.prev_steer_ts_ns + interval_ns // 2
cloudlog.error("PADDLE MID: Δafter=%.1fms Δbefore=%.1fms credits=%.3f timer=%d",
(now_nanos - self.last_steer_ts_ns) * 1e-6,
(now_nanos - self.prev_steer_ts_ns) * 1e-6,
self.spoof_accum,
self.regen_paddle_timer)
# Compute spacing to last and next steer (two-sided guard) # 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 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_after_ns = now_nanos - self.last_steer_ts_ns
@@ -219,7 +253,7 @@ class CarController(CarControllerBase):
and delta_before_ns >= gap_ns): and delta_before_ns >= gap_ns):
# Non-blocking 1 ms spacing for paddle frames # Non-blocking 1 ms spacing for paddle frames
if now_nanos - self.last_paddle_ts_ns >= PADDLE_NONBLOCK_GAP_NS: if now_nanos - self.last_paddle_ts_ns >= PADDLE_NONBLOCK_GAP_NS:
paddle_sends.append(gmcan.create_prndl2_command(self.packer_pt, CanBus.POWERTRAIN, True)) paddle_sends.append(gmcan.create_prndl2_command(self.packer_pt, CanBus.POWERTRAIN, True, self.CP))
paddle_sends.append(gmcan.create_regen_paddle_command(self.packer_pt, CanBus.POWERTRAIN, True)) paddle_sends.append(gmcan.create_regen_paddle_command(self.packer_pt, CanBus.POWERTRAIN, True))
self.last_paddle_ts_ns = now_nanos self.last_paddle_ts_ns = now_nanos
self.last_spoof_ts_ns = now_nanos self.last_spoof_ts_ns = now_nanos
@@ -228,12 +262,6 @@ class CarController(CarControllerBase):
# Overflow spoof: insert extra when accumulator allows # Overflow spoof: insert extra when accumulator allows
if self.spoof_accum >= OVERFLOW_THRESH and not self.spoof_over_sent and interval_ns > 0: 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 slot2_ns = self.prev_steer_ts_ns + (interval_ns * 2) // 3
cloudlog.error("PADDLE OFL: Δafter=%.1fms Δbefore=%.1fms credits=%.3f thresh=%.1f timer=%d",
(now_nanos - self.last_steer_ts_ns) * 1e-6,
(now_nanos - self.prev_steer_ts_ns) * 1e-6,
self.spoof_accum,
OVERFLOW_THRESH,
self.regen_paddle_timer)
# Two-sided spacing relative to steer # Two-sided spacing relative to steer
next_steer_ts_ns = self.last_steer_ts_ns + interval_ns if interval_ns > 0 else 0 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_after_ns = now_nanos - self.last_steer_ts_ns
@@ -244,7 +272,7 @@ class CarController(CarControllerBase):
and delta_before_ns >= gap_ns): and delta_before_ns >= gap_ns):
# Non-blocking 1 ms spacing for paddle frames # Non-blocking 1 ms spacing for paddle frames
if now_nanos - self.last_paddle_ts_ns >= PADDLE_NONBLOCK_GAP_NS: if now_nanos - self.last_paddle_ts_ns >= PADDLE_NONBLOCK_GAP_NS:
paddle_sends.append(gmcan.create_prndl2_command(self.packer_pt, CanBus.POWERTRAIN, True)) paddle_sends.append(gmcan.create_prndl2_command(self.packer_pt, CanBus.POWERTRAIN, True, self.CP))
paddle_sends.append(gmcan.create_regen_paddle_command(self.packer_pt, CanBus.POWERTRAIN, True)) paddle_sends.append(gmcan.create_regen_paddle_command(self.packer_pt, CanBus.POWERTRAIN, True))
self.last_paddle_ts_ns = now_nanos self.last_paddle_ts_ns = now_nanos
self.last_spoof_ts_ns = now_nanos self.last_spoof_ts_ns = now_nanos
@@ -266,11 +294,6 @@ class CarController(CarControllerBase):
if hasattr(self, "off_schedule_ns"): if hasattr(self, "off_schedule_ns"):
for i, t_ns in enumerate(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): if not self.off_sent[i] and now_nanos >= (t_ns - PADDLE_SLOT_EARLY_NS):
cloudlog.error("PADDLE OFF %d: Δafter=%.1fms Δto_slot=%.1fms timer=%d",
i,
(now_nanos - self.last_steer_ts_ns) * 1e-6,
(now_nanos - t_ns) * 1e-6,
self.regen_paddle_timer)
# Two-sided spacing to steer before sending # Two-sided spacing to steer before sending
interval_ns = self.last_steer_ts_ns - self.prev_steer_ts_ns interval_ns = self.last_steer_ts_ns - self.prev_steer_ts_ns
gap_ns = (PADDLE_STEER_GAP_MIN_NS if interval_ns <= 0 else gap_ns = (PADDLE_STEER_GAP_MIN_NS if interval_ns <= 0 else
@@ -283,7 +306,7 @@ class CarController(CarControllerBase):
if (delta_after_ns >= gap_ns and delta_before_ns >= gap_ns): if (delta_after_ns >= gap_ns and delta_before_ns >= gap_ns):
# Non-blocking 1 ms spacing for paddle frames # Non-blocking 1 ms spacing for paddle frames
if now_nanos - self.last_paddle_ts_ns >= PADDLE_NONBLOCK_GAP_NS: if now_nanos - self.last_paddle_ts_ns >= PADDLE_NONBLOCK_GAP_NS:
paddle_sends.append(gmcan.create_prndl2_command(self.packer_pt, CanBus.POWERTRAIN, False)) paddle_sends.append(gmcan.create_prndl2_command(self.packer_pt, CanBus.POWERTRAIN, False, self.CP))
paddle_sends.append(gmcan.create_regen_paddle_command(self.packer_pt, CanBus.POWERTRAIN, False)) paddle_sends.append(gmcan.create_regen_paddle_command(self.packer_pt, CanBus.POWERTRAIN, False))
self.last_paddle_ts_ns = now_nanos self.last_paddle_ts_ns = now_nanos
self.off_sent[i] = True self.off_sent[i] = True
@@ -350,14 +373,6 @@ class CarController(CarControllerBase):
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
@@ -369,9 +384,54 @@ 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:
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:
self.apply_brake = int(round(interp(brake_accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V))) volt_pitch_accel = math.sin(CC.orientationNED[1]) * ACCELERATION_DUE_TO_GRAVITY
else:
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:
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)))
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:
@@ -394,7 +454,13 @@ class CarController(CarControllerBase):
can_sends.extend(gmcan.create_gm_cc_spam_command(self.packer_pt, self, CS, actuators, frogpilot_toggles)) 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 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): CS.cruise_buttons == CruiseButtons.UNPRESS and CS.out.gasPressed and CS.out.cruiseState.speed < CS.out.vEgo < hud_v_cruise):
can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, (CS.buttons_counter + 1) % 4, CruiseButtons.DECEL_SET)) 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:
@@ -404,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
@@ -415,7 +483,8 @@ 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))
@@ -430,26 +499,55 @@ class CarController(CarControllerBase):
# 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 (5hz, previously 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 = 20 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))
can_sends.append(gmcan.create_adas_steering_status(CanBus.OBSTACLE, idx))
can_sends.append(gmcan.create_adas_accelerometer_speed_status(CanBus.OBSTACLE, CS.out.vEgo, idx))
if self.CP.networkLocation == NetworkLocation.gateway and self.frame % (self.params.ADAS_KEEPALIVE_STEP * 2) == 0: if send_adas:
tt = self.frame * DT_CTRL
if self.CP.carFingerprint in kaofui_cars:
time_and_headlights_step = 10
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 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.
@@ -460,14 +558,20 @@ 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))
if self.CP.networkLocation == NetworkLocation.fwdCamera: if self.CP.networkLocation == NetworkLocation.fwdCamera:
# Silence "Take Steering" alert sent by camera, forward PSCMStatus with HandsOffSWlDetectionStatus=1 # Silence "Take Steering" alert sent by camera, forward PSCMStatus with HandsOffSWlDetectionStatus=1
if self.frame % 20 == 0: if self.frame % 10 == 0:
can_sends.append(gmcan.create_pscm_status(self.packer_pt, CanBus.CAMERA, CS.pscm_status)) can_sends.append(gmcan.create_pscm_status(self.packer_pt, CanBus.CAMERA, CS.pscm_status))
new_actuators = actuators.as_builder() new_actuators = actuators.as_builder()
+83 -22
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, CC_REGEN_PADDLE_CAR from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, STEER_THRESHOLD, GMFlags, CC_ONLY_CAR, CAMERA_ACC_CAR, SDGM_CAR, 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"]
@@ -78,25 +92,44 @@ class CarState(CarStateBase):
# sample rear wheel speeds, standstill=True if ECM allows engagement with brake # sample rear wheel speeds, standstill=True if ECM allows engagement with brake
ret.standstill = ret.wheelSpeeds.rl <= STANDSTILL_THRESHOLD and ret.wheelSpeeds.rr <= STANDSTILL_THRESHOLD ret.standstill = ret.wheelSpeeds.rl <= STANDSTILL_THRESHOLD and ret.wheelSpeeds.rr <= STANDSTILL_THRESHOLD
ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(pt_cp.vl["ECMPRDNL2"]["PRNDL2"], None)) if pt_cp.vl["ECMPRDNL2"]["ManualMode"] == 1:
ret.gearShifter = self.parse_gear_shifter("T")
else:
ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(pt_cp.vl["ECMPRDNL2"]["PRNDL2"], None))
if self.CP.flags & GMFlags.NO_ACCELERATOR_POS_MSG.value: 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.
@@ -117,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
@@ -153,29 +186,39 @@ 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:
ret.leftBlindspot = cam_cp.vl["BCMBlindSpotMonitor"]["LeftBSM"] == 1 ret.leftBlindspot = cam_cp.vl["BCMBlindSpotMonitor"]["LeftBSM"] == 1
ret.rightBlindspot = cam_cp.vl["BCMBlindSpotMonitor"]["RightBSM"] == 1 ret.rightBlindspot = cam_cp.vl["BCMBlindSpotMonitor"]["RightBSM"] == 1
# 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"]
@@ -190,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),
@@ -202,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),
] ]
@@ -226,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", 40), ("ECMPRDNL2", prndl2_rate),
("AcceleratorPedal2", 33), ("AcceleratorPedal2", 33),
("ECMEngineStatus", 100), ("ECMEngineStatus", 100),
("BCMTurnSignals", 1), ("BCMTurnSignals", 1),
@@ -255,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", 40), ("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]]] = {
+77 -5
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,8 +239,11 @@ 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): def create_prndl2_command(packer, bus, press_regen_paddle, CP):
prndl2_value = 7 if press_regen_paddle else 6 if CP.carFingerprint in (CAR.CHEVROLET_BOLT_ACC_2022_2023, CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL, CAR.CHEVROLET_BOLT_CC_2022_2023):
prndl2_value = 5 if press_regen_paddle else 6
else:
prndl2_value = 7 if press_regen_paddle else 6
manual_mode = 1 if press_regen_paddle else 0 manual_mode = 1 if press_regen_paddle else 0
values = { values = {
"Byte0": 0x0C, "Byte0": 0x0C,
@@ -242,6 +307,13 @@ def create_gm_cc_spam_command(packer, controller, CS, actuators, frogpilot_toggl
# TODO: Cleanup the timing - normal is every 30ms... # 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:
+251 -64
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,22 +26,47 @@ 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: { CAR.CHEVROLET_BOLT_ACC_2022_2023: {
"left": [2.6531724862969748, 1.1, 0.1919764879840985, 0.0],
"right": [2.7031724862969748, 1.0, 0.1469764879840985, 0.0],
},
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], "left": [1.8, 1.1, 0.27, 0.0],
"right": [2.0, 1.0, 0.205, 0.0], "right": [2.0, 1.0, 0.205, 0.0],
}, },
CAR.CHEVROLET_BOLT_CC: { CAR.CHEVROLET_BOLT_CC_2017: {
"left": [1.8, 1.1, 0.27, 0.0], "left": [2.15, 1.0, 0.21, 0.0],
"right": [2.0, 1.0, 0.205, 0.0], "right": [2.15, 1.0, 0.21, 0.0],
}, },
CAR.GMC_ACADIA: { CAR.GMC_ACADIA: {
"left": [4.78003305, 1.0, 0.3122, 0.05591772], "left": [4.78003305, 1.0, 0.3122, 0.05591772],
"right": [4.78003305, 1.0, 0.3122, 0.05591772], "right": [4.78003305, 1.0, 0.3122, 0.05591772],
}, },
CAR.CHEVROLET_SILVERADO: { CAR.CHEVROLET_SILVERADO: {
"left": [3.29974374, 1.0, 0.25571356, 0.0465122], "left": [3.8, 0.81, 0.24, 0.0465122],
"right": [3.29974374, 1.0, 0.25571356, 0.0465122], "right": [3.8, 0.81, 0.24, 0.0465122],
}, },
} }
@@ -63,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
@@ -120,33 +145,85 @@ 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
# When a pedal interceptor is present, always use normal longitudinal (block stock cruise) if candidate == CAR.CHEVROLET_BOLT_ACC_2022_2023:
experimental_long = False # 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., 60.] 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.radarUnavailable = 0x460 not in fingerprint.get(CanBus.OBSTACLE, {})
ret.pcmCruise = True
ret.minEnableSpeed = 5 * CV.KPH_TO_MS
ret.minSteerSpeed = 10 * CV.KPH_TO_MS
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM
# Tuning for experimental long
ret.longitudinalTuning.kiV = [0.5, 0.5]
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 is_camera_acc:
# TorqueTune camera-ACC behavior
ret.experimentalLongitudinalAvailable = (candidate not in CC_ONLY_CAR) and not ret.enableGasInterceptor
ret.networkLocation = NetworkLocation.fwdCamera ret.networkLocation = NetworkLocation.fwdCamera
ret.radarUnavailable = True # no radar ret.radarUnavailable = True # no radar
ret.pcmCruise = True ret.pcmCruise = not ret.enableGasInterceptor
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM gm_safety_cfg.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
@@ -163,33 +240,89 @@ class CarInterface(CarInterfaceBase):
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 candidate in SDGM_CAR: elif candidate in SDGM_CAR:
ret.longitudinalTuning.kiV = [0., 0., 0.] # TODO: tuning # kaofui parity: SDGM cars require SASCM for experimental long
ret.experimentalLongitudinalAvailable = False 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 = 0x460 not in fingerprint.get(CanBus.OBSTACLE, {})
ret.pcmCruise = True ret.pcmCruise = True
ret.radarUnavailable = True ret.minEnableSpeed = -1. # engage speed is decided by pcm
ret.minEnableSpeed = -1. # engage speed is decided by ASCM ret.minSteerSpeed = 7 * CV.MPH_TO_MS
ret.minSteerSpeed = 30 * CV.MPH_TO_MS gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_SDGM
ret.safetyConfigs[0].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 = [0.5, 0.5, 0.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.]]
@@ -203,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
@@ -235,7 +371,7 @@ 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)
@@ -245,11 +381,20 @@ class CarInterface(CarInterfaceBase):
ret.lateralTuning.torque.kd = 0.93 ret.lateralTuning.torque.kd = 0.93
ret.lateralTuning.torque.kfDEPRECATED = 0.02 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
@@ -272,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:
@@ -302,30 +459,50 @@ 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: #pedal interceptor tuning 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., 3., 6., 35.] if candidate in (CAR.CHEVROLET_MALIBU_CC, CAR.CHEVROLET_MALIBU_HYBRID_CC):
ret.longitudinalTuning.kiV = [0.125, 0.175, 0.225, 0.33] ret.longitudinalTuning.kiBP = [0.0, 5., 35.]
ret.longitudinalTuning.kfDEPRECATED = 0.25 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
@@ -333,24 +510,29 @@ class CarInterface(CarInterfaceBase):
ret.pcmCruise = False ret.pcmCruise = False
if not ret.enableGasInterceptor and candidate in CC_ONLY_CAR: #redneck tuning if not ret.enableGasInterceptor and candidate in CC_ONLY_CAR: #redneck tuning
ret.longitudinalTuning.kpBP = [10.7, 10.8, 28.] # 10.7 m/s == 24 mph if candidate == CAR.CHEVROLET_MALIBU_HYBRID_CC:
ret.longitudinalTuning.kpV = [0., 5., 2.] # set lower end to 0 since we can't drive below that speed pass
ret.longitudinalTuning.deadzoneBP = [0., 1.] else:
ret.longitudinalTuning.deadzoneV = [0.9, 0.9] # == 2 km/h/s, 1.25 mph/s ret.longitudinalTuning.kpBP = [10.7, 10.8, 28.] # 10.7 m/s == 24 mph
ret.longitudinalActuatorDelay = 1. # TODO: measure this ret.longitudinalTuning.kpV = [0., 5., 2.] # set lower end to 0 since we can't drive below that speed
ret.longitudinalTuning.kiBP = [0.] ret.longitudinalTuning.deadzoneBP = [0., 1.]
ret.longitudinalTuning.kiV = [0.1] ret.longitudinalTuning.deadzoneV = [0.9, 0.9] # == 2 km/h/s, 1.25 mph/s
ret.stoppingDecelRate = 11.18 # == 25 mph/s (.04 rate) ret.longitudinalActuatorDelay = 1. # TODO: measure this
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
@@ -382,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)
@@ -395,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
+236 -43
View File
@@ -37,44 +37,123 @@ class CarControllerParams:
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 = 6144 # 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 and CP.carFingerprint != CAR.CHEVROLET_BOLT_EUV: kaofui_cars = SDGM_CAR | ASCM_INT | {
self.MAX_GAS = 7496 CAR.CHEVROLET_VOLT,
self.MAX_GAS_PLUS = 8848 CAR.CHEVROLET_VOLT_2019,
self.MAX_ACC_REGEN = 5610 CAR.CHEVROLET_VOLT_ASCM,
self.INACTIVE_REGEN = 5650 CAR.CHEVROLET_VOLT_CAMERA,
# Camera ACC vehicles have no regen while enabled. CAR.CHEVROLET_VOLT_CC,
# Camera transitions to MAX_ACC_REGEN from ZERO_GAS and uses friction brakes instantly CAR.CHEVROLET_MALIBU_CC,
self.max_regen_acceleration = 0. 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 = 7496 if (CP.carFingerprint in (CAMERA_ACC_CAR | SDGM_CAR) and
self.MAX_GAS_PLUS = 7496 CP.carFingerprint not in CC_ONLY_CAR and
self.MAX_ACC_REGEN = 7110 CP.carFingerprint != CAR.CHEVROLET_BOLT_ACC_2022_2023):
self.INACTIVE_REGEN = 5650 self.MAX_GAS = 8848
self.max_regen_acceleration = 0. 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 = 7168 # Safety limit, not ACC max. Stock ACC >8192 from standstill. if CP.carFingerprint in CAMERA_ACC_CAR and CP.carFingerprint not in CC_ONLY_CAR:
self.MAX_GAS_PLUS = 8191 # 8292 uses new bit, possible but not tested. Matches Twilsonco tw-main max self.MAX_GAS = 8848
self.MAX_ACC_REGEN = 7110 # Increased for stronger regen braking self.MAX_GAS_PLUS = 8848
self.INACTIVE_REGEN = 5500 self.MAX_ACC_REGEN = 5610
# ICE has much less engine braking force compared to regen in EVs, self.INACTIVE_REGEN = 5650
# lower threshold removes some braking deadzone # Camera ACC vehicles have no regen while enabled.
self.max_regen_acceleration = -3. if CP.carFingerprint in EV_CAR else -0.1 # More aggressive regen for EVs # 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
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 = [self.max_regen_acceleration, 0., self.ACCEL_MAX]
self.GAS_LOOKUP_BP_PLUS = [self.max_regen_acceleration, 0., self.ACCEL_MAX_PLUS] self.GAS_LOOKUP_BP_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.GAS_LOOKUP_V_PLUS = [self.MAX_ACC_REGEN, self.ZERO_GAS, self.MAX_GAS_PLUS]
self.BRAKE_LOOKUP_BP = [self.ACCEL_MIN, self.max_regen_acceleration]
self.BRAKE_LOOKUP_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,
# and by letting off gas and allowing car to creep, for determining
# the positive threshold values at very low speed
EV_GAS_BRAKE_THRESHOLD_BP = [1.29, 1.52, 1.55, 1.6, 1.7, 1.8, 2.0, 2.2, 2.5, 5.52, 9.6, 20.5, 23.5, 35.0] # [m/s]
EV_GAS_BRAKE_THRESHOLD_V = [0.0, -0.14, -0.16, -0.18, -0.215, -0.255, -0.32, -0.41, -0.5, -0.72, -0.895, -1.125, -1.145, -1.16] # [m/s^s]
def update_ev_gas_brake_threshold(self, v_ego):
gas_brake_threshold = interp(v_ego, self.EV_GAS_BRAKE_THRESHOLD_BP, self.EV_GAS_BRAKE_THRESHOLD_V)
self.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_PLUS = [gas_brake_threshold, max(0., gas_brake_threshold), self.ACCEL_MAX_PLUS]
self.EV_BRAKE_LOOKUP_BP = [self.ACCEL_MIN, gas_brake_threshold]
@dataclass @dataclass
class GMCarDocs(CarDocs): class GMCarDocs(CarDocs):
@@ -114,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),
@@ -122,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),
@@ -146,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),
) )
@@ -158,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")],
@@ -174,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")],
@@ -194,15 +306,15 @@ class CAR(Platforms):
CHEVROLET_SUBURBAN.specs, CHEVROLET_SUBURBAN.specs,
) )
GMC_YUKON_CC = GMPlatformConfig( GMC_YUKON_CC = GMPlatformConfig(
[GMCarDocs("GMC Yukon No ACC")], [GMCarDocs("GMC Yukon - No-ACC")],
CarSpecs(mass=2541, wheelbase=2.95, steerRatio=16.3, centerToFrontRatio=0.4), CarSpecs(mass=2541, wheelbase=2.95, steerRatio=16.3, centerToFrontRatio=0.4),
) )
CADILLAC_CT6_CC = GMPlatformConfig( CADILLAC_CT6_CC = GMPlatformConfig(
[GMCarDocs("Cadillac CT6 No ACC")], [GMCarDocs("Cadillac CT6 - No-ACC")],
CarSpecs(mass=2358, wheelbase=3.11, steerRatio=17.7, centerToFrontRatio=0.4), CarSpecs(mass=2358, wheelbase=3.11, steerRatio=17.7, centerToFrontRatio=0.4),
) )
CHEVROLET_TRAILBLAZER_CC = GMPlatformConfig( CHEVROLET_TRAILBLAZER_CC = GMPlatformConfig(
[GMCarDocs("Chevrolet Trailblazer 2021-22")], [GMCarDocs("Chevrolet Trailblazer 2021-22 - No-ACC")],
CHEVROLET_TRAILBLAZER.specs, CHEVROLET_TRAILBLAZER.specs,
) )
CADILLAC_XT4 = GMPlatformConfig( CADILLAC_XT4 = GMPlatformConfig(
@@ -210,25 +322,45 @@ class CAR(Platforms):
CarSpecs(mass=1660, wheelbase=2.78, steerRatio=14.4, centerToFrontRatio=0.4), CarSpecs(mass=1660, wheelbase=2.78, steerRatio=14.4, centerToFrontRatio=0.4),
) )
CADILLAC_XT5_CC = GMPlatformConfig( CADILLAC_XT5_CC = GMPlatformConfig(
[GMCarDocs("Cadillac XT5 No ACC")], [GMCarDocs("Cadillac XT5 - No-ACC")],
CarSpecs(mass=1810, wheelbase=2.86, steerRatio=16.34, centerToFrontRatio=0.5), 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:
@@ -253,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
@@ -311,17 +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_REGEN_PADDLE_CAR = {CAR.CHEVROLET_BOLT_CC, CAR.CHEVROLET_BOLT_EUV} CAR.CHEVROLET_VOLT_2019,
# CC_ONLY_CAR = set(c for c in CAR if str(c).endswith('_CC')) 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
+5 -5
View File
@@ -286,11 +286,11 @@ class CarController(CarControllerBase):
self.gas = pcm_accel / self.params.NIDEC_GAS_MAX self.gas = pcm_accel / self.params.NIDEC_GAS_MAX
new_actuators = actuators.as_builder() new_actuators = actuators.as_builder()
new_actuators.speed = self.speed new_actuators.speed = float(self.speed)
new_actuators.accel = self.accel new_actuators.accel = float(self.accel)
new_actuators.gas = self.gas new_actuators.gas = float(self.gas)
new_actuators.brake = self.brake new_actuators.brake = float(self.brake)
new_actuators.steer = self.last_steer new_actuators.steer = float(self.last_steer)
new_actuators.steerOutputCan = apply_steer new_actuators.steerOutputCan = apply_steer
self.frame += 1 self.frame += 1
+3 -3
View File
@@ -76,14 +76,14 @@ def create_brake_command(packer, CAN, apply_brake, pump_on, pcm_override, pcm_ca
return packer.make_can_msg("BRAKE_COMMAND", CAN.pt, values) return packer.make_can_msg("BRAKE_COMMAND", CAN.pt, values)
def create_acc_commands(packer, CAN, enabled, active, accel, gas, stopping_counter, car_fingerprint): def create_acc_commands(packer, CAN, enabled, active, accel, gas, stopping_counter, car_fingerprint, gas_force):
commands = [] commands = []
min_gas_accel = CarControllerParams.BOSCH_GAS_LOOKUP_BP[0] min_gas_accel = CarControllerParams.BOSCH_GAS_LOOKUP_BP[0]
control_on = 5 if enabled else 0 control_on = 5 if enabled else 0
gas_command = gas if active and accel > min_gas_accel else -30000 gas_command = gas if active and gas_force > min_gas_accel else -30000
accel_command = accel if active else 0 accel_command = accel if active else 0
braking = 1 if active and accel < min_gas_accel else 0 braking = 1 if active and gas_force < min_gas_accel else 0
standstill = 1 if active and stopping_counter > 0 else 0 standstill = 1 if active and stopping_counter > 0 else 0
standstill_release = 1 if active and stopping_counter == 0 else 0 standstill_release = 1 if active and stopping_counter == 0 else 0
+7 -4
View File
@@ -85,10 +85,10 @@ class CarInterface(CarInterfaceBase):
ret.longitudinalActuatorDelay = 0.5 # s ret.longitudinalActuatorDelay = 0.5 # s
if candidate in HONDA_BOSCH_RADARLESS: if candidate in HONDA_BOSCH_RADARLESS:
ret.stopAccel = CarControllerParams.BOSCH_ACCEL_MIN # stock uses -4.0 m/s^2 once stopped but limited by safety model ret.stopAccel = CarControllerParams.BOSCH_ACCEL_MIN # stock uses -4.0 m/s^2 once stopped but limited by safety model
else:
# default longitudinal tuning for all hondas # default longitudinal tuning for all hondas
ret.longitudinalTuning.kiBP = [0., 5., 35.] ret.longitudinalTuning.kiBP = [0., 5., 35.]
ret.longitudinalTuning.kiV = [1.2, 0.8, 0.5] ret.longitudinalTuning.kiV = [1.2, 0.8, 0.5]
eps_modified = False eps_modified = False
for fw in car_fw: for fw in car_fw:
@@ -117,6 +117,9 @@ class CarInterface(CarInterfaceBase):
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]] ret.lateralTuning.pid.kpV, ret.lateralTuning.pid.kiV = [[0.8], [0.24]]
if candidate == CAR.HONDA_CIVIC_BOSCH:
CarControllerParams.BOSCH_GAS_LOOKUP_V = [0, 750]
elif candidate == CAR.HONDA_ACCORD: elif candidate == CAR.HONDA_ACCORD:
ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end ret.lateralParams.torqueBP, ret.lateralParams.torqueV = [[0, 4096], [0, 4096]] # TODO: determine if there is a dead zone at the top end
+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.09] "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)
+3 -3
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.)
+5 -1
View File
@@ -43,7 +43,11 @@ DEADZONE_BOOST_LAT_ACCEL = 0.08
UNWIND_D_DES_THRESHOLD = -1.0 UNWIND_D_DES_THRESHOLD = -1.0
UNWIND_LAT_ACCEL_NEAR_ZERO = 0.3 UNWIND_LAT_ACCEL_NEAR_ZERO = 0.3
BOLT_CARS = (GM_CAR.CHEVROLET_BOLT_EUV, GM_CAR.CHEVROLET_BOLT_CC) 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):
+1 -1
View File
@@ -151,7 +151,7 @@ def laplacian_pdf(x: float, mu: float, b: float):
def match_vision_to_track(v_ego: float, lead: capnp._DynamicStructReader, model_data: capnp._DynamicStructReader, tracks: dict[int, Track], frogpilot_toggles: SimpleNamespace): def match_vision_to_track(v_ego: float, lead: capnp._DynamicStructReader, model_data: capnp._DynamicStructReader, tracks: dict[int, Track], frogpilot_toggles: SimpleNamespace):
if model_data.meta.laneChangeState == LaneChangeState.laneChangeStarting and frogpilot_toggles.human_lane_changes: if model_data.meta.laneChangeState == LaneChangeState.laneChangeStarting and getattr(frogpilot_toggles, "human_lane_changes", False):
direction = model_data.meta.laneChangeDirection direction = model_data.meta.laneChangeDirection
if direction == LaneChangeDirection.left: if direction == LaneChangeDirection.left:
+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.
+59
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):
+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"))