Compare commits

..

116 Commits

Author SHA1 Message Date
firestar5683 4795656d6c User adjustable offsets 2026-02-07 23:34:03 -06:00
firestar5683 8cb3ded338 Integrator Smooth On Handoff 2026-02-06 15:48:11 -06:00
firestar5683 17d5f8d611 Malibu ASCM Fingerprint 2026-02-06 12:29:39 -06:00
firestar5683 c77a3f2e6a Lights 2026-02-05 22:40:31 -06:00
firestar5683 1f4ad6a588 New Models 2026-02-05 15:06:41 -06:00
firestar5683 fe8f2ef2db Increase Fault Resilience 2026-02-05 13:35:58 -06:00
firestarsdog 6adacfdbf6 Stats 2026-02-01 22:46:48 -06:00
firestar5683 5b8df0f73c Revert "Mac Update"
This reverts commit bfc24b8882.
2026-01-19 11:42:32 -06:00
firestarsdog be969f716c Add SASCM to vehicle settings detection/stats 2026-01-19 10:34:34 -06:00
firestar5683 bfc24b8882 Mac Update 2026-01-18 22:22:34 -06:00
firestarsdog 165ee6eb68 Stats 2026-01-18 22:17:25 -06:00
firestar5683 48b44ed1e4 Update redneck 2026-01-15 22:53:42 -06:00
firestar5683 437979e0f4 fix redneck v2 2026-01-14 13:59:35 -06:00
firestar5683 499e77ce23 Remove lat smooth seconds 2026-01-14 13:50:26 -06:00
firestar5683 1068bf2644 frogpilot migration 2026-01-12 22:10:56 -06:00
firestar5683 51eb994927 Update defaults 2026-01-12 22:05:26 -06:00
firestar5683 0a1916d08f More defaults 2026-01-12 22:05:18 -06:00
firestar5683 6b0ca6ef8d Big Mac 2026-01-11 16:59:12 -06:00
firestar5683 edd8257985 Try Higher Friction 2026-01-10 14:04:54 -06:00
firestar5683 2f779de7f1 Autotune Off 2026-01-09 22:44:21 -06:00
firestar5683 642d43c764 merry christmas 2025-12-24 22:23:54 -06:00
firestar5683 26486e5f6a ds2 2025-12-24 21:28:57 -06:00
firestar5683 c35c687bfc No sub? 2025-12-18 12:29:34 -06:00
firestar5683 9be6134a5b Use new torque Controller 2025-12-16 22:12:57 -06:00
firestar5683 ba7d5f7ab7 Fix Volt 2019? 2025-12-16 17:18:19 -06:00
firestar5683 b094ebf9f2 Update interface.py 2025-12-16 16:34:52 -06:00
firestar5683 e24df5c403 volt 2019 torquetune 2025-12-16 14:45:18 -06:00
firestar5683 87160b52f9 Try friction adjustment 2025-12-16 14:38:40 -06:00
firestar5683 ddd2a8fadd Red Panda 2025-12-15 14:55:02 -06:00
firestar5683 1470baffa7 Update frogpilot_tracking.py 2025-12-15 00:55:44 -06:00
firestar5683 24cccabeb1 minsteer speed 2025-12-14 14:46:33 -06:00
firestar5683 649a9f648c test 2025-12-13 23:51:39 -06:00
firestar5683 f2fbcb5539 Reapply "Rest of Fleet V2"
This reverts commit db3fbcb687.
2025-12-13 23:51:12 -06:00
firestar5683 db3fbcb687 Revert "Rest of Fleet V2"
This reverts commit 22eb74e4c8.
2025-12-13 23:50:15 -06:00
firestar5683 22eb74e4c8 Rest of Fleet V2 2025-12-13 23:44:46 -06:00
firestar5683 214b6ab711 Update values.py 2025-12-13 23:23:00 -06:00
firestar5683 1b49bafc0d Reapply "Gas"
This reverts commit 08e1ee83ae.
2025-12-13 23:08:16 -06:00
firestar5683 896b3bb454 Revert "Torque Rest of Fleet"
This reverts commit eee41cbf77.
2025-12-13 23:08:03 -06:00
firestar5683 08e1ee83ae Revert "Gas"
This reverts commit 43818e0d48.
2025-12-13 22:57:55 -06:00
firestar5683 92fbc1ceb3 Update Percentages 2025-12-13 19:13:49 -06:00
firestar5683 43818e0d48 Gas 2025-12-13 19:07:17 -06:00
firestar5683 eee41cbf77 Torque Rest of Fleet 2025-12-13 18:51:46 -06:00
firestar5683 365bf72ca2 Update ui 2025-12-12 12:01:29 -06:00
firestar5683 7af2d11cab Update frogpilot_variables.py 2025-12-12 11:38:21 -06:00
firestar5683 319b8c03f6 Trailer Load Gas Tuning 2025-12-12 10:50:45 -06:00
firestar5683 42cf37d175 With Clamping 2025-12-12 02:09:20 -06:00
firestar5683 e767f8a3d2 Volt TorqueTune 2025-12-12 02:04:01 -06:00
firestar5683 c159747e76 Live Friction 2025-12-11 16:55:36 -06:00
firestar5683 5e97a89432 Zero error 2025-12-11 15:13:01 -06:00
firestar5683 d056ca7a3f Updates 2025-12-09 19:59:54 -06:00
firestar5683 a3df9b39f4 Patch 2025-12-08 11:37:40 -06:00
firestar5683 8818b7a1e2 UI 2025-12-05 20:13:07 -06:00
firestar5683 7baa741d4f LattyBoi2.0 2025-12-03 23:31:13 -06:00
firestar5683 becda14f28 Latty Boi
Revert "Latty Boi"

This reverts commit af687e501cc4bdcda7840453d06595d7ea674148.

Reapply "Latty Boi"

This reverts commit ff5566d4439f5e4997fe83f4f21d0be62b75d75d.
2025-12-02 20:30:36 -06:00
firestar5683 e9081aa1b7 Recovery Power 2025-12-02 17:19:30 -06:00
firestar5683 f86622bc96 New planplus 2025-12-02 12:09:16 -06:00
firestar5683 a74fc22d71 stopngo 2025-12-01 16:06:31 -06:00
firestar5683 ce0323e4c0 Update interface.py 2025-11-28 19:21:04 -06:00
Woohyun Rho ec63eca6ab Update 2025-11-28 17:11:04 -06:00
firestar5683 d79d4e9efd BlazeIt 2025-11-28 17:06:33 -06:00
firestar5683 00a594f106 Create CHEVROLET_MALIBU_CC.json 2025-11-21 18:30:58 -06:00
firestar5683 e7ec4df222 New Lateral Changes 2025-11-18 20:49:13 -06:00
firestar5683 abac2983b5 Update 2025-11-15 14:45:36 -06:00
firestar5683 50514c1e0e Revert "Upstream Lateral"
This reverts commit d4b1f9612b.
2025-11-10 23:07:10 -06:00
firestar5683 d4b1f9612b Upstream Lateral
Revert "Upstream Lateral"

This reverts commit 20f7d6631bb152860781b46533bb0e96223be132.

Reapply "Upstream Lateral"

This reverts commit 2a7a563e219a1b688529d341919fc377fed5038e.

Update latcontrol_torque.py

more lateral

Update ui
2025-11-07 00:13:57 -06:00
firestarsdog 6492e43ba3 chevrolet_volt_camera manual selection only 2025-11-05 14:57:19 -05:00
firestar5683 9d96d2678e Volt Camera? 2025-11-05 11:44:54 -06:00
firestar5683 1d7934d112 nnff 2025-10-28 20:58:44 -05:00
firestar5683 9fe567174d NNFF on 2025-10-27 15:10:10 -05:00
firestar5683 daf2e2e139 Update 2025-10-25 15:45:41 -05:00
firestar5683 028eb11d88 Medium Fanta 2025-10-22 22:26:45 -05:00
firestar5683 54d02f9990 Update interfaces.py 2025-10-20 13:50:05 -05:00
firestar5683 6cad16a714 no nnff 2025-10-19 17:59:54 -05:00
firestar5683 be6b3ea4ff Scene Complexity 2025-10-18 14:25:15 -05:00
firestar5683 47516dc865 Update carcontroller.py 2025-10-17 19:10:24 -05:00
firestar5683 84da3740ee Update interface.py 2025-10-17 18:12:43 -05:00
firestar5683 c41dc651c2 CEM 2025-10-17 17:40:03 -05:00
firestar5683 454c11b083 lite 2025-10-17 17:14:13 -05:00
firestar5683 aa51eee24e Redneck 2.0 2025-10-17 16:58:39 -05:00
firestar5683 89d49e4d8d Modify torque tuning parameters in interfaces.py
Adjusted torque tuning parameters for improved performance.
2025-10-17 16:55:36 -05:00
firestar5683 f266e7de9d Hurts Donut 2025-10-16 23:57:47 -05:00
firestar5683 dbef810865 Smoothy Boi 2025-10-16 23:39:45 -05:00
firestar5683 fd5033b16d lat3 2025-10-15 22:21:03 -05:00
firestar5683 e5d59e6c45 oopsie doopsie 2025-10-12 00:12:12 -05:00
firestar5683 d7231a1a74 Revert "Humanlanechanges fix"
This reverts commit e79f98816d.
2025-10-12 00:11:24 -05:00
firestar5683 0bb8f383bf Revert "Duh"
This reverts commit f558bc6b61.
2025-10-12 00:11:21 -05:00
firestarsdog f558bc6b61 Duh 2025-10-11 20:58:51 -04:00
niknak6 e79f98816d Humanlanechanges fix 2025-10-11 19:45:18 -04:00
firestar5683 52f6ec0001 New Lateral Changes 2025-10-10 20:59:53 -05:00
firestar5683 f67af0f222 Fix Standard 2025-10-10 19:25:02 -05:00
firestar5683 76d2b1eb56 Update interface.py 2025-10-08 23:28:31 -05:00
firestar5683 8d9f88009d error? 2025-10-08 23:14:33 -05:00
firestar5683 ab036f7451 Fix New Devices 2025-10-08 22:20:38 -05:00
firestar5683 2792c69652 No positive P-response for long control if user-selected parameter set 2025-10-08 07:43:54 -05:00
firestar5683 d6ca567d5d Update frogpilot_acceleration.py 2025-10-04 23:55:37 -05:00
firestar5683 01be6c4d81 Automatic updates 2025-10-04 16:03:20 -05:00
firestar5683 f23b77180e Steer Alerts 2025-10-04 01:48:51 -05:00
firestar5683 4df8dda8ba Update frogpilot_acceleration.py 2025-10-03 22:41:48 -05:00
firestar5683 23bc2b80d8 Revert "Update latcontrol_torque.py"
This reverts commit 13c3070fa1.
2025-10-03 22:05:10 -05:00
firestar5683 5b823fee98 SteerAlerts
Revert "SteerAlerts"

This reverts commit cbaba399c5b9caac5a8faf3917f0929d747a0acc.

Update controlsd.py
2025-10-03 22:05:01 -05:00
firestar5683 a67d46b953 Donut DM 2025-10-03 20:47:20 -05:00
firestar5683 13c3070fa1 Update latcontrol_torque.py 2025-10-03 20:11:45 -05:00
firestar5683 72dc8dd753 sp 2025-10-03 18:40:23 -05:00
firestar5683 b499c34970 Update gm_global_a_powertrain_generated.dbc 2025-10-03 16:15:40 -05:00
firestar5683 0325685719 Update 2025-10-03 00:43:14 -05:00
firestar5683 0d4ec3f1d8 Panda 2025-10-03 00:22:24 -05:00
firestar5683 8f010a4c3f Kao Panda 2025-10-03 00:16:05 -05:00
firestar5683 2cafeee8c1 Cruise Fault?
Revert "Cruise Fault?"

This reverts commit 4a160adff3de7428808476056ba1489484dd09cd.
2025-10-02 23:45:11 -05:00
firestar5683 8bd757ca63 Cleanup: Nuke of the Bad Stuff Cont 2025-10-01 18:51:05 -04:00
firestar5683 8cd5ee4f80 Cleanup: Nuke of the Bad Stuff 2025-10-01 18:48:05 -04:00
firestar5683 40bcc00261 Revert "Camera Volts"
This reverts commit 9e52017553.
2025-10-01 14:02:11 -04:00
firestar5683 785eee7fdb firehose 2025-10-01 14:00:18 -04:00
firestarsdog 9e52017553 Camera Volts 2025-10-01 09:54:15 -04:00
firestar5683 8907ac78c8 Update 2025-09-30 14:31:12 -05:00
firestar5683 ba5eea4253 Kaofui 2025-09-30 10:13:43 -05:00
firestar5683 7421c67a17 Dom 2025-09-30 09:15:54 -05:00
76 changed files with 420 additions and 2813 deletions
-6
View File
@@ -247,7 +247,6 @@ 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},
@@ -273,7 +272,6 @@ 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},
@@ -312,7 +310,6 @@ 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},
@@ -326,7 +323,6 @@ 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},
@@ -473,8 +469,6 @@ 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.
+11 -28
View File
@@ -29,15 +29,13 @@ 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, allow_unknown_size=False, suppress_errors=False): def download_file(cancel_param, destination, progress_param, url, download_param, params_memory):
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, suppress_errors=suppress_errors or allow_unknown_size) total_size = get_remote_file_size(url)
if total_size == 0 and not allow_unknown_size: if total_size == 0:
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
@@ -58,30 +56,24 @@ 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)
if total_size > 0: progress = (downloaded_size / total_size) * 100
progress = (downloaded_size / total_size) * 100 if progress != 100:
if progress != 100: params_memory.put(progress_param, f"{progress:.0f}%")
params_memory.put(progress_param, f"{progress:.0f}%") else:
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, suppress_errors=False): def get_remote_file_size(url):
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:
if not suppress_errors: handle_request_error(error, None, None, None, None)
handle_request_error(error, None, None, None, None)
return 0 return 0
def get_repository_url(): def get_repository_url():
@@ -112,17 +104,8 @@ 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, allow_unknown_size=False): def verify_download(file_path, url):
remote_file_size = get_remote_file_size(url, suppress_errors=allow_unknown_size) remote_file_size = get_remote_file_size(url)
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}")
Binary file not shown.

Before

Width:  |  Height:  |  Size: 503 KiB

After

Width:  |  Height:  |  Size: 1.3 MiB

+50 -140
View File
@@ -37,7 +37,6 @@ 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",
@@ -94,16 +93,8 @@ 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:
@@ -111,12 +102,7 @@ class ThemeManager:
self.downloading_theme = False self.downloading_theme = False
return return
if theme_component == "boot_logos": if theme_component == "distance_icons":
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"]
@@ -131,40 +117,37 @@ 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_urls = [f"{download_link}/{candidate}{extension}" for candidate in name_candidates] theme_url = download_link + extension
if theme_component != "boot_logos":
theme_urls = [download_link + extension]
for theme_url in theme_urls: delete_file(theme_path)
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)
print(f"Downloading theme from GitHub: {theme_name}") self.downloading_theme = False
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) return
if params_memory.get_bool(CANCEL_DOWNLOAD_PARAM): if verify_download(theme_path, theme_url):
delete_file(theme_path) print(f"Theme {theme_name} downloaded and verified successfully from GitHub!")
handle_error(None, "Download cancelled...", "Download cancelled...", asset_param, DOWNLOAD_PROGRESS_PARAM, params_memory) self.update_theme_size(theme_component, theme_name, theme_path.stat().st_size)
self.downloading_theme = False if extension == ".zip":
return params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Unpacking theme...")
extract_zip(theme_path, download_path)
if verify_download(theme_path, theme_url, allow_unknown_size=allow_unknown_size): params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Downloaded!")
print(f"Theme {theme_name} downloaded and verified successfully from GitHub!") params_memory.remove(asset_param)
self.update_theme_size(theme_component, theme_name, theme_path.stat().st_size)
if extension == ".zip": self.downloading_theme = False
params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Unpacking theme...")
extract_zip(theme_path, download_path)
params_memory.put(DOWNLOAD_PROGRESS_PARAM, "Downloaded!") self.update_themes(frogpilot_toggles)
params_memory.remove(asset_param) return
elif self.handle_verification_failure(extension, theme_component, theme_name, asset_param, theme_path, download_path, frogpilot_toggles):
self.downloading_theme = False return
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
@@ -175,7 +158,7 @@ class ThemeManager:
repo_encoded = quote_plus(RESOURCES_REPO) repo_encoded = quote_plus(RESOURCES_REPO)
assets = {"boot_logos": [], "themes": {}, "wheels": []} assets = {"themes": {}, "wheels": []}
try: try:
def list_files(branch): def list_files(branch):
if is_github: if is_github:
@@ -251,20 +234,6 @@ 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)
@@ -277,7 +246,6 @@ 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
@@ -297,7 +265,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 not in {"boot_logos", "steering_wheels"}: if len(capitalized_parts) > 1 and component != "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)
@@ -353,44 +321,37 @@ 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):
allow_unknown_size = theme_component in {"boot_logos", "steering_wheels"} if theme_component == "distance_icons":
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]
for candidate in name_candidates: delete_file(theme_path)
delete_file(theme_path)
theme_url = f"{download_link}/{candidate}{extension}" if theme_component == "boot_logos" else download_link + extension theme_url = 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, allow_unknown_size=allow_unknown_size, suppress_errors=allow_unknown_size) download_file(CANCEL_DOWNLOAD_PARAM, theme_path, DOWNLOAD_PROGRESS_PARAM, theme_url, asset_param, params_memory)
if verify_download(theme_path, theme_url, allow_unknown_size=allow_unknown_size): if verify_download(theme_path, theme_url):
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
# Let the caller continue trying alternate extensions before surfacing failure. handle_error(None, "Download failed...", "Download failed...", asset_param, DOWNLOAD_PROGRESS_PARAM, params_memory)
self.downloading_theme = False
return False return False
@staticmethod @staticmethod
@@ -454,8 +415,6 @@ 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:
@@ -463,7 +422,6 @@ 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),
@@ -476,7 +434,6 @@ 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),
@@ -487,7 +444,6 @@ 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),
@@ -502,9 +458,7 @@ 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 == "boot_logo": if asset_type == "wheel_image":
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)
@@ -545,16 +499,9 @@ 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_boot_logos, downloadable_colors, downloadable_distance_icons, downloadable_icons, downloadable_signals, downloadable_sounds, downloadable_wheels): def update_theme_params(self, 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 == "boot_logos": if subfolder == "steering_wheels":
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:
@@ -564,7 +511,6 @@ 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")
@@ -583,20 +529,12 @@ 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)
})) }))
@@ -604,9 +542,7 @@ 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 == "boot_logos": if theme_component == "steering_wheels":
key = "boot_logos"
elif theme_component == "steering_wheels":
key = "wheels" key = "wheels"
else: else:
key = "themes" key = "themes"
@@ -614,7 +550,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 in {"boot_logos", "wheels"}: if key == "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]:
@@ -636,7 +572,6 @@ 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 = []
@@ -658,10 +593,8 @@ 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}")
@@ -672,21 +605,7 @@ 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_boot_logos, downloadable_colors, downloadable_distance_icons, downloadable_icons, downloadable_signals, downloadable_sounds, downloadable_wheels) self.update_theme_params(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"
@@ -722,15 +641,6 @@ 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")
+2 -13
View File
@@ -2,7 +2,6 @@
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
@@ -23,7 +22,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, FW_PATH from panda import Panda
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
@@ -152,21 +151,11 @@ 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(fn=flash_fn) panda.flash()
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}")
+5 -28
View File
@@ -133,7 +133,6 @@ 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"),
@@ -160,7 +159,6 @@ 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"),
@@ -239,8 +237,6 @@ 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"),
@@ -304,7 +300,7 @@ frogpilot_default_params: list[tuple[str, str | bytes, int, str]] = [
("NavSettingLeftSide", "0", 0, "0"), ("NavSettingLeftSide", "0", 0, "0"),
("NavSettingTime24h", "0", 0, "0"), ("NavSettingTime24h", "0", 0, "0"),
("NewLongAPI", "0", 2, "1"), ("NewLongAPI", "0", 2, "1"),
("NNFF", "0", 2, "0"), ("NNFF", "1", 2, "0"),
("NNFFLite", "0", 2, "0"), ("NNFFLite", "0", 2, "0"),
("NoLogging", "0", 2, "0"), ("NoLogging", "0", 2, "0"),
("NoUploads", "0", 2, "0"), ("NoUploads", "0", 2, "0"),
@@ -624,34 +620,19 @@ 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.5, latAccelFactor * 1.25) if advanced_lateral_tuning and tuning_level >= level["SteerLatAccel"] else latAccelFactor toggle.latAccelFactor = np.clip(params.get_float("SteerLatAccel"), latAccelFactor * 0.75, latAccelFactor * 1.25) if advanced_lateral_tuning and tuning_level >= level["SteerLatAccel"] else latAccelFactor
toggle.use_custom_latAccelFactor = bool(round(toggle.latAccelFactor, 2) != round(latAccelFactor, 2)) and is_torque_car and not toggle.force_auto_tune or toggle.force_auto_tune_off toggle.use_custom_latAccelFactor = bool(round(toggle.latAccelFactor, 2) != round(latAccelFactor, 2)) and is_torque_car and not toggle.force_auto_tune or toggle.force_auto_tune_off
toggle.steerRatio = np.clip(params.get_float("SteerRatio"), steerRatio * 0.25, steerRatio * 1.5) if advanced_lateral_tuning and tuning_level >= level["SteerRatio"] else steerRatio toggle.steerRatio = np.clip(params.get_float("SteerRatio"), steerRatio * 0.5, steerRatio * 1.5) if advanced_lateral_tuning and tuning_level >= level["SteerRatio"] else steerRatio
toggle.use_custom_steerRatio = bool(round(toggle.steerRatio, 2) != round(steerRatio, 2)) and not toggle.force_auto_tune or toggle.force_auto_tune_off 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")
gm_ev_vehicle = toggle.car_make == "gm" and CP.carFingerprint in GM_EV_CAR ev_vehicle = toggle.car_make == "gm" and not (toggle.car_model.startswith("CHEVROLET_VOLT") and not toggle.car_model.endswith("_CC")) and CP.carFingerprint in GM_EV_CAR or toggle.car_make == "hyundai" and CP.carFingerprint in HYUNDAI_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)
if params.get("TruckTuning") == b"": toggle.ev_tuning = params.get_bool("EVTuning") if advanced_longitudinal_tuning and tuning_level >= level["EVTuning"] else ev_vehicle
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
@@ -827,9 +808,6 @@ 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"))
@@ -939,7 +917,6 @@ 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"
@@ -47,53 +47,26 @@ 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.12, 1.12, 1.45] A_CRUISE_MAX_VALS_ECO_EV = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.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.5, 1.5, 2.0]
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, truck_tuning=False): def get_max_accel_eco(v_ego, ev_tuning=True):
if ev_tuning: cruise_vals = A_CRUISE_MAX_VALS_ECO_EV if ev_tuning else A_CRUISE_MAX_VALS_ECO_GAS
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, truck_tuning=False): def get_max_accel_sport(v_ego, ev_tuning=True):
if ev_tuning: cruise_vals = A_CRUISE_MAX_VALS_SPORT_EV if ev_tuning else A_CRUISE_MAX_VALS_SPORT_GAS
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, ev_tuning=True, truck_tuning=False): def get_max_allowed_accel(v_ego):
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:
@@ -107,27 +80,26 @@ 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_standard(v_ego, ev_tuning, truck_tuning) self.max_accel = get_max_accel(v_ego)
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, truck_tuning) self.max_accel = get_max_accel_eco(v_ego, ev_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, truck_tuning) self.max_accel = get_max_accel_sport(v_ego, ev_tuning)
else: else:
self.max_accel = get_max_allowed_accel(v_ego, ev_tuning, truck_tuning) self.max_accel = get_max_allowed_accel(v_ego)
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, truck_tuning) self.max_accel = get_max_accel_eco(v_ego, ev_tuning)
elif frogpilot_toggles.acceleration_profile == 2: elif frogpilot_toggles.acceleration_profile == 2:
self.max_accel = get_max_accel_sport(v_ego, ev_tuning, truck_tuning) self.max_accel = get_max_accel_sport(v_ego, ev_tuning)
elif frogpilot_toggles.acceleration_profile == 3: elif frogpilot_toggles.acceleration_profile == 3:
self.max_accel = get_max_allowed_accel(v_ego, ev_tuning, truck_tuning) self.max_accel = get_max_allowed_accel(v_ego)
else: else:
self.max_accel = get_max_accel_standard(v_ego, ev_tuning, truck_tuning) self.max_accel = get_max_accel(v_ego)
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)
@@ -215,6 +215,7 @@ class LatControlNNFF(LatControl):
def update(self, active, CS, VM, params, steer_limited_by_safety, desired_curvature, curvature_limited, lat_delay, llk, model_data, frogpilot_toggles): def update(self, active, CS, VM, params, steer_limited_by_safety, desired_curvature, curvature_limited, lat_delay, llk, model_data, frogpilot_toggles):
pid_log = log.ControlsState.LateralTorqueState.new_message() pid_log = log.ControlsState.LateralTorqueState.new_message()
pid_log.error = 0.0
if not active: if not active:
output_torque = 0.0 output_torque = 0.0
pid_log.active = False pid_log.active = False
@@ -300,7 +301,7 @@ class LatControlNNFF(LatControl):
torque_from_setpoint = self.lat_torque_nn_model.evaluate(nnff_setpoint_input) torque_from_setpoint = self.lat_torque_nn_model.evaluate(nnff_setpoint_input)
torque_from_measurement = self.lat_torque_nn_model.evaluate(nnff_measurement_input) torque_from_measurement = self.lat_torque_nn_model.evaluate(nnff_measurement_input)
pid_log.error = torque_from_setpoint - torque_from_measurement pid_log.error = float(torque_from_setpoint - torque_from_measurement)
error_blend = interp(abs(desired_lateral_accel), [1.0, 2.0], [0.0, 1.0]) error_blend = interp(abs(desired_lateral_accel), [1.0, 2.0], [0.0, 1.0])
if error_blend > 0.0: # blend in stronger error response when in high lat accel if error_blend > 0.0: # blend in stronger error response when in high lat accel
@@ -316,7 +317,7 @@ class LatControlNNFF(LatControl):
# apply friction override for cars with low NN friction response # apply friction override for cars with low NN friction response
if self.nn_friction_override: if self.nn_friction_override:
pid_log.error += self.torque_from_lateral_accel(0.0, self.torque_params) pid_log.error += float(self.torque_from_lateral_accel(0.0, self.torque_params))
else: else:
torque_from_measurement = self.torque_from_lateral_accel(measurement, self.torque_params) torque_from_measurement = self.torque_from_lateral_accel(measurement, self.torque_params)
torque_from_setpoint = self.torque_from_lateral_accel(setpoint, self.torque_params) torque_from_setpoint = self.torque_from_lateral_accel(setpoint, self.torque_params)
+11 -11
View File
@@ -180,19 +180,14 @@ def send_stats():
user_point = ( user_point = (
Point("user_stats") Point("user_stats")
.tag("car_make", "GM" if frogpilot_toggles.car_make == "gm" else frogpilot_toggles.car_make.title())
.tag("car_model", frogpilot_toggles.car_model)
.tag("city", city)
.tag("country", country)
.tag("device", HARDWARE.get_device_type())
.tag("driving_model", clean_model_name(frogpilot_toggles.model_name))
.tag("state", state)
.tag("theme", selected_theme.title())
.tag("branch", build_metadata.channel)
.tag("dongle_id", params.get("FrogPilotDongleId", encoding="utf-8"))
.field("blocked_user", frogpilot_toggles.block_user) .field("blocked_user", frogpilot_toggles.block_user)
.field("car_make", "GM" if frogpilot_toggles.car_make == "gm" else frogpilot_toggles.car_make.title())
.field("car_model", frogpilot_toggles.car_model)
.field("city", city)
.field("country", country)
.field("current_months_kilometers", int(frogpilot_stats.get("CurrentMonthsKilometers", 0))) .field("current_months_kilometers", int(frogpilot_stats.get("CurrentMonthsKilometers", 0)))
.field("device", HARDWARE.get_device_type())
.field("driving_model", clean_model_name(frogpilot_toggles.model_name))
.field("event", 1) .field("event", 1)
.field("frogpilot_drives", int(frogpilot_stats.get("FrogPilotDrives", 0))) .field("frogpilot_drives", int(frogpilot_stats.get("FrogPilotDrives", 0)))
.field("frogpilot_hours", float(frogpilot_stats.get("FrogPilotSeconds", 0)) / (60 * 60)) .field("frogpilot_hours", float(frogpilot_stats.get("FrogPilotSeconds", 0)) / (60 * 60))
@@ -208,6 +203,8 @@ def send_stats():
.field("longitude", longitude) .field("longitude", longitude)
.field("rainbow_path", frogpilot_toggles.rainbow_path) .field("rainbow_path", frogpilot_toggles.rainbow_path)
.field("random_events", frogpilot_toggles.random_events) .field("random_events", frogpilot_toggles.random_events)
.field("state", state)
.field("theme", selected_theme.title())
.field("total_aol_seconds", float(frogpilot_stats.get("AOLTime", 0))) .field("total_aol_seconds", float(frogpilot_stats.get("AOLTime", 0)))
.field("total_lateral_seconds", float(frogpilot_stats.get("LateralTime", 0))) .field("total_lateral_seconds", float(frogpilot_stats.get("LateralTime", 0)))
.field("total_longitudinal_seconds", float(frogpilot_stats.get("LongitudinalTime", 0))) .field("total_longitudinal_seconds", float(frogpilot_stats.get("LongitudinalTime", 0)))
@@ -216,6 +213,9 @@ def send_stats():
.field("up_to_date", is_up_to_date(build_metadata)) .field("up_to_date", is_up_to_date(build_metadata))
.field("using_stock_acc", not (frogpilot_toggles.has_cc_long or frogpilot_toggles.openpilot_longitudinal)) .field("using_stock_acc", not (frogpilot_toggles.has_cc_long or frogpilot_toggles.openpilot_longitudinal))
.tag("branch", build_metadata.channel)
.tag("dongle_id", params.get("FrogPilotDongleId", encoding="utf-8"))
.time(now) .time(now)
) )
@@ -273,10 +273,7 @@ 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_ACC_2022_2023" || isBolt = carFingerprint == "CHEVROLET_BOLT_CC" || carFingerprint == "CHEVROLET_BOLT_EUV";
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;
@@ -284,7 +281,8 @@ void FrogPilotSettingsWindow::updateVariables() {
isTorqueCar = CP.getLateralTuning().which() == cereal::CarParams::LateralTuning::TORQUE; isTorqueCar = CP.getLateralTuning().which() == cereal::CarParams::LateralTuning::TORQUE;
isToyota = carMake == "toyota"; isToyota = carMake == "toyota";
isTSK = CP.getSecOcRequired(); isTSK = CP.getSecOcRequired();
isVolt = carFingerprint == "CHEVROLET_VOLT"; isVolt = carFingerprint.find("CHEVROLET_VOLT") == 0;
if (isVolt) hasSNG = false;
longitudinalActuatorDelay = CP.getLongitudinalActuatorDelay(); longitudinalActuatorDelay = CP.getLongitudinalActuatorDelay();
startAccel = CP.getStartAccel(); startAccel = CP.getStartAccel();
steerActuatorDelay = CP.getSteerActuatorDelay(); steerActuatorDelay = CP.getSteerActuatorDelay();
@@ -103,10 +103,6 @@ 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)"))
@@ -1129,21 +1125,6 @@ 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 =
@@ -1655,12 +1636,6 @@ 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", "TruckTuning", "LongitudinalActuatorDelay", "StartAccel", "StopAccel", "StoppingDecelRate", "VEgoStarting", "VEgoStopping"}; QSet<QString> advancedLongitudinalTuneKeys = {"EVTuning", "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,11 +66,6 @@ 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) {
@@ -233,7 +228,6 @@ 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!"), ""},
@@ -258,57 +252,6 @@ 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) {
@@ -761,7 +704,6 @@ 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();
@@ -814,7 +756,6 @@ 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;
@@ -824,7 +765,6 @@ 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();
@@ -842,11 +782,6 @@ 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);
+1 -6
View File
@@ -19,8 +19,6 @@ 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;
@@ -42,11 +40,10 @@ private:
std::map<QString, AbstractControl*> toggles; std::map<QString, AbstractControl*> toggles;
QSet<QString> customThemeKeys = {"BootLogo", "CustomColors", "CustomDistanceIcons", "CustomIcons", "CustomSignals", "CustomSounds", "DownloadStatusLabel", "WheelIcon"}; QSet<QString> customThemeKeys = {"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;
@@ -58,13 +55,11 @@ 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,9 +1,6 @@
#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) {
@@ -173,8 +170,6 @@ 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>"), ""},
@@ -305,25 +300,6 @@ 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]() {
+1 -2
View File
@@ -36,7 +36,7 @@ private:
std::map<QString, AbstractControl*> toggles; std::map<QString, AbstractControl*> toggles;
QSet<QString> gmKeys = {"ExperimentalGMTune", "GMPedalLongitudinal", "LongPitch", "RedPanda", "RemoteStartBootsComma", "VoltSNG"}; QSet<QString> gmKeys = {"ExperimentalGMTune", "GMPedalLongitudinal", "LongPitch", "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,7 +50,6 @@ 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,7 +171,6 @@ 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,11 +13,6 @@ 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*
+5 -28
View File
@@ -33,7 +33,6 @@ 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
@@ -201,24 +200,12 @@ void ignition_can_hook(CANPacket_t *to_push) {
if (bus == 0) { if (bus == 0) {
int addr = GET_ADDR(to_push); int addr = GET_ADDR(to_push);
int len = GET_LEN(to_push); int len = GET_LEN(to_push);
// GM exception // GM exception
#ifdef PANDA_GM_REMOTE_START_C9 if ((addr == 0xC9) && (len == 8)) {
if (true) { // Matches SystemPowerMode (1=Run, 0=Off)
#else ignition_can = (GET_BYTE(to_push, 6) & 0x10U) != 0U;
if (gm_remote_start_boots_comma) { ignition_can_cnt = 0U;
#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
@@ -233,16 +220,6 @@ void ignition_can_hook(CANPacket_t *to_push) {
ignition_can = (GET_BYTE(to_push, 0) >> 5) == 0x6U; ignition_can = (GET_BYTE(to_push, 0) >> 5) == 0x6U;
ignition_can_cnt = 0U; ignition_can_cnt = 0U;
} }
} else if (bus == 2) {
int addr = GET_ADDR(to_push);
int len = GET_LEN(to_push);
// GM exception, SDGM cars have this message on bus 2
if ((addr == 0x1F1) && (len == 8)) {
// SystemPowerMode (2=Run, 3=Crank Request)
ignition_can = (GET_BYTE(to_push, 0) & 0x2U) != 0U;
ignition_can_cnt = 0U;
}
} }
} }
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+1 -1
View File
@@ -1 +1 @@
const uint8_t gitversion[] = "DEV-4d1efbb2-DEBUG"; const uint8_t gitversion[] = "DEV-87d2f6ab-DEBUG";
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+18 -79
View File
@@ -9,17 +9,6 @@ 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 = 8191, .max_gas = 8191,
.min_gas = 5500, .min_gas = 5500,
@@ -34,7 +23,6 @@ const LongitudinalLimits GM_CAM_LONG_LIMITS = {
.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
@@ -54,20 +42,15 @@ const CanMsg GM_CAM_TX_MSGS[] = {{0x180, 0, 4}, {0x200, 0, 6}, {0x1E1, 0, 7}, {0
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
{0x315, 2, 5}, {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_CC_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus
{0x184, 2, 8}}; // camera bus
const CanMsg GM_CC_LONG_TX_MSGS[] = {{0x180, 0, 4}, {0x1E1, 0, 7}, {0xBD, 0, 7}, {0x1F5, 0, 8}, // pt bus
{0x184, 2, 8}, {0x1E1, 2, 7}}; // camera bus {0x184, 2, 8}, {0x1E1, 2, 7}}; // camera bus
// TODO: do checksum and counter checks. Add correct timestep, 0.1s for now. // TODO: do checksum and counter checks. Add correct timestep, 0.1s for now.
RxCheck gm_rx_checks[] = { RxCheck gm_rx_checks[] = {
{.msg = {{0x184, 0, 8, .frequency = 10U}, { 0 }, { 0 }}}, {.msg = {{0x184, 0, 8, .frequency = 10U}, { 0 }, { 0 }}},
{.msg = {{0x34A, 0, 5, .frequency = 10U}, { 0 }, { 0 }}}, {.msg = {{0x34A, 0, 5, .frequency = 10U}, { 0 }, { 0 }}},
{.msg = {{0x1E1, 0, 7, .frequency = 10U}, // Non-SDGM Car {.msg = {{0x1E1, 0, 7, .frequency = 10U}, { 0 }, { 0 }}},
{0x1E1, 2, 7, .frequency = 100000U}}}, // SDGM Car {.msg = {{0xF1, 0, 6, .frequency = 10U}, { 0 }, { 0 }}},
{.msg = {{0xF1, 0, 6, .frequency = 10U}, // Non-SDGM Car
{0xF1, 2, 6, .frequency = 100000U}}}, // SDGM Car
{.msg = {{0x1C4, 0, 8, .frequency = 10U}, { 0 }, { 0 }}}, {.msg = {{0x1C4, 0, 8, .frequency = 10U}, { 0 }, { 0 }}},
{.msg = {{0xC9, 0, 8, .frequency = 10U}, { 0 }, { 0 }}}, {.msg = {{0xC9, 0, 8, .frequency = 10U}, { 0 }, { 0 }}},
}; };
@@ -83,9 +66,6 @@ const uint16_t GM_PARAM_PEDAL_INTERCEPTOR = 128;
const uint16_t GM_PARAM_ASCM_INT = 256; const uint16_t GM_PARAM_ASCM_INT = 256;
const uint16_t GM_PARAM_FORCE_BRAKE_C9 = 512; const uint16_t GM_PARAM_FORCE_BRAKE_C9 = 512;
const uint16_t GM_PARAM_HW_SDGM = 1024; 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,
@@ -107,10 +87,7 @@ 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;
bool gm_ascm_int = false;
bool gm_force_brake_c9 = false; bool gm_force_brake_c9 = false;
bool gm_remote_start_boots_comma = false;
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) == 0U) { if (GET_BUS(to_push) == 0U) {
@@ -152,6 +129,7 @@ static void gm_rx_hook(const CANPacket_t *to_push) {
// 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
// Prefer 0xC9 (ECMEngineStatus) when gm_force_brake_c9 is set, otherwise keep legacy behavior. // Prefer 0xC9 (ECMEngineStatus) when gm_force_brake_c9 is set, otherwise keep legacy behavior.
// This allows SDGM/Traverse variants without 0xBE (ECMAcceleratorPos) to report brake correctly.
if ((addr == 0xC9) && gm_force_brake_c9) { if ((addr == 0xC9) && gm_force_brake_c9) {
brake_pressed = GET_BIT(to_push, 40U) != 0U; brake_pressed = GET_BIT(to_push, 40U) != 0U;
} else if ((addr == 0xBE) && ((gm_hw == GM_ASCM) || (gm_hw == GM_SDGM))) { } else if ((addr == 0xBE) && ((gm_hw == GM_ASCM) || (gm_hw == GM_SDGM))) {
@@ -176,11 +154,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 && 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;
@@ -211,14 +184,13 @@ 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)
// Cruise check for ASCMActiveCruiseControlStatus on bus 2. int addr = GET_ADDR(to_push);
// Keep kaofui behavior for non-Bolt paths; Bolt pedal path keeps local tracking. if ((addr == 0x370) && (GET_BUS(to_push) == 2U)) {
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
if (gm_bolt_2022_pedal) { // Align SDGM/camera PCM cruise behavior with ASCM path: when using stock PCM cruise,
cruise_engaged_prev = cruise_engaged; // drive controls_allowed via pcm_cruise_check on ACC engaged edges.
} else if (gm_pcm_cruise && gm_has_acc) { if (gm_pcm_cruise && gm_has_acc) {
pcm_cruise_check(cruise_engaged); pcm_cruise_check(cruise_engaged);
} else { } else {
cruise_engaged_prev = cruise_engaged; cruise_engaged_prev = cruise_engaged;
@@ -246,7 +218,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_steer_limits)) { if (steer_torque_cmd_checks(desired_torque, steer_req, GM_STEERING_LIMITS)) {
tx = false; tx = false;
} }
} }
@@ -278,9 +250,6 @@ 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;
if (gm_hw == GM_CAM && enable_gas_interceptor && gm_bolt_2022_pedal && button == GM_BTN_CANCEL) {
allowed_btn = true;
}
// For CC_LONG or PCM cruise vehicles, allow SET/RESUME when cruise is engaged // For CC_LONG or PCM cruise vehicles, allow SET/RESUME when cruise is engaged
if (gm_cc_long || gm_pcm_cruise) { 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);
@@ -290,23 +259,6 @@ static bool gm_tx_hook(const CANPacket_t *to_send) {
tx = false; tx = false;
} }
} }
// REGEN PADDLE
if (addr == 0xBD) {
bool regen_apply = GET_BIT(to_send, 7) || GET_BIT(to_send, 6) || GET_BIT(to_send, 5) || GET_BIT(to_send, 4);
if (!controls_allowed && regen_apply) {
tx = false;
}
}
// PRNDL2 regen check (7 for Gen0, Gen1. 5 For Gen2)
if (addr == 0x1F5) {
uint8_t prndl2 = GET_BYTE(to_send, 3) & 0xF;
bool prndl_apply = (prndl2 == 7) || (prndl2 == 5);
if (!controls_allowed && prndl_apply) {
tx = false;
}
}
return tx; return tx;
} }
@@ -323,20 +275,10 @@ static int gm_fwd_hook(int bus_num, int addr) {
} }
if (bus_num == 2) { if (bus_num == 2) {
// block lkas message and acc messages if gm_cam_long, forward all others
bool is_lkas_msg = (addr == 0x180); bool is_lkas_msg = (addr == 0x180);
bool block_msg = false; bool is_acc_msg = (addr == 0x315) || (addr == 0x2CB) || (addr == 0x370);
if (gm_bolt_2022_pedal) { bool block_msg = is_lkas_msg || (is_acc_msg && gm_cam_long);
// Block 0x370 only for experimental long without pedal interceptor
bool is_acc_msg = (addr == 0x315) || (addr == 0x2CB);
if (gm_cam_long && !enable_gas_interceptor) {
is_acc_msg = is_acc_msg || (addr == 0x370);
}
block_msg = is_lkas_msg || (is_acc_msg && gm_cam_long);
} else {
// block lkas message and acc messages if gm_cam_long, forward all others
bool is_acc_msg = (addr == 0x315) || (addr == 0x2CB) || (addr == 0x370);
block_msg = is_lkas_msg || (is_acc_msg && gm_cam_long);
}
if (!block_msg) { if (!block_msg) {
bus_fwd = 0; bus_fwd = 0;
} }
@@ -347,7 +289,7 @@ 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) {
gm_ascm_int = GET_FLAG(param, GM_PARAM_ASCM_INT); const bool gm_ascm_int = GET_FLAG(param, GM_PARAM_ASCM_INT);
if (GET_FLAG(param, GM_PARAM_HW_CAM)) { 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)) {
@@ -357,25 +299,22 @@ static safety_config gm_init(uint16_t param) {
} }
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 || gm_ascm_int) { if (gm_hw == GM_ASCM || gm_force_ascm || gm_ascm_int) {
gm_long_limits = &GM_ASCM_LONG_LIMITS; gm_long_limits = &GM_ASCM_LONG_LIMITS;
} else if ((gm_hw == GM_CAM) || (gm_hw == GM_SDGM)) { } else if ((gm_hw == GM_CAM) || (gm_hw == GM_SDGM)) {
gm_long_limits = &GM_CAM_LONG_LIMITS; gm_long_limits = &GM_CAM_LONG_LIMITS;
} else { } else {
} }
gm_pedal_long = GET_FLAG(param, GM_PARAM_PEDAL_LONG); gm_pedal_long = GET_FLAG(param, GM_PARAM_PEDAL_LONG);
gm_cc_long = GET_FLAG(param, GM_PARAM_CC_LONG); gm_cc_long = GET_FLAG(param, GM_PARAM_CC_LONG);
enable_gas_interceptor = GET_FLAG(param, GM_PARAM_PEDAL_INTERCEPTOR);
gm_cam_long = GET_FLAG(param, GM_PARAM_HW_CAM_LONG) && !gm_cc_long; gm_cam_long = GET_FLAG(param, GM_PARAM_HW_CAM_LONG) && !gm_cc_long;
gm_bolt_2022_pedal = GET_FLAG(param, GM_PARAM_BOLT_2022_PEDAL);
gm_pcm_cruise = (((gm_hw == GM_CAM) || (gm_hw == GM_SDGM)) && (!gm_cam_long || gm_cc_long) && !gm_force_ascm && !gm_pedal_long); gm_pcm_cruise = (((gm_hw == GM_CAM) || (gm_hw == GM_SDGM)) && (!gm_cam_long || gm_cc_long) && !gm_force_ascm && !gm_pedal_long);
gm_skip_relay_check = GET_FLAG(param, GM_PARAM_NO_CAMERA); gm_skip_relay_check = GET_FLAG(param, GM_PARAM_NO_CAMERA);
gm_has_acc = !GET_FLAG(param, GM_PARAM_NO_ACC); gm_has_acc = !GET_FLAG(param, GM_PARAM_NO_ACC);
enable_gas_interceptor = GET_FLAG(param, GM_PARAM_PEDAL_INTERCEPTOR);
gm_force_brake_c9 = GET_FLAG(param, GM_PARAM_FORCE_BRAKE_C9); gm_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) {
-4
View File
@@ -211,7 +211,6 @@ class Panda:
FLAG_HYUNDAI_ALT_LIMITS = 64 FLAG_HYUNDAI_ALT_LIMITS = 64
FLAG_HYUNDAI_CANFD_HDA2_ALT_STEERING = 128 FLAG_HYUNDAI_CANFD_HDA2_ALT_STEERING = 128
FLAG_HYUNDAI_LFA_BTN = 256 FLAG_HYUNDAI_LFA_BTN = 256
FLAG_HYUNDAI_TACO_TUNE_HACK = 512
FLAG_TESLA_POWERTRAIN = 1 FLAG_TESLA_POWERTRAIN = 1
FLAG_TESLA_LONG_CONTROL = 2 FLAG_TESLA_LONG_CONTROL = 2
@@ -240,9 +239,6 @@ class Panda:
FLAG_GM_ASCM_INT = 256 FLAG_GM_ASCM_INT = 256
FLAG_GM_FORCE_BRAKE_C9 = 512 FLAG_GM_FORCE_BRAKE_C9 = 512
FLAG_GM_HW_SDGM = 1024 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,14 +11,12 @@ 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
@@ -190,64 +188,6 @@ 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)
@@ -262,80 +202,10 @@ 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_ACC_2022_2023, "CHEVROLET BOLT EUV 2022": GM.CHEVROLET_BOLT_EUV,
"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,
+57 -325
View File
@@ -1,7 +1,5 @@
from typing import Tuple
import time
import math 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
@@ -11,11 +9,10 @@ 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 CAR, DBC, AccState, CanBus, CarControllerParams, CruiseButtons, GMFlags, CC_ONLY_CAR, SDGM_CAR, ASCM_INT, EV_CAR, CC_REGEN_PADDLE_CAR from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, CarControllerParams, CruiseButtons, GMFlags, CC_ONLY_CAR, SDGM_CAR, EV_CAR, CAR
from openpilot.selfdrive.car.interfaces import CarControllerBase from openpilot.selfdrive.car.interfaces import CarControllerBase
from openpilot.selfdrive.controls.lib.drive_helpers import apply_deadzone from openpilot.selfdrive.controls.lib.drive_helpers import apply_deadzone
from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY
from openpilot.common.swaglog import cloudlog
VisualAlert = car.CarControl.HUDControl.VisualAlert VisualAlert = car.CarControl.HUDControl.VisualAlert
NetworkLocation = car.CarParams.NetworkLocation NetworkLocation = car.CarParams.NetworkLocation
@@ -27,15 +24,7 @@ TransmissionType = car.CarParams.TransmissionType
CAMERA_CANCEL_DELAY_FRAMES = 10 CAMERA_CANCEL_DELAY_FRAMES = 10
# Enforce a minimum interval between steering messages to avoid a fault # Enforce a minimum interval between steering messages to avoid a fault
MIN_STEER_MSG_INTERVAL_MS = 15 MIN_STEER_MSG_INTERVAL_MS = 15
# Twosided spacing tuned for ~33 Hz steer; target a 10 ms wide window per interval
# Paddle spoofing and scheduling constants
PADDLE_STEER_GAP_MIN_NS = 5_000_000 # ≥5 ms each side (EPS guard)
PADDLE_STEER_GAP_MAX_NS = 12_000_000 # cap for long intervals
PADDLE_GAP_TARGET_NS = 5_000_000 # aim perside gap even if interval//2 early is larger
PADDLE_NONBLOCK_GAP_NS = 1_000_000 # ≥1 ms since last paddle send
PADDLE_SLOT_EARLY_NS = 1_000_000 # allow firing up to 1 ms before slot
OVERFLOW_THRESH = 1.00 # fire one extra slot whenever credits ≥ 1.0
PADDLE_TARGET_HZ = 42.0 # desired paddle rate (Hz) when regen active; steer is ~33 Hz
# Constants for pitch compensation # Constants for pitch compensation
BRAKE_PITCH_FACTOR_BP = [5., 10.] # [m/s] smoothly revert to planned accel at low speeds BRAKE_PITCH_FACTOR_BP = [5., 10.] # [m/s] smoothly revert to planned accel at low speeds
BRAKE_PITCH_FACTOR_V = [0., 1.] # [unitless in [0,1]]; don't touch BRAKE_PITCH_FACTOR_V = [0., 1.] # [unitless in [0,1]]; don't touch
@@ -51,11 +40,6 @@ class CarController(CarControllerBase):
self.apply_speed = 0 self.apply_speed = 0
self.frame = 0 self.frame = 0
self.last_steer_frame = 0 self.last_steer_frame = 0
self.last_steer_ts_ns = 0
self.last_regen_active = False
self.prev_steer_ts_ns = 0
self.last_spoof_ts_ns = 0
self.last_paddle_ts_ns = 0
self.last_button_frame = 0 self.last_button_frame = 0
self.cancel_counter = 0 self.cancel_counter = 0
self.pedal_steady = 0. self.pedal_steady = 0.
@@ -65,21 +49,12 @@ class CarController(CarControllerBase):
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.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.mass = CP.mass self.mass = CP.mass
self.tireRadius = 0.075 * CP.wheelbase + 0.1453 self.tireRadius = 0.075 * CP.wheelbase + 0.1453
self.frontalArea = 1.05 * CP.wheelbase + 0.0679 self.frontalArea = 1.05 * CP.wheelbase + 0.0679
self.coeffDrag = 0.30 self.coeffDrag = 0.30
self.airDensity = 1.225 self.airDensity = 1.225
self.params_ = Params()
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'])
@@ -89,101 +64,25 @@ class CarController(CarControllerBase):
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.aego = 0.0
self.regen_paddle_timer = 0
self.planner_regen_hold = False
@staticmethod
def calc_pedal_command(accel: float, long_active: bool) -> float:
if not long_active: return 0.
zero = 0.15625 # 40/256
if accel > 0.:
# Scales the accel from 0-1 to 0.156-1
pedal_gas = clip(((1 - zero) * accel + zero), 0., 1.)
else:
# if accel is negative, -0.1 -> 0.015625
pedal_gas = clip(zero + accel, 0., zero) # Make brake the same size as gas, but clip to regen
# Midpoint + overflow spoof accumulator and flags return pedal_gas
self.spoof_accum = 0.0
self.spoof_mid_sent = False
self.spoof_over_sent = False
self.last_interval_ns = 0
def calc_pedal_command(self, accel: float, long_active: bool, car_velocity) -> Tuple[float, bool]:
if not long_active:
self.planner_regen_hold = False
return 0., False
# Regen paddle hysteresis (frame-based): hold 10 frames, with decrement dead-zone
if not hasattr(self, 'regen_paddle_timer'):
self.regen_paddle_timer = 0 # frames
# Regen paddle hysteresis (framebased): count frames when decelerating hard, decrement only when truly released
if self.aego < -0.7:
self.regen_paddle_timer += 1
elif self.aego > -0.3:
self.regen_paddle_timer = max(self.regen_paddle_timer - 1, 0)
# else: hold timer between -0.7 and -0.3
# Base paddle press hysteresis
self.regen_paddle_pressed = self.regen_paddle_timer >= 10 # 10 frames
press_regen_paddle = self.regen_paddle_pressed or self.planner_regen_hold
# Regen gain ratios from bin-averaged 600 deceleration sweep; Calculates stronger decel from paddle
speed_mps = [0.559, 1.678, 2.797, 3.916, 5.035, 6.154, 7.273, 8.392, 9.511, 10.63,
11.749, 12.868, 13.987, 15.106, 16.225, 17.344, 18.463, 19.582, 20.701, 21.820,
22.939, 24.058, 25.177, 26.296]
regen_gain_ratio = [
1.000000, 1.057308, 1.131123, 1.220611, 1.270247, 1.300253, 1.339543, 1.361002,
1.388410, 1.403253, 1.414721, 1.430949, 1.420289, 1.436787, 1.434116, 1.436805,
1.417508, 1.402213, 1.395360, 1.360921, 1.342030, 1.292219, 1.270048, 1.239172
]
gain = interp(car_velocity, speed_mps, regen_gain_ratio)
pedaloffset = interp(car_velocity, [0., 3, 6, 30], [0.10, 0.175, 0.240, 0.240])
# Compute raw pedal gas
raw_pedal_gas = clip((pedaloffset + (accel / gain) * 0.6), 0.0, 1.0) if press_regen_paddle else clip((pedaloffset + accel * 0.6), 0.0, 1.0)
# --- Immediate application of raw pedal gas, no blending ---
pedal_gas = raw_pedal_gas
# Safety cap: ramp from 22% at 0 m/s to 37.25% at 10 mph (4.47 m/s), then allow full throttle
pedal_gas_max = interp(car_velocity, [0.0, 4.47, 4.48], [0.22, 0.3725, 1.0])
pedal_gas = clip(pedal_gas, 0.0, pedal_gas_max)
return pedal_gas, press_regen_paddle
def update(self, CC, CS, now_nanos, frogpilot_toggles): def update(self, CC, CS, now_nanos, frogpilot_toggles):
self.CS = CS
self.aego = CS.out.aEgo
actuators = CC.actuators actuators = CC.actuators
accel = brake_accel = actuators.accel accel = brake_accel = actuators.accel
press_regen_paddle = False
kaofui_cars = SDGM_CAR | ASCM_INT | {
CAR.CHEVROLET_VOLT,
CAR.CHEVROLET_VOLT_2019,
CAR.CHEVROLET_VOLT_ASCM,
CAR.CHEVROLET_VOLT_CAMERA,
CAR.CHEVROLET_VOLT_CC,
CAR.CHEVROLET_MALIBU_CC,
CAR.CHEVROLET_MALIBU_HYBRID_CC,
}
volt_like = {
CAR.CHEVROLET_VOLT,
CAR.CHEVROLET_VOLT_2019,
CAR.CHEVROLET_VOLT_ASCM,
CAR.CHEVROLET_VOLT_CAMERA,
CAR.CHEVROLET_VOLT_CC,
}
# Planner-driven regen hold: gate by car support and OP long active, use commanded accel thresholds
if (self.CP.enableGasInterceptor and self.CP.carFingerprint in CC_REGEN_PADDLE_CAR
and self.CP.openpilotLongitudinalControl and CC.longActive):
# Match original hysteresis intent: vehicle can usually stop without paddle up to ~1.0 m/s^2
# Use the same thresholds as the aEgo-based hysteresis, but on commanded accel for preemption
planner_press_threshold = -0.7
planner_release_threshold = -0.3
if accel <= planner_press_threshold:
self.planner_regen_hold = True
elif accel >= planner_release_threshold:
self.planner_regen_hold = False
else:
self.planner_regen_hold = False
hud_control = CC.hudControl hud_control = CC.hudControl
hud_alert = hud_control.visualAlert hud_alert = hud_control.visualAlert
hud_v_cruise = hud_control.setSpeed hud_v_cruise = hud_control.setSpeed
@@ -192,129 +91,6 @@ class CarController(CarControllerBase):
# Send CAN commands. # Send CAN commands.
can_sends = [] can_sends = []
paddle_sends = []
if self.CP.carFingerprint == CAR.CHEVROLET_MALIBU_HYBRID_CC:
phase_map = gmcan.malibu_phase_map_for_acc(CS.cruise_buttons)
if phase_map and CS.steering_button_checksum in phase_map:
phase = (phase_map[CS.steering_button_checksum] + 1) % 4
self.malibu_cancel_phase = phase
self.malibu_button_phase = phase
raw_regen_active = (
self.CP.carFingerprint in CC_REGEN_PADDLE_CAR and
self.CP.openpilotLongitudinalControl and
CC.longActive and
self.CP.enableGasInterceptor and
(self.regen_paddle_timer >= 10 or self.planner_regen_hold) # hysteresis or planner hint
)
regen_active = raw_regen_active
# === Spoof scheduling: midpoint + overflow (~target Hz) ===
# Rising-edge reset on regen start
if raw_regen_active and not self.last_regen_active:
self.prev_steer_ts_ns = self.last_steer_ts_ns
self.last_spoof_ts_ns = 0
self.spoof_accum = 0.0
self.spoof_mid_sent = False
self.spoof_over_sent = False
if raw_regen_active:
# Interval between last two bus-0 steer sends
interval_ns = self.last_steer_ts_ns - self.prev_steer_ts_ns
# Adaptive twosided gap sized to the current steer interval, but capped to a target so the window stays wide enough
gap_ns = (PADDLE_STEER_GAP_MIN_NS if interval_ns <= 0 else
max(PADDLE_STEER_GAP_MIN_NS,
min(PADDLE_STEER_GAP_MAX_NS,
min((interval_ns // 2) - PADDLE_SLOT_EARLY_NS, PADDLE_GAP_TARGET_NS))))
# New steer interval? clear per-interval flags and add credits to reach target Hz
if interval_ns != self.last_interval_ns:
self.spoof_mid_sent = False
self.spoof_over_sent = False
self.last_interval_ns = interval_ns
# Add credits once per new steer interval to reach the desired paddle rate
if interval_ns > 0:
steer_hz = 1e9 / float(interval_ns)
extra_needed = max(0.0, (PADDLE_TARGET_HZ / steer_hz) - 1.0) # e.g., 42/33 1 ≈ 0.2727
self.spoof_accum += extra_needed
# Midpoint spoof: one per interval
if not self.spoof_mid_sent and interval_ns > 0:
midpoint_ns = self.prev_steer_ts_ns + interval_ns // 2
# Compute spacing to last and next steer (two-sided guard)
next_steer_ts_ns = self.last_steer_ts_ns + interval_ns if interval_ns > 0 else 0
delta_after_ns = now_nanos - self.last_steer_ts_ns
delta_before_ns = (next_steer_ts_ns - now_nanos) if interval_ns > 0 else 1_000_000_000
if (CS.out.vEgo > 2.68
and now_nanos >= (midpoint_ns - PADDLE_SLOT_EARLY_NS)
and delta_after_ns >= gap_ns
and delta_before_ns >= gap_ns):
# Non-blocking 1 ms spacing for paddle frames
if now_nanos - self.last_paddle_ts_ns >= PADDLE_NONBLOCK_GAP_NS:
paddle_sends.append(gmcan.create_prndl2_command(self.packer_pt, CanBus.POWERTRAIN, True, self.CP))
paddle_sends.append(gmcan.create_regen_paddle_command(self.packer_pt, CanBus.POWERTRAIN, True))
self.last_paddle_ts_ns = now_nanos
self.last_spoof_ts_ns = now_nanos
self.spoof_mid_sent = True
# Overflow spoof: insert extra when accumulator allows
if self.spoof_accum >= OVERFLOW_THRESH and not self.spoof_over_sent and interval_ns > 0:
slot2_ns = self.prev_steer_ts_ns + (interval_ns * 2) // 3
# Two-sided spacing relative to steer
next_steer_ts_ns = self.last_steer_ts_ns + interval_ns if interval_ns > 0 else 0
delta_after_ns = now_nanos - self.last_steer_ts_ns
delta_before_ns = (next_steer_ts_ns - now_nanos) if interval_ns > 0 else 1_000_000_000
if (CS.out.vEgo > 2.68
and now_nanos >= (slot2_ns - PADDLE_SLOT_EARLY_NS)
and delta_after_ns >= gap_ns
and delta_before_ns >= gap_ns):
# Non-blocking 1 ms spacing for paddle frames
if now_nanos - self.last_paddle_ts_ns >= PADDLE_NONBLOCK_GAP_NS:
paddle_sends.append(gmcan.create_prndl2_command(self.packer_pt, CanBus.POWERTRAIN, True, self.CP))
paddle_sends.append(gmcan.create_regen_paddle_command(self.packer_pt, CanBus.POWERTRAIN, True))
self.last_paddle_ts_ns = now_nanos
self.last_spoof_ts_ns = now_nanos
self.spoof_over_sent = True
self.spoof_accum -= OVERFLOW_THRESH
# === End Spoof scheduling ===
# === Off-pulse scheduling on regen release ===
if not raw_regen_active and self.last_regen_active:
# schedule two off-slots at 1/3 and 2/3 of the last steer interval
if self.prev_steer_ts_ns and self.last_steer_ts_ns:
intv = self.last_steer_ts_ns - self.prev_steer_ts_ns
self.off_schedule_ns = [
self.prev_steer_ts_ns + intv // 3,
self.prev_steer_ts_ns + (2 * intv) // 3
]
self.off_sent = [False, False]
if hasattr(self, "off_schedule_ns"):
for i, t_ns in enumerate(self.off_schedule_ns):
if not self.off_sent[i] and now_nanos >= (t_ns - PADDLE_SLOT_EARLY_NS):
# Two-sided spacing to steer before sending
interval_ns = self.last_steer_ts_ns - self.prev_steer_ts_ns
gap_ns = (PADDLE_STEER_GAP_MIN_NS if interval_ns <= 0 else
max(PADDLE_STEER_GAP_MIN_NS,
min(PADDLE_STEER_GAP_MAX_NS,
min((interval_ns // 2) - PADDLE_SLOT_EARLY_NS, PADDLE_GAP_TARGET_NS))))
next_steer_ts_ns = self.last_steer_ts_ns + interval_ns if interval_ns > 0 else 0
delta_after_ns = now_nanos - self.last_steer_ts_ns
delta_before_ns = (next_steer_ts_ns - now_nanos) if interval_ns > 0 else 1_000_000_000
if (delta_after_ns >= gap_ns and delta_before_ns >= gap_ns):
# Non-blocking 1 ms spacing for paddle frames
if now_nanos - self.last_paddle_ts_ns >= PADDLE_NONBLOCK_GAP_NS:
paddle_sends.append(gmcan.create_prndl2_command(self.packer_pt, CanBus.POWERTRAIN, False, self.CP))
paddle_sends.append(gmcan.create_regen_paddle_command(self.packer_pt, CanBus.POWERTRAIN, False))
self.last_paddle_ts_ns = now_nanos
self.off_sent[i] = True
# clean up once both off pulses are sent
if hasattr(self, "off_sent") and all(self.off_sent):
del self.off_schedule_ns
del self.off_sent
# === End off-pulse scheduling ===
# Steering (Active: 50Hz, inactive: 10Hz) # Steering (Active: 50Hz, inactive: 10Hz)
steer_step = self.params.STEER_STEP if CC.latActive else self.params.INACTIVE_STEER_STEP steer_step = self.params.STEER_STEP if CC.latActive else self.params.INACTIVE_STEER_STEP
@@ -347,32 +123,24 @@ class CarController(CarControllerBase):
if (self.CP.flags & GMFlags.CC_LONG.value) and CC.enabled and not CS.out.cruiseState.enabled: # Send 0 so Panda doesn't error if (self.CP.flags & GMFlags.CC_LONG.value) and CC.enabled and not CS.out.cruiseState.enabled: # Send 0 so Panda doesn't error
apply_steer = 0 apply_steer = 0
# shift previous steer timestamp
self.prev_steer_ts_ns = self.last_steer_ts_ns
self.last_steer_ts_ns = now_nanos
self.last_steer_frame = self.frame self.last_steer_frame = self.frame
self.apply_steer_last = apply_steer self.apply_steer_last = apply_steer
idx = self.lka_steering_cmd_counter % 4 idx = self.lka_steering_cmd_counter % 4
can_sends.append(gmcan.create_steering_control(self.packer_pt, CanBus.POWERTRAIN, apply_steer, idx, CC.latActive)) can_sends.append(gmcan.create_steering_control(self.packer_pt, CanBus.POWERTRAIN, apply_steer, idx, CC.latActive))
# Update regen_active state and last_regen_paddle_pressed for next loop
self.last_regen_active = regen_active
self.last_regen_paddle_pressed = self.regen_paddle_pressed or self.planner_regen_hold
if paddle_sends:
interval_ns = self.last_steer_ts_ns - self.prev_steer_ts_ns
flush_gap_ns = (PADDLE_STEER_GAP_MIN_NS if interval_ns <= 0 else
max(PADDLE_STEER_GAP_MIN_NS,
min(PADDLE_STEER_GAP_MAX_NS,
min((interval_ns // 2) - PADDLE_SLOT_EARLY_NS, PADDLE_GAP_TARGET_NS))))
if now_nanos - self.last_steer_ts_ns >= flush_gap_ns:
can_sends.extend(paddle_sends)
if self.CP.openpilotLongitudinalControl: if self.CP.openpilotLongitudinalControl:
# Gas/regen, brakes, and UI commands - all at 25Hz # Gas/regen, brakes, and UI commands - all at 25Hz
if self.frame % 4 == 0: if self.frame % 4 == 0:
stopping = actuators.longControlState == LongCtrlState.stopping stopping = actuators.longControlState == LongCtrlState.stopping
# Pitch compensated acceleration;
# TODO: include future pitch (sm['modelDataV2'].orientation.y) to account for long actuator delay
if frogpilot_toggles.long_pitch and len(CC.orientationNED) > 1 and not self.is_volt:
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
@@ -384,6 +152,7 @@ class CarController(CarControllerBase):
self.apply_gas = self.params.INACTIVE_REGEN self.apply_gas = self.params.INACTIVE_REGEN
self.apply_brake = int(min(-100 * frogpilot_toggles.stopAccel, self.params.MAX_BRAKE)) self.apply_brake = int(min(-100 * frogpilot_toggles.stopAccel, self.params.MAX_BRAKE))
else: else:
# Normal operation
if self.is_volt: if self.is_volt:
if len(CC.orientationNED) == 3 and CS.out.vEgo > self.CP.vEgoStopping: if len(CC.orientationNED) == 3 and CS.out.vEgo > self.CP.vEgoStopping:
volt_pitch_accel = math.sin(CC.orientationNED[1]) * ACCELERATION_DUE_TO_GRAVITY volt_pitch_accel = math.sin(CC.orientationNED[1]) * ACCELERATION_DUE_TO_GRAVITY
@@ -419,26 +188,30 @@ class CarController(CarControllerBase):
gas_max = self.params.MAX_GAS gas_max = self.params.MAX_GAS
accel_max = self.params.ACCEL_MAX accel_max = self.params.ACCEL_MAX
accel = clip(actuators.accel + accel_due_to_pitch, self.params.ACCEL_MIN, 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)) 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 scaled_torque = torque + self.params.ZERO_GAS
apply_gas_torque = clip(scaled_torque, self.params.MAX_ACC_REGEN, gas_max) 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_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) brake_accel = min((scaled_torque - BRAKE_SWITCH) / (self.tireRadius * self.mass), 0)
self.apply_gas = int(round(apply_gas_torque)) self.apply_gas = int(round(apply_gas_torque))
self.apply_brake = int(round(interp(brake_accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V))) self.apply_brake = int(round(interp(brake_accel, self.params.BRAKE_LOOKUP_BP, self.params.BRAKE_LOOKUP_V)))
if self.apply_brake > 0:
self.apply_gas = self.params.INACTIVE_REGEN
# 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 and self.apply_gas > self.params.INACTIVE_REGEN:
self.apply_gas = self.params.INACTIVE_REGEN
# Don't allow any gas above inactive regen while stopping # Don't allow any gas above inactive regen while stopping
# FIXME: brakes aren't applied immediately when enabling at a stop # FIXME: brakes aren't applied immediately when enabling at a stop
if stopping: if stopping:
self.apply_gas = self.params.INACTIVE_REGEN self.apply_gas = self.params.INACTIVE_REGEN
if self.CP.carFingerprint in CC_ONLY_CAR: if self.CP.carFingerprint in CC_ONLY_CAR:
# gas interceptor only used for full long control on cars without ACC # gas interceptor only used for full long control on cars without ACC
interceptor_gas_cmd, press_regen_paddle = self.calc_pedal_command(actuators.accel, CC.longActive, CS.out.vEgo) interceptor_gas_cmd = self.calc_pedal_command(actuators.accel, CC.longActive)
if self.CP.enableGasInterceptor and self.apply_gas > self.params.INACTIVE_REGEN and CS.out.cruiseState.standstill: if self.CP.enableGasInterceptor and self.apply_gas > self.params.INACTIVE_REGEN and CS.out.cruiseState.standstill:
# "Tap" the accelerator pedal to re-engage ACC # "Tap" the accelerator pedal to re-engage ACC
@@ -454,13 +227,7 @@ 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):
if self.CP.carFingerprint == CAR.CHEVROLET_MALIBU_HYBRID_CC: can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, (CS.buttons_counter + 1) % 4, CruiseButtons.DECEL_SET))
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:
@@ -483,10 +250,9 @@ class CarController(CarControllerBase):
acc_engaged = CC.enabled acc_engaged = CC.enabled
# GasRegenCmdActive needs to be 1 to avoid cruise faults. It describes the ACC state, not actuation # GasRegenCmdActive needs to be 1 to avoid cruise faults. It describes the ACC state, not actuation
can_sends.append(gmcan.create_gas_regen_command(self.packer_pt, CanBus.POWERTRAIN, self.apply_gas, idx, acc_engaged, at_full_stop, can_sends.append(gmcan.create_gas_regen_command(self.packer_pt, CanBus.POWERTRAIN, self.apply_gas, idx, acc_engaged, at_full_stop))
include_always_one3=self.CP.carFingerprint in kaofui_cars))
can_sends.append(gmcan.create_friction_brake_command(self.packer_ch, friction_brake_bus, self.apply_brake, can_sends.append(gmcan.create_friction_brake_command(self.packer_ch, friction_brake_bus, self.apply_brake,
idx, CC.enabled, near_stop, at_full_stop, self.CP)) idx, CC.enabled, near_stop, at_full_stop, self.CP))
# Send dashboard UI commands (ACC status) # Send dashboard UI commands (ACC status)
send_fcw = hud_alert == VisualAlert.fcw send_fcw = hud_alert == VisualAlert.fcw
@@ -497,57 +263,32 @@ class CarController(CarControllerBase):
accel += self.accel_g accel += self.accel_g
# Radar needs to know current speed and yaw rate (50hz), # Radar needs to know current speed and yaw rate (50hz),
# and that ADAS is alive (5hz, previously 10hz) # and that ADAS is alive (10hz)
if not self.CP.radarUnavailable: if not self.CP.radarUnavailable and self.CP.networkLocation != NetworkLocation.fwdCamera and self.CP.carFingerprint not in SDGM_CAR:
send_adas = True tt = self.frame * DT_CTRL
if self.CP.carFingerprint in kaofui_cars: time_and_headlights_step = 10
send_adas = (self.CP.networkLocation != NetworkLocation.fwdCamera) and (self.CP.carFingerprint not in SDGM_CAR) 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 send_adas: speed_and_accelerometer_step = 2
tt = self.frame * DT_CTRL if self.frame % speed_and_accelerometer_step == 0:
if self.CP.carFingerprint in kaofui_cars: idx = (self.frame // speed_and_accelerometer_step) % 4
time_and_headlights_step = 10 can_sends.append(gmcan.create_adas_steering_status(CanBus.OBSTACLE, idx))
speed_and_accelerometer_step = 2 can_sends.append(gmcan.create_adas_accelerometer_speed_status(CanBus.OBSTACLE, CS.out.vEgo, idx))
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: if self.CP.networkLocation == NetworkLocation.gateway and self.frame % self.params.ADAS_KEEPALIVE_STEP == 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 stock_cc_active: ) and CS.out.cruiseState.enabled:
if self.CP.carFingerprint == CAR.CHEVROLET_MALIBU_HYBRID_CC: if (self.frame - self.last_button_frame) * DT_CTRL > 0.04:
# Match 33 Hz cadence (every 3 frames) and align phase to the last seen checksum. self.last_button_frame = self.frame
if self.malibu_cancel_frame % 3 == 0: can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.POWERTRAIN, (CS.buttons_counter + 1) % 4, CruiseButtons.CANCEL))
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.
@@ -558,16 +299,7 @@ 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 == CAR.CHEVROLET_MALIBU_HYBRID_CC: can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.CAMERA, CS.buttons_counter, 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
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))
else:
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
+39 -146
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, ASCM_INT, CAR from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, STEER_THRESHOLD, GMFlags, CC_ONLY_CAR, CAMERA_ACC_CAR, SDGM_CAR, ASCM_INT, CAR
TransmissionType = car.CarParams.TransmissionType TransmissionType = car.CarParams.TransmissionType
NetworkLocation = car.CarParams.NetworkLocation NetworkLocation = car.CarParams.NetworkLocation
@@ -26,8 +26,6 @@ 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
@@ -38,29 +36,12 @@ 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 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:
self.cruise_buttons = cam_cp.vl["ASCMSteeringButton"]["ACCButtons"]
self.distance_button = cam_cp.vl["ASCMSteeringButton"]["DistanceButton"]
self.buttons_counter = cam_cp.vl["ASCMSteeringButton"]["RollingCounter"]
self.pscm_status = copy.copy(pt_cp.vl["PSCMStatus"]) self.pscm_status = copy.copy(pt_cp.vl["PSCMStatus"])
# This is to avoid a fault where you engage while still moving backwards after shifting to D. # This is to avoid a fault where you engage while still moving backwards after shifting to D.
# An Equinox has been seen with an unsupported status (3), so only check if either wheel is in reverse (2) # An Equinox has been seen with an unsupported status (3), so only check if either wheel is in reverse (2)
@@ -70,13 +51,6 @@ class CarState(CarStateBase):
self.loopback_lka_steering_cmd_updated = len(loopback_cp.vl_all["ASCMLKASteeringCmd"]["RollingCounter"]) > 0 self.loopback_lka_steering_cmd_updated = len(loopback_cp.vl_all["ASCMLKASteeringCmd"]["RollingCounter"]) > 0
if self.loopback_lka_steering_cmd_updated: if self.loopback_lka_steering_cmd_updated:
self.loopback_lka_steering_cmd_ts_nanos = loopback_cp.ts_nanos["ASCMLKASteeringCmd"]["RollingCounter"] self.loopback_lka_steering_cmd_ts_nanos = loopback_cp.ts_nanos["ASCMLKASteeringCmd"]["RollingCounter"]
# Track timestamps for OEM PRNDL2 and Regen Paddle messages (used to sync spoofing timing)
self.prndl2_ts_nanos = pt_cp.ts_nanos["ECMPRDNL2"]["PRNDL2"]
if self.CP.carFingerprint in CC_REGEN_PADDLE_CAR:
self.regen_paddle_ts_nanos = pt_cp.ts_nanos["EBCMRegenPaddle"]["RegenPaddle"]
else:
self.regen_paddle_ts_nanos = 0
if self.CP.networkLocation == NetworkLocation.fwdCamera and not self.CP.flags & GMFlags.NO_CAMERA.value: if self.CP.networkLocation == NetworkLocation.fwdCamera and not self.CP.flags & GMFlags.NO_CAMERA.value:
self.pt_lka_steering_cmd_counter = pt_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"] self.pt_lka_steering_cmd_counter = pt_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"]
self.cam_lka_steering_cmd_counter = cam_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"] self.cam_lka_steering_cmd_counter = cam_cp.vl["ASCMLKASteeringCmd"]["RollingCounter"]
@@ -98,38 +72,24 @@ class CarState(CarStateBase):
ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(pt_cp.vl["ECMPRDNL2"]["PRNDL2"], None)) ret.gearShifter = self.parse_gear_shifter(self.shifter_values.get(pt_cp.vl["ECMPRDNL2"]["PRNDL2"], None))
if self.CP.flags & GMFlags.NO_ACCELERATOR_POS_MSG.value: if self.CP.flags & GMFlags.NO_ACCELERATOR_POS_MSG.value:
if self.CP.carFingerprint in kaofui_state_cars: ret.brake = pt_cp.vl.get("EBCMBrakePedalPosition", {}).get("BrakePedalPosition", 0) / 0xd0
ret.brake = pt_cp.vl.get("EBCMBrakePedalPosition", {}).get("BrakePedalPosition", 0) / 0xd0
else:
ret.brake = pt_cp.vl["EBCMBrakePedalPosition"]["BrakePedalPosition"] / 0xd0
else: else:
if self.CP.carFingerprint in kaofui_state_cars: ret.brake = pt_cp.vl.get("ECMAcceleratorPos", {}).get("BrakePedalPos", 0)
ret.brake = pt_cp.vl.get("ECMAcceleratorPos", {}).get("BrakePedalPos", 0)
else: if (self.CP.flags & GMFlags.FORCE_BRAKE_C9.value) or ((self.CP.networkLocation == NetworkLocation.fwdCamera) and (self.CP.carFingerprint != CAR.CHEVROLET_BLAZER)):
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
analog_thresh = 0.15 if (self.CP.flags & GMFlags.NO_ACCELERATOR_POS_MSG.value) else 8 analog_thresh = 0.07 if (self.CP.flags & GMFlags.NO_ACCELERATOR_POS_MSG.value) else 8
ret.brakePressed = ret.brake >= analog_thresh 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 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_EUV, CAR.CHEVROLET_BOLT_CC] and self.CP.enableGasInterceptor)
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.
@@ -150,32 +110,19 @@ 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 not sdgm_non_volt:
# 1 - open, 0 - closed
ret.doorOpen = (pt_cp.vl["BCMDoorBeltStatus"]["FrontLeftDoor"] == 1 or
pt_cp.vl["BCMDoorBeltStatus"]["FrontRightDoor"] == 1 or
pt_cp.vl["BCMDoorBeltStatus"]["RearLeftDoor"] == 1 or
pt_cp.vl["BCMDoorBeltStatus"]["RearRightDoor"] == 1)
# 1 - latched # 1 - open, 0 - closed
ret.seatbeltUnlatched = pt_cp.vl["BCMDoorBeltStatus"]["LeftSeatBelt"] == 0 ret.doorOpen = (pt_cp.vl["BCMDoorBeltStatus"]["FrontLeftDoor"] == 1 or
ret.leftBlinker = pt_cp.vl["BCMTurnSignals"]["TurnSignals"] == 1 pt_cp.vl["BCMDoorBeltStatus"]["FrontRightDoor"] == 1 or
ret.rightBlinker = pt_cp.vl["BCMTurnSignals"]["TurnSignals"] == 2 pt_cp.vl["BCMDoorBeltStatus"]["RearLeftDoor"] == 1 or
pt_cp.vl["BCMDoorBeltStatus"]["RearRightDoor"] == 1)
ret.parkingBrake = pt_cp.vl["BCMGeneralPlatformStatus"]["ParkBrakeSwActive"] == 1 # 1 - latched
else: ret.seatbeltUnlatched = pt_cp.vl["BCMDoorBeltStatus"]["LeftSeatBelt"] == 0
# 1 - open, 0 - closed ret.leftBlinker = pt_cp.vl["BCMTurnSignals"]["TurnSignals"] == 1
ret.doorOpen = (cam_cp.vl["BCMDoorBeltStatus"]["FrontLeftDoor"] == 1 or ret.rightBlinker = pt_cp.vl["BCMTurnSignals"]["TurnSignals"] == 2
cam_cp.vl["BCMDoorBeltStatus"]["FrontRightDoor"] == 1 or
cam_cp.vl["BCMDoorBeltStatus"]["RearLeftDoor"] == 1 or
cam_cp.vl["BCMDoorBeltStatus"]["RearRightDoor"] == 1)
# 1 - latched ret.parkingBrake = pt_cp.vl["BCMGeneralPlatformStatus"]["ParkBrakeSwActive"] == 1
ret.seatbeltUnlatched = cam_cp.vl["BCMDoorBeltStatus"]["LeftSeatBelt"] == 0
ret.leftBlinker = cam_cp.vl["BCMTurnSignals"]["TurnSignals"] == 1
ret.rightBlinker = cam_cp.vl["BCMTurnSignals"]["TurnSignals"] == 2
ret.parkingBrake = cam_cp.vl["BCMGeneralPlatformStatus"]["ParkBrakeSwActive"] == 1
ret.cruiseState.available = pt_cp.vl["ECMEngineStatus"]["CruiseMainOn"] != 0 ret.cruiseState.available = pt_cp.vl["ECMEngineStatus"]["CruiseMainOn"] != 0
ret.espDisabled = pt_cp.vl["ESPStatus"]["TractionControlOn"] != 1 ret.espDisabled = pt_cp.vl["ESPStatus"]["TractionControlOn"] != 1
ret.accFaulted = (pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.FAULTED or ret.accFaulted = (pt_cp.vl["AcceleratorPedal2"]["CruiseState"] == AccState.FAULTED or
@@ -186,42 +133,23 @@ 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 | ASCM_INT): 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:
ret.stockAeb = False
# openpilot controls nonAdaptive when not pcmCruise # openpilot controls nonAdaptive when not pcmCruise
# 2016-2018 Volt won't identify non-adaptive cruise state since switchable cruise state was not introduced till 2019 model year / SDGM Global AAdd commentMore actions
if self.CP.pcmCruise and self.CP.carFingerprint not in ASCM_INT: 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
if self.CP.carFingerprint == CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL: ret.cruiseState.enabled = pt_cp.vl["ECMCruiseControl"]["CruiseActive"] != 0
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 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:
ret.leftBlindspot = cam_cp.vl["BCMBlindSpotMonitor"]["LeftBSM"] == 1
ret.rightBlindspot = cam_cp.vl["BCMBlindSpotMonitor"]["RightBSM"] == 1
# FrogPilot CarState functions
self.lkas_previously_enabled = self.lkas_enabled self.lkas_previously_enabled = self.lkas_enabled
if sdgm_non_volt: self.lkas_enabled = pt_cp.vl["ASCMSteeringButton"]["LKAButton"]
self.lkas_enabled = cam_cp.vl["ASCMSteeringButton"]["LKAButton"]
else:
self.lkas_enabled = pt_cp.vl["ASCMSteeringButton"]["LKAButton"]
self.pcm_acc_status = pt_cp.vl["AcceleratorPedal2"]["CruiseState"] self.pcm_acc_status = pt_cp.vl["AcceleratorPedal2"]["CruiseState"]
@@ -233,31 +161,14 @@ 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 sdgm_non_volt: if CP.carFingerprint not in (SDGM_CAR|ASCM_INT):
messages += [
("BCMTurnSignals", 1),
("BCMDoorBeltStatus", 10),
("BCMGeneralPlatformStatus", 10),
("ASCMSteeringButton", 33),
]
if CP.enableBsm:
messages.append(("BCMBlindSpotMonitor", 10))
elif CP.carFingerprint not in (SDGM_CAR | ASCM_INT):
messages += [ messages += [
("AEBCmd", 10), ("AEBCmd", 10),
] ]
if CP.carFingerprint not in CC_ONLY_CAR or CP.carFingerprint == CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL: if CP.carFingerprint not in CC_ONLY_CAR:
messages += [ messages += [
("ASCMActiveCruiseControlStatus", 25), ("ASCMActiveCruiseControlStatus", 25),
] ]
@@ -267,43 +178,25 @@ class CarState(CarStateBase):
@staticmethod @staticmethod
def get_can_parser(CP, FPCP): def get_can_parser(CP, FPCP):
messages = [ messages = [
("BCMTurnSignals", 1),
("ECMPRDNL2", 10),
("PSCMStatus", 10), ("PSCMStatus", 10),
("ESPStatus", 10), ("ESPStatus", 10),
("BCMDoorBeltStatus", 10),
("BCMGeneralPlatformStatus", 10),
("EBCMWheelSpdFront", 20), ("EBCMWheelSpdFront", 20),
("EBCMWheelSpdRear", 20), ("EBCMWheelSpdRear", 20),
("EBCMFrictionBrakeStatus", 20), ("EBCMFrictionBrakeStatus", 20),
("AcceleratorPedal2", 33),
("ASCMSteeringButton", 33),
("ECMEngineStatus", 100),
("PSCMSteeringAngle", 100), ("PSCMSteeringAngle", 100),
("ECMAcceleratorPos", 80), ("ECMAcceleratorPos", 80),
("SportMode", 0), ("SportMode", 0),
] ]
volt_like = {CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_2019, CAR.CHEVROLET_VOLT_ASCM, CAR.CHEVROLET_VOLT_CAMERA, CAR.CHEVROLET_VOLT_CC} if CP.enableBsm:
kaofui_state_cars = volt_like | SDGM_CAR | ASCM_INT | { messages.append(("BCMBlindSpotMonitor", 10))
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 += [
("ECMPRDNL2", prndl2_rate),
("AcceleratorPedal2", 40),
("ECMEngineStatus", 80),
]
else:
messages += [
("ECMPRDNL2", prndl2_rate),
("AcceleratorPedal2", 33),
("ECMEngineStatus", 100),
("BCMTurnSignals", 1),
("BCMDoorBeltStatus", 10),
("BCMGeneralPlatformStatus", 10),
("ASCMSteeringButton", 33),
]
if CP.enableBsm:
messages.append(("BCMBlindSpotMonitor", 10))
# Used to read back last counter sent to PT by camera # Used to read back last counter sent to PT by camera
if CP.networkLocation == NetworkLocation.fwdCamera: if CP.networkLocation == NetworkLocation.fwdCamera:
@@ -315,9 +208,8 @@ 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", regen_paddle_rate), ("EBCMRegenPaddle", 50),
("EVDriveMode", 0), ("EVDriveMode", 0),
] ]
@@ -331,6 +223,7 @@ class CarState(CarStateBase):
("GAS_SENSOR", 50), ("GAS_SENSOR", 50),
] ]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus.POWERTRAIN) return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus.POWERTRAIN)
@staticmethod @staticmethod
+16 -25
View File
@@ -84,34 +84,14 @@ 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_ACC_2022_2023: [{ CAR.CHEVROLET_BOLT_EUV: [{
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_ACC_2022_2023_PEDAL: [{ CAR.CHEVROLET_BOLT_CC: [
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
@@ -132,6 +112,18 @@ 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
@@ -203,8 +195,7 @@ 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, 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 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
{ {
@@ -237,7 +228,7 @@ FINGERPRINTS = {
}], }],
CAR.CHEVROLET_MALIBU_HYBRID_CC: [ 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 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: [
{ {
+3 -102
View File
@@ -6,56 +6,6 @@ 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 = {
@@ -73,17 +23,6 @@ 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 [
@@ -118,7 +57,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, include_always_one3=False): def create_gas_regen_command(packer, bus, throttle, idx, enabled, at_full_stop):
values = { values = {
"GasRegenCmdActive": enabled, "GasRegenCmdActive": enabled,
"RollingCounter": idx, "RollingCounter": idx,
@@ -127,9 +66,8 @@ 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) | \
@@ -143,7 +81,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_ACC_2022_2023,): if enabled and CP.carFingerprint in (CAR.CHEVROLET_BOLT_EUV,):
mode = 0x9 mode = 0x9
if apply_brake > 0: if apply_brake > 0:
@@ -239,36 +177,6 @@ def create_lka_icon_command(bus, active, critical, steer):
dat = b"\x00\x00\x00" dat = b"\x00\x00\x00"
return make_can_msg(0x104c006c, dat, bus) return make_can_msg(0x104c006c, dat, bus)
def create_prndl2_command(packer, bus, press_regen_paddle, CP):
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
values = {
"Byte0": 0x0C,
"Byte1": 0x0C,
"Byte2": 0x00,
"PRNDL2": prndl2_value,
"Byte4": 0x00,
"ManualMode": manual_mode,
"TransmissionState": 1,
"Byte7": 0x00
}
return packer.make_can_msg("ECMPRDNL2", bus, values)
def create_regen_paddle_command(packer, bus, press_regen_paddle):
regen_paddle_value = 2 if press_regen_paddle else 0
values = {
"RegenPaddle": regen_paddle_value,
"Byte1": 0,
"Byte2": 0,
"Byte3": 0,
"Byte4": 0,
"Byte5": 0,
"Byte6": 0
}
return packer.make_can_msg("EBCMRegenPaddle", bus, values)
def create_gm_cc_spam_command(packer, controller, CS, actuators, frogpilot_toggles): def create_gm_cc_spam_command(packer, controller, CS, actuators, frogpilot_toggles):
accel = actuators.accel accel = actuators.accel
@@ -307,13 +215,6 @@ 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:
+88 -249
View File
@@ -7,10 +7,12 @@ 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, ASCM_INT, set_red_panda_canbus from openpilot.selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus, GMFlags, CC_ONLY_CAR, SDGM_CAR, ASCM_INT
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
ButtonType = car.CarState.ButtonEvent.Type ButtonType = car.CarState.ButtonEvent.Type
FrogPilotButtonType = custom.FrogPilotCarState.ButtonEvent.Type FrogPilotButtonType = custom.FrogPilotCarState.ButtonEvent.Type
EventName = car.CarEvent.EventName EventName = car.CarEvent.EventName
@@ -26,7 +28,7 @@ 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 = { VOLT_LIKE_CARS = (
CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT,
CAR.CHEVROLET_VOLT_2019, CAR.CHEVROLET_VOLT_2019,
CAR.CHEVROLET_VOLT_CC, CAR.CHEVROLET_VOLT_CC,
@@ -37,37 +39,14 @@ VOLT_LIKE_CARS = {
CAR.CHEVROLET_MALIBU_SDGM, CAR.CHEVROLET_MALIBU_SDGM,
CAR.CHEVROLET_MALIBU_CC, CAR.CHEVROLET_MALIBU_CC,
CAR.CHEVROLET_MALIBU_HYBRID_CC, CAR.CHEVROLET_MALIBU_HYBRID_CC,
} )
NON_LINEAR_TORQUE_PARAMS = { NON_LINEAR_TORQUE_PARAMS = {
CAR.CHEVROLET_BOLT_ACC_2022_2023: { CAR.CHEVROLET_BOLT_EUV: [2.6531724862969748, 1.0, 0.1919764879840985, 0.009054123646805178],
"left": [2.6531724862969748, 1.1, 0.1919764879840985, 0.0], CAR.CHEVROLET_BOLT_CC: [2.6531724862969748, 1.0, 0.1919764879840985, 0.009054123646805178],
"right": [2.7031724862969748, 1.0, 0.1469764879840985, 0.0], CAR.GMC_ACADIA: [4.78003305, 1.0, 0.3122, 0.05591772],
}, CAR.GMC_ACADIA_ASCM: [4.78003305, 1.0, 0.3122, 0.05591772],
CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL: { CAR.CHEVROLET_SILVERADO: [3.29974374, 1.0, 0.25571356, 0.0465122]
"left": [2.6531724862969748, 1.1, 0.1919764879840985, 0.0],
"right": [2.7031724862969748, 1.0, 0.1469764879840985, 0.0],
},
CAR.CHEVROLET_BOLT_CC_2022_2023: {
"left": [2.6531724862969748, 1.1, 0.1919764879840985, 0.0],
"right": [2.7031724862969748, 1.0, 0.1469764879840985, 0.0],
},
CAR.CHEVROLET_BOLT_CC_2019_2021: {
"left": [1.8, 1.1, 0.27, 0.0],
"right": [2.0, 1.0, 0.205, 0.0],
},
CAR.CHEVROLET_BOLT_CC_2017: {
"left": [2.15, 1.0, 0.21, 0.0],
"right": [2.15, 1.0, 0.21, 0.0],
},
CAR.GMC_ACADIA: {
"left": [4.78003305, 1.0, 0.3122, 0.05591772],
"right": [4.78003305, 1.0, 0.3122, 0.05591772],
},
CAR.CHEVROLET_SILVERADO: {
"left": [3.8, 0.81, 0.24, 0.0465122],
"right": [3.8, 0.81, 0.24, 0.0465122],
},
} }
@@ -101,9 +80,7 @@ class CarInterface(CarInterfaceBase):
# This has big effect on the stability about 0 (noise when going straight) # This has big effect on the stability about 0 (noise when going straight)
non_linear_torque_params = NON_LINEAR_TORQUE_PARAMS.get(self.CP.carFingerprint) non_linear_torque_params = NON_LINEAR_TORQUE_PARAMS.get(self.CP.carFingerprint)
assert non_linear_torque_params, "The params are not defined" assert non_linear_torque_params, "The params are not defined"
# Left is positive a, b, c, d = non_linear_torque_params
side_key = "left" if lateral_acceleration >= 0 else "right"
a, b, c, d = non_linear_torque_params[side_key]
sig_input = a * lateral_acceleration sig_input = a * lateral_acceleration
sig = np.sign(sig_input) * (1 / (1 + exp(-fabs(sig_input))) - 0.5) sig = np.sign(sig_input) * (1 / (1 + exp(-fabs(sig_input))) - 0.5)
steer_torque = (sig * b) + (lateral_acceleration * c) + d steer_torque = (sig * b) + (lateral_acceleration * c) + d
@@ -145,92 +122,52 @@ 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) ret.safetyConfigs = [get_safety_config(car.CarParams.SafetyModel.noOutput),
set_red_panda_canbus(red_panda) 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.get(CanBus.POWERTRAIN, {}) ret.enableBsm = 0x142 in fingerprint[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 has_sascm(fingerprint): if 0x2FF in fingerprint[0]:
ret.flags |= GMFlags.SASCM.value ret.flags |= GMFlags.SASCM.value
if PEDAL_MSG in fingerprint.get(CanBus.POWERTRAIN, {}): if PEDAL_MSG in fingerprint[0]:
ret.enableGasInterceptor = True ret.enableGasInterceptor = True
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_GAS_INTERCEPTOR ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_GM_GAS_INTERCEPTOR
if candidate == CAR.CHEVROLET_BOLT_ACC_2022_2023: # When a pedal interceptor is present, always use normal longitudinal (block stock cruise)
# Hard-block pedal interceptor for ACC fingerprinted Bolts experimental_long = False
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
kaofui_cars = SDGM_CAR | ASCM_INT | VOLT_LIKE_CARS | {CAR.CHEVROLET_MALIBU_HYBRID_CC} ret.longitudinalTuning.kiBP = [5., 35.]
ret.longitudinalTuning.kiBP = [5., 35.] if candidate in kaofui_cars else [5., 35., 60.]
is_bolt_2022_2023_pedal = candidate == CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL and ret.enableGasInterceptor if candidate in (CAMERA_ACC_CAR | SDGM_CAR | ASCM_INT) or candidate == CAR.CHEVROLET_VOLT_CAMERA:
ret.experimentalLongitudinalAvailable = candidate not in (CC_ONLY_CAR | ASCM_INT | SDGM_CAR) or 0x2FF in fingerprint[CanBus.POWERTRAIN]
kaofui_camera_cars = {
CAR.CHEVROLET_VOLT_CAMERA,
CAR.CHEVROLET_VOLT_CC,
CAR.CHEVROLET_MALIBU_HYBRID_CC,
}
bolt_cc_camera_cars = {
CAR.CHEVROLET_BOLT_CC_2017,
CAR.CHEVROLET_BOLT_CC_2019_2021,
CAR.CHEVROLET_BOLT_ACC_2022_2023_PEDAL,
CAR.CHEVROLET_BOLT_CC_2022_2023,
}
is_camera_acc = candidate in CAMERA_ACC_CAR and candidate not in kaofui_cars and \
(candidate not in CC_ONLY_CAR or candidate in bolt_cc_camera_cars)
if candidate in kaofui_camera_cars:
# Keep Volt/Malibu camera path functionally aligned with kaofui.
ret.experimentalLongitudinalAvailable = candidate not in (CC_ONLY_CAR | ASCM_INT | SDGM_CAR) or has_sascm(fingerprint)
ret.networkLocation = NetworkLocation.fwdCamera ret.networkLocation = NetworkLocation.fwdCamera
ret.radarUnavailable = 0x460 not in fingerprint.get(CanBus.OBSTACLE, {}) ret.radarUnavailable = 0x460 not in fingerprint[CanBus.OBSTACLE]
ret.pcmCruise = True ret.pcmCruise = True
ret.minEnableSpeed = 5 * CV.KPH_TO_MS ret.minEnableSpeed = 5 * CV.KPH_TO_MS
ret.minSteerSpeed = 10 * CV.KPH_TO_MS ret.minSteerSpeed = 10 * CV.KPH_TO_MS
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM if candidate in SDGM_CAR:
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_GM_HW_SDGM
# Use C9 brake bit only on SDGM variants that lack 0xBE (ECMAcceleratorPos)
if ACCELERATOR_POS_MSG not in fingerprint[CanBus.POWERTRAIN]:
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_GM_FORCE_BRAKE_C9
ret.flags |= GMFlags.FORCE_BRAKE_C9.value
ret.minEnableSpeed = -1. # engage speed is decided by pcm
ret.minSteerSpeed = 7 * CV.MPH_TO_MS
elif candidate in ASCM_INT:
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_GM_HW_CAM
ret.minSteerSpeed = 7 * CV.MPH_TO_MS
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_GM_ASCM_INT
else:
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_GM_HW_CAM
# Tuning for experimental long # Tuning for experimental long
ret.longitudinalTuning.kiV = [0.5, 0.5] 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.radarUnavailable = True # no radar
ret.pcmCruise = not ret.enableGasInterceptor
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM
ret.minEnableSpeed = 5 * CV.KPH_TO_MS
ret.minSteerSpeed = 10 * CV.KPH_TO_MS
# Tuning for experimental long
ret.longitudinalTuning.kiV = [0.5, 0.5, 0.5]
ret.vEgoStopping = 0.1
ret.vEgoStarting = 0.1
ret.stoppingDecelRate = 1.0 # reach brake quickly after enabling ret.stoppingDecelRate = 1.0 # reach brake quickly after enabling
ret.vEgoStopping = 0.25 ret.vEgoStopping = 0.25
@@ -240,89 +177,27 @@ 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
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM_LONG ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_GM_HW_CAM_LONG
elif candidate in SDGM_CAR:
# kaofui parity: SDGM cars require SASCM for experimental long
ret.experimentalLongitudinalAvailable = candidate not in (CC_ONLY_CAR | ASCM_INT | SDGM_CAR) or has_sascm(fingerprint)
ret.networkLocation = NetworkLocation.fwdCamera
ret.radarUnavailable = 0x460 not in fingerprint.get(CanBus.OBSTACLE, {})
ret.pcmCruise = True
ret.minEnableSpeed = -1. # engage speed is decided by pcm
ret.minSteerSpeed = 7 * CV.MPH_TO_MS
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_SDGM
# Use C9 brake bit on Blazer and SDGM variants that lack 0xBE (ECMAcceleratorPos),
# so panda brake_pressed source matches carstate on light taps.
if candidate == CAR.CHEVROLET_BLAZER or ACCELERATOR_POS_MSG not in fingerprint.get(CanBus.POWERTRAIN, {}):
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_FORCE_BRAKE_C9
ret.flags |= GMFlags.FORCE_BRAKE_C9.value
# Tuning for experimental long
ret.longitudinalTuning.kiV = [0.5, 0.5] if candidate in kaofui_cars else [0.5, 0.5, 0.5]
ret.vEgoStopping = 0.1
ret.vEgoStarting = 0.1
ret.stoppingDecelRate = 1.0 # reach brake quickly after enabling
ret.vEgoStopping = 0.25
ret.vEgoStarting = 0.25
ret.stopAccel = -0.25
if ret.experimentalLongitudinalAvailable and experimental_long:
ret.pcmCruise = False
ret.openpilotLongitudinalControl = True
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM_LONG
if is_bolt_2022_2023_pedal:
ret.experimentalLongitudinalAvailable = False
ret.pcmCruise = False
elif candidate in ASCM_INT and has_sascm(fingerprint):
ret.experimentalLongitudinalAvailable = True
ret.networkLocation = NetworkLocation.fwdCamera
ret.radarUnavailable = 0x460 not in fingerprint.get(CanBus.OBSTACLE, {})
ret.pcmCruise = True
ret.minEnableSpeed = 5 * CV.KPH_TO_MS
ret.minSteerSpeed = 7 * CV.MPH_TO_MS
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_ASCM_INT
# Tuning for experimental long
ret.longitudinalTuning.kiV = [0.5, 0.5] if candidate in kaofui_cars else [0.5, 0.5, 0.5]
ret.vEgoStopping = 0.1
ret.vEgoStarting = 0.1
ret.stoppingDecelRate = 1.0 # reach brake quickly after enabling
ret.vEgoStopping = 0.25
ret.vEgoStarting = 0.25
ret.stopAccel = -0.25
if ret.experimentalLongitudinalAvailable and experimental_long:
ret.pcmCruise = False
ret.openpilotLongitudinalControl = True
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM_LONG
if is_bolt_2022_2023_pedal:
ret.experimentalLongitudinalAvailable = False
ret.pcmCruise = False
else: # ASCM, OBD-II harness else: # ASCM, OBD-II harness
ret.openpilotLongitudinalControl = not frogpilot_toggles.disable_openpilot_long ret.openpilotLongitudinalControl = not frogpilot_toggles.disable_openpilot_long
ret.networkLocation = NetworkLocation.gateway ret.networkLocation = NetworkLocation.gateway
ret.radarUnavailable = RADAR_HEADER_MSG not in fingerprint.get(CanBus.OBSTACLE, {}) and not docs ret.radarUnavailable = RADAR_HEADER_MSG not in fingerprint[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] if candidate in kaofui_cars else [0.5, 0.5, 0.5] ret.longitudinalTuning.kiV = [0.5, 0.5]
if candidate in kaofui_cars: ret.stoppingDecelRate = 3
ret.stoppingDecelRate = 3 ret.vEgoStopping = 0.75
ret.vEgoStopping = 0.75 ret.vEgoStarting = 0.75
ret.vEgoStarting = 0.75 ret.stopAccel = -1.5
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
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_ASCM_LONG ret.safetyConfigs[-1].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.]]
@@ -345,14 +220,17 @@ class CarInterface(CarInterfaceBase):
if candidate in VOLT_LIKE_CARS: if candidate in VOLT_LIKE_CARS:
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) 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
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.GMC_ACADIA_ASCM:
ret.minEnableSpeed = -1. # engage speed is decided by pcm
ret.steerActuatorDelay = 0.2
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate == CAR.BUICK_LACROSSE: elif candidate == CAR.BUICK_LACROSSE:
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
@@ -371,30 +249,15 @@ 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_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): elif candidate in (CAR.CHEVROLET_BOLT_EUV, CAR.CHEVROLET_BOLT_CC):
ret.steerActuatorDelay = 0.2 ret.steerActuatorDelay = 0.2
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
# Bolt-only lateral tuning overrides
ret.lateralTuning.torque.kp = 1.03
ret.lateralTuning.torque.ki = 1.07
ret.lateralTuning.torque.kd = 0.93
ret.lateralTuning.torque.kfDEPRECATED = 0.02
if candidate == CAR.CHEVROLET_BOLT_CC_2017:
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_BOLT_2017
if ret.enableGasInterceptor: if ret.enableGasInterceptor:
# ACC Bolts use pedal for full longitudinal control, not just sng # ACC Bolts use pedal for full longitudinal control, not just sng
ret.flags |= GMFlags.PEDAL_LONG.value ret.flags |= GMFlags.PEDAL_LONG.value
# Enable pedal interceptor for ACC models when detected elif candidate == CAR.CHEVROLET_SILVERADO:
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
@@ -438,8 +301,9 @@ class CarInterface(CarInterfaceBase):
if not ret.openpilotLongitudinalControl: if not ret.openpilotLongitudinalControl:
ret.minEnableSpeed = -1. # engage speed is decided by pcm 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.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
@@ -449,90 +313,69 @@ class CarInterface(CarInterfaceBase):
elif candidate == CAR.CADILLAC_CT6_CC: elif candidate == CAR.CADILLAC_CT6_CC:
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate == CAR.CHEVROLET_MALIBU_CC:
ret.steerActuatorDelay = 0.2
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
elif candidate == CAR.CHEVROLET_TRAX: elif candidate == CAR.CHEVROLET_TRAX:
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning) CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
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
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM ret.safetyConfigs[-1].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 or (candidate in CAMERA_ACC_CAR and ret.enableGasInterceptor): #pedal interceptor tuning if candidate in CC_ONLY_CAR:
ret.flags |= GMFlags.PEDAL_LONG.value ret.flags |= GMFlags.PEDAL_LONG.value
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_PEDAL_LONG ret.safetyConfigs[-1].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
if candidate in (CAR.CHEVROLET_MALIBU_CC, CAR.CHEVROLET_MALIBU_HYBRID_CC): ret.longitudinalTuning.kiBP = [0.0, 5., 35.]
ret.longitudinalTuning.kiBP = [0.0, 5., 35.] ret.longitudinalTuning.kiV = [0.0, 0.35, 0.5]
ret.longitudinalTuning.kiV = [0.0, 0.35, 0.5] ret.longitudinalTuning.kfDEPRECATED = 0.15
ret.longitudinalTuning.kfDEPRECATED = 0.15 ret.stoppingDecelRate = 0.8
ret.stoppingDecelRate = 0.8 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
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
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_HW_CAM_LONG ret.safetyConfigs[-1].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
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: elif candidate in CC_ONLY_CAR:
ret.flags |= GMFlags.CC_LONG.value ret.flags |= GMFlags.CC_LONG.value
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_CC_LONG ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_GM_CC_LONG
ret.radarUnavailable = True ret.radarUnavailable = True
ret.experimentalLongitudinalAvailable = False ret.experimentalLongitudinalAvailable = False
ret.minEnableSpeed = 24 * CV.MPH_TO_MS ret.minEnableSpeed = 24 * CV.MPH_TO_MS
ret.openpilotLongitudinalControl = not frogpilot_toggles.disable_openpilot_long ret.openpilotLongitudinalControl = not frogpilot_toggles.disable_openpilot_long
ret.pcmCruise = False ret.pcmCruise = False
if not ret.enableGasInterceptor and candidate in CC_ONLY_CAR: #redneck tuning ret.stoppingDecelRate = 11.18
if candidate == CAR.CHEVROLET_MALIBU_HYBRID_CC:
pass if candidate not in (CAR.CHEVROLET_BOLT_CC, CAR.CHEVROLET_MALIBU_HYBRID_CC):
else: ret.longitudinalTuning.kpBP = [10.7, 10.8, 28.] # 10.7 m/s == 24 mph
ret.longitudinalTuning.kpBP = [10.7, 10.8, 28.] # 10.7 m/s == 24 mph ret.longitudinalTuning.kpV = [0., 5., 2.] # set lower end to 0 since we can't drive below that speed
ret.longitudinalTuning.kpV = [0., 5., 2.] # set lower end to 0 since we can't drive below that speed ret.longitudinalTuning.deadzoneBP = [0., 1.]
ret.longitudinalTuning.deadzoneBP = [0., 1.] ret.longitudinalTuning.deadzoneV = [0.9, 0.9] # == 2 km/h/s, 1.25 mph/s
ret.longitudinalTuning.deadzoneV = [0.9, 0.9] # == 2 km/h/s, 1.25 mph/s ret.longitudinalActuatorDelay = 1. # TODO: measure this
ret.longitudinalActuatorDelay = 1. # TODO: measure this
if candidate == CAR.CHEVROLET_MALIBU_CC: ret.longitudinalTuning.kpBP = [10.7, 10.8, 28.] # 10.7 m/s == 24 mph
ret.longitudinalTuning.kpV = [0., 20., 20.] ret.longitudinalTuning.kpV = [0., 20., 20.] # set lower end to 0 since we can't drive below that speed
ret.longitudinalTuning.kiBP = [0.] ret.longitudinalTuning.kiBP = [0.]
ret.longitudinalTuning.kiV = [0.1] 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:
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_NO_ACC ret.safetyConfigs[-1].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.get(CanBus.CAMERA, {}) and not candidate in (SDGM_CAR | ASCM_INT): 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 | ASCM_INT):
ret.flags |= GMFlags.NO_CAMERA.value ret.flags |= GMFlags.NO_CAMERA.value
gm_safety_cfg.safetyParam |= Panda.FLAG_GM_NO_CAMERA ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_GM_NO_CAMERA
if ACCELERATOR_POS_MSG not in fingerprint.get(CanBus.POWERTRAIN, {}): if ACCELERATOR_POS_MSG not in fingerprint[CanBus.POWERTRAIN]:
ret.flags |= GMFlags.NO_ACCELERATOR_POS_MSG.value ret.flags |= GMFlags.NO_ACCELERATOR_POS_MSG.value
return ret return ret
@@ -564,11 +407,11 @@ 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 self.CP.networkLocation == NetworkLocation.fwdCamera):
(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)
if ret.vEgo < self.CP.minSteerSpeed: if ret.vEgo < self.CP.minSteerSpeed:
events.add(EventName.belowSteerSpeed) events.add(EventName.belowSteerSpeed)
@@ -578,14 +421,10 @@ 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
+42 -183
View File
@@ -37,108 +37,42 @@ 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 = 6150 # 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
self.BRAKE_SWITCH_MAX = self.ZERO_GAS
kaofui_cars = SDGM_CAR | ASCM_INT | { if CP.carFingerprint in (CAMERA_ACC_CAR | SDGM_CAR) and CP.carFingerprint not in CC_ONLY_CAR and CP.carFingerprint != CAR.CHEVROLET_BOLT_EUV:
CAR.CHEVROLET_VOLT, self.MAX_GAS = 8848
CAR.CHEVROLET_VOLT_2019, self.MAX_GAS_PLUS = 8848
CAR.CHEVROLET_VOLT_ASCM, self.MAX_ACC_REGEN = 5610
CAR.CHEVROLET_VOLT_CAMERA, self.INACTIVE_REGEN = 5650
CAR.CHEVROLET_VOLT_CC, # Camera ACC vehicles have no regen while enabled.
CAR.CHEVROLET_MALIBU_CC, # Camera transitions to MAX_ACC_REGEN from ZERO_GAS and uses friction brakes instantly
CAR.CHEVROLET_MALIBU_HYBRID_CC, self.max_regen_acceleration = 0.
}
volt_like = {
CAR.CHEVROLET_VOLT,
CAR.CHEVROLET_VOLT_ASCM,
CAR.CHEVROLET_VOLT_CAMERA,
CAR.CHEVROLET_VOLT_CC,
}
if CP.carFingerprint in kaofui_cars:
if (CP.carFingerprint in (CAMERA_ACC_CAR | SDGM_CAR) and
CP.carFingerprint not in CC_ONLY_CAR and
CP.carFingerprint != CAR.CHEVROLET_BOLT_ACC_2022_2023):
self.MAX_GAS = 8848
self.MAX_GAS_PLUS = 8848
self.MAX_ACC_REGEN = 5610
self.INACTIVE_REGEN = 5650
# Camera ACC vehicles have no regen while enabled.
# Camera transitions to MAX_ACC_REGEN from ZERO_GAS and uses friction brakes instantly
max_regen_acceleration = 0.
else:
self.MAX_GAS = 8191 # Safety limit, not ACC max. Stock ACC >8192 from standstill.
self.MAX_GAS_PLUS = 8191
self.MAX_ACC_REGEN = 5500 # Max ACC regen is slightly less than max paddle regen
self.INACTIVE_REGEN = 5500
# ICE has much less engine braking force compared to regen in EVs,
# lower threshold removes some braking deadzone
max_regen_acceleration = -1. if CP.carFingerprint in EV_CAR else -0.1
self.BRAKE_SWITCH_MAX = self.MAX_ACC_REGEN if CP.carFingerprint in EV_CAR else self.ZERO_GAS
if CP.carFingerprint in volt_like:
self.BRAKE_LOOKUP_BP = [self.ACCEL_MIN, 0.]
else:
self.BRAKE_LOOKUP_BP = [self.ACCEL_MIN, max_regen_acceleration]
else: else:
if CP.carFingerprint in CAMERA_ACC_CAR and CP.carFingerprint not in CC_ONLY_CAR: self.MAX_GAS = 8191 # Safety limit, not ACC max. Stock ACC >8192 from standstill.
self.MAX_GAS = 8848 self.MAX_GAS_PLUS = 8191
self.MAX_GAS_PLUS = 8848 self.MAX_ACC_REGEN = 5500 # Max ACC regen is slightly less than max paddle regen
self.MAX_ACC_REGEN = 5610 self.INACTIVE_REGEN = 5500
self.INACTIVE_REGEN = 5650 # ICE has much less engine braking force compared to regen in EVs,
# Camera ACC vehicles have no regen while enabled. # lower threshold removes some braking deadzone
# Camera transitions to MAX_ACC_REGEN from ZERO_GAS and uses friction brakes instantly self.max_regen_acceleration = -1. if CP.carFingerprint in EV_CAR else -0.1
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
if CP.carFingerprint in (CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_ASCM, CAR.CHEVROLET_VOLT_CAMERA, CAR.CHEVROLET_VOLT_CC):
self.ZERO_GAS = 6150
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.BRAKE_LOOKUP_BP = [self.ACCEL_MIN, 0.]
else:
self.BRAKE_LOOKUP_BP = [self.ACCEL_MIN, self.max_regen_acceleration]
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_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_BP = [0.5, 10]
self.BRAKE_SWITCH_LOOKUP_V = [self.ZERO_GAS, self.BRAKE_SWITCH_MAX] self.BRAKE_SWITCH_LOOKUP_V = [self.ZERO_GAS, self.BRAKE_SWITCH_MAX]
@@ -179,8 +113,7 @@ class GMPlatformConfig(PlatformConfig):
@dataclass @dataclass
class GMASCMPlatformConfig(GMPlatformConfig): class GMASCMPlatformConfig(GMPlatformConfig):
def init(self): def init(self):
# ASCM is supported, but due to a janky install and hardware configuration, we are not showing in the car docs pass
self.car_docs = []
class CAR(Platforms): class CAR(Platforms):
@@ -244,10 +177,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_ACC_2022_2023 = GMPlatformConfig( CHEVROLET_BOLT_EUV = GMPlatformConfig(
[ [
GMCarDocs("Chevrolet Bolt ACC 2022-2023", "Premier or Premier Redline Trim without Super Cruise Package", video_link="https://youtu.be/xvwzGMUA210"), GMCarDocs("Chevrolet Bolt EUV 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", video_link="https://youtu.be/xvwzGMUA210"),
GMCarDocs("Chevrolet Bolt EV ACC 2022-2023", "2LT Trim with Adaptive Cruise Control Package"), GMCarDocs("Chevrolet Bolt EV 2022-23", "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),
) )
@@ -256,7 +189,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=2994, wheelbase=3.75, steerRatio=16.3, tireStiffnessFactor=1.0), GMCarSpecs(mass=2450, 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")],
@@ -272,26 +205,12 @@ 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_2019_2021 = GMPlatformConfig( CHEVROLET_BOLT_CC = 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 EV 2022-2023 ACC w Pedal"), GMCarDocs("Chevrolet Bolt EUV 2022-23 - No-ACC"),
GMCarDocs("Chevrolet Bolt EV 2017-23 - No-ACC"),
], ],
CHEVROLET_BOLT_ACC_2022_2023.specs, CHEVROLET_BOLT_EUV.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")],
@@ -343,7 +262,7 @@ class CAR(Platforms):
) )
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), CarSpecs(mass=1450, wheelbase=2.8, steerRatio=15.8, centerToFrontRatio=0.4),
) )
CHEVROLET_MALIBU_HYBRID_CC = GMPlatformConfig( CHEVROLET_MALIBU_HYBRID_CC = GMPlatformConfig(
[GMCarDocs("Chevrolet Malibu Hybrid 2017 - No-ACC")], [GMCarDocs("Chevrolet Malibu Hybrid 2017 - No-ACC")],
@@ -378,28 +297,12 @@ class AccState:
STANDSTILL = 4 STANDSTILL = 4
class CanBus: class CanBus:
POWERTRAIN = 0 POWERTRAIN = 4
OBSTACLE = 1 OBSTACLE = 5
CAMERA = 2 CAMERA = 6
CHASSIS = 2 CHASSIS = 6
LOOPBACK = 128 LOOPBACK = 132
DROPPED = 192 DROPPED = 196
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
@@ -459,40 +362,9 @@ FW_QUERY_CONFIG = FwQueryConfig(
extra_ecus=[(Ecu.fwdCamera, 0x24b, None)], extra_ecus=[(Ecu.fwdCamera, 0x24b, None)],
) )
EV_CAR = { EV_CAR = {CAR.CHEVROLET_VOLT, CAR.CHEVROLET_VOLT_2019, CAR.CHEVROLET_BOLT_EUV, CAR.CHEVROLET_VOLT_CC, CAR.CHEVROLET_VOLT_CAMERA, CAR.CHEVROLET_BOLT_CC, CAR.CHEVROLET_VOLT_ASCM, CAR.CHEVROLET_MALIBU_HYBRID_CC}
CAR.CHEVROLET_VOLT, 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_MALIBU_HYBRID_CC}
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.CADILLAC_XT6, CAR.CHEVROLET_TRAVERSE, CAR.CHEVROLET_BLAZER, CAR.CHEVROLET_MALIBU_SDGM, CAR.BUICK_BABYENCLAVE, CAR.CHEVROLET_VOLT_2019} 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}
@@ -500,21 +372,8 @@ SDGM_CAR = {CAR.CADILLAC_XT4, CAR.CADILLAC_XT6, CAR.CHEVROLET_TRAVERSE, CAR.CHEV
ASCM_INT = {CAR.CHEVROLET_VOLT_ASCM, CAR.GMC_ACADIA_ASCM, CAR.CHEVROLET_MALIBU_ASCM} 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_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 = {CAR.CHEVROLET_BOLT_EUV, CAR.CHEVROLET_SILVERADO, CAR.CHEVROLET_EQUINOX, CAR.CHEVROLET_TRAILBLAZER, CAR.CHEVROLET_TRAX, CAR.CHEVROLET_VOLT_CAMERA, CAR.CHEVROLET_BLAZER}
CAMERA_ACC_CAR.update({ 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, CAR.CHEVROLET_MALIBU_HYBRID_CC})
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 = float(self.speed) new_actuators.speed = self.speed
new_actuators.accel = float(self.accel) new_actuators.accel = self.accel
new_actuators.gas = float(self.gas) new_actuators.gas = self.gas
new_actuators.brake = float(self.brake) new_actuators.brake = self.brake
new_actuators.steer = float(self.last_steer) new_actuators.steer = 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, gas_force): def create_acc_commands(packer, CAN, enabled, active, accel, gas, stopping_counter, car_fingerprint):
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 gas_force > min_gas_accel else -30000 gas_command = gas if active and accel > min_gas_accel else -30000
accel_command = accel if active else 0 accel_command = accel if active else 0
braking = 1 if active and gas_force < min_gas_accel else 0 braking = 1 if active and accel < 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
+4 -7
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,9 +117,6 @@ 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
+3 -3
View File
@@ -37,12 +37,12 @@ EventName = car.CarEvent.EventName
MAX_CTRL_SPEED = (V_CRUISE_MAX + 4) * CV.KPH_TO_MS MAX_CTRL_SPEED = (V_CRUISE_MAX + 4) * CV.KPH_TO_MS
ACCEL_MAX = 2.0 ACCEL_MAX = 2.0
ACCEL_MIN = -3.5 ACCEL_MIN = -3.5
FRICTION_THRESHOLD = 0.12 FRICTION_THRESHOLD = 0.09
def get_friction_threshold(v_ego): def get_friction_threshold(v_ego):
# Interpolate friction threshold # Interpolate friction threshold from 0.09 at 50 mph to 0.15 at 75 mph
from openpilot.common.numpy_fast import interp from openpilot.common.numpy_fast import interp
return interp(v_ego, [1 * CV.MPH_TO_MS, 75 * CV.MPH_TO_MS], [0.12, 0.3]) return interp(v_ego, [1 * CV.MPH_TO_MS, 75 * CV.MPH_TO_MS], [0.12, 0.25])
TORQUE_PARAMS_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/params.toml') TORQUE_PARAMS_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/params.toml')
TORQUE_OVERRIDE_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/override.toml') TORQUE_OVERRIDE_PATH = os.path.join(BASEDIR, 'selfdrive/car/torque_data/override.toml')
+2 -3
View File
@@ -44,10 +44,9 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
"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]
"CADILLAC_XT6" = [1.33, 1.9, 0.16] "CADILLAC_XT6" = [1.33, 1.9, 0.16]
"CHEVROLET_BOLT_ACC_2022_2023" = [2.0, 2.0, 0.09] "CHEVROLET_BOLT_EUV" = [1.0, 2.0, 0.175]
"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_BLAZER" = [1.33, 1.33, 0.18]
"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]
"CHEVROLET_EQUINOX" = [2.5, 2.5, 0.05] "CHEVROLET_EQUINOX" = [2.5, 2.5, 0.05]
+2 -5
View File
@@ -58,16 +58,14 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
"CHEVROLET_MALIBU" = "CHEVROLET_VOLT" "CHEVROLET_MALIBU" = "CHEVROLET_VOLT"
"CHEVROLET_MALIBU_ASCM" = "CHEVROLET_VOLT" "CHEVROLET_MALIBU_ASCM" = "CHEVROLET_VOLT"
"CHEVROLET_MALIBU_SDGM" = "CHEVROLET_VOLT" "CHEVROLET_MALIBU_SDGM" = "CHEVROLET_VOLT"
"CHEVROLET_MALIBU_CC" = "CHEVROLET_VOLT"
"HOLDEN_ASTRA" = "CHEVROLET_VOLT" "HOLDEN_ASTRA" = "CHEVROLET_VOLT"
"CHEVROLET_VOLT_CC" = "CHEVROLET_VOLT" "CHEVROLET_VOLT_CC" = "CHEVROLET_VOLT"
"CHEVROLET_VOLT_CAMERA" = "CHEVROLET_VOLT" "CHEVROLET_VOLT_CAMERA" = "CHEVROLET_VOLT"
"CHEVROLET_VOLT_ASCM" = "CHEVROLET_VOLT" "CHEVROLET_VOLT_ASCM" = "CHEVROLET_VOLT"
"GMC_ACADIA_ASCM" = "GMC_ACADIA" "GMC_ACADIA_ASCM" = "GMC_ACADIA"
"CHEVROLET_VOLT_2019" = "CHEVROLET_VOLT" "CHEVROLET_VOLT_2019" = "CHEVROLET_VOLT"
"CHEVROLET_BOLT_CC_2019_2021" = "CHEVROLET_BOLT_ACC_2022_2023" "CHEVROLET_BOLT_CC" = "CHEVROLET_BOLT_EUV"
"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"
@@ -75,7 +73,6 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
"CHEVROLET_TRAX" = "CHEVROLET_VOLT" "CHEVROLET_TRAX" = "CHEVROLET_VOLT"
"CADILLAC_CT6_CC" = "CHEVROLET_VOLT" "CADILLAC_CT6_CC" = "CHEVROLET_VOLT"
"CADILLAC_XT5_CC" = "GMC_ACADIA" "CADILLAC_XT5_CC" = "GMC_ACADIA"
"SKODA_FABIA_MK4" = "VOLKSWAGEN_GOLF_MK7" "SKODA_FABIA_MK4" = "VOLKSWAGEN_GOLF_MK7"
"SKODA_OCTAVIA_MK3" = "SKODA_SUPERB_MK3" "SKODA_OCTAVIA_MK3" = "SKODA_SUPERB_MK3"
"SKODA_KODIAQ_MK1" = "SKODA_SUPERB_MK3" "SKODA_KODIAQ_MK1" = "SKODA_SUPERB_MK3"
+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) 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.frogpilot_AM = AlertManager() self.frogpilot_AM = AlertManager()
self.frogpilot_events = Events(frogpilot=True) self.frogpilot_events = Events(frogpilot=True)
+4 -4
View File
@@ -357,8 +357,8 @@ def forcing_stop_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMas
def holiday_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, frogpilot_toggles: SimpleNamespace) -> Alert: def holiday_alert(CP: car.CarParams, CS: car.CarState, sm: messaging.SubMaster, metric: bool, soft_disable_time: int, frogpilot_toggles: SimpleNamespace) -> Alert:
holiday_messages = { holiday_messages = {
"new_years": "Happy New Year! 🎉", "new_years": "Happy New Year! 🎉",
"valentines_day": "Happy Valentine's Day! ❤️", "valentines": "Happy Valentine's Day! ❤️",
"st_patricks_day": "Happy St. Patrick's Day! 🍀", "st_patricks": "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, "Happy Holidays!"), holiday_messages.get(frogpilot_toggles.current_holiday_theme),
"", "",
AlertStatus.normal, AlertSize.small, AlertStatus.normal, AlertSize.small,
Priority.LOWEST, VisualAlert.none, FrogPilotAudibleAlert.startup, 5.) Priority.LOWEST, VisualAlert.none, FrogPilotAudibleAlert.startup, 5.)
@@ -982,7 +982,7 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = {
"", "",
AlertStatus.normal, AlertSize.full, AlertStatus.normal, AlertSize.full,
Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2, creation_delay=0.5), Priority.LOWEST, VisualAlert.none, AudibleAlert.none, .2, creation_delay=0.5),
ET.USER_DISABLE: ImmediateDisableAlert("Wrong Gear"), ET.USER_DISABLE: ImmediateDisableAlert("Reverse Gear"),
ET.NO_ENTRY: NoEntryAlert("Reverse Gear"), ET.NO_ENTRY: NoEntryAlert("Reverse Gear"),
}, },
+3 -53
View File
@@ -7,7 +7,6 @@ from openpilot.selfdrive.car.interfaces import FRICTION_THRESHOLD, get_friction_
from openpilot.selfdrive.controls.lib.drive_helpers import MIN_SPEED, get_friction from openpilot.selfdrive.controls.lib.drive_helpers import MIN_SPEED, get_friction
from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.filter_simple import FirstOrderFilter
from openpilot.selfdrive.controls.lib.latcontrol import LatControl, MIN_LATERAL_CONTROL_SPEED from openpilot.selfdrive.controls.lib.latcontrol import LatControl, MIN_LATERAL_CONTROL_SPEED
from openpilot.selfdrive.car.gm.values import CAR as GM_CAR
from openpilot.selfdrive.controls.lib.pid import PIDController from openpilot.selfdrive.controls.lib.pid import PIDController
from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY
@@ -22,8 +21,8 @@ from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_G
# Additionally, there is friction in the steering wheel that needs # Additionally, there is friction in the steering wheel that needs
# to be overcome to move it at all, this is compensated for too. # to be overcome to move it at all, this is compensated for too.
KP = 0.7 KP = 0.6
KI = 0.35 KI = 0.3
INTERP_SPEEDS = [1, 1.5, 2.0, 3.0, 5, 7.5, 10, 15, 30] INTERP_SPEEDS = [1, 1.5, 2.0, 3.0, 5, 7.5, 10, 15, 30]
KP_INTERP = [250, 120, 65, 30, 11.5, 5.5, 3.5, 2.0, KP] KP_INTERP = [250, 120, 65, 30, 11.5, 5.5, 3.5, 2.0, KP]
@@ -37,17 +36,6 @@ JERK_LOOKAHEAD_SECONDS = 0.19
JERK_GAIN = 0.22 JERK_GAIN = 0.22
LAT_ACCEL_REQUEST_BUFFER_SECONDS = 1.0 LAT_ACCEL_REQUEST_BUFFER_SECONDS = 1.0
VERSION = 2 VERSION = 2
DEBUG_TORQUE_TUNE = False
FF_SCALE_BLEND_LAT_ACCEL = 0.05
DEADZONE_BOOST_LAT_ACCEL = 0.08
UNWIND_D_DES_THRESHOLD = -1.0
UNWIND_LAT_ACCEL_NEAR_ZERO = 0.3
BOLT_CARS = (
GM_CAR.CHEVROLET_BOLT_ACC_2022_2023,
GM_CAR.CHEVROLET_BOLT_CC_2022_2023,
GM_CAR.CHEVROLET_BOLT_CC_2019_2021,
)
class LatControlTorque(LatControl): class LatControlTorque(LatControl):
def __init__(self, CP, CI, dt): def __init__(self, CP, CI, dt):
@@ -67,21 +55,6 @@ class LatControlTorque(LatControl):
self.previous_measurement = 0.0 self.previous_measurement = 0.0
self.measurement_rate_filter = FirstOrderFilter(0.0, 1 / (2 * np.pi * (MAX_LAT_JERK_UP - 0.5)), self.dt) self.measurement_rate_filter = FirstOrderFilter(0.0, 1 / (2 * np.pi * (MAX_LAT_JERK_UP - 0.5)), self.dt)
self.low_speed_reset_threshold = max(CP.minSteerSpeed, MIN_LATERAL_CONTROL_SPEED) self.low_speed_reset_threshold = max(CP.minSteerSpeed, MIN_LATERAL_CONTROL_SPEED)
self.debug_counter = 0
self.prev_desired_lateral_accel = 0.0
self.is_bolt = CP.carFingerprint in BOLT_CARS
self.torque_ff_scale_pos = 1.0
self.torque_ff_scale_neg = 1.0
self.torque_deadzone_boost_neg = 0.0
self.torque_ki_mult = 1.0
if self.is_bolt:
self.torque_ff_scale_pos = float(self.torque_params.kp)
self.torque_ff_scale_neg = float(self.torque_params.ki)
self.torque_ki_mult = float(self.torque_params.kd)
self.torque_deadzone_boost_neg = float(getattr(self.torque_params, "kfDEPRECATED", 0.0))
if self.torque_ki_mult > 0.0 and self.torque_ki_mult != 1.0:
self.pid._k_i = [self.pid._k_i[0], [k * self.torque_ki_mult for k in self.pid._k_i[1]]]
def update_live_torque_params(self, latAccelFactor, latAccelOffset, friction): def update_live_torque_params(self, latAccelFactor, latAccelOffset, friction):
self.torque_params.latAccelFactor = latAccelFactor self.torque_params.latAccelFactor = latAccelFactor
@@ -103,7 +76,6 @@ class LatControlTorque(LatControl):
self.previous_measurement = 0.0 self.previous_measurement = 0.0
self.measurement_rate_filter.x = 0.0 self.measurement_rate_filter.x = 0.0
self.lat_accel_request_buffer = deque([0.] * self.lat_accel_request_buffer_len , maxlen=self.lat_accel_request_buffer_len) self.lat_accel_request_buffer = deque([0.] * self.lat_accel_request_buffer_len , maxlen=self.lat_accel_request_buffer_len)
self.prev_desired_lateral_accel = 0.0
else: else:
if self.prev_steering_pressed and not CS.steeringPressed: if self.prev_steering_pressed and not CS.steeringPressed:
self.pid.i *= self.steer_release_i_decay self.pid.i *= self.steer_release_i_decay
@@ -122,10 +94,6 @@ class LatControlTorque(LatControl):
desired_lateral_jerk = np.clip(self.jerk_filter.update(raw_lateral_jerk), -MAX_LAT_JERK_UP, MAX_LAT_JERK_UP) desired_lateral_jerk = np.clip(self.jerk_filter.update(raw_lateral_jerk), -MAX_LAT_JERK_UP, MAX_LAT_JERK_UP)
gravity_adjusted_future_lateral_accel = future_desired_lateral_accel - roll_compensation gravity_adjusted_future_lateral_accel = future_desired_lateral_accel - roll_compensation
setpoint = expected_lateral_accel + desired_lateral_jerk * lat_delay setpoint = expected_lateral_accel + desired_lateral_jerk * lat_delay
desired_lateral_accel_rate = (setpoint - self.prev_desired_lateral_accel) / self.dt
unwind_detected = (desired_lateral_accel_rate < UNWIND_D_DES_THRESHOLD and
abs(setpoint) < UNWIND_LAT_ACCEL_NEAR_ZERO)
self.prev_desired_lateral_accel = setpoint
measurement = measured_curvature * CS.vEgo ** 2 measurement = measured_curvature * CS.vEgo ** 2
measurement_rate = self.measurement_rate_filter.update((measurement - self.previous_measurement) / self.dt) measurement_rate = self.measurement_rate_filter.update((measurement - self.previous_measurement) / self.dt)
@@ -142,23 +110,11 @@ class LatControlTorque(LatControl):
ff = gravity_adjusted_future_lateral_accel ff = gravity_adjusted_future_lateral_accel
# latAccelOffset corrects roll compensation bias from device roll misalignment relative to car roll # latAccelOffset corrects roll compensation bias from device roll misalignment relative to car roll
ff -= self.torque_params.latAccelOffset ff -= self.torque_params.latAccelOffset
ff_scale = 1.0
if self.is_bolt:
ff_scale = np.interp(ff, [-FF_SCALE_BLEND_LAT_ACCEL, 0.0, FF_SCALE_BLEND_LAT_ACCEL],
[self.torque_ff_scale_neg, 1.0, self.torque_ff_scale_pos])
ff *= ff_scale
ff += get_friction(error_with_lsf + JERK_GAIN * desired_lateral_jerk, lateral_accel_deadzone, get_friction_threshold(CS.vEgo), self.torque_params) ff += get_friction(error_with_lsf + JERK_GAIN * desired_lateral_jerk, lateral_accel_deadzone, get_friction_threshold(CS.vEgo), self.torque_params)
deadzone_boost_active = False
if self.is_bolt and self.torque_deadzone_boost_neg > 0.0 and gravity_adjusted_future_lateral_accel < 0.0:
if abs(gravity_adjusted_future_lateral_accel) < DEADZONE_BOOST_LAT_ACCEL:
boost_scale = np.interp(abs(gravity_adjusted_future_lateral_accel), [0.0, DEADZONE_BOOST_LAT_ACCEL], [1.0, 0.0])
ff -= self.torque_deadzone_boost_neg * boost_scale
deadzone_boost_active = True
if CS.vEgo < self.low_speed_reset_threshold: if CS.vEgo < self.low_speed_reset_threshold:
self.pid.reset() self.pid.reset()
freeze_integrator = (steer_limited_by_safety or CS.steeringPressed or freeze_integrator = steer_limited_by_safety or CS.steeringPressed or CS.vEgo < self.low_speed_reset_threshold
CS.vEgo < self.low_speed_reset_threshold or unwind_detected)
output_lataccel = self.pid.update(pid_log.error, error_rate=-measurement_rate, speed=CS.vEgo, feedforward=ff, freeze_integrator=freeze_integrator) output_lataccel = self.pid.update(pid_log.error, error_rate=-measurement_rate, speed=CS.vEgo, feedforward=ff, freeze_integrator=freeze_integrator)
output_torque = self.torque_from_lateral_accel(output_lataccel, self.torque_params) output_torque = self.torque_from_lateral_accel(output_lataccel, self.torque_params)
@@ -173,12 +129,6 @@ class LatControlTorque(LatControl):
pid_log.desiredLateralJerk = float(desired_lateral_jerk) pid_log.desiredLateralJerk = float(desired_lateral_jerk)
pid_log.saturated = bool(self._check_saturation(self.steer_max - abs(output_torque) < 1e-3, CS, steer_limited_by_safety, curvature_limited)) pid_log.saturated = bool(self._check_saturation(self.steer_max - abs(output_torque) < 1e-3, CS, steer_limited_by_safety, curvature_limited))
if DEBUG_TORQUE_TUNE and self.is_bolt:
self.debug_counter += 1
if self.debug_counter % 50 == 0:
print(f"bolt_torque ff_scale={ff_scale:.3f} pos={self.torque_ff_scale_pos:.3f} "
f"neg={self.torque_ff_scale_neg:.3f} deadzone_boost_active={deadzone_boost_active}")
self.prev_steering_pressed = CS.steeringPressed self.prev_steering_pressed = CS.steeringPressed
# TODO left is positive in this convention # TODO left is positive in this convention
@@ -17,9 +17,9 @@ from openpilot.selfdrive.controls.lib.drive_helpers import V_CRUISE_UNSET, CONTR
from openpilot.common.swaglog import cloudlog from openpilot.common.swaglog import cloudlog
LON_MPC_STEP = 0.2 # first step is 0.2s LON_MPC_STEP = 0.2 # first step is 0.2s
A_CRUISE_MIN = -1.0 A_CRUISE_MIN = -1.2
A_CRUISE_MAX_BP = [0.0, 5., 10., 15., 20., 25., 40.] A_CRUISE_MAX_VALS = [1.6, 1.2, 0.8, 0.6]
A_CRUISE_MAX_VALS = [1.125, 1.125, 1.125, 1.125, 1.25, 1.25, 1.5] A_CRUISE_MAX_BP = [0., 10.0, 25., 40.]
CONTROL_N_T_IDX = ModelConstants.T_IDXS[:CONTROL_N] CONTROL_N_T_IDX = ModelConstants.T_IDXS[:CONTROL_N]
ALLOW_THROTTLE_THRESHOLD = 0.5 ALLOW_THROTTLE_THRESHOLD = 0.5
MIN_ALLOW_THROTTLE_SPEED = 2.5 MIN_ALLOW_THROTTLE_SPEED = 2.5
+1 -1
View File
@@ -118,7 +118,7 @@ std::optional<std::string> Panda::get_serial() {
bool Panda::up_to_date() { bool Panda::up_to_date() {
if (auto fw_sig = get_firmware_version()) { if (auto fw_sig = get_firmware_version()) {
for (auto fn : { "panda.bin.signed", "panda_h7.bin.signed", "panda_remote.bin.signed", "panda_h7_remote.bin.signed" }) { for (auto fn : { "panda.bin.signed", "panda_h7.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.
+6 -24
View File
@@ -13,25 +13,15 @@ from openpilot.system.hardware import HARDWARE
from openpilot.common.swaglog import cloudlog from openpilot.common.swaglog import cloudlog
def get_expected_firmware_path(panda: Panda, remote_start: bool) -> str: def get_expected_signature(panda: Panda) -> bytes:
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 = get_expected_firmware_path(panda, remote_start) fn = os.path.join(FW_PATH, panda.get_mcu_type().config.app_fn)
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, remote_start: bool) -> Panda: def flash_panda(panda_serial: str) -> Panda:
try: try:
panda = Panda(panda_serial) panda = Panda(panda_serial)
except PandaProtocolMismatch: except PandaProtocolMismatch:
@@ -39,8 +29,7 @@ def flash_panda(panda_serial: str, remote_start: bool) -> Panda:
HARDWARE.recover_internal_panda() HARDWARE.recover_internal_panda()
raise raise
fw_path = get_expected_firmware_path(panda, remote_start) fw_signature = get_expected_signature(panda)
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()
@@ -49,7 +38,7 @@ def flash_panda(panda_serial: str, remote_start: bool) -> 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(fn=fw_path) panda.flash()
cloudlog.info("Done flashing") cloudlog.info("Done flashing")
if panda.bootstub: if panda.bootstub:
@@ -116,9 +105,8 @@ 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, remote_start)) pandas.append(flash_panda(serial))
# 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()]
@@ -170,12 +158,6 @@ 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,7 +2,6 @@
#include <QHBoxLayout> #include <QHBoxLayout>
#include <QMouseEvent> #include <QMouseEvent>
#include <QSet>
#include <QStackedWidget> #include <QStackedWidget>
#include <QVBoxLayout> #include <QVBoxLayout>
@@ -173,22 +172,6 @@ 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();
@@ -285,21 +268,10 @@ 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,7 +41,6 @@ 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,14 +2134,6 @@
<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,30 +3364,6 @@ 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>
@@ -3846,22 +3814,6 @@ 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>
@@ -3870,10 +3822,6 @@ 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>
@@ -4808,10 +4756,6 @@ 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,14 +2136,6 @@
<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>
@@ -3376,30 +3368,6 @@ 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>
@@ -3850,22 +3818,6 @@ 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>
@@ -3874,10 +3826,6 @@ 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>
@@ -4810,10 +4758,6 @@ 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,14 +2134,6 @@
<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,30 +3364,6 @@ 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>
@@ -3846,22 +3814,6 @@ 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>
@@ -3870,10 +3822,6 @@ 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>
@@ -4804,10 +4752,6 @@ 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,14 +2136,6 @@
<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>
@@ -3374,30 +3366,6 @@ 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>
@@ -3848,22 +3816,6 @@ 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>
@@ -3872,10 +3824,6 @@ 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>
@@ -4806,10 +4754,6 @@ 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,14 +2134,6 @@
<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>
@@ -3371,30 +3363,6 @@ 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>
@@ -3845,22 +3813,6 @@ 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>
@@ -3869,10 +3821,6 @@ 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>
@@ -4803,10 +4751,6 @@ 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,14 +2134,6 @@
<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>
@@ -3371,30 +3363,6 @@ 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>
@@ -3845,22 +3813,6 @@ 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>
@@ -3869,10 +3821,6 @@ 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>
@@ -4803,10 +4751,6 @@ 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,14 +2134,6 @@
<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,30 +3364,6 @@ 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>
@@ -3846,22 +3814,6 @@ 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>
@@ -3870,10 +3822,6 @@ 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>
@@ -4804,10 +4752,6 @@ 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,14 +2134,6 @@
<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>
@@ -3370,30 +3362,6 @@ 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>
@@ -3844,22 +3812,6 @@ 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>
@@ -3868,10 +3820,6 @@ 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>
@@ -4801,10 +4749,6 @@ 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,14 +2134,6 @@
<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>
@@ -3371,30 +3363,6 @@ 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>
@@ -3845,22 +3813,6 @@ 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>
@@ -3869,10 +3821,6 @@ 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>
@@ -4802,10 +4750,6 @@ 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,14 +2134,6 @@
<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,30 +3364,6 @@ 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>
@@ -3846,22 +3814,6 @@ 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>
@@ -3870,10 +3822,6 @@ 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>
@@ -4804,10 +4752,6 @@ 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,14 +2134,6 @@
<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,30 +3364,6 @@ 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>
@@ -3846,22 +3814,6 @@ 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>
@@ -3870,10 +3822,6 @@ 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>
@@ -4804,10 +4752,6 @@ 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,14 +2140,6 @@
<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>
@@ -3380,30 +3372,6 @@ 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>
@@ -3856,22 +3824,6 @@ 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>
@@ -3880,10 +3832,6 @@ 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>
@@ -4816,10 +4764,6 @@ 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,14 +2134,6 @@
<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,30 +3364,6 @@ 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>
@@ -3846,22 +3814,6 @@ 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>
@@ -3870,10 +3822,6 @@ 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>
@@ -4803,10 +4751,6 @@ 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,14 +2134,6 @@
<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>
@@ -3371,30 +3363,6 @@ 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>
@@ -3845,22 +3813,6 @@ 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>
@@ -3869,10 +3821,6 @@ 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>
@@ -4802,10 +4750,6 @@ 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,14 +2134,6 @@
<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,30 +3364,6 @@ 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>
@@ -3846,22 +3814,6 @@ 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>
@@ -3870,10 +3822,6 @@ 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>
@@ -4803,10 +4751,6 @@ 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,14 +2134,6 @@
<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,30 +3364,6 @@ 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>
@@ -3846,22 +3814,6 @@ 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>
@@ -3870,10 +3822,6 @@ 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>
@@ -4803,10 +4751,6 @@ 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.
+10 -59
View File
@@ -92,65 +92,6 @@ 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):
@@ -203,6 +144,16 @@ def manager_init() -> None:
with open(nnfflite_migration_flag_file, "w") as f: with open(nnfflite_migration_flag_file, "w") as f:
f.write("migrated") f.write("migrated")
# One-time migration to force NNFF + NNFFLite off
nnff_reset_flag_file = "/data/media/0/frogpilot_nnff_reset.flag"
if not os.path.exists(nnff_reset_flag_file):
if params.get_bool("NNFF"):
params.put_bool("NNFF", False)
if params.get_bool("NNFFLite"):
params.put_bool("NNFFLite", False)
with open(nnff_reset_flag_file, "w") as f:
f.write("reset")
# One-time migration for CEM settings # One-time migration for CEM settings
cem_migration_flag_file = "/data/media/0/frogpilot_cem_migrated.flag" cem_migration_flag_file = "/data/media/0/frogpilot_cem_migrated.flag"
if not os.path.exists(cem_migration_flag_file): if not os.path.exists(cem_migration_flag_file):
-39
View File
@@ -36,19 +36,6 @@ 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
@@ -293,7 +280,6 @@ 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:
@@ -306,31 +292,6 @@ 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"))