diff --git a/frogpilot.diff b/frogpilot.diff
new file mode 100644
index 0000000..c5a5172
--- /dev/null
+++ b/frogpilot.diff
@@ -0,0 +1,17119 @@
+Only in FrogPilot/body: Dockerfile
+Only in FrogPilot/body/.github/workflows: test.yaml
+Only in FrogPilot/body: LICENSE
+Only in FrogPilot/body: .pre-commit-config.yaml
+Only in FrogPilot/body: pyproject.toml
+Only in FrogPilot/body: README.md
+Only in FrogPilot/body: requirements.txt
+Only in FrogPilot/body: SConstruct
+Only in FrogPilot/body/STL: device_holder.stl
+Only in FrogPilot/body/STL: training_stand.stl
+Only in clearpilot/: clearpiliot_devqueue.txt
+Only in clearpilot/: clearpilot_design.txt
+Only in clearpilot/: clearpilot_notes.txt
+Only in clearpilot/: clearpilot_settings.txt
+Only in clearpilot/: clearpilot_testme.txt
+Only in clearpilot/: commit_and_push
+diff -r clearpilot/common/params.cc FrogPilot/common/params.cc
+231a232
+> {"CameraViewReset", PERSISTENT},
+276d276
+< {"DoSoftReboot", CLEAR_ON_MANAGER_START},
+279a280
+> {"EcoGearOn", PERSISTENT},
+436a438
+> {"SportGearOn", PERSISTENT},
+diff -r clearpilot/common/realtime.py FrogPilot/common/realtime.py
+37,40c37
+< try: # CLEARPILOT ....
+< os.sched_setaffinity(0, cores)
+< except:
+< nothing=0
+---
+> os.sched_setaffinity(0, cores)
+Only in FrogPilot/docs/assets: icon-star-empty.svg
+Only in FrogPilot/docs/assets: icon-star-full.svg
+Only in FrogPilot/docs/assets: icon-star-half.svg
+Only in FrogPilot/docs/assets: icon-youtube.svg
+Only in FrogPilot/docs: BOUNTIES.md
+diff -r clearpilot/docs/CARS.md FrogPilot/docs/CARS.md
+7c7
+< # 279 Supported Cars
+---
+> # 289 Supported Cars
+38c38
+< |Ford|Bronco Sport 2021-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+---
+> |Ford|Bronco Sport 2021-23|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+39a40,41
+> |Ford|Escape Hybrid 2020-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+> |Ford|Escape Plug-in Hybrid 2020-22|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+40a43
+> |Ford|Explorer Hybrid 2020-23|Co-Pilot360 Assist+|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+41a45
+> |Ford|Focus Hybrid 2018[3](#footnotes)|Adaptive Cruise Control with Lane Centering|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+42a47,48
+> |Ford|Kuga Hybrid 2020-22|Adaptive Cruise Control with Lane Centering|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+> |Ford|Kuga Plug-in Hybrid 2020-22|Adaptive Cruise Control with Lane Centering|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+44c50,52
+< |Ford|Maverick 2023|Co-Pilot360 Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+---
+> |Ford|Maverick 2023-24|Co-Pilot360 Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+> |Ford|Maverick Hybrid 2022|LARIAT Luxury|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+> |Ford|Maverick Hybrid 2023-24|Co-Pilot360 Assist|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 angled mount (8 degrees)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+46c54
+< |Genesis|G70 2020|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+---
+> |Genesis|G70 2020-23|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+49c57
+< |Genesis|G90 2017-18|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai C connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+---
+> |Genesis|G90 2017-20|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai C connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+105c113
+< |Hyundai|Santa Cruz 2022-23[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+---
+> |Hyundai|Santa Cruz 2022-24[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+137a146
+> |Kia|Niro Hybrid 2018|All|Stock|10 mph|32 mph|[](##)|[](##)|Parts
- 1 Hyundai C connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+142,144c151,153
+< |Kia|Niro Plug-in Hybrid 2020|All|Stock|0 mph|32 mph|[](##)|[](##)|Parts
- 1 Hyundai D connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+< |Kia|Niro Plug-in Hybrid 2021|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai D connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+< |Kia|Niro Plug-in Hybrid 2022|All|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+---
+> |Kia|Niro Plug-in Hybrid 2020|Smart Cruise Control (SCC)|Stock|0 mph|32 mph|[](##)|[](##)|Parts
- 1 Hyundai D connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+> |Kia|Niro Plug-in Hybrid 2021|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai D connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+> |Kia|Niro Plug-in Hybrid 2022|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai F connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+154c163
+< |Kia|Sportage 2023[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+---
+> |Kia|Sportage 2023-24[6](#footnotes)|Smart Cruise Control (SCC)|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Hyundai N connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+180c189,190
+< |Lincoln|Aviator 2020-21|Co-Pilot360 Plus|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+---
+> |Lincoln|Aviator 2020-23|Co-Pilot360 Plus|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+> |Lincoln|Aviator Plug-in Hybrid 2020-23|Co-Pilot360 Plus|openpilot available[1](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 Ford Q3 connector
- 1 RJ45 cable (7 ft)
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+233c243
+< |Toyota|Highlander 2017-19|All|openpilot available[2](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here |
|
+---
+> |Toyota|Highlander 2017-19|All|openpilot available[2](#footnotes)|19 mph|0 mph|[](##)|[](##)|Parts
- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here |
|
+235c245
+< |Toyota|Highlander Hybrid 2017-19|All|openpilot available[2](#footnotes)|0 mph|0 mph|[](##)|[](##)|Parts
- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+---
+> |Toyota|Highlander Hybrid 2017-19|All|openpilot available[2](#footnotes)|19 mph|0 mph|[](##)|[](##)|Parts
- 1 RJ45 cable (7 ft)
- 1 Toyota A connector
- 1 comma 3X
- 1 comma power v2
- 1 harness box
- 1 mount
- 1 right angle OBD-C cable (1.5 ft)
Buy Here ||
+345a356
+> * Toyota Highlander 2024+
+Only in FrogPilot/docs: c_docs.rst
+Only in FrogPilot/docs: conf.py
+diff -r clearpilot/docs/CONTRIBUTING.md FrogPilot/docs/CONTRIBUTING.md
+65c65
+< * Annotate images in the [comma10k dateset](https://github.com/commaai/comma10k).
+---
+> * Annotate images in the [comma10k dataset](https://github.com/commaai/comma10k).
+Only in FrogPilot/docs: index.md
+Only in FrogPilot/docs: Makefile
+Only in FrogPilot/docs: overview.rst
+Only in FrogPilot/docs: README.md
+Only in FrogPilot/docs: SAFETY.md
+Only in FrogPilot/docs/_static: favicon.ico
+Only in FrogPilot/docs/_static: logo.png
+Only in FrogPilot/docs/_static: robots.txt
+Only in FrogPilot/docs: WORKFLOW.md
+Only in clearpilot/: frogpilot.diff
+diff -r clearpilot/.git/COMMIT_EDITMSG FrogPilot/.git/COMMIT_EDITMSG
+1c1,11
+< wip
+---
+> foo
+> # Please enter the commit message for your changes. Lines starting
+> # with '#' will be ignored, and an empty message aborts the commit.
+> #
+> # On branch FrogPilot
+> # Your branch is up to date with 'origin/FrogPilot'.
+> #
+> # Changes to be committed:
+> # modified: third_party/acados/larch64/lib/libqpOASES_e.so
+> # modified: third_party/maplibre-native-qt/x86_64/lib/libQMapLibre.so
+> #
+diff -r clearpilot/.git/config FrogPilot/.git/config
+7c7
+< url = git@privategit.hanson.xyz:brianhansonxyz/clearpilot.git
+---
+> url = https://github.com/FrogAi/FrogPilot.git
+9c9
+< [branch "clearpilot"]
+---
+> [branch "FrogPilot"]
+11c11,14
+< merge = refs/heads/clearpilot
+---
+> merge = refs/heads/FrogPilot
+> [branch "FrogPilot-Development"]
+> remote = origin
+> merge = refs/heads/FrogPilot-Development
+diff -r clearpilot/.git/FETCH_HEAD FrogPilot/.git/FETCH_HEAD
+1c1
+< c3754cc196c80a53b8464c6edd7a3b009bb90129 branch 'clearpilot' of privategit.hanson.xyz:brianhansonxyz/clearpilot
+---
+> 8eb522021d8567d4f3dbdb8197098d479b142af6 branch 'FrogPilot-Development' of https://github.com/FrogAi/FrogPilot
+diff -r clearpilot/.git/HEAD FrogPilot/.git/HEAD
+1c1
+< ref: refs/heads/clearpilot
+---
+> ref: refs/heads/FrogPilot-Development
+Binary files clearpilot/.git/index and FrogPilot/.git/index differ
+diff -r clearpilot/.git/logs/HEAD FrogPilot/.git/logs/HEAD
+1,100c1,7
+< 0000000000000000000000000000000000000000 38ae44ed4e9aeba444cc9483a380efb267f49732 Your Name 1714240831 -0500 clone: from privategit.hanson.xyz:brianhansonxyz/clearpilot.git
+< 38ae44ed4e9aeba444cc9483a380efb267f49732 fe5f722eda227f152924d3aa17492c9d459f40f8 Your Name 1714240918 -0500 commit: wip
+< fe5f722eda227f152924d3aa17492c9d459f40f8 71b83ffe7fed8ec67d33fbd7c9d24137e73a0ebf Your Name 1714241023 -0500 commit: wip
+< 71b83ffe7fed8ec67d33fbd7c9d24137e73a0ebf ab7726ef50fc8ffb1e9927f1c519e6873d982fda Your Name 1714241191 -0500 commit: wip
+< ab7726ef50fc8ffb1e9927f1c519e6873d982fda 21363ce751f480e0d1aefdbf21d6631db7b9dcb9 Your Name 1714243281 -0500 commit: wip
+< 21363ce751f480e0d1aefdbf21d6631db7b9dcb9 ea1aad5ed1423f3b88647d799b8d808199408328 Your Name 1714243396 -0500 commit: wip
+< ea1aad5ed1423f3b88647d799b8d808199408328 2fbe9dbea1fd74e16fb73a804e313be94dfe87a2 Your Name 1714243474 -0500 commit: wip
+< 2fbe9dbea1fd74e16fb73a804e313be94dfe87a2 931db76fc6ad379f61ba61163f602b04e5e7d709 Your Name 1714243685 -0500 commit: wip
+< 931db76fc6ad379f61ba61163f602b04e5e7d709 d8f24f93803e4f77d848bcd6d2bc3f1cef6bdca0 Your Name 1714243711 -0500 commit: wip
+< d8f24f93803e4f77d848bcd6d2bc3f1cef6bdca0 50be724af117da8432b990d33fbc42c57fc62600 Your Name 1714248898 -0500 commit: wip
+< 50be724af117da8432b990d33fbc42c57fc62600 b6e1ed1d068b69b4063663c9aa4e3e170c703a2b Your Name 1714250666 -0500 commit: wip
+< b6e1ed1d068b69b4063663c9aa4e3e170c703a2b 38238548a9a4df771b9bfd024c53f65afee17106 Your Name 1714251110 -0500 commit: wip
+< 38238548a9a4df771b9bfd024c53f65afee17106 f6521ed78e266c14b1aadc2312c782b25ca890d1 Your Name 1714251410 -0500 commit: wip
+< f6521ed78e266c14b1aadc2312c782b25ca890d1 c1b8d65f3baf3eb1cb44f0c65e7f71260417df53 Your Name 1714252319 -0500 commit: wip
+< c1b8d65f3baf3eb1cb44f0c65e7f71260417df53 225849913e73e6b883357e1c7d6234073743d351 Your Name 1714252584 -0500 commit: wip
+< 225849913e73e6b883357e1c7d6234073743d351 00e8cd6b3f214e0bc23987274ca1364565bad7f9 Your Name 1714252909 -0500 commit: wip
+< 00e8cd6b3f214e0bc23987274ca1364565bad7f9 a53e5fce788859ef3fc018ccda6bf09b47e858f6 Your Name 1714253013 -0500 commit: wip
+< a53e5fce788859ef3fc018ccda6bf09b47e858f6 7dde84a7f641f60a530a65cac2bccfc047841c68 Your Name 1714253375 -0500 commit: wip
+< 7dde84a7f641f60a530a65cac2bccfc047841c68 9244b84ae4a3b4173f02c141295ab8f3f83065a5 Your Name 1714253468 -0500 commit: wip
+< 9244b84ae4a3b4173f02c141295ab8f3f83065a5 8a47c27cb08b6d0c46e2ca737d846e60612793b0 Your Name 1714253677 -0500 commit: wip
+< 8a47c27cb08b6d0c46e2ca737d846e60612793b0 2bb63f3e64461008a2962e406c8677a3685a3d61 Your Name 1714277756 -0500 commit: wip
+< 2bb63f3e64461008a2962e406c8677a3685a3d61 72e8bd8589bc2b5b6ef88e6559f177814e30b12f Your Name 1714277819 -0500 pull origin clearpilot --rebase (start): checkout 72e8bd8589bc2b5b6ef88e6559f177814e30b12f
+< 72e8bd8589bc2b5b6ef88e6559f177814e30b12f 5307c44635e316c5bba931515c0c261238bf7048 Your Name 1714277819 -0500 pull origin clearpilot --rebase (pick): wip
+< 5307c44635e316c5bba931515c0c261238bf7048 5307c44635e316c5bba931515c0c261238bf7048 Your Name 1714277819 -0500 pull origin clearpilot --rebase (finish): returning to refs/heads/clearpilot
+< 5307c44635e316c5bba931515c0c261238bf7048 2b4ba52cf05d3c84d567e243c5f751e9618ccdaf Your Name 1714277991 -0500 commit: wip
+< 2b4ba52cf05d3c84d567e243c5f751e9618ccdaf 926a1b9f4afa3e30078473c57e81964bc4b7e717 Your Name 1714278401 -0500 commit: wip
+< 926a1b9f4afa3e30078473c57e81964bc4b7e717 224327480a88175423a40b270ce0945460ec30dd concordia 1714292663 -0500 commit: wip
+< 224327480a88175423a40b270ce0945460ec30dd 6b584bc335f176d0f2b2de727e85ccfcbff021d1 Your Name 1714328466 -0500 commit: wip
+< 6b584bc335f176d0f2b2de727e85ccfcbff021d1 784daf270a47a97e766cf76415236e7320e5de52 Your Name 1714328547 -0500 pull origin clearpilot --rebase (start): checkout 784daf270a47a97e766cf76415236e7320e5de52
+< 784daf270a47a97e766cf76415236e7320e5de52 dd6ead0477304ac35a84c5c2a953fe79dec75591 Your Name 1714328548 -0500 pull origin clearpilot --rebase (pick): wip
+< dd6ead0477304ac35a84c5c2a953fe79dec75591 dd6ead0477304ac35a84c5c2a953fe79dec75591 Your Name 1714328548 -0500 pull origin clearpilot --rebase (finish): returning to refs/heads/clearpilot
+< dd6ead0477304ac35a84c5c2a953fe79dec75591 30f217ef628b60ded5e37fb6367f63c0c8ef9905 Your Name 1714328569 -0500 commit: wip
+< 30f217ef628b60ded5e37fb6367f63c0c8ef9905 a44d5633760c7f8ed65cb3e5f29152ae01488944 Your Name 1714330106 -0500 commit: wip
+< a44d5633760c7f8ed65cb3e5f29152ae01488944 6ebd9e07a181d9304f26546226afa1577996c5a6 Your Name 1714331863 -0500 commit: wip
+< 6ebd9e07a181d9304f26546226afa1577996c5a6 19ba7d9780c6468c45d028dc78e6d0968e1159bf Your Name 1714331871 -0500 pull origin clearpilot --no-rebase: Merge made by the 'ort' strategy.
+< 19ba7d9780c6468c45d028dc78e6d0968e1159bf 60b05f3b5b80ec69b558260e414ced8aba125b89 Your Name 1714331958 -0500 commit: wip
+< 60b05f3b5b80ec69b558260e414ced8aba125b89 5d4d06a5ecd0653e2fa028ad17cbb610aa749726 Your Name 1714332097 -0500 commit: wip
+< 5d4d06a5ecd0653e2fa028ad17cbb610aa749726 5e4ce05f6bb345d0c8a5a6fbfcbdcf1139a13af4 Your Name 1714332283 -0500 commit: wip
+< 5e4ce05f6bb345d0c8a5a6fbfcbdcf1139a13af4 8aa23c5317be3b73ced0d35525018e59e55bbb5d Your Name 1714332396 -0500 commit: wip
+< 8aa23c5317be3b73ced0d35525018e59e55bbb5d ca72245a5336ef2e84388cb918a91f6e52a2893f Your Name 1714332580 -0500 commit: wip
+< ca72245a5336ef2e84388cb918a91f6e52a2893f 90a4ed9cab76ab57594796a35f5db4a0e94e5b5d Your Name 1714332683 -0500 commit: wip
+< 90a4ed9cab76ab57594796a35f5db4a0e94e5b5d b2767a27f65024daac41738518d5c00e442841b7 Your Name 1714334101 -0500 commit: wip
+< b2767a27f65024daac41738518d5c00e442841b7 bbc881a913ab1c924762f6360f6c87f90a49bc7f Your Name 1714334349 -0500 commit: wip
+< bbc881a913ab1c924762f6360f6c87f90a49bc7f 0f3bcab1477f591f4445d4ae3087e384f607db88 Your Name 1714334440 -0500 commit: wip
+< 0f3bcab1477f591f4445d4ae3087e384f607db88 7c118edb76f6a9d861626bcf214ec838932b8fc5 Your Name 1714334651 -0500 commit: wip
+< 7c118edb76f6a9d861626bcf214ec838932b8fc5 96dcadfb7e891748d576297fe504cdd58e481a1d Your Name 1714335195 -0500 commit: wip
+< 96dcadfb7e891748d576297fe504cdd58e481a1d 7bcb838017943e81ed50fa7c5bfa5fccf9056791 Your Name 1714335309 -0500 commit: wip
+< 7bcb838017943e81ed50fa7c5bfa5fccf9056791 244b27e467e37c258bb2dce3112755ee216bc527 Your Name 1714335623 -0500 commit: wip
+< 244b27e467e37c258bb2dce3112755ee216bc527 0ec0d8368fce836cbefc5cdeadf9e3333e77fd35 Your Name 1714337073 -0500 commit: wip
+< 0ec0d8368fce836cbefc5cdeadf9e3333e77fd35 0ed3fb31e860bf68b0dd253356941c274dd9ab04 Your Name 1714337644 -0500 commit: wip
+< 0ed3fb31e860bf68b0dd253356941c274dd9ab04 14adade45e19ffaf2769b93df33ca7c04803d446 Your Name 1714337853 -0500 commit: wip
+< 14adade45e19ffaf2769b93df33ca7c04803d446 08e52cce7ff75f127cf9d03d97687ee087a148f1 Your Name 1714338014 -0500 commit: wip
+< 08e52cce7ff75f127cf9d03d97687ee087a148f1 80b75ca9cfa6fd1e5a047bf560e21a9a29e64242 Your Name 1714347063 -0500 commit: wip
+< 80b75ca9cfa6fd1e5a047bf560e21a9a29e64242 a40c766deac1d6bce1ea7ff8e5c5c3ab05f5a04b Your Name 1714347143 -0500 commit: wip
+< a40c766deac1d6bce1ea7ff8e5c5c3ab05f5a04b e92a8ae6f8f09ace8c4a8f2517c324c679e7f624 Your Name 1714348496 -0500 commit: wip
+< e92a8ae6f8f09ace8c4a8f2517c324c679e7f624 e3eeb293db5cf5eb2cd83757cc25efa59d1e7bfd Your Name 1714348593 -0500 commit: wip
+< e3eeb293db5cf5eb2cd83757cc25efa59d1e7bfd 68c29c684266d38e30763614a5557d80d326f6c3 Your Name 1714368211 -0500 commit: wip
+< 68c29c684266d38e30763614a5557d80d326f6c3 2c575dae830b1ab71864cd11d39a74a77c7c4877 Your Name 1714411692 -0500 commit: wip
+< 2c575dae830b1ab71864cd11d39a74a77c7c4877 406a29796e79ccc7fa7e4d32a8326daff3f2586a Your Name 1714412026 -0500 commit: wip
+< 406a29796e79ccc7fa7e4d32a8326daff3f2586a 1f340a499622e57c6c4fc11c608964aad2216fbf Your Name 1714412102 -0500 commit: wip
+< 1f340a499622e57c6c4fc11c608964aad2216fbf f4145d48e62f22d07ba162b04050604d73c9d7bb Your Name 1714413327 -0500 commit: wip
+< f4145d48e62f22d07ba162b04050604d73c9d7bb 6a39c30cc0904d251f1b12af30078230d5027f71 Your Name 1714414755 -0500 commit: wip
+< 6a39c30cc0904d251f1b12af30078230d5027f71 17a4045ee57878676a4354826552e0b57af90cbf Your Name 1714414985 -0500 commit: wip
+< 17a4045ee57878676a4354826552e0b57af90cbf 3fb1bac8f8057c0281322b2bc2a98124e0ffea10 Your Name 1714416721 -0500 commit: wip
+< 3fb1bac8f8057c0281322b2bc2a98124e0ffea10 1847dc78e3f1ea7d57ccc81211d84f42859811d2 Your Name 1714437622 -0500 commit: wip
+< 1847dc78e3f1ea7d57ccc81211d84f42859811d2 5d3d2d7a39b272fe7049bf1304574f9f963b8efb Your Name 1714437886 -0500 commit: wip
+< 5d3d2d7a39b272fe7049bf1304574f9f963b8efb e3b5a88027a24d57e60352f5af2b53008a75256a Your Name 1714438740 -0500 commit: wip
+< e3b5a88027a24d57e60352f5af2b53008a75256a 3733baa6712cc70ac379350464d6f4db0af5cbd8 Your Name 1714438940 -0500 commit: wip
+< 3733baa6712cc70ac379350464d6f4db0af5cbd8 0e229c0b6d29c5059edd65aa9c687def6731fbd3 Your Name 1714490830 -0500 commit: wip
+< 0e229c0b6d29c5059edd65aa9c687def6731fbd3 95a98a8fe865f1ecec820010243ae74844546b02 Your Name 1714501353 -0500 commit: wip
+< 95a98a8fe865f1ecec820010243ae74844546b02 c55a879968c80b803a561496075f38a2fc4d5e9a Your Name 1714630071 -0500 commit: wip
+< c55a879968c80b803a561496075f38a2fc4d5e9a 98751c5a5b17fa7a350b0e479704c20da56ad98e concordia 1714691671 -0500 commit: wip
+< 98751c5a5b17fa7a350b0e479704c20da56ad98e 7fa4ca62a81e431cdd069b4bf2167720f9ed5ab7 Your Name 1714692143 -0500 commit: wip
+< 7fa4ca62a81e431cdd069b4bf2167720f9ed5ab7 a22c5ca6767e886f42fc392014d60bc169da3855 Your Name 1714692670 -0500 commit: wip
+< a22c5ca6767e886f42fc392014d60bc169da3855 76f445636d1ac36d6ea6e5f192bd59c602fcf275 Your Name 1714693513 -0500 commit: wip
+< 76f445636d1ac36d6ea6e5f192bd59c602fcf275 9a76e175699a863ec2125a9bff37b4e6890e89c7 Your Name 1714694761 -0500 commit: wip
+< 9a76e175699a863ec2125a9bff37b4e6890e89c7 7ff225b87a829fb3470a538ae3f65cd5af90010a Your Name 1714694780 -0500 commit: wip
+< 7ff225b87a829fb3470a538ae3f65cd5af90010a 3e8215406e591eedd11c22a4cc764b1db492bde6 Your Name 1714694876 -0500 commit: wip
+< 3e8215406e591eedd11c22a4cc764b1db492bde6 3bab3c881091175e564fdbf6134c2f8b539d6680 Your Name 1714695051 -0500 commit: wip
+< 3bab3c881091175e564fdbf6134c2f8b539d6680 141af97aa665a9d3db155712bd85c2f28c02632d Your Name 1714695317 -0500 commit: wip
+< 141af97aa665a9d3db155712bd85c2f28c02632d 63d44d21a1f0bd8a88b829a2bdb2882538abb1c4 Your Name 1714695949 -0500 commit: wip
+< 63d44d21a1f0bd8a88b829a2bdb2882538abb1c4 1ce0b6abc6029dfdbd16e60f81bb0c7e1bdf3e84 Your Name 1714696685 -0500 commit: wip
+< 1ce0b6abc6029dfdbd16e60f81bb0c7e1bdf3e84 132171d23b6034abf4f9a9478f6f2b2d49aad3dc Your Name 1714697265 -0500 commit: wip
+< 132171d23b6034abf4f9a9478f6f2b2d49aad3dc 1b13eaf1ebd0949d2cfed436a568aeef118e1611 Your Name 1714698993 -0500 commit: wip
+< 1b13eaf1ebd0949d2cfed436a568aeef118e1611 7f42a4ba2889ad6b047adf6c5c817c3fb154a59c Your Name 1714699134 -0500 commit: wip
+< 7f42a4ba2889ad6b047adf6c5c817c3fb154a59c fd0029be6c51669b79ff69ba3ea82e303ea68df0 Your Name 1714699823 -0500 commit: wip
+< fd0029be6c51669b79ff69ba3ea82e303ea68df0 f0c82bf2d27bc61e04d33ed70b96e9ed3500366c Your Name 1714699953 -0500 commit: wip
+< f0c82bf2d27bc61e04d33ed70b96e9ed3500366c 526612b2bfc0eab9e47431e0b60af1ea86d8bfb3 Your Name 1714700111 -0500 commit: wip
+< 526612b2bfc0eab9e47431e0b60af1ea86d8bfb3 0f7aa64d3be020c2ffcdfe672c88535520c8ca20 Your Name 1714700240 -0500 commit: wip
+< 0f7aa64d3be020c2ffcdfe672c88535520c8ca20 dc561e3c2dd69f198f14c392f43fd8db73fec9fa concordia 1714702147 -0500 commit: wip
+< dc561e3c2dd69f198f14c392f43fd8db73fec9fa f56042fcb9656e111c90be4d42ba579e4c7eb435 concordia 1714702943 -0500 commit: wip
+< f56042fcb9656e111c90be4d42ba579e4c7eb435 00f797f931c97239797558595b5979da3f859c56 concordia 1714703350 -0500 commit: wip
+< 00f797f931c97239797558595b5979da3f859c56 84088529661307af53964d4d03d9d0131faf22a8 Your Name 1714704251 -0500 commit: wip
+< 84088529661307af53964d4d03d9d0131faf22a8 e2cde8e886eb9160fc4645c75d0738e96b88e33a Your Name 1714704353 -0500 commit: wip
+< e2cde8e886eb9160fc4645c75d0738e96b88e33a 7ca074cd79a9792da3b6f64d440fc29098f63def Your Name 1714708048 -0500 commit: wip
+< 7ca074cd79a9792da3b6f64d440fc29098f63def 98f79c0c1fc3cdc48d4a10bd11f879e721b2dada Your Name 1714709570 -0500 commit: wip
+< 98f79c0c1fc3cdc48d4a10bd11f879e721b2dada ba9a9f4cf11e51c8fab6d1e7ab2f3683d227a7e3 Your Name 1714709707 -0500 commit: wip
+< ba9a9f4cf11e51c8fab6d1e7ab2f3683d227a7e3 93bf01f185c8c9c2922199687568e7808c0bc452 Your Name 1714709856 -0500 commit: wip
+< 93bf01f185c8c9c2922199687568e7808c0bc452 b94be3e23e50547295308d94aa1d5aa313ad15fc Your Name 1714709974 -0500 commit: wip
+< b94be3e23e50547295308d94aa1d5aa313ad15fc 02513c94c69fc99c20eef9cc392558491bb520a1 Your Name 1714716767 -0500 commit: wip
+---
+> 0000000000000000000000000000000000000000 e4de63a35195e574622e80aa883d9f04623ab541 Your Name 1714204857 -0500 clone: from https://github.com/FrogAi/FrogPilot.git
+> e4de63a35195e574622e80aa883d9f04623ab541 e4de63a35195e574622e80aa883d9f04623ab541 Your Name 1714205412 -0500 reset: moving to HEAD
+> e4de63a35195e574622e80aa883d9f04623ab541 e4de63a35195e574622e80aa883d9f04623ab541 Your Name 1714205492 -0500 reset: moving to HEAD
+> e4de63a35195e574622e80aa883d9f04623ab541 94a74b730977180f1d2f14c0c4c5c822867a6961 Your Name 1714205500 -0500 commit: foo
+> 94a74b730977180f1d2f14c0c4c5c822867a6961 f01126e52b95fb979ef25f43f7b6d1053da2aa5f Your Name 1714205506 -0500 checkout: moving from FrogPilot to FrogPilot-Development
+> f01126e52b95fb979ef25f43f7b6d1053da2aa5f 8eb522021d8567d4f3dbdb8197098d479b142af6 Your Name 1714716867 -0500 pull origin FrogPilot-Development --rebase (start): checkout 8eb522021d8567d4f3dbdb8197098d479b142af6
+> 8eb522021d8567d4f3dbdb8197098d479b142af6 8eb522021d8567d4f3dbdb8197098d479b142af6 Your Name 1714716867 -0500 pull origin FrogPilot-Development --rebase (finish): returning to refs/heads/FrogPilot-Development
+Only in clearpilot/.git/logs/refs/heads: clearpilot
+Only in FrogPilot/.git/logs/refs/heads: FrogPilot
+Only in FrogPilot/.git/logs/refs/heads: FrogPilot-Development
+Only in clearpilot/.git/logs/refs/remotes/origin: clearpilot
+Only in FrogPilot/.git/logs/refs/remotes/origin: FrogPilot-Development
+diff -r clearpilot/.git/logs/refs/remotes/origin/HEAD FrogPilot/.git/logs/refs/remotes/origin/HEAD
+1c1
+< 0000000000000000000000000000000000000000 38ae44ed4e9aeba444cc9483a380efb267f49732 Your Name 1714240831 -0500 clone: from privategit.hanson.xyz:brianhansonxyz/clearpilot.git
+---
+> 0000000000000000000000000000000000000000 e4de63a35195e574622e80aa883d9f04623ab541 Your Name 1714204857 -0500 clone: from https://github.com/FrogAi/FrogPilot.git
+Only in FrogPilot/.git/logs/refs: stash
+Only in clearpilot/.git/objects: 00
+Only in FrogPilot/.git/objects/01: 5f032cfaeed5f3a54756506615fd89b5062f20
+Only in clearpilot/.git/objects/01: 5f42544f6d8a40fe8e6ad83ce2543f1384b91a
+Only in clearpilot/.git/objects/01: 9352754cd621061866abe80d307bef41e892bd
+Only in clearpilot/.git/objects/01: b40bd7f28e875c7b1077f15ebb5b3cbf1e6f54
+Only in clearpilot/.git/objects/01: d6ffb6d9ca04ceeaffec4311ff226fb87a19e7
+Only in clearpilot/.git/objects: 02
+Only in clearpilot/.git/objects/03: 7ed8d8fa6c7a255ab57094d7792378ab894a81
+Only in FrogPilot/.git/objects/03: 91c5e908e3d61ee00b78b11ee6e4391c520992
+Only in clearpilot/.git/objects/03: a0b789d4e606b0442a537e353d8e4dd331206f
+Only in clearpilot/.git/objects/03: df2c91b1b85783e3ec43369152876c8be5b1f0
+Only in clearpilot/.git/objects: 04
+Only in clearpilot/.git/objects: 05
+Only in clearpilot/.git/objects: 06
+Only in clearpilot/.git/objects: 07
+Only in clearpilot/.git/objects: 08
+Only in clearpilot/.git/objects: 0a
+Only in clearpilot/.git/objects: 0b
+Only in clearpilot/.git/objects: 0c
+Only in clearpilot/.git/objects: 0d
+Only in clearpilot/.git/objects: 0e
+Only in clearpilot/.git/objects: 0f
+Only in clearpilot/.git/objects: 10
+Only in clearpilot/.git/objects: 11
+Only in clearpilot/.git/objects: 12
+Only in clearpilot/.git/objects: 13
+Only in clearpilot/.git/objects: 14
+Only in clearpilot/.git/objects: 15
+Only in clearpilot/.git/objects: 16
+Only in clearpilot/.git/objects: 17
+Only in clearpilot/.git/objects: 18
+Only in clearpilot/.git/objects: 19
+Only in clearpilot/.git/objects: 1a
+Only in clearpilot/.git/objects: 1b
+Only in clearpilot/.git/objects: 1c
+Only in clearpilot/.git/objects: 1d
+Only in clearpilot/.git/objects: 1e
+Only in clearpilot/.git/objects: 1f
+Only in clearpilot/.git/objects: 20
+Only in clearpilot/.git/objects: 21
+Only in clearpilot/.git/objects: 22
+Only in clearpilot/.git/objects: 23
+Only in clearpilot/.git/objects: 24
+Only in clearpilot/.git/objects: 25
+Only in clearpilot/.git/objects: 26
+Only in clearpilot/.git/objects: 27
+Only in clearpilot/.git/objects: 28
+Only in clearpilot/.git/objects: 29
+Only in clearpilot/.git/objects: 2a
+Only in clearpilot/.git/objects: 2b
+Only in clearpilot/.git/objects: 2c
+Only in clearpilot/.git/objects: 2d
+Only in clearpilot/.git/objects: 2e
+Only in clearpilot/.git/objects: 2f
+Only in clearpilot/.git/objects: 30
+Only in clearpilot/.git/objects: 32
+Only in clearpilot/.git/objects: 33
+Only in clearpilot/.git/objects: 34
+Only in clearpilot/.git/objects: 35
+Only in clearpilot/.git/objects: 36
+Only in clearpilot/.git/objects: 37
+Only in clearpilot/.git/objects: 38
+Only in clearpilot/.git/objects: 39
+Only in clearpilot/.git/objects: 3a
+Only in clearpilot/.git/objects: 3b
+Only in clearpilot/.git/objects: 3c
+Only in clearpilot/.git/objects: 3d
+Only in clearpilot/.git/objects: 3e
+Only in clearpilot/.git/objects: 3f
+Only in clearpilot/.git/objects: 40
+Only in clearpilot/.git/objects: 41
+Only in clearpilot/.git/objects: 42
+Only in clearpilot/.git/objects: 43
+Only in clearpilot/.git/objects: 44
+Only in clearpilot/.git/objects: 45
+Only in clearpilot/.git/objects: 46
+Only in clearpilot/.git/objects: 47
+Only in clearpilot/.git/objects: 48
+Only in clearpilot/.git/objects: 49
+Only in clearpilot/.git/objects: 4a
+Only in clearpilot/.git/objects: 4b
+Only in clearpilot/.git/objects: 4c
+Only in clearpilot/.git/objects: 4d
+Only in clearpilot/.git/objects: 4e
+Only in clearpilot/.git/objects: 4f
+Only in clearpilot/.git/objects: 50
+Only in clearpilot/.git/objects: 51
+Only in clearpilot/.git/objects: 52
+Only in clearpilot/.git/objects: 53
+Only in clearpilot/.git/objects: 54
+Only in clearpilot/.git/objects: 55
+Only in clearpilot/.git/objects: 56
+Only in clearpilot/.git/objects: 57
+Only in clearpilot/.git/objects: 58
+Only in clearpilot/.git/objects/59: 1c1ce7ca6d04827d67619f20df0877dbfc9883
+Only in clearpilot/.git/objects/59: 3909894a527f108ce9eb62812eb8fc313e78d6
+Only in clearpilot/.git/objects/59: 3b8f0ea0b9ac037dc11d550e497b830e237a5f
+Only in clearpilot/.git/objects/59: 420547570b0e2269d28f02b83569d115628abf
+Only in clearpilot/.git/objects/59: 7ea17f0c3182ddeb4dcccc5f0f11aeaa1ca1d8
+Only in clearpilot/.git/objects/59: 9ab310591bb35fbf1d6ad9e7dccbcafef8d1a1
+Only in clearpilot/.git/objects/59: c1827d1ce3ca23cb23145ef6e4a51ccc3bda12
+Only in clearpilot/.git/objects/59: c5ea56151feb0ff502dde9d3c8277a7c407b4d
+Only in FrogPilot/.git/objects/59: efe0a5dd89dc1feba54fb0592003cd622090b1
+Only in clearpilot/.git/objects: 5a
+Only in clearpilot/.git/objects: 5b
+Only in clearpilot/.git/objects: 5c
+Only in clearpilot/.git/objects: 5d
+Only in clearpilot/.git/objects: 5e
+Only in clearpilot/.git/objects: 5f
+Only in clearpilot/.git/objects: 60
+Only in clearpilot/.git/objects: 61
+Only in clearpilot/.git/objects: 62
+Only in clearpilot/.git/objects: 63
+Only in clearpilot/.git/objects: 64
+Only in FrogPilot/.git/objects/65: 13f1219304b040fb3f63116a1eab92946017b9
+Only in clearpilot/.git/objects/65: 27ec3ff7299b249878ba9d82427100ffeea2cb
+Only in clearpilot/.git/objects/65: 5645dd6816da0c873a6a8efe9f5618cea4265e
+Only in clearpilot/.git/objects/65: 628c15256492ecde0645debfaec47a646407ad
+Only in clearpilot/.git/objects/65: a278d2407c1959681cebaa2dbcd9068d7b8473
+Only in FrogPilot/.git/objects/65: f53d6b7887e15ac5f852c465fa9192190c3673
+Only in clearpilot/.git/objects: 66
+Only in clearpilot/.git/objects: 67
+Only in clearpilot/.git/objects: 68
+Only in clearpilot/.git/objects: 69
+Only in clearpilot/.git/objects: 6a
+Only in clearpilot/.git/objects: 6b
+Only in clearpilot/.git/objects: 6c
+Only in clearpilot/.git/objects: 6d
+Only in clearpilot/.git/objects: 6e
+Only in clearpilot/.git/objects: 6f
+Only in clearpilot/.git/objects: 70
+Only in clearpilot/.git/objects: 71
+Only in clearpilot/.git/objects/72: 48a75e011f8ae5a799344151e46820677ae2be
+Only in clearpilot/.git/objects/72: 742656f34be035f94fd7f4460a721beafeacc6
+Only in FrogPilot/.git/objects/72: a1019a1efa1ca05936953dfc6583486edbd333
+Only in clearpilot/.git/objects/72: c9ef1b3dee40e8dcee70d302f826b042cee9bb
+Only in clearpilot/.git/objects/72: d26ebd6c95c40ca97f00b6136161fcf3b145dc
+Only in clearpilot/.git/objects/72: e8bd8589bc2b5b6ef88e6559f177814e30b12f
+Only in clearpilot/.git/objects: 73
+Only in clearpilot/.git/objects: 74
+Only in clearpilot/.git/objects: 75
+Only in clearpilot/.git/objects: 76
+Only in clearpilot/.git/objects: 77
+Only in clearpilot/.git/objects: 78
+Only in clearpilot/.git/objects: 79
+Only in clearpilot/.git/objects: 7a
+Only in clearpilot/.git/objects: 7b
+Only in clearpilot/.git/objects: 7c
+Only in clearpilot/.git/objects: 7d
+Only in clearpilot/.git/objects: 7e
+Only in clearpilot/.git/objects: 7f
+Only in clearpilot/.git/objects: 80
+Only in clearpilot/.git/objects: 81
+Only in clearpilot/.git/objects: 82
+Only in clearpilot/.git/objects: 83
+Only in clearpilot/.git/objects: 84
+Only in clearpilot/.git/objects: 85
+Only in clearpilot/.git/objects: 86
+Only in FrogPilot/.git/objects/87: 4137efc71cc54bf79e467f584dac9517a1a6dd
+Only in clearpilot/.git/objects/87: 45fefc124b0e386a3ed358b003751a28a78caf
+Only in clearpilot/.git/objects/87: 532f5834f9bc37358923e07f854ebcfb3c6c53
+Only in clearpilot/.git/objects/87: 98d62b9361fa8130d57fcf420ecc2a4cde256d
+Only in clearpilot/.git/objects/87: 9e6eebca749819ad39c88a4a1b892229d38421
+Only in clearpilot/.git/objects: 88
+Only in clearpilot/.git/objects: 89
+Only in clearpilot/.git/objects: 8a
+Only in clearpilot/.git/objects: 8b
+Only in clearpilot/.git/objects: 8c
+Only in clearpilot/.git/objects: 8d
+Only in clearpilot/.git/objects: 8e
+Only in clearpilot/.git/objects: 8f
+Only in clearpilot/.git/objects: 90
+Only in clearpilot/.git/objects: 91
+Only in clearpilot/.git/objects: 92
+Only in clearpilot/.git/objects: 93
+Only in clearpilot/.git/objects/94: 2199790a4e2b9a864c7ad5ec0a86e2f2a36e9a
+Only in clearpilot/.git/objects/94: 366eb65193072c8baba6caaac593f850bfd8d3
+Only in clearpilot/.git/objects/94: 895285df02d78d5c60c6e392e56b88d40ecd97
+Only in clearpilot/.git/objects/94: 96892f29e06d18bdd85993ff4a4bc845bf6a7f
+Only in FrogPilot/.git/objects/94: a74b730977180f1d2f14c0c4c5c822867a6961
+Only in clearpilot/.git/objects/94: b32a9f761b133602984025b1126969dec4c0eb
+Only in clearpilot/.git/objects/94: ce26eb4797d1b6aeda4321fee9e6422786e0bd
+Only in clearpilot/.git/objects/94: e9d309d62e792548425e83f1337899bd73a1b0
+Only in clearpilot/.git/objects/94: ea031dad857a35d835e990236496c3303a7fa1
+Only in clearpilot/.git/objects: 95
+Only in clearpilot/.git/objects: 96
+Only in clearpilot/.git/objects: 97
+Only in clearpilot/.git/objects: 98
+Only in clearpilot/.git/objects/99: 30ea8bd5cc7b41e73bf8a62287551c4b63ae5a
+Only in FrogPilot/.git/objects/99: b1cfa50c94621a5fa05bc6e38a03b4d384b831
+Only in clearpilot/.git/objects: 9a
+Only in clearpilot/.git/objects: 9b
+Only in clearpilot/.git/objects: 9c
+Only in clearpilot/.git/objects: 9d
+Only in clearpilot/.git/objects: 9e
+Only in clearpilot/.git/objects: 9f
+Only in clearpilot/.git/objects: a0
+Only in clearpilot/.git/objects: a1
+Only in clearpilot/.git/objects: a2
+Only in clearpilot/.git/objects: a3
+Only in clearpilot/.git/objects: a4
+Only in clearpilot/.git/objects: a5
+Only in clearpilot/.git/objects/a6: 1da9fd98f3e685e0e39a47d3c41b8a8688ae23
+Only in FrogPilot/.git/objects/a6: 710a71ab0b70f91e9cf3fbc2c8d7bf282faa1e
+Only in clearpilot/.git/objects/a6: 9625930505ac144429fa4221483adba54406af
+Only in clearpilot/.git/objects/a6: a7f0da1b93426f77424e8e2b8a194c0465afb3
+Only in clearpilot/.git/objects/a6: be2cd1057cc7e286e606c32b401c14203d8862
+Only in clearpilot/.git/objects/a6: c4c7179032e5711d1f177f152c11918a85311d
+Only in clearpilot/.git/objects/a6: e28fb892f5d0c26a54f185526273fb2e636938
+Only in clearpilot/.git/objects/a6: e8bc32400650d7bb4d4b6e9d3f4cab84c83c09
+Only in clearpilot/.git/objects: a7
+Only in clearpilot/.git/objects: a8
+Only in clearpilot/.git/objects: a9
+Only in clearpilot/.git/objects: aa
+Only in clearpilot/.git/objects: ab
+Only in clearpilot/.git/objects: ac
+Only in clearpilot/.git/objects: ad
+Only in clearpilot/.git/objects: ae
+Only in clearpilot/.git/objects: af
+Only in clearpilot/.git/objects: b1
+Only in clearpilot/.git/objects: b2
+Only in clearpilot/.git/objects: b3
+Only in clearpilot/.git/objects: b4
+Only in clearpilot/.git/objects: b5
+Only in clearpilot/.git/objects: b6
+Only in clearpilot/.git/objects: b7
+Only in clearpilot/.git/objects: b8
+Only in clearpilot/.git/objects: b9
+Only in clearpilot/.git/objects: ba
+Only in clearpilot/.git/objects: bb
+Only in clearpilot/.git/objects: bc
+Only in clearpilot/.git/objects: bd
+Only in clearpilot/.git/objects: be
+Only in clearpilot/.git/objects: bf
+Only in clearpilot/.git/objects: c0
+Only in clearpilot/.git/objects: c1
+Only in clearpilot/.git/objects: c2
+Only in clearpilot/.git/objects: c3
+Only in clearpilot/.git/objects: c4
+Only in clearpilot/.git/objects: c5
+Only in clearpilot/.git/objects: c6
+Only in clearpilot/.git/objects: c7
+Only in clearpilot/.git/objects: c8
+Only in clearpilot/.git/objects: c9
+Only in clearpilot/.git/objects: ca
+Only in clearpilot/.git/objects: cb
+Only in clearpilot/.git/objects: cc
+Only in clearpilot/.git/objects/cd: 3b0f90fee6010a33d3e8d8b3e6c52dbffebc85
+Only in clearpilot/.git/objects/cd: 537fb05ba7dbb38bfca9c54039a8287bdff79c
+Only in FrogPilot/.git/objects/cd: 84e55593a4cd391b49004b0e0d2dc940001e03
+Only in clearpilot/.git/objects/cd: 89d29889fc24172eabd8cf5e85414e5f448105
+Only in clearpilot/.git/objects/cd: 9920f63b7e6dc333f18ab0ec11132e1eda229b
+Only in clearpilot/.git/objects/cd: a030b6dc0d92dd734b8032cb87eedb69394048
+Only in clearpilot/.git/objects/cd: cea247784e246e7c33208517de5d69fda09b9b
+Only in clearpilot/.git/objects/cd: dab2ec0dcc9e12b66ab5978875637f4981aa8e
+Only in clearpilot/.git/objects/cd: f9b211dd8a2fe1046fdc375889804783a12f8d
+Only in clearpilot/.git/objects: ce
+Only in clearpilot/.git/objects: cf
+Only in clearpilot/.git/objects: d0
+Only in clearpilot/.git/objects: d1
+Only in clearpilot/.git/objects: d3
+Only in clearpilot/.git/objects: d4
+Only in clearpilot/.git/objects: d5
+Only in clearpilot/.git/objects: d6
+Only in clearpilot/.git/objects/d7: 380bb75f782709f4cd568b74c4959e1e94a8b7
+Only in clearpilot/.git/objects/d7: 5d1ec133152dd2c47f7146b99f3a7c150e4782
+Only in clearpilot/.git/objects/d7: 9604087836d9bbb3c7e96a48438e9abdec6d28
+Only in clearpilot/.git/objects/d7: c5e98d2d44fcf4ed69efc0138df220dec19106
+Only in FrogPilot/.git/objects/d7: d70f928be351a904f8cc3a54a713a72cb39403
+Only in clearpilot/.git/objects: d8
+Only in clearpilot/.git/objects: d9
+Only in clearpilot/.git/objects: da
+Only in clearpilot/.git/objects: db
+Only in clearpilot/.git/objects: dc
+Only in clearpilot/.git/objects: dd
+Only in clearpilot/.git/objects: de
+Only in clearpilot/.git/objects: df
+Only in clearpilot/.git/objects: e0
+Only in clearpilot/.git/objects: e1
+Only in clearpilot/.git/objects: e2
+Only in clearpilot/.git/objects: e3
+Only in clearpilot/.git/objects: e4
+Only in clearpilot/.git/objects: e5
+Only in clearpilot/.git/objects: e6
+Only in clearpilot/.git/objects: e7
+Only in clearpilot/.git/objects: e8
+Only in clearpilot/.git/objects: e9
+Only in clearpilot/.git/objects/ea: 1aad5ed1423f3b88647d799b8d808199408328
+Only in clearpilot/.git/objects/ea: 1e88e26ba1e1c4d3642cdd03717c507a47e4c7
+Only in clearpilot/.git/objects/ea: 291d7633d4acf704e9af1cd15813aac56b5e58
+Only in clearpilot/.git/objects/ea: 38a4191e5c0d3d9d1bab54bd5ba18bff7be644
+Only in FrogPilot/.git/objects/ea: 3ff939a04704b7a3a02320c5507e73dfdcfbf5
+Only in clearpilot/.git/objects/ea: 4692cc720e66f4bc179c32b96ab1eb2eb9c5ce
+Only in clearpilot/.git/objects/ea: 639e7fbc23e323694a22712a4d43ade89461aa
+Only in clearpilot/.git/objects/ea: 8710c4fd328616df5ec1436dff97c6c3b60f7e
+Only in clearpilot/.git/objects/ea: 8d898f90858b880c2e139bad9085986557e870
+Only in clearpilot/.git/objects/ea: f9002dcd61d9bb5b2cf05a75c4321c59e3d81b
+Only in clearpilot/.git/objects/ea: ff21dfc95fc27a1ae794ea806187f658452ea8
+Only in clearpilot/.git/objects: eb
+Only in clearpilot/.git/objects: ec
+Only in clearpilot/.git/objects: ed
+Only in clearpilot/.git/objects: ee
+Only in clearpilot/.git/objects: ef
+Only in clearpilot/.git/objects: f0
+Only in clearpilot/.git/objects: f1
+Only in clearpilot/.git/objects: f2
+Only in clearpilot/.git/objects: f3
+Only in clearpilot/.git/objects: f4
+Only in clearpilot/.git/objects: f5
+Only in clearpilot/.git/objects: f6
+Only in clearpilot/.git/objects: f8
+Only in FrogPilot/.git/objects/f9: 6ec1a8358556543a73b3fb93a0d1c2aad8432a
+Only in clearpilot/.git/objects/f9: 948e663f3aa31c88bdbac2a16316cbff38c2b7
+Only in clearpilot/.git/objects/f9: 9a846db3ca25e5efa5b85ce510886d3d3b21df
+Only in clearpilot/.git/objects/f9: d948344e9707556b1b8e7e404fae7a332ad1ca
+Only in clearpilot/.git/objects: fa
+Only in clearpilot/.git/objects: fb
+Only in clearpilot/.git/objects: fc
+Only in clearpilot/.git/objects: fd
+Only in clearpilot/.git/objects: fe
+Only in clearpilot/.git/objects/ff: 2a77a391b1d52d6449bb5a8c1195ff57fffa07
+Only in FrogPilot/.git/objects/ff: 62d5fcaa825039d6419b86608af84f15e8fae2
+Only in clearpilot/.git/objects/ff: 7538aa64fe2bb187d9a4d9083293ac8797d6a0
+Only in clearpilot/.git/objects/ff: 7893e3e526bdd8aa09ac70dc79a9922b6b1e34
+Only in clearpilot/.git/objects/ff: 987167defc0064c4a559f9612175545edc2d41
+Only in clearpilot/.git/objects/ff: a30b6c925db85ef4a4018a3d26ccfbfcacfc4c
+Only in FrogPilot/.git/objects/pack: pack-0503da4c1fb80d6422e9406b9374af997d8c390c.idx
+Only in FrogPilot/.git/objects/pack: pack-0503da4c1fb80d6422e9406b9374af997d8c390c.pack
+Only in clearpilot/.git/objects/pack: pack-bf005036f4ff5ebfd8068a6f3182d4398ba71542.idx
+Only in clearpilot/.git/objects/pack: pack-bf005036f4ff5ebfd8068a6f3182d4398ba71542.pack
+Only in FrogPilot/.git/objects/pack: pack-c97237f2dedd525298821974ebea80b78d687000.idx
+Only in FrogPilot/.git/objects/pack: pack-c97237f2dedd525298821974ebea80b78d687000.pack
+diff -r clearpilot/.git/ORIG_HEAD FrogPilot/.git/ORIG_HEAD
+1c1
+< 6ebd9e07a181d9304f26546226afa1577996c5a6
+---
+> f01126e52b95fb979ef25f43f7b6d1053da2aa5f
+diff -r clearpilot/.git/packed-refs FrogPilot/.git/packed-refs
+2c2,113
+< 38ae44ed4e9aeba444cc9483a380efb267f49732 refs/remotes/origin/clearpilot
+---
+> e4de63a35195e574622e80aa883d9f04623ab541 refs/remotes/origin/FrogPilot
+> f01126e52b95fb979ef25f43f7b6d1053da2aa5f refs/remotes/origin/FrogPilot-Development
+> 7f8d6d7ceb4f7a57279c95167f202dc0cc910691 refs/remotes/origin/FrogPilot-Old
+> a8e30af82fc1ae641f5f42c2c09cae05a977370b refs/remotes/origin/FrogPilot-Staging
+> 5daf01e3efb898465d58c3c63e41cc8ba4050727 refs/remotes/origin/FrogPilot-Testing
+> 0ac5e5aa1c524b6e288cf8a83da5c56a3d1dbb4f refs/remotes/origin/MAKE-PRS-HERE
+> 718d980ff7ddc23f3325e44acc9f4fc1ab5450db refs/tags/March-15th,-2024
+> 7aedfde644f60a0d69b31017b8e1e8d5fdbbd5fd refs/tags/March-1st,-2024
+> ^99690d9eb1431111531be8731e6f34d0b4c8f42f
+> d247ea118080342eeb835704ad343475a7cd35eb refs/tags/March-29th,-2024
+> c3b4b289e058b1e58206b9bb2938befd4dbed92e refs/tags/v0.1
+> ^e94a30bec07e719c5a7b037ca1f4db8312702cce
+> 142bb58d772e2982f8a78c76df9a9ea9bdfc0b4d refs/tags/v0.2
+> ^449b482cc3236ccf31829830b4f6a44b2dcc06c2
+> 5c985741ef933615a2d8efb58ac21e1a07900192 refs/tags/v0.2.1
+> ^17d9becd3c673091b22f09aa02559a9ed9230f50
+> e8f20b85a8dfcdfdc08a646818fae6a820b9b7f8 refs/tags/v0.2.2
+> ^a64b9aa9b8cb5863c917b6926516291a63c02fe5
+> 867aab9f971f90be0329bef085e3ee05c4a3430e refs/tags/v0.2.3
+> ^adaa4ed350acda4067fc0b455ad15b54cdf4c768
+> 5195cf447267246f6b8ef2bd73074b83dd907614 refs/tags/v0.2.4
+> ^ecc565aa3fdc4c7e719aadc000e1fdc4d80d4fe0
+> 1ac33efa07f6dca8730467207b587029e79416b3 refs/tags/v0.2.5
+> ^29c58b45882ac79595356caf98580c1d2a626011
+> b6632a5973720e7cfdad60109335d7cb4a139360 refs/tags/v0.2.6
+> ^6c3afeec0fb439070b2912978b8dbb659033b1d9
+> 28f35c97c5a1bd6c633478b800c55720a4724907 refs/tags/v0.2.7
+> ^c6ba5dc5391d3ca6cda479bf1923b88ce45509a0
+> a741ed8dcc4e072c18b0fe4d8c6a52f5c9b2f59b refs/tags/v0.2.8
+> ^95a349abcc050712c50d4d85a1c8a804eee7f6c2
+> 429a88db63264bfbf05279fdbc5ca6f7a9f14a04 refs/tags/v0.2.9
+> ^693bcb0f83478f2651db6bac9be5ca5ad60d03f3
+> 19d30f26f18eb8d08d298113eb65a4d8928bb52b refs/tags/v0.3.0
+> ^c5d8aec28b5230d34ae4b677c2091cc3dec7e3e8
+> 36ffe1cdd954448fafece583d2e2f31a437cecf5 refs/tags/v0.3.1
+> ^41e3a0f699f5c39cb61a15c0eb7a4aa816d47c24
+> e21af5cf95ad445954081ef341b4a988f46fea3f refs/tags/v0.3.2
+> ^7fe46f1e1df5dec08a940451ba0feefd5c039165
+> 75538bdcbe7869b10657d31e19f323143afb14d4 refs/tags/v0.3.3
+> ^5cf91d0496688fed4f2a6c7021349b1fc0e057a2
+> 1b8c44b5067525a5d266b6e99799d8097da76a29 refs/tags/v0.3.4
+> b111277f464cf66fa34b67819a83ea683e0f64df refs/tags/v0.3.5
+> 81eea6c40d18d76104285116b0df3934de6dc15f refs/tags/v0.4.0.2
+> ^da52d065a4c4f52d6017a537f3a80326f5af8bdc
+> af68dc5d45025e1c2d3c200bc4a768bd7519f1d5 refs/tags/v0.4.1
+> ^4474b9b3718653aeb0aee26422caefb90460cc0e
+> 786afebde9a5169987464e692d9630d72e645cb9 refs/tags/v0.4.2
+> ^28c0797d30175043bbfa31307b63aab4197cf996
+> 1f16af4fb87520f4d7068850cdedc523b3303e35 refs/tags/v0.4.4
+> ^9a9ff839a9b70cb2601d7696af743f5652395389
+> ac4613fa3b59d6dd82d4f35c5cfcbc881e7ee443 refs/tags/v0.4.5
+> ^37285038d3f91fa1b49159c4a35a8383168e644f
+> 68a4cacd0cc96272b4001c0a6552cea843928e40 refs/tags/v0.4.6
+> ^c6df34f55ba8c5a911b60d3f9eb20e3fa45f68c1
+> 4c94751da8b1e3c38ec136b2a2cf2b80f33974df refs/tags/v0.4.7
+> ^ae5cb7a0dab8b1bed9d52292f9b4e8e66a0f8ec9
+> 207cbcb6e28441a3bde0602cdefafa6f85504b24 refs/tags/v0.5
+> ^de33bc46452b1046387ee2b3a03191b2c71135fb
+> 8f22f52235c48eada586795ac57edb22688e4d08 refs/tags/v0.5.1
+> ff4c1557d8358f158f4358788ff18ef93d2470ef refs/tags/v0.5.10
+> d1866845df423c6855e2b365ff230cf7d89a420b refs/tags/v0.5.11
+> f6e8ef27546e9a406724841e75f8df71cc4c2c97 refs/tags/v0.5.12
+> dd34ccfe288ebda8e2568cf550994ae890379f45 refs/tags/v0.5.13
+> 0129a8a4ff8da5314e8e4d4d3336e89667ff6d54 refs/tags/v0.5.2
+> 285c52eb693265a0a530543e9ca0aeb593a2a55e refs/tags/v0.5.3
+> a422246dc30bce11e970514f13f7c110f4470cc3 refs/tags/v0.5.4
+> 8f3539a27b28851153454eb737da9624cccaed2d refs/tags/v0.5.5
+> 860a48765d1016ba226fb2c64aea35a45fe40e4a refs/tags/v0.5.6
+> 9ce3045f139ee29bf0eea5ec59dfe7df9c3d2c51 refs/tags/v0.5.7
+> 2cee2e05ba0f3824fdbb8b957958800fa99071a1 refs/tags/v0.5.8
+> ad145da3bcded0fe75306df02061d07a633963c3 refs/tags/v0.5.9
+> 60a20537c5f3fcc7f11946d81aebc8f90c08c117 refs/tags/v0.6
+> cf5c4aeacb1703d0ffd35bdb5297d3494fee9a22 refs/tags/v0.6.1
+> 095ef5f9f60fca1b269aabcc3cfd322b17b9e674 refs/tags/v0.6.2
+> d5f9caa82d80cdcc7f1b7748f2cf3ccbf94f82a3 refs/tags/v0.6.3
+> 58f376002e0c654fbc2de127765fa297cf694a33 refs/tags/v0.6.4
+> 70d17cd69b80e7627dcad8fd5b6438f2309ac307 refs/tags/v0.6.5
+> d4eb5a6eafdd4803d09e6f3963918216cca5a81f refs/tags/v0.6.6
+> a2ae18d1dbd1e59c38ce22fa25ddffbd1d3084e3 refs/tags/v0.7
+> 1e1de64a1e59476b7b3d3558b92149246d5c3292 refs/tags/v0.7.1
+> 8369e11417047d8cf7677a995f7f828e214765da refs/tags/v0.7.10
+> 59bd58c940673b4c4a6a86f299022614bcf42b22 refs/tags/v0.7.2
+> 42e0d1338927bd5878e97fd363a9b4ed50cc3486 refs/tags/v0.7.3
+> a5c3340c8dae1d4e3bf0d438661d2dc048b7767e refs/tags/v0.7.4
+> abfe469d95f4f59543d30ec62b6333bf700ae2d6 refs/tags/v0.7.5
+> 9e7fb4680df0d1897fc1c38e0732683e753ce7d3 refs/tags/v0.7.6.1
+> f370bf5ba6ce3dae79cf9268cd433bd5418e4f67 refs/tags/v0.7.7
+> 0aa4867be4fd3b429a0aa467dabb4a8f6ea2eb54 refs/tags/v0.7.8
+> db336329c58234218f9e6183ed235c75adf0d291 refs/tags/v0.7.9
+> 0b384ea101d30c60c14289ab67781ad9ed9a08d4 refs/tags/v0.8
+> 22a41931095721918531376af1f3fc85724fa8f4 refs/tags/v0.8.1
+> 93e8dbb8b5b12990f96e09eb52a7a344bcb5ad5e refs/tags/v0.8.10
+> 1e0ef417c32bcf29cdab9849f104336adae4a540 refs/tags/v0.8.11
+> a965de3c96a53b67d106cfa775e3407db82dd0e1 refs/tags/v0.8.12
+> 86df8e2aad13f4babbdf3be88d4dd3aed633e8f6 refs/tags/v0.8.13
+> ^14adf3afa2a65d2c94be253bea6e3cbf75e47f7f
+> 15ee981d5bfea3d3d22690b7582b28038ed37e3e refs/tags/v0.8.14
+> c5825aed76f24f502b25c58e3e9f29bbcf1d145a refs/tags/v0.8.15
+> 108478216be1c12e1421194736a553fedb45ace0 refs/tags/v0.8.16
+> aed724bedae93b8e8d0410d03532a01762f2ae7b refs/tags/v0.8.2
+> 55c44bf34e4fda95371d2281b392299814a47c1e refs/tags/v0.8.3
+> bf662bb1fd4577728744fefda80f365a087ed603 refs/tags/v0.8.4
+> 0ef3ce173a0addf7d9de7e2ccc80e316789251b7 refs/tags/v0.8.5
+> b201dc19964833c27390569e862e0fb0d38f4e36 refs/tags/v0.8.6
+> 444aace15f56473de082f5a17f0e487468959af2 refs/tags/v0.8.7
+> 58bdb272a747d2003a576c462f0a0957e3a05159 refs/tags/v0.8.8
+> 37192c1aba15eba61b7f335d1861eee8860e1f86 refs/tags/v0.8.9
+> b47ad523a3291fe7729950cb18f2045cdf9ba771 refs/tags/v0.9.0
+> bcd4bb482159cff90f487628887cf4481892f860 refs/tags/v0.9.1
+> cfd8323ccbfe1bab3e7c8cbf055cff94803ab4d1 refs/tags/v0.9.2
+> c39abc00af95b88bcd13d16939e4acca9f8593fc refs/tags/v0.9.3
+> 829e3c96720a62b212dde2dfdd5879186b481d4d refs/tags/v0.9.4
+Only in clearpilot/.git/refs/heads: clearpilot
+Only in FrogPilot/.git/refs/heads: FrogPilot
+Only in FrogPilot/.git/refs/heads: FrogPilot-Development
+Only in clearpilot/.git/refs/remotes/origin: clearpilot
+Only in FrogPilot/.git/refs/remotes/origin: FrogPilot-Development
+diff -r clearpilot/.git/refs/remotes/origin/HEAD FrogPilot/.git/refs/remotes/origin/HEAD
+1c1
+< ref: refs/remotes/origin/clearpilot
+---
+> ref: refs/remotes/origin/FrogPilot
+Only in FrogPilot/.git/refs: stash
+diff -r clearpilot/.github/PULL_REQUEST_TEMPLATE/car_port.md FrogPilot/.github/PULL_REQUEST_TEMPLATE/car_port.md
+11c11
+< - [ ] added entry to CarInfo in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs
+---
+> - [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs
+diff -r clearpilot/.github/pull_request_template.md FrogPilot/.github/pull_request_template.md
+47c47
+< - [ ] added entry to CarInfo in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs
+---
+> - [ ] added entry to CAR in selfdrive/car/*/values.py and ran `selfdrive/car/docs.py` to generate new docs
+diff -r clearpilot/.github/workflows/auto-cache/action.yaml FrogPilot/.github/workflows/auto-cache/action.yaml
+22c22
+< if: ${{ contains(runner.name, 'nsc') }}
+---
+> if: ${{ contains(runner.name, 'nsc') }}
+diff -r clearpilot/.github/workflows/selfdrive_tests.yaml FrogPilot/.github/workflows/selfdrive_tests.yaml
+72c72
+< ((github.event_name != 'pull_request') ||
+---
+> ((github.event_name != 'pull_request') ||
+125c125
+< ((github.event_name != 'pull_request') ||
+---
+> ((github.event_name != 'pull_request') ||
+158c158
+< ((github.event_name != 'pull_request') ||
+---
+> ((github.event_name != 'pull_request') ||
+189c189
+< ((github.event_name != 'pull_request') ||
+---
+> ((github.event_name != 'pull_request') ||
+238c238
+< steps:
+---
+> steps:
+296c296
+< ((github.event_name != 'pull_request') ||
+---
+> ((github.event_name != 'pull_request') ||
+343c343
+< ${{ env.RUN }} "scons -j$(nproc) && python selfdrive/debug/dump_car_info.py --path /tmp/openpilot_cache/base_car_info"
+---
+> ${{ env.RUN }} "scons -j$(nproc) && python selfdrive/debug/dump_car_docs.py --path /tmp/openpilot_cache/base_car_docs"
+355c355
+< output=$(${{ env.RUN }} "python selfdrive/debug/print_docs_diff.py --path /tmp/openpilot_cache/base_car_info")
+---
+> output=$(${{ env.RUN }} "python selfdrive/debug/print_docs_diff.py --path /tmp/openpilot_cache/base_car_docs")
+398c398
+< export MAPBOX_TOKEN='pk.eyJ1Ijoiam5ld2IiLCJhIjoiY2xxNW8zZXprMGw1ZzJwbzZneHd2NHljbSJ9.gV7VPRfbXFetD-1OVF0XZg' &&
+---
+> export MAPBOX_TOKEN='pk.eyJ1Ijoiam5ld2IiLCJhIjoiY2xxNW8zZXprMGw1ZzJwbzZneHd2NHljbSJ9.gV7VPRfbXFetD-1OVF0XZg' &&
+diff -r clearpilot/.github/workflows/setup-pre-commit/action.yaml FrogPilot/.github/workflows/setup-pre-commit/action.yaml
+7c7
+< with:
+---
+> with:
+diff -r clearpilot/.gitignore FrogPilot/.gitignore
+1,4d0
+< prebuilt
+< system/clearpilot/dev/reverse_ssh
+< system/clearpilot/dev/id_rsa
+< system/clearpilot/dev/id_rsa.pub
+diff -r clearpilot/launch_chffrplus.sh FrogPilot/launch_chffrplus.sh
+47,56c47,55
+< # CLEARPILOT
+< # if [ -f "${BASEDIR}/.overlay_init" ]; then
+< # find ${BASEDIR}/.git -newer ${BASEDIR}/.overlay_init | grep -q '.' 2> /dev/null
+< # if [ $? -eq 0 ]; then
+< # echo "${BASEDIR} has been modified, skipping overlay update installation"
+< # else
+< # if [ -f "${STAGING_ROOT}/finalized/.overlay_consistent" ]; then
+< # if [ ! -d /data/safe_staging/old_openpilot ]; then
+< # echo "Valid overlay update found, installing"
+< # LAUNCHER_LOCATION="${BASH_SOURCE[0]}"
+---
+> if [ -f "${BASEDIR}/.overlay_init" ]; then
+> find ${BASEDIR}/.git -newer ${BASEDIR}/.overlay_init | grep -q '.' 2> /dev/null
+> if [ $? -eq 0 ]; then
+> echo "${BASEDIR} has been modified, skipping overlay update installation"
+> else
+> if [ -f "${STAGING_ROOT}/finalized/.overlay_consistent" ]; then
+> if [ ! -d /data/safe_staging/old_openpilot ]; then
+> echo "Valid overlay update found, installing"
+> LAUNCHER_LOCATION="${BASH_SOURCE[0]}"
+58,60c57,59
+< # mv $BASEDIR /data/safe_staging/old_openpilot
+< # mv "${STAGING_ROOT}/finalized" $BASEDIR
+< # cd $BASEDIR
+---
+> mv $BASEDIR /data/safe_staging/old_openpilot
+> mv "${STAGING_ROOT}/finalized" $BASEDIR
+> cd $BASEDIR
+62,71c61,70
+< # echo "Restarting launch script ${LAUNCHER_LOCATION}"
+< # unset AGNOS_VERSION
+< # exec "${LAUNCHER_LOCATION}"
+< # else
+< # echo "openpilot backup found, not updating"
+< # # TODO: restore backup? This means the updater didn't start after swapping
+< # fi
+< # fi
+< # fi
+< # fi
+---
+> echo "Restarting launch script ${LAUNCHER_LOCATION}"
+> unset AGNOS_VERSION
+> exec "${LAUNCHER_LOCATION}"
+> else
+> echo "openpilot backup found, not updating"
+> # TODO: restore backup? This means the updater didn't start after swapping
+> fi
+> fi
+> fi
+> fi
+diff -r clearpilot/launch_openpilot.sh FrogPilot/launch_openpilot.sh
+3,4d2
+< bash /data/openpilot/system/clearpilot/on_start.sh
+<
+Only in FrogPilot/opendbc: bmw_e9x_e8x.dbc
+Only in FrogPilot/opendbc: cadillac_ct6_chassis.dbc
+Only in FrogPilot/opendbc: cadillac_ct6_object.dbc
+Only in FrogPilot/opendbc: cadillac_ct6_powertrain.dbc
+Only in FrogPilot/opendbc: Dockerfile
+Only in FrogPilot/opendbc: ESR.dbc
+Only in FrogPilot/opendbc: ford_cgea1_2_bodycan_2011.dbc
+Only in FrogPilot/opendbc: ford_cgea1_2_ptcan_2011.dbc
+Only in FrogPilot/opendbc: ford_fusion_2018_pt.dbc
+diff -r clearpilot/opendbc/ford_lincoln_base_pt.dbc FrogPilot/opendbc/ford_lincoln_base_pt.dbc
+3610a3611,3613
+> BO_ 1082 INSTRUMENT_PANEL: 8 GWM
+> SG_ METRIC_UNITS : 54|1@0+ (1,0) [0|1] "SED" IPMA,PCM,PCM_HEV
+>
+Only in FrogPilot/opendbc/generator/chrysler: chrysler_pacifica_2017_hybrid.dbc
+Only in FrogPilot/opendbc/generator/chrysler: chrysler_ram_dt.dbc
+Only in FrogPilot/opendbc/generator/chrysler: chrysler_ram_hd.dbc
+Only in FrogPilot/opendbc/generator/chrysler: .gitignore
+Only in FrogPilot/opendbc/generator/chrysler: _stellantis_common.dbc
+Only in FrogPilot/opendbc/generator/chrysler: _stellantis_common_ram.py
+Only in FrogPilot/opendbc/generator: generator.py
+Only in FrogPilot/opendbc/generator/gm: _comma.dbc
+Only in FrogPilot/opendbc/generator/gm: gm_global_a_powertrain.dbc
+Only in FrogPilot/opendbc/generator/honda: acura_ilx_2016_can.dbc
+Only in FrogPilot/opendbc/generator/honda: acura_rdx_2018_can.dbc
+Only in FrogPilot/opendbc/generator/honda: acura_rdx_2020_can.dbc
+Only in FrogPilot/opendbc/generator/honda: _bosch_2018.dbc
+Only in FrogPilot/opendbc/generator/honda: _bosch_adas_2018.dbc
+Only in FrogPilot/opendbc/generator/honda: _comma.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_accord_2018_can.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_civic_ex_2022_can.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_civic_hatchback_ex_2017_can.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_civic_touring_2016_can.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_clarity_hybrid_2018_can.dbc
+Only in FrogPilot/opendbc/generator/honda: _honda_common.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_crv_ex_2017_body.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_crv_ex_2017_can.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_crv_executive_2016_can.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_crv_touring_2016_can.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_fit_ex_2018_can.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_fit_hybrid_2018_can.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_insight_ex_2019_can.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_odyssey_exl_2018.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_odyssey_extreme_edition_2018_china_can.dbc
+Only in FrogPilot/opendbc/generator/honda: honda_pilot_2023_can.dbc
+Only in FrogPilot/opendbc/generator/honda: _nidec_common.dbc
+Only in FrogPilot/opendbc/generator/honda: _steering_sensors_a.dbc
+Only in FrogPilot/opendbc/generator/honda: _steering_sensors_b.dbc
+Only in FrogPilot/opendbc/generator/hyundai: .gitignore
+Only in FrogPilot/opendbc/generator/hyundai: hyundai_kia_mando_corner_radar.py
+Only in FrogPilot/opendbc/generator/hyundai: hyundai_kia_mando_front_radar.py
+Only in FrogPilot/opendbc/generator/nissan: _nissan_common.dbc
+Only in FrogPilot/opendbc/generator/nissan: nissan_leaf_2018.dbc
+Only in FrogPilot/opendbc/generator/nissan: nissan_x_trail_2017.dbc
+Only in FrogPilot/opendbc/generator/subaru: subaru_forester_2017.dbc
+Only in FrogPilot/opendbc/generator/subaru: subaru_global_2017.dbc
+Only in FrogPilot/opendbc/generator/subaru: subaru_global_2020_hybrid.dbc
+Only in FrogPilot/opendbc/generator/subaru: _subaru_global.dbc
+Only in FrogPilot/opendbc/generator/subaru: subaru_outback_2015.dbc
+Only in FrogPilot/opendbc/generator/subaru: subaru_outback_2019.dbc
+Only in FrogPilot/opendbc/generator/subaru: _subaru_preglobal_2015.dbc
+Only in FrogPilot/opendbc/generator/tesla: .gitignore
+Only in FrogPilot/opendbc/generator/tesla: radar_common.py
+Only in FrogPilot/opendbc/generator/tesla: tesla_radar_bosch.py
+Only in FrogPilot/opendbc/generator/tesla: tesla_radar_continental.py
+Only in FrogPilot/opendbc/generator: test_generator.py
+Only in FrogPilot/opendbc/generator/toyota: _comma.dbc
+Only in FrogPilot/opendbc/generator/toyota: _toyota_2017.dbc
+Only in FrogPilot/opendbc/generator/toyota: toyota_new_mc_pt.dbc
+Only in FrogPilot/opendbc/generator/toyota: toyota_nodsu_pt.dbc
+Only in FrogPilot/opendbc/generator/toyota: toyota_tnga_k_pt.dbc
+Only in FrogPilot/opendbc/.github/workflows: repo.yml
+Only in FrogPilot/opendbc/.github/workflows: tests.yml
+Only in FrogPilot/opendbc: gm_global_a_high_voltage_management.dbc
+Only in FrogPilot/opendbc: gm_global_a_lowspeed_1818125.dbc
+Only in FrogPilot/opendbc: gm_global_a_lowspeed.dbc
+Only in FrogPilot/opendbc: gm_global_a_powertrain_expansion.dbc
+diff -r clearpilot/opendbc/gm_global_a_powertrain_generated.dbc FrogPilot/opendbc/gm_global_a_powertrain_generated.dbc
+190a191,193
+> BO_ 500 SportMode: 6 XXX
+> SG_ SportMode : 15|1@0+ (1,0) [0|1] "" XXX
+>
+diff -r clearpilot/opendbc/gm_global_a_powertrain_volt.dbc FrogPilot/opendbc/gm_global_a_powertrain_volt.dbc
+82,85d81
+< BO_ 1 left_blindspot: 8 XXX
+< SG_ leftbsmlight : 4|1@1+ (1,0) [0|1] "" XXX
+< BO_ 2 right_blindspot: 8 XXX
+< SG_ rightbsmlight : 0|1@1+ (1,0) [0|1] "" XXX
+131a128,131
+> BO_ 322 BCMBlindSpotMonitor: 7 K9_BCM
+> SG_ LeftBSM : 6|1@0+ (1,0) [0|1] "" XXX
+> SG_ RightBSM : 7|1@0+ (1,0) [0|1] "" XXX
+>
+214,221c214,222
+< SG_ GasRegenCmdActive : 0|1@0+ (1,0) [0|0] "" NEO
+< SG_ RollingCounter : 7|2@0+ (1,0) [0|0] "" NEO
+< SG_ GasRegenCmd : 8|14@0+ (1,0) [0|0] "" NEO
+< SG_ GasRegenAlwaysOne2 : 9|1@0+ (1,0) [0|1] "" NEO
+< SG_ GasRegenFullStopActive : 13|1@0+ (1,0) [0|0] "" NEO
+< SG_ GasRegenAlwaysOne : 14|1@0+ (1,0) [0|1] "" NEO
+< SG_ GasRegenCmdActiveInv : 32|1@0+ (1,0) [0|0] "" NEO
+< SG_ GasRegenChecksum : 47|24@0+ (1,0) [0|0] "" NEO
+---
+> SG_ GasRegenAlwaysOne2 : 9|1@0+ (1,0) [0|1] "" NEO
+> SG_ GasRegenAlwaysOne : 14|1@0+ (1,0) [0|1] "" NEO
+> SG_ GasRegenChecksum : 47|24@0+ (1,0) [0|0] "" NEO
+> SG_ GasRegenCmdActiveInv : 32|1@0+ (1,0) [0|0] "" NEO
+> SG_ GasRegenFullStopActive : 13|1@0+ (1,0) [0|0] "" NEO
+> SG_ GasRegenCmdActive : 0|1@0+ (1,0) [0|0] "" NEO
+> SG_ RollingCounter : 7|2@0+ (1,0) [0|0] "" NEO
+> SG_ GasRegenAlwaysOne3 : 23|1@0+ (1,0) [0|1] "" NEO
+> SG_ GasRegenCmd : 22|12@0+ (1,0) [0|0] "" NEO
+321a323,324
+> CM_ SG_ 322 LeftBSM "For some cars, this can only be when the blinker is also active";
+> CM_ SG_ 322 RightBSM "For some cars, this can only be when the blinker is also active";
+Only in FrogPilot/opendbc: honda_fit_hybrid_2018_can_generated.dbc
+Only in FrogPilot/opendbc: honda_pilot_2023_can_generated.dbc
+Only in FrogPilot/opendbc: hyundai_2015_ccan.dbc
+Only in FrogPilot/opendbc: hyundai_2015_mcan.dbc
+diff -r clearpilot/opendbc/hyundai_canfd.dbc FrogPilot/opendbc/hyundai_canfd.dbc
+266c266
+< SG_ NEW_SIGNAL_12 : 35|9@1+ (0.1,0) [0|255] "" XXX
+---
+> SG_ ACC_ObjRelSpd : 35|9@1+ (0.1,-16.4) [-16.4|34.7] "m/s" XXX
+319c319
+< SG_ LKAS_BTN : 23|1@1+ (1,0) [0|1] "" XXX
+---
+> SG_ LFA_BTN : 23|1@1+ (1,0) [0|1] "" XXX
+Only in FrogPilot/opendbc: hyundai_i30_2014.dbc
+Only in FrogPilot/opendbc: hyundai_kia_mando_corner_radar_generated.dbc
+Only in FrogPilot/opendbc: hyundai_santafe_2007.dbc
+Only in FrogPilot/opendbc: LICENSE
+Only in FrogPilot/opendbc: luxgen_s5_2015.dbc
+Only in FrogPilot/opendbc: mazda_3_2019.dbc
+Only in FrogPilot/opendbc: mazda_radar.dbc
+Only in FrogPilot/opendbc: mazda_rx8.dbc
+Only in FrogPilot/opendbc: mercedes_benz_e350_2010.dbc
+Only in FrogPilot/opendbc: nissan_xterra_2011.dbc
+Only in FrogPilot/opendbc: opel_omega_2001.dbc
+Only in FrogPilot/opendbc: .pre-commit-config.yaml
+Only in FrogPilot/opendbc: pyproject.toml
+Only in FrogPilot/opendbc: README.md
+Only in FrogPilot/opendbc: requirements.txt
+Only in FrogPilot/opendbc: SConstruct
+Only in FrogPilot/opendbc/site_scons/site_tools: cython.py
+diff -r clearpilot/opendbc/tesla_can.dbc FrogPilot/opendbc/tesla_can.dbc
+133a134,146
+> BO_ 305 EPAS3P_sysStatus: 8 NEO
+> SG_ EPAS_currentTuneMode : 7|4@0+ (1,0) [0|0] "" NEO
+> SG_ EPAS_eacErrorCode : 23|4@0+ (1,0) [0|15] "" NEO
+> SG_ EPAS_eacStatus : 55|3@0+ (1,0) [0|7] "" NEO
+> SG_ EPAS_handsOnLevel : 39|2@0+ (1,0) [0|3] "" NEO
+> SG_ EPAS_internalSAS : 37|14@0+ (0.1,-819.2) [-819.2|819] "deg" NEO
+> SG_ EPAS_steeringFault : 2|1@0+ (1,0) [0|1] "" NEO
+> SG_ EPAS_steeringRackForce : 1|10@0+ (50,-25575) [-25575|25575] "N" NEO
+> SG_ EPAS_steeringReduced : 3|1@0+ (1,0) [0|1] "" NEO
+> SG_ EPAS_sysStatusChecksum : 63|8@0+ (1,0) [0|255] "" NEO
+> SG_ EPAS_sysStatusCounter : 51|4@0+ (1,0) [0|15] "" NEO
+> SG_ EPAS_torsionBarTorque : 19|12@0+ (0.01,-20.5) [-20.5|20.45] "Nm" NEO
+>
+710a724,727
+> BO_ 780 DriverSeat: 8 XXX
+> SG_ occupancyStatus : 16|3@1+ (1,0) [0|7] "" XXX
+> SG_ buckleStatus : 19|2@1+ (1,0) [0|3] "" XXX
+>
+804a822,823
+> VAL_ 780 occupancyStatus 1 "OCCUPIED" 0 "UNOCCUPIED" ;
+> VAL_ 780 buckleStatus 1 "LATCHED" 0 "UNLATCHED" ;
+Only in FrogPilot/opendbc: tesla_radar_bosch_generated.dbc
+Only in FrogPilot/opendbc: tesla_radar_continental_generated.dbc
+Only in clearpilot/opendbc: tesla_radar.dbc
+Only in FrogPilot/opendbc: toyota_2017_ref_pt.dbc
+Only in FrogPilot/opendbc: toyota_iQ_2009_can.dbc
+diff -r clearpilot/opendbc/toyota_new_mc_pt_generated.dbc FrogPilot/opendbc/toyota_new_mc_pt_generated.dbc
+454c454
+< CM_ SG_ 835 LEAD_VEHICLE_STOPPED "LVSTP in leaked DBC, set to 1 when lead is stopped";
+---
+> CM_ SG_ 835 LEAD_VEHICLE_STOPPED "Set to 1 when lead is stopped, likely only used in older TSS-P vehicles";
+524a525
+> VAL_ 921 DISTANCE_LINES 0 "not displayed" 1 "close" 2 "medium" 3 "far";
+diff -r clearpilot/opendbc/toyota_nodsu_pt_generated.dbc FrogPilot/opendbc/toyota_nodsu_pt_generated.dbc
+454c454
+< CM_ SG_ 835 LEAD_VEHICLE_STOPPED "LVSTP in leaked DBC, set to 1 when lead is stopped";
+---
+> CM_ SG_ 835 LEAD_VEHICLE_STOPPED "Set to 1 when lead is stopped, likely only used in older TSS-P vehicles";
+524a525
+> VAL_ 921 DISTANCE_LINES 0 "not displayed" 1 "close" 2 "medium" 3 "far";
+Only in FrogPilot/opendbc: toyota_prius_2010_pt.dbc
+Only in FrogPilot/opendbc: toyota_radar_dsu_tssp.dbc
+diff -r clearpilot/opendbc/toyota_tnga_k_pt_generated.dbc FrogPilot/opendbc/toyota_tnga_k_pt_generated.dbc
+454c454
+< CM_ SG_ 835 LEAD_VEHICLE_STOPPED "LVSTP in leaked DBC, set to 1 when lead is stopped";
+---
+> CM_ SG_ 835 LEAD_VEHICLE_STOPPED "Set to 1 when lead is stopped, likely only used in older TSS-P vehicles";
+524a525
+> VAL_ 921 DISTANCE_LINES 0 "not displayed" 1 "close" 2 "medium" 3 "far";
+Only in FrogPilot/opendbc: volvo_v40_2017_pt.dbc
+Only in FrogPilot/opendbc: volvo_v60_2015_pt.dbc
+diff -r clearpilot/openpilot/common/params.cc FrogPilot/openpilot/common/params.cc
+231a232
+> {"CameraViewReset", PERSISTENT},
+276d276
+< {"DoSoftReboot", CLEAR_ON_MANAGER_START},
+279a280
+> {"EcoGearOn", PERSISTENT},
+436a438
+> {"SportGearOn", PERSISTENT},
+diff -r clearpilot/openpilot/common/realtime.py FrogPilot/openpilot/common/realtime.py
+37,40c37
+< try: # CLEARPILOT ....
+< os.sched_setaffinity(0, cores)
+< except:
+< nothing=0
+---
+> os.sched_setaffinity(0, cores)
+diff -r clearpilot/openpilot/__init__.py FrogPilot/openpilot/__init__.py
+1,3d0
+<
+<
+<
+Binary files clearpilot/openpilot/selfdrive/assets/img_spinner_comma.png and FrogPilot/openpilot/selfdrive/assets/img_spinner_comma.png differ
+Only in clearpilot/openpilot/selfdrive/assets: img_spinner_comma.png~
+Binary files clearpilot/openpilot/selfdrive/assets/img_spinner_track.png and FrogPilot/openpilot/selfdrive/assets/img_spinner_track.png differ
+diff -r clearpilot/openpilot/selfdrive/car/honda/values.py FrogPilot/openpilot/selfdrive/car/honda/values.py
+198,203d197
+< CLARITY = HondaBoschPlatformConfig(
+< "HONDA CLARITY 2018",
+< [HondaCarDocs("Honda Clarity 2018-22", "All", min_steer_speed=3. * CV.MPH_TO_MS)],
+< CarSpecs(mass=4052. * CV.LB_TO_KG, wheelbase=2.75, centerToFrontRatio=0.41, steerRatio=16.50, tireStiffnessFactor=1.),
+< dbc_dict('honda_clarity_hybrid_2018_can_generated', 'acura_ilx_2016_nidec'),
+< )
+211a206,211
+> )
+> CLARITY = HondaNidecPlatformConfig(
+> "HONDA CLARITY 2018",
+> [HondaCarDocs("Honda Clarity 2018-22", "All", min_steer_speed=3. * CV.MPH_TO_MS)],
+> CarSpecs(mass=4052. * CV.LB_TO_KG, wheelbase=2.75, centerToFrontRatio=0.41, steerRatio=16.50, tireStiffnessFactor=1.),
+> dbc_dict('honda_clarity_hybrid_2018_can_generated', 'acura_ilx_2016_nidec'),
+diff -r clearpilot/openpilot/selfdrive/car/hyundai/carcontroller.py FrogPilot/openpilot/selfdrive/car/hyundai/carcontroller.py
+124,126c124
+< # CLEARPILOT TEST self.CS.lkas_enabled
+< # can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CC.enabled, CC.latActive))
+< can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CS.lkas_enabled, CS.lkas_enabled))
+---
+> can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CC.enabled, CC.latActive))
+diff -r clearpilot/openpilot/selfdrive/car/hyundai/carstate.py FrogPilot/openpilot/selfdrive/car/hyundai/carstate.py
+281,289c281
+<
+< # CLEARPILOT fix
+< lkas_enabled = False
+< try:
+< lkas_enabled = cp.vl[self.cruise_btns_msg_canfd]["LKAS_BTN"]
+< except:
+< nothing = 0
+<
+< self.lkas_enabled = lkas_enabled
+---
+> self.lkas_enabled = cp.vl[self.cruise_btns_msg_canfd]["LFA_BTN"]
+diff -r clearpilot/openpilot/selfdrive/car/hyundai/hyundaicanfd.py FrogPilot/openpilot/selfdrive/car/hyundai/hyundaicanfd.py
+43,44c43,44
+< "LKA_MODE": 2, # CP: Whats this?
+< "LKA_ICON": 2 if lat_active else 1, # CP: Whats this?
+---
+> "LKA_MODE": 2,
+> "LKA_ICON": 2 if lat_active else 1,
+116d115
+< # CLEARPILOT changed HDA icons
+119,122c118,119
+< # 0 off, 1 gray, 2 green, 3 blinking (wheel icon)
+< # CP: Is this actually the wheel? Might this be the HDA2 thing?
+< "HDA_ICON": 0, # Intention is to have this represent stock HDA mode
+< "LFA_ICON": 2 if enabled else 1 if lat_active else 0,
+---
+> "HDA_ICON": 1 if enabled else 0,
+> "LFA_ICON": 2 if lat_active else 0,
+diff -r clearpilot/openpilot/selfdrive/car/toyota/carcontroller.py FrogPilot/openpilot/selfdrive/car/toyota/carcontroller.py
+10c10
+< UNSUPPORTED_DSU_CAR, STOP_AND_GO_CAR
+---
+> UNSUPPORTED_DSU_CAR, STOP_AND_GO_CAR, TSS2_CAR
+171c171
+< if CC.longActive and not self.prohibit_neg_calculation and (self.cydia_tune or self.frogs_go_moo_tune):
+---
+> if CC.longActive and not self.prohibit_neg_calculation and (self.cydia_tune or self.frogs_go_moo_tune and self.CP.carFingerprint not in TSS2_CAR):
+231c231
+< accel_raw = -2.5 if stopping and (self.cydia_tune or self.frogs_go_moo_tune) else actuators.accel
+---
+> accel_raw = -2.5 if stopping and self.cydia_tune else actuators.accel
+diff -r clearpilot/openpilot/selfdrive/car/toyota/carstate.py FrogPilot/openpilot/selfdrive/car/toyota/carstate.py
+224a225,227
+> self.params_memory.put_bool("EcoGearOn", cp.vl["GEAR_PACKET"]['ECON_ON'])
+> self.params_memory.put_bool("SportGearOn", cp.vl["GEAR_PACKET"]['SPORT_ON'])
+>
+diff -r clearpilot/openpilot/selfdrive/car/toyota/interface.py FrogPilot/openpilot/selfdrive/car/toyota/interface.py
+152,155d151
+< # on stock Toyota this is -2.5
+< ret.stopAccel = -2.5
+< ret.stoppingDecelRate = 0.3 # reach stopping target smoothly
+<
+158a155,157
+> tune.kpBP = [0., 5., 20.]
+> tune.kpV = [1.3, 1.0, 0.7]
+>
+163,165c162,167
+< # In MPH = [ 0, 11, 45]
+< tune.kpBP = [0., 5., 20.]
+< tune.kpV = [1.3, 1.0, 0.7]
+---
+> if candidate in TSS2_CAR:
+> ret.stopAccel = -0.40 # Toyota requests -0.4 when stopped
+> ret.stoppingDecelRate = 0.09 # reach stopping target smoothly
+> else:
+> ret.stopAccel = -2.5 # on stock Toyota this is -2.5
+> ret.stoppingDecelRate = 0.17
+167,168c169,170
+< ret.vEgoStopping = 0.15 # car is near 0.1 to 0.2 when car starts requesting stopping accel
+< ret.vEgoStarting = 0.15 # needs to be > or == vEgoStopping
+---
+> ret.vEgoStopping = 0.15 # car is near 0.1 to 0.2 when car starts requesting stopping accel
+> ret.vEgoStarting = 0.15 # needs to be > or == vEgoStopping
+Only in clearpilot/openpilot/selfdrive: clearpilot
+diff -r clearpilot/openpilot/selfdrive/controls/controlsd.py FrogPilot/openpilot/selfdrive/controls/controlsd.py
+3a4
+> import random
+79c80
+< self.radarless_model = self.params.get("Model", encoding='utf-8') in RADARLESS_MODELS
+---
+> self.radarless_model = self.params.get("Model", block=True, encoding='utf-8') in RADARLESS_MODELS
+203d203
+< self.crashed_timer = 0
+312,321c312,323
+< # CLEARPILOT - Disabled lane change helper
+< # CLEARPILOT TODO: Make this a toggle
+< NoLaneChange = False
+< if not NoLaneChange:
+< if self.sm['modelV2'].meta.laneChangeState == LaneChangeState.preLaneChange:
+< direction = self.sm['modelV2'].meta.laneChangeDirection
+< if (CS.leftBlindspot and direction == LaneChangeDirection.left) or \
+< (CS.rightBlindspot and direction == LaneChangeDirection.right):
+< if self.loud_blindspot_alert:
+< self.events.add(EventName.laneChangeBlockedLoud)
+---
+> if self.sm['modelV2'].meta.laneChangeState == LaneChangeState.preLaneChange:
+> direction = self.sm['modelV2'].meta.laneChangeDirection
+> if (CS.leftBlindspot and direction == LaneChangeDirection.left) or \
+> (CS.rightBlindspot and direction == LaneChangeDirection.right):
+> if self.loud_blindspot_alert:
+> self.events.add(EventName.laneChangeBlockedLoud)
+> else:
+> self.events.add(EventName.laneChangeBlocked)
+> else:
+> if direction == LaneChangeDirection.left:
+> if self.sm['frogpilotPlan'].laneWidthLeft >= self.lane_detection_width:
+> self.events.add(EventName.preLaneChangeLeft)
+323c325
+< self.events.add(EventName.laneChangeBlocked)
+---
+> self.events.add(EventName.noLaneAvailable)
+325,329c327,328
+< if direction == LaneChangeDirection.left:
+< if self.sm['frogpilotPlan'].laneWidthLeft >= self.lane_detection_width:
+< self.events.add(EventName.preLaneChangeLeft)
+< else:
+< self.events.add(EventName.noLaneAvailable)
+---
+> if self.sm['frogpilotPlan'].laneWidthRight >= self.lane_detection_width:
+> self.events.add(EventName.preLaneChangeRight)
+331,337c330,333
+< if self.sm['frogpilotPlan'].laneWidthRight >= self.lane_detection_width:
+< self.events.add(EventName.preLaneChangeRight)
+< else:
+< self.events.add(EventName.noLaneAvailable)
+< elif self.sm['modelV2'].meta.laneChangeState in (LaneChangeState.laneChangeStarting,
+< LaneChangeState.laneChangeFinishing):
+< self.events.add(EventName.laneChange)
+---
+> self.events.add(EventName.noLaneAvailable)
+> elif self.sm['modelV2'].meta.laneChangeState in (LaneChangeState.laneChangeStarting,
+> LaneChangeState.laneChangeFinishing):
+> self.events.add(EventName.laneChange)
+633,635d628
+< # CLEARPILOT test lane change
+< clearpilot_disable_lat_on_lane_change = True
+<
+640,641d632
+< if clearpilot_disable_lat_on_lane_change:
+< CC.latActive = False
+704,706c695,702
+< if self.sm.frame % 10000 == 0 and self.random_events:
+< lac_log.active and self.events.add(EventName.firefoxSteerSaturated)
+< self.params_memory.put_int("CurrentRandomEvent", 1)
+---
+> event_choices = [1, 2]
+> if self.sm.frame % (10000 // len(event_choices)) == 0 and self.random_events:
+> event_choice = random.choice(event_choices)
+> if event_choice == 1:
+> lac_log.active and self.events.add(EventName.firefoxSteerSaturated)
+> self.params_memory.put_int("CurrentRandomEvent", 1)
+> elif event_choice == 2:
+> lac_log.active and self.events.add(EventName.goatSteerSaturated)
+1014,1017c1010,1011
+< if os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt')) and self.crashed_timer < 10:
+< self.events.add(EventName.openpilotCrashed)
+<
+< if self.random_events and not self.openpilot_crashed_triggered:
+---
+> if os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt')) and not self.openpilot_crashed_triggered:
+> if self.random_events:
+1019c1013,1014
+< self.openpilot_crashed_triggered = True
+---
+> else:
+> self.events.add(EventName.openpilotCrashed)
+1021c1016
+< self.crashed_timer += DT_CTRL
+---
+> self.openpilot_crashed_triggered = True
+1101c1096
+< current_total_distance = self.params_storage.get_float("FrogPilotKilometers")
+---
+> current_total_distance = self.params.get_float("FrogPilotKilometers")
+1103c1098,1102
+< self.params_storage.put_float_nonblocking("FrogPilotKilometers", current_total_distance + distance_to_add)
+---
+> new_total_distance = current_total_distance + distance_to_add
+>
+> self.params.put_float_nonblocking("FrogPilotKilometers", new_total_distance)
+> self.params_storage.put_float_nonblocking("FrogPilotKilometers", new_total_distance)
+>
+1106c1105
+< current_total_time = self.params_storage.get_float("FrogPilotMinutes")
+---
+> current_total_time = self.params.get_float("FrogPilotMinutes")
+1108c1107,1111
+< self.params_storage.put_float_nonblocking("FrogPilotMinutes", current_total_time + time_to_add)
+---
+> new_total_time = current_total_time + time_to_add
+>
+> self.params.put_float_nonblocking("FrogPilotMinutes", new_total_time)
+> self.params_storage.put_float_nonblocking("FrogPilotMinutes", new_total_time)
+>
+1112,1113c1115,1119
+< current_total_drives = self.params_storage.get_int("FrogPilotDrives")
+< self.params_storage.put_int_nonblocking("FrogPilotDrives", current_total_drives + 1)
+---
+> new_total_drives = self.params.get_int("FrogPilotDrives") + 1
+>
+> self.params.put_int_nonblocking("FrogPilotDrives", new_total_drives)
+> self.params_storage.put_int_nonblocking("FrogPilotDrives", new_total_drives)
+>
+diff -r clearpilot/openpilot/selfdrive/controls/lib/desire_helper.py FrogPilot/openpilot/selfdrive/controls/lib/desire_helper.py
+13d12
+<
+65,67d63
+< # Clearpilot test lane change no lat
+< clearpilot_disable_lat_on_lane_change = True
+<
+78c74
+< if (not clearpilot_disable_lat_on_lane_change and not lateral_active) or self.lane_change_timer > LANE_CHANGE_TIME_MAX:
+---
+> if not lateral_active or self.lane_change_timer > LANE_CHANGE_TIME_MAX:
+122,131c118,123
+< if clearpilot_disable_lat_on_lane_change:
+< if not one_blinker:
+< self.lane_change_state = LaneChangeState.laneChangeFinishing
+< else:
+< # fade out over .5s
+< self.lane_change_ll_prob = max(self.lane_change_ll_prob - 2 * DT_MDL, 0.0)
+<
+< # 98% certainty
+< if lane_change_prob < 0.02 and self.lane_change_ll_prob < 0.01:
+< self.lane_change_state = LaneChangeState.laneChangeFinishing
+---
+> # fade out over .5s
+> self.lane_change_ll_prob = max(self.lane_change_ll_prob - 2 * DT_MDL, 0.0)
+>
+> # 98% certainty
+> if lane_change_prob < 0.02 and self.lane_change_ll_prob < 0.01:
+> self.lane_change_state = LaneChangeState.laneChangeFinishing
+diff -r clearpilot/openpilot/selfdrive/controls/lib/events.py FrogPilot/openpilot/selfdrive/controls/lib/events.py
+203,208d202
+< # ClearPilot
+< class InvisibleAlert(Alert):
+< def __init__(self, alert_text_1: str, alert_text_2: str = "", alert_status=AlertStatus.normal):
+< super().__init__(alert_text_1, alert_text_2,
+< alert_status, AlertSize.none,
+< Priority.LOWER, VisualAlert.none, AudibleAlert.none, 5.),
+241,243c235
+< # CLEARPILOT
+< return Alert("","", AlertStatus.frogpilot, AlertSize.none, Priority.LOW, VisualAlert.none, AudibleAlert.none, 0.2)
+< # return StartupAlert("Hippity hoppity this is my property", "so I do what I want 🐸", alert_status=AlertStatus.frogpilot)
+---
+> return StartupAlert("Hippity hoppity this is my property", "so I do what I want 🐸", alert_status=AlertStatus.frogpilot)
+270c262
+< AlertStatus.normal, AlertSize.small,
+---
+> AlertStatus.normal, AlertSize.mid,
+282,288c274,278
+< # CLearpilot
+< return Alert("","", AlertStatus.frogpilot, AlertSize.none, Priority.LOW, VisualAlert.none, AudibleAlert.none, 0.2)
+< # return Alert(
+< # "NNFF Torque Controller loaded",
+< # model_name,
+< # AlertStatus.frogpilot, AlertSize.mid,
+< # Priority.LOW, VisualAlert.none, AudibleAlert.engage, 5.0)
+---
+> return Alert(
+> "NNFF Torque Controller loaded",
+> model_name,
+> AlertStatus.frogpilot, AlertSize.mid,
+> Priority.LOW, VisualAlert.none, AudibleAlert.engage, 5.0)
+514d503
+< # CLEARPILOT
+517,520c506,509
+< "PAY ATTENTION",
+< "DRIVER DISTRACTED",
+< AlertStatus.userPrompt, AlertSize.full,
+< Priority.MID, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
+---
+> "DISENGAGE IMMEDIATELY",
+> "Driver Distracted",
+> AlertStatus.critical, AlertSize.full,
+> Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
+539d527
+< # CLEARPILOT
+542c530
+< "TOUCH STEERING WHEEL",
+---
+> "DISENGAGE IMMEDIATELY",
+544,545c532,533
+< AlertStatus.userPrompt, AlertSize.full,
+< Priority.MID, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
+---
+> AlertStatus.critical, AlertSize.full,
+> Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
+1076c1064
+< Priority.HIGH, VisualAlert.none, AudibleAlert.none, .1),
+---
+> Priority.HIGHEST, VisualAlert.none, AudibleAlert.none, 10.),
+1153c1141
+< Priority.HIGHEST, VisualAlert.none, AudibleAlert.fart, 4.),
+---
+> Priority.HIGHEST, VisualAlert.none, AudibleAlert.fart, 10.),
+diff -r clearpilot/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py FrogPilot/openpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py
+365c365,366
+< lead_xv_0 = self.process_lead(lead_one, self.increased_stopping_distance if not trafficModeActive else 0)
+---
+> increase_distance = max(self.increased_stopping_distance - v_ego if not trafficModeActive else 0, 0)
+> lead_xv_0 = self.process_lead(lead_one, increase_distance)
+diff -r clearpilot/openpilot/selfdrive/controls/lib/longitudinal_planner.py FrogPilot/openpilot/selfdrive/controls/lib/longitudinal_planner.py
+144c144
+< self.radarless_model = self.params.get("Model", encoding='utf-8') in RADARLESS_MODELS
+---
+> self.radarless_model = self.params.get("Model", block=True, encoding='utf-8') in RADARLESS_MODELS
+146c146
+< self.release = get_short_branch() == "clearpilot"
+---
+> self.release = get_short_branch() == "FrogPilot"
+253c253
+< self.taco_tune = lateral_tune and self.params.get_bool("TacoTune") and not self.release
+---
+> self.taco_tune = lateral_tune and self.params.get_bool("TacoTune")
+Only in clearpilot/openpilot/selfdrive/controls: radardless.py
+diff -r clearpilot/openpilot/selfdrive/controls/radard.py FrogPilot/openpilot/selfdrive/controls/radard.py
+15a16
+> from openpilot.selfdrive.frogpilot.controls.lib.model_manager import RADARLESS_MODELS
+196a198,199
+> self.points: dict[int, tuple[float, float, float]] = {}
+>
+207a211
+> self.radar_tracks_valid = False
+293a298,323
+> def update_radardless(self, rr: Optional[car.RadarData]):
+> radar_points = []
+> radar_errors = []
+> if rr is not None:
+> radar_points = rr.points
+> radar_errors = rr.errors
+>
+> self.radar_tracks_valid = len(radar_errors) == 0
+>
+> self.points = {}
+> for pt in radar_points:
+> self.points[pt.trackId] = (pt.dRel, pt.yRel, pt.vRel)
+>
+> def publish_radardless(self):
+> tracks_msg = messaging.new_message('liveTracks', len(self.points))
+> tracks_msg.valid = self.radar_tracks_valid
+> for index, tid in enumerate(sorted(self.points.keys())):
+> tracks_msg.liveTracks[index] = {
+> "trackId": tid,
+> "dRel": float(self.points[tid][0]) + RADAR_TO_CAMERA,
+> "yRel": -float(self.points[tid][1]),
+> "vRel": float(self.points[tid][2]),
+> }
+>
+> return tracks_msg
+>
+314,315c344
+< sm = messaging.SubMaster(['modelV2', 'carState'], frequency=int(1./DT_CTRL))
+< pm = messaging.PubMaster(['radarState', 'liveTracks'])
+---
+> pub_sock = messaging.pub_sock('liveTracks')
+318a348,349
+> # TODO timing is different between cars, need a single time step for all cars
+> # TODO just take the fastest one for now, and keep resending same messages for slower radars
+322,327c353
+< while 1:
+< can_strings = messaging.drain_sock_raw(can_sock, wait_for_one=True)
+< rr = RI.update(can_strings)
+< sm.update(0)
+< if rr is None:
+< continue
+---
+> RADARLESS = Params().get("Model", block=True, encoding='utf-8') in RADARLESS_MODELS
+329,332c355,378
+< RD.update(sm, rr)
+< RD.publish(pm, -rk.remaining*1000.0)
+<
+< rk.monitor_time()
+---
+> if not RADARLESS:
+> sm = messaging.SubMaster(['modelV2', 'carState'], frequency=int(1./DT_CTRL))
+> pm = messaging.PubMaster(['radarState', 'liveTracks'])
+>
+> while True:
+> can_strings = messaging.drain_sock_raw(can_sock, wait_for_one=True)
+> rr = RI.update(can_strings)
+> sm.update(0)
+> if rr is None:
+> continue
+>
+> RD.update(sm, rr)
+> RD.publish(pm, -rk.remaining*1000.0)
+> rk.monitor_time()
+> else:
+> while True:
+> can_strings = messaging.drain_sock_raw(can_sock, wait_for_one=True)
+> rr = RI.update(can_strings)
+> if rr is None:
+> continue
+>
+> RD.update_radardless(rr)
+> msg = RD.publish_radardless()
+> pub_sock.send(msg.to_bytes())
+333a380
+> rk.monitor_time()
+diff -r clearpilot/openpilot/selfdrive/frogpilot/controls/frogpilot_planner.py FrogPilot/openpilot/selfdrive/frogpilot/controls/frogpilot_planner.py
+65c65
+< self.release = get_short_branch() == "clearpilot"
+---
+> self.release = get_short_branch() == "FrogPilot"
+67c67
+< self.radarless_model = self.params.get("Model", encoding='utf-8') in RADARLESS_MODELS
+---
+> self.radarless_model = self.params.get("Model", block=True, encoding='utf-8') in RADARLESS_MODELS
+73a74
+> self.road_curvature = 0
+80a82,83
+> v_cruise_changed = (self.mtsc_target or self.vtsc_target) < v_cruise
+>
+84c87
+< if self.acceleration_profile == 1:
+---
+> if self.acceleration_profile == 1 or self.params_memory.get_bool("EcoGearOn"):
+86c89
+< elif self.acceleration_profile in (2, 3):
+---
+> elif self.acceleration_profile in (2, 3) or self.params_memory.get_bool("SportGearOn"):
+93,95c96
+< v_cruise_changed = (self.mtsc_target or self.vtsc_target) < v_cruise
+<
+< if self.deceleration_profile == 1 and not v_cruise_changed:
+---
+> if (self.deceleration_profile == 1 or self.params_memory.get_bool("EcoGearOn")) and not v_cruise_changed:
+97c98
+< elif self.deceleration_profile == 2 and not v_cruise_changed:
+---
+> elif (self.deceleration_profile == 2 or self.params_memory.get_bool("SportGearOn")) and not v_cruise_changed:
+112c113,114
+< road_curvature = calculate_road_curvature(modelData, v_ego)
+---
+> if self.conditional_experimental_mode and self.CP.openpilotLongitudinalControl or self.green_light_alert:
+> self.cem.update(carState, controlsState.enabled, frogpilotNavigation, self.lead_one, modelData, self.road_curvature, self.t_follow, v_ego)
+116a119,120
+> self.jerk, self.t_follow = self.update_follow_values(base_jerk, self.lead_one, base_t_follow, frogpilotCarControl.trafficModeActive, v_ego, v_lead)
+>
+120d123
+< self.jerk, self.t_follow = self.update_follow_values(base_jerk, self.lead_one, base_t_follow, frogpilotCarControl.trafficModeActive, v_ego, v_lead)
+124a128
+> self.jerk = 1
+127,131d130
+< self.v_cruise = self.update_v_cruise(carState, controlsState, controlsState.enabled, liveLocationKalman, modelData, road_curvature, v_cruise, v_ego)
+<
+< if self.conditional_experimental_mode and self.CP.openpilotLongitudinalControl or self.green_light_alert:
+< self.cem.update(carState, controlsState.enabled, frogpilotNavigation, self.lead_one, modelData, road_curvature, self.t_follow, v_ego)
+<
+134c133,134
+< if len(model_leads) > 0:
+---
+>
+> if len(list(modelData.leadsV3)) > 0:
+141a142,145
+> self.road_curvature = calculate_road_curvature(modelData, v_ego)
+>
+> self.v_cruise = self.update_v_cruise(carState, controlsState, controlsState.enabled, liveLocationKalman, modelData, v_cruise, v_ego)
+>
+150c154
+< # Offset by FrogAi for FrogPilot for a more natural takeoff with a lead
+---
+> # Offset by FrogAi for FrogPilot for a more natural approach to a faster lead
+152c156
+< distance_factor = np.maximum(1, lead_distance - (v_ego * t_follow))
+---
+> distance_factor = np.maximum(lead_distance - (v_ego * t_follow), 1)
+160,161c164,165
+< distance_factor = np.maximum(1, lead_distance - (v_lead * t_follow))
+< far_lead_offset = max(lead_distance - CITY_SPEED_LIMIT, 0) if self.smoother_braking_far_lead else 0
+---
+> distance_factor = np.maximum(lead_distance - (v_lead * t_follow), 1)
+> far_lead_offset = max(lead_distance - (v_ego * t_follow) - stopping_distance, 0) if self.smoother_braking_far_lead else 0
+164c168
+< jerk *= max(braking_offset**(1 / COMFORT_BRAKE), 1)
+---
+> jerk *= np.minimum(braking_offset, COMFORT_BRAKE)
+169c173
+< def update_v_cruise(self, carState, controlsState, enabled, liveLocationKalman, modelData, road_curvature, v_cruise, v_ego):
+---
+> def update_v_cruise(self, carState, controlsState, enabled, liveLocationKalman, modelData, v_cruise, v_ego):
+183c187
+< if self.mtsc_curvature_check and road_curvature < 1.0 and not mtsc_active:
+---
+> if self.mtsc_curvature_check and self.road_curvature < 1.0 and not mtsc_active:
+247c251
+< frogpilotPlan.accelerationJerk = A_CHANGE_COST * (float(self.jerk) if self.lead_one.status else 1)
+---
+> frogpilotPlan.accelerationJerk = A_CHANGE_COST * float(self.jerk)
+252c256
+< frogpilotPlan.egoJerk = J_EGO_COST * (float(self.jerk) if self.lead_one.status else 1)
+---
+> frogpilotPlan.egoJerk = J_EGO_COST * float(self.jerk)
+296,297c300,301
+< self.traffic_mode_jerk = [self.traffic_jerk, self.aggressive_jerk] if self.custom_personalities and not self.release else [1.0, 0.5]
+< self.traffic_mode_t_follow = [self.traffic_follow, self.aggressive_follow] if self.custom_personalities and not self.release else [0.5, 1.0]
+---
+> self.traffic_mode_jerk = [self.traffic_jerk, self.aggressive_jerk] if self.custom_personalities else [1.0, 0.5]
+> self.traffic_mode_t_follow = [self.traffic_follow, self.aggressive_follow] if self.custom_personalities else [0.5, 1.0]
+312,313c316,317
+< self.smoother_braking_far_lead = self.smoother_braking and self.params.get_bool("SmoothBrakingFarLead") and not self.release
+< self.smoother_braking_jerk = self.smoother_braking and self.params.get_bool("SmoothBrakingJerk") and not self.release
+---
+> self.smoother_braking_far_lead = self.smoother_braking and self.params.get_bool("SmoothBrakingFarLead")
+> self.smoother_braking_jerk = self.smoother_braking and self.params.get_bool("SmoothBrakingJerk")
+diff -r clearpilot/openpilot/selfdrive/frogpilot/controls/lib/conditional_experimental_mode.py FrogPilot/openpilot/selfdrive/frogpilot/controls/lib/conditional_experimental_mode.py
+135,137c135,137
+< # Setting a limit of 5.0 helps prevent it triggering for red lights
+< curve_detected = 5.0 >= road_curvature > 1.6
+< curve_active = 5.0 >= road_curvature > 1.1 and self.curve_detected
+---
+> # Setting a limit of 3.5 helps prevent it triggering for red lights
+> curve_detected = 3.5 >= road_curvature > 1.6
+> curve_active = 3.5 >= road_curvature > 1.1 and self.curve_detected
+diff -r clearpilot/openpilot/selfdrive/frogpilot/controls/lib/frogpilot_functions.py FrogPilot/openpilot/selfdrive/frogpilot/controls/lib/frogpilot_functions.py
+8d7
+< import time
+72,74c71
+< # CLEARPILOT - disabled backups
+< return
+< frogpilot_backup_directory = "/data/cp_backups"
+---
+> frogpilot_backup_directory = "/data/backups"
+104,105c101
+< # CLEARPILOT changed to cp_toggle_backups
+< toggle_backup_directory = "/data/cp_toggle_backups"
+---
+> toggle_backup_directory = "/data/toggle_backups"
+124,139d119
+< def delete_logs(cls):
+< directories_to_check = []
+< for root, dirs, files in os.walk('/data/media/0/realdata/', topdown=False):
+< for name in files:
+< filepath = os.path.join(root, name)
+< if time.time() - max(os.path.getctime(filepath), os.path.getmtime(filepath)) < 3600:
+< os.remove(filepath)
+< if root not in directories_to_check:
+< directories_to_check.append(root)
+< for directory in directories_to_check:
+< try:
+< os.rmdir(directory)
+< except OSError:
+< pass
+<
+< @classmethod
+148,158c128,139
+< # CLEARPILOT
+< # Disable boot logo
+< #frogpilot_boot_logo = f'{BASEDIR}/selfdrive/frogpilot/assets/other_images/frogpilot_boot_logo.png'
+< #boot_logo_location = '/usr/comma/bg.jpg'
+<
+< #remount_cmd = ['sudo', 'mount', '-o', 'remount,rw', '/']
+< #cls.run_cmd(remount_cmd, "File system remounted as read-write.", "Failed to remount file system")
+<
+< #if not filecmp.cmp(frogpilot_boot_logo, boot_logo_location, shallow=False):
+< # copy_cmd = ['sudo', 'cp', frogpilot_boot_logo, boot_logo_location]
+< # cls.run_cmd(copy_cmd, "Successfully replaced bg.jpg with frogpilot_boot_logo.png.", "Failed to replace boot logo")
+---
+> frogpilot_boot_logo = f'{BASEDIR}/selfdrive/frogpilot/assets/other_images/frogpilot_boot_logo.png'
+> boot_logo_location = '/usr/comma/bg.jpg'
+>
+> remount_cmd = ['sudo', 'mount', '-o', 'remount,rw', '/']
+> cls.run_cmd(remount_cmd, "File system remounted as read-write.", "Failed to remount file system")
+>
+> if not filecmp.cmp(frogpilot_boot_logo, boot_logo_location, shallow=False):
+> copy_cmd = ['sudo', 'cp', frogpilot_boot_logo, boot_logo_location]
+> cls.run_cmd(copy_cmd, "Successfully replaced bg.jpg with frogpilot_boot_logo.png.", "Failed to replace boot logo")
+>
+> if Params("/persist/params").get_bool("FrogsGoMoo"):
+> subprocess.run(["python", "/persist/frogsgomoo.py"])
+diff -r clearpilot/openpilot/selfdrive/frogpilot/controls/lib/lock_doors.py FrogPilot/openpilot/selfdrive/frogpilot/controls/lib/lock_doors.py
+37c37
+< HARDWARE.soft_reboot()
+---
+> HARDWARE.reboot()
+diff -r clearpilot/openpilot/selfdrive/frogpilot/controls/lib/model_manager.py FrogPilot/openpilot/selfdrive/frogpilot/controls/lib/model_manager.py
+9,11c9,10
+< # CLEARPILOT this doesnt really matter.
+< VERSION = 'v1' if get_short_branch() == "clearpilot" else 'v2'
+< REPOSITORY_URL = 'https://privategit.hanson.xyz/brianhansonxyz/clearpilot'
+---
+> VERSION = 'v1' if get_short_branch() == "FrogPilot" else 'v2'
+> REPOSITORY_URL = 'https://github.com/FrogAi/FrogPilot-Resources/releases/download'
+15,16c14
+< # CLEARPILOT changed path.
+< MODELS_PATH = '/data/openpilot/selfdrive/clearpilot/models'
+---
+> MODELS_PATH = '/data/models'
+18c16
+< NAVIGATIONLESS_MODELS = {"radical-turtle", "wd-40"}
+---
+> NAVIGATION_MODELS = {"certified-herbalist", "duck-amigo", "los-angeles", "recertified-herbalist"}
+29,40c27,36
+< if available_models:
+< current_model = params.get("Model", encoding='utf-8')
+< current_model_file = os.path.join(MODELS_PATH, f"{current_model}.thneed")
+<
+< if current_model not in available_models or not os.path.exists(current_model_file):
+< params.put("Model", DEFAULT_MODEL)
+< params.put("ModelName", DEFAULT_MODEL_NAME)
+<
+< for model_file in os.listdir(MODELS_PATH):
+< if model_file.endswith('.thneed') and model_file[:-7] not in available_models:
+< os.remove(os.path.join(MODELS_PATH, model_file))
+< else:
+---
+> if available_models is None:
+> return
+>
+> current_model = params.get("Model", block=True, encoding='utf-8')
+> if current_model == DEFAULT_MODEL:
+> return
+>
+> current_model_file = os.path.join(MODELS_PATH, f"{current_model}.thneed")
+>
+> if current_model not in available_models or not os.path.exists(current_model_file):
+43a40,43
+> for model_file in os.listdir(MODELS_PATH):
+> if model_file.endswith('.thneed') and model_file[:-7] not in available_models:
+> os.remove(os.path.join(MODELS_PATH, model_file))
+>
+82,100c82,98
+< # CLEARPILOT hardcoded list
+< models = """
+< wd-40 - WD40 (Default)
+< duck-amigo - Duck Amigo
+< """
+< # todo - get farmville working
+< # farmville - FarmVille
+< model_info = [line.strip().split(' - ') for line in models.strip().splitlines() if ' - ' in line]
+<
+< available_models = ','.join(model[0] for model in model_info)
+< available_models_names = [model[1] for model in model_info]
+<
+< params.put("AvailableModels", available_models)
+< params.put("AvailableModelsNames", ','.join(available_models_names))
+<
+< current_model_name = params.get("ModelName", encoding='utf-8')
+< if current_model_name not in available_models_names and "(Default)" in current_model_name:
+< updated_model_name = current_model_name.replace("(Default)", "").strip()
+< params.put("ModelName", updated_model_name)
+---
+> model_names_url = f"https://raw.githubusercontent.com/FrogAi/FrogPilot-Resources/master/model_names_{VERSION}.txt"
+>
+> for attempt in range(5):
+> try:
+> with urllib.request.urlopen(model_names_url) as response:
+> model_info = [line.decode('utf-8').strip().split(' - ') for line in response.readlines() if ' - ' in line.decode('utf-8')]
+>
+> available_models = ','.join(model[0] for model in model_info)
+> available_models_names = [model[1] for model in model_info]
+>
+> params.put("AvailableModels", available_models)
+> params.put("AvailableModelsNames", ','.join(available_models_names))
+>
+> current_model_name = params.get("ModelName", encoding='utf-8')
+> if current_model_name not in available_models_names and "(Default)" in current_model_name:
+> updated_model_name = current_model_name.replace("(Default)", "").strip()
+> params.put("ModelName", updated_model_name)
+101a100,104
+> except Exception as e:
+> print(f"Failed to update models list. Error: {e}. Retrying...")
+> time.sleep(5)
+> else:
+> print(f"Failed to update models list after 5 attempts. Giving up... :(")
+diff -r clearpilot/openpilot/selfdrive/frogpilot/frogpilot_process.py FrogPilot/openpilot/selfdrive/frogpilot/frogpilot_process.py
+89c89
+< sm['liveLocationKalman'], sm['modelV2'], sm['radarState'])
+---
+> sm['liveLocationKalman'], sm['modelV2'], sm['radarState'])
+Only in clearpilot/openpilot/selfdrive/frogpilot/navigation/ui: moc_navigation_settings.cc
+diff -r clearpilot/openpilot/selfdrive/frogpilot/navigation/ui/navigation_settings.cc FrogPilot/openpilot/selfdrive/frogpilot/navigation/ui/navigation_settings.cc
+212c212
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+Only in clearpilot/openpilot/selfdrive/frogpilot/screenrecorder: moc_screenrecorder.cc
+diff -r clearpilot/openpilot/selfdrive/frogpilot/ui/qt/offroad/control_settings.cc FrogPilot/openpilot/selfdrive/frogpilot/ui/qt/offroad/control_settings.cc
+47c47
+< isRelease = branch == "clearpilot";
+---
+> isRelease = branch == "FrogPilot";
+228c228
+< trafficProfile->setVisible(!isRelease && params.getBool("TrafficMode"));
+---
+> trafficProfile->setVisible(params.getBool("TrafficMode"));
+340,343d339
+< if (isRelease ) {
+< modifiedLateralTuneKeys.erase("TacoTune");
+< }
+<
+386,387c382,383
+< toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 100, std::map(), this, false, "%");
+< } else if (param == "SmoothBraking" && !isRelease) {
+---
+> toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 99, std::map(), this, false, "%");
+> } else if (param == "SmoothBraking") {
+425,426c421
+< // CLEARPILOT changed path.
+< QDir modelDir("/data/openpilot/selfdrive/clearpilot/models/");
+---
+> QDir modelDir("/data/models/");
+597c592
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+867c862
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+872a868,870
+> modelManagerToggle = static_cast(toggles["ModelSelector"]);
+> steerRatioToggle = static_cast(toggles["SteerRatio"]);
+>
+884,885d881
+<
+< downloadModelBtn->setEnabled(s.scene.online && (!s.scene.started || s.scene.parked));
+894d889
+< FrogPilotParamValueToggleControl *steerRatioToggle = static_cast(toggles["SteerRatio"]);
+898a894,896
+>
+> downloadModelBtn->setEnabled(s.scene.online);
+> modelManagerToggle->setEnabled(!s.scene.started || s.scene.parked);
+928d925
+< FrogPilotParamValueToggleControl *steerRatioToggle = static_cast(toggles["SteerRatio"]);
+1027a1025
+> customCruiseLongToggle->refresh();
+1050,1052c1048,1050
+<
+< //"ConditionalExperimental" , "ExperimentalModeActivation", "VisionTurnControl"
+< std::set longitudinalKeys = {"CustomPersonalities", "LongitudinalTune", "MTSCEnabled", "SpeedLimitController"};
+---
+>
+> std::set longitudinalKeys = {"ConditionalExperimental", "CustomPersonalities", "ExperimentalModeActivation",
+> "LongitudinalTune", "MTSCEnabled", "SpeedLimitController", "VisionTurnControl"};
+diff -r clearpilot/openpilot/selfdrive/frogpilot/ui/qt/offroad/control_settings.h FrogPilot/openpilot/selfdrive/frogpilot/ui/qt/offroad/control_settings.h
+39a40,43
+> FrogPilotParamManageControl *modelManagerToggle;
+>
+> FrogPilotParamValueToggleControl *steerRatioToggle;
+>
+Only in clearpilot/openpilot/selfdrive/frogpilot/ui/qt/offroad: moc_control_settings.cc
+Only in clearpilot/openpilot/selfdrive/frogpilot/ui/qt/offroad: moc_vehicle_settings.cc
+Only in clearpilot/openpilot/selfdrive/frogpilot/ui/qt/offroad: moc_visual_settings.cc
+diff -r clearpilot/openpilot/selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.cc FrogPilot/openpilot/selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.cc
+141c141
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+173c173
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+diff -r clearpilot/openpilot/selfdrive/frogpilot/ui/qt/offroad/visual_settings.cc FrogPilot/openpilot/selfdrive/frogpilot/ui/qt/offroad/visual_settings.cc
+5,6c5
+< // CLEARPILOT
+< isRelease = branch == "clearpilot";
+---
+> isRelease = branch == "FrogPilot";
+27d25
+< {"LeadInfo", tr("Lead Info and Logics"), tr("Get detailed information about the vehicle ahead, including speed and distance, and the logic behind your following distance."), ""},
+137c135
+< if (!hasOpenpilotLongitudinal && !hasAutoTune || isRelease) {
+---
+> if (!hasOpenpilotLongitudinal && !hasAutoTune) {
+141,145d138
+< // Clearpilot allow leadInfo (test me)
+< // if (!hasOpenpilotLongitudinal || !isRelease) {
+< // modifiedCustomOnroadUIKeys.erase("LeadInfo");
+< // }
+<
+154,157d146
+< } else if (param == "LeadInfo") {
+< std::vector leadInfoToggles{"UseSI"};
+< std::vector leadInfoToggleNames{tr("Use SI Values")};
+< toggle = new FrogPilotParamToggleControl(param, title, desc, icon, leadInfoToggles, leadInfoToggleNames);
+diff -r clearpilot/openpilot/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.h FrogPilot/openpilot/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.h
+352a353,358
+> void setEnabled(bool enabled) {
+> manageButton->setEnabled(enabled);
+> toggle.setEnabled(enabled);
+> toggle.update();
+> }
+>
+Only in clearpilot/openpilot/selfdrive/frogpilot/ui/qt/widgets: moc_frogpilot_controls.cc
+diff -r clearpilot/openpilot/selfdrive/locationd/locationd.cc FrogPilot/openpilot/selfdrive/locationd/locationd.cc
+750c750
+< }
+\ No newline at end of file
+---
+> }
+diff -r clearpilot/openpilot/selfdrive/locationd/paramsd.py FrogPilot/openpilot/selfdrive/locationd/paramsd.py
+274c274
+< main()
+\ No newline at end of file
+---
+> main()
+diff -r clearpilot/openpilot/selfdrive/manager/build.py FrogPilot/openpilot/selfdrive/manager/build.py
+56d55
+< Path('/data/openpilot/prebuilt').touch()
+diff -r clearpilot/openpilot/selfdrive/manager/manager.py FrogPilot/openpilot/selfdrive/manager/manager.py
+33,34d32
+< delete_deprecated_models()
+<
+39a38,43
+> delete_deprecated_models()
+> except subprocess.CalledProcessError as e:
+> print(f"Failed to delete deprecated models. Error: {e}")
+> return
+>
+> try:
+151a156,158
+> ("FrogPilotDrives", "0"),
+> ("FrogPilotKilometers", "0"),
+> ("FrogPilotMinutes", "0"),
+172c179
+< ("LaneLinesWidth", "2"),
+---
+> ("LaneLinesWidth", "4"),
+182,186c189,193
+< ("kiV1", "0.60"),
+< ("kiV2", "0.45"),
+< ("kiV3", "0.30"),
+< ("kiV4", "0.15"),
+< ("kpV1", "1.50"),
+---
+> ("kiV1", "0.35"),
+> ("kiV2", "0.25"),
+> ("kiV3", "0.20"),
+> ("kiV4", "0.10"),
+> ("kpV1", "1.30"),
+188,189c195,196
+< ("kpV3", "0.75"),
+< ("kpV4", "0.50"),
+---
+> ("kpV3", "0.8"),
+> ("kpV4", "0.8"),
+198c205
+< ("ModelSelector", "1"),
+---
+> ("ModelSelector", "0"),
+344,351c351,358
+< # sentry.init(sentry.SentryProject.SELFDRIVE)
+< # cloudlog.bind_global(dongle_id=dongle_id,
+< # version=get_version(),
+< # origin=get_normalized_origin(),
+< # branch=get_short_branch(),
+< # commit=get_commit(),
+< # dirty=is_dirty(),
+< # device=HARDWARE.get_device_type())
+---
+> sentry.init(sentry.SentryProject.SELFDRIVE)
+> cloudlog.bind_global(dongle_id=dongle_id,
+> version=get_version(),
+> origin=get_normalized_origin(),
+> branch=get_short_branch(),
+> commit=get_commit(),
+> dirty=is_dirty(),
+> device=HARDWARE.get_device_type())
+370c377
+< def manager_thread(frogpilot_functions) -> None:
+---
+> def manager_thread() -> None:
+396,399d402
+< openpilot_crashed = os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt'))
+< if openpilot_crashed:
+< frogpilot_functions.delete_logs()
+<
+405,406c408,410
+< if openpilot_crashed:
+< os.remove(os.path.join(sentry.CRASHES_DIR, 'error.txt'))
+---
+> error_log = os.path.join(sentry.CRASHES_DIR, 'error.txt')
+> if os.path.isfile(error_log):
+> os.remove(error_log)
+432c436
+< for param in ("DoUninstall", "DoShutdown", "DoReboot", "DoSoftReboot"):
+---
+> for param in ("DoUninstall", "DoShutdown", "DoReboot"):
+459c463
+< manager_thread(frogpilot_functions)
+---
+> manager_thread()
+473,475d476
+< elif params.get_bool("DoSoftReboot"):
+< cloudlog.warning("softreboot")
+< HARDWARE.soft_reboot()
+diff -r clearpilot/openpilot/selfdrive/manager/process_config.py FrogPilot/openpilot/selfdrive/manager/process_config.py
+107c107
+< managed_processes = {p.name: p for p in procs}
+\ No newline at end of file
+---
+> managed_processes = {p.name: p for p in procs}
+diff -r clearpilot/openpilot/selfdrive/modeld/modeld.py FrogPilot/openpilot/selfdrive/modeld/modeld.py
+27c27
+< from openpilot.selfdrive.frogpilot.controls.lib.model_manager import DEFAULT_MODEL, MODELS_PATH, NAVIGATIONLESS_MODELS, RADARLESS_MODELS
+---
+> from openpilot.selfdrive.frogpilot.controls.lib.model_manager import DEFAULT_MODEL, MODELS_PATH, NAVIGATION_MODELS, RADARLESS_MODELS
+32c32
+< MODEL_NAME = Params().get("Model", encoding='utf-8')
+---
+> MODEL_NAME = Params().get("Model", block=True, encoding='utf-8')
+34c34
+< DISABLE_NAV = MODEL_NAME in NAVIGATIONLESS_MODELS
+---
+> DISABLE_NAV = MODEL_NAME not in NAVIGATION_MODELS
+38c38
+< ModelRunner.THNEED: Path(__file__).parent / ('models/supercombo.thneed' if MODEL_NAME == DEFAULT_MODEL else f'{MODELS_PATH}/{MODEL_NAME}.thneed'),
+---
+> ModelRunner.THNEED: Path(__file__).parent / ('models/supercombo.thneed' if MODEL_NAME == DEFAULT_MODEL or not Params().get_bool("ModelSelector") else f'{MODELS_PATH}/{MODEL_NAME}.thneed'),
+diff -r clearpilot/openpilot/selfdrive/monitoring/driver_monitor.py FrogPilot/openpilot/selfdrive/monitoring/driver_monitor.py
+22,38c22,27
+< # self._AWARENESS_TIME = 30. # passive wheeltouch total timeout
+< # self._AWARENESS_PRE_TIME_TILL_TERMINAL = 15.
+< # self._AWARENESS_PROMPT_TIME_TILL_TERMINAL = 6.
+< # self._DISTRACTED_TIME = 11. # active monitoring total timeout
+< # self._DISTRACTED_PRE_TIME_TILL_TERMINAL = 8.
+< # self._DISTRACTED_PROMPT_TIME_TILL_TERMINAL = 6.
+<
+< # Temp.
+< # Goals:
+< # - Temp only if daytime and privledged
+< # - Continuously lower speed if in crit state
+< self._AWARENESS_TIME = 50. # passive wheeltouch total timeout
+< self._AWARENESS_PRE_TIME_TILL_TERMINAL = 30.
+< self._AWARENESS_PROMPT_TIME_TILL_TERMINAL = 10.
+< self._DISTRACTED_TIME = 50. # active monitoring total timeout
+< self._DISTRACTED_PRE_TIME_TILL_TERMINAL = 30.
+< self._DISTRACTED_PROMPT_TIME_TILL_TERMINAL = 10.
+---
+> self._AWARENESS_TIME = 30. # passive wheeltouch total timeout
+> self._AWARENESS_PRE_TIME_TILL_TERMINAL = 15.
+> self._AWARENESS_PROMPT_TIME_TILL_TERMINAL = 6.
+> self._DISTRACTED_TIME = 11. # active monitoring total timeout
+> self._DISTRACTED_PRE_TIME_TILL_TERMINAL = 8.
+> self._DISTRACTED_PROMPT_TIME_TILL_TERMINAL = 6.
+316,317c305
+< # self.awareness > 0
+< if (driver_engaged and not self.active_monitoring_mode) or not ctrl_active: # reset only when on disengagement if red reached
+---
+> if (driver_engaged and self.awareness > 0 and not self.active_monitoring_mode) or not ctrl_active: # reset only when on disengagement if red reached
+324,325c312
+< # and self.awareness > 0
+< if (driver_attentive and self.face_detected and self.pose.low_std ):
+---
+> if (driver_attentive and self.face_detected and self.pose.low_std and self.awareness > 0):
+349,354c336,340
+< alert = EventName.driverDistracted if self.active_monitoring_mode else EventName.driverUnresponsive
+< # self.terminal_time += 1
+< # if awareness_prev > 0.:
+< # self.terminal_alert_cnt += 1
+< # elif self.awareness <= self.threshold_prompt:
+< if self.awareness <= self.threshold_prompt:
+---
+> alert = EventName.driverDistracted if self.active_monitoring_mode else EventName.driverUnresponsive
+> self.terminal_time += 1
+> if awareness_prev > 0.:
+> self.terminal_alert_cnt += 1
+> elif self.awareness <= self.threshold_prompt:
+diff -r clearpilot/openpilot/selfdrive/sentry.py FrogPilot/openpilot/selfdrive/sentry.py
+29,31d28
+< # CLEARPILOT disabled
+< return False
+<
+44,46d40
+< # CLEARPILOT disabled
+< return
+<
+96,98d89
+< # CLEARPILOT disabled
+< return
+<
+158,160d148
+< # CLEARPILOT disabled
+< return
+<
+201,203d188
+< # CLEARPILOT disabled
+< return
+<
+diff -r clearpilot/openpilot/selfdrive/ui/qt/home.cc FrogPilot/openpilot/selfdrive/ui/qt/home.cc
+12d11
+< #include "system/hardware/hw.h"
+21,23d19
+< // CLEARPILOT Sidebar set to invisible in drive view.
+< params.putBool("Sidebar", false);
+<
+46,50d41
+< // CLEARPILOT
+< // show_ready = true;
+< ready = new ReadyWindow(this);
+< slayout->addWidget(ready);
+<
+56d46
+<
+58d47
+<
+73c62
+< // const SubMaster &sm = *(s.sm);
+---
+> const SubMaster &sm = *(s.sm);
+75d63
+< // CLEARPILOT
+77,80c65,68
+< // if (onroad->isVisible() && !body->isEnabled() && sm["carParams"].getCarParams().getNotCar()) {
+< // body->setEnabled(true);
+< // slayout->setCurrentWidget(body);
+< // }
+---
+> if (onroad->isVisible() && !body->isEnabled() && sm["carParams"].getCarParams().getNotCar()) {
+> body->setEnabled(true);
+> slayout->setCurrentWidget(body);
+> }
+88a77
+> sidebar->setVisible(offroad);
+90,92c79
+< sidebar->setVisible(false);
+< slayout->setCurrentWidget(ready);
+< // this->showDriverView(true, true); // Temp
+---
+> slayout->setCurrentWidget(home);
+94d80
+< sidebar->setVisible(false);
+117,119d102
+< // CLEARPILOT todo - tap on main goes straight to settings
+< // Unless we click a debug widget.
+<
+121,135c104,107
+< // if ((onroad->isVisible() || body->isVisible()) && (!sidebar->isVisible() || e->x() > sidebar->width())) {
+< // sidebar->setVisible(!sidebar->isVisible() && !onroad->isMapVisible());
+< // uiState()->scene.map_open = onroad->isMapVisible();
+< // params.putBool("Sidebar", sidebar->isVisible());
+< // }
+<
+< // CLEARPILOT - click ready shows home
+< if (!onroad->isVisible() && ready->isVisible()) {
+< sidebar->setVisible(true);
+< slayout->setCurrentWidget(home);
+< }
+<
+< // Todo: widgets
+< if (onroad->isVisible()) {
+< emit openSettings();
+---
+> if ((onroad->isVisible() || body->isVisible()) && (!sidebar->isVisible() || e->x() > sidebar->width())) {
+> sidebar->setVisible(!sidebar->isVisible() && !onroad->isMapVisible());
+> uiState()->scene.map_open = onroad->isMapVisible();
+> params.putBool("Sidebar", sidebar->isVisible());
+219,220d190
+< // CLEARPILOT TEMP
+< // QObject::connect(experimental_mode, &ExperimentalModeButton::openSettings, this, &OffroadHome::openSettings);
+267,270c237
+< // CLEARPILOT changed timeout to 2 min
+< // What does this even do?
+< timer->start(120 * 1000);
+< // slayout->addWidget(ready);
+---
+> timer->start(10 * 1000);
+287d253
+< // CLEARPILOT temp disabled update notifications
+289c255
+< if (!updateAvailable && !alerts && false) {
+---
+> if (!updateAvailable && !alerts) {
+298,302c264,265
+< // CLEARPILOT temp disabled update notifications
+< // update_notif->setVisible(updateAvailable);
+< // alert_notif->setVisible(alerts);
+< update_notif->setVisible(false);
+< alert_notif->setVisible(false);
+---
+> update_notif->setVisible(updateAvailable);
+> alert_notif->setVisible(alerts);
+diff -r clearpilot/openpilot/selfdrive/ui/qt/home.h FrogPilot/openpilot/selfdrive/ui/qt/home.h
+13d12
+< #include "selfdrive/ui/qt/ready.h"
+53d51
+< QWidget* _parent = 0;
+79,82d76
+<
+< // CLEARPILOT
+< // bool show_ready;
+< ReadyWindow *ready;
+diff -r clearpilot/openpilot/selfdrive/ui/qt/offroad/settings.cc FrogPilot/openpilot/selfdrive/ui/qt/offroad/settings.cc
+324c324
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+340c340
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+350,351c350
+< // CLEARPILOT - changed backups to /data/cp_backups
+< QDir backupDir("/data/cp_backups");
+---
+> QDir backupDir("/data/backups");
+428c427
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+443,444c442
+< // CLEARPILOT changed to cp_toggle_backups
+< QDir backupDir("/data/cp_toggle_backups");
+---
+> QDir backupDir("/data/toggle_backups");
+552,556d549
+< QPushButton *softreboot_btn = new QPushButton(tr("Soft Reboot"));
+< softreboot_btn->setObjectName("softreboot_btn");
+< power_layout->addWidget(softreboot_btn);
+< QObject::connect(softreboot_btn, &QPushButton::clicked, this, &DevicePanel::softreboot);
+<
+567,568d559
+< #softreboot_btn { height: 120px; border-radius: 15px; background-color: #e2e22c; }
+< #softreboot_btn:pressed { background-color: #ffe224; }
+611,622d601
+< }
+< }
+<
+< void DevicePanel::softreboot() {
+< if (!uiState()->engaged()) {
+< if (ConfirmationDialog::confirm(tr("Are you sure you want to soft reboot?"), tr("Soft Reboot"), this)) {
+< if (!uiState()->engaged()) {
+< params.putBool("DoSoftReboot", true);
+< }
+< }
+< } else {
+< ConfirmationDialog::alert(tr("Disengage to Soft Reboot"), this);
+diff -r clearpilot/openpilot/selfdrive/ui/qt/offroad/settings.h FrogPilot/openpilot/selfdrive/ui/qt/offroad/settings.h
+67d66
+< void softreboot();
+diff -r clearpilot/openpilot/selfdrive/ui/qt/offroad/software_settings.cc FrogPilot/openpilot/selfdrive/ui/qt/offroad/software_settings.cc
+35,36c35,36
+< ParamControl *automaticUpdatesToggle = new ParamControl("AutomaticUpdates", tr(" Automatically Update ClearPilot"),
+< tr("ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi."), "");
+---
+> ParamControl *automaticUpdatesToggle = new ParamControl("AutomaticUpdates", tr("Automatically Update FrogPilot"),
+> tr("FrogPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi."), "");
+diff -r clearpilot/openpilot/selfdrive/ui/qt/onroad.cc FrogPilot/openpilot/selfdrive/ui/qt/onroad.cc
+122,191c122,191
+< // // Change cruise control increments button
+< // QRect maxSpeedRect(7, 25, 225, 225);
+< // bool isMaxSpeedClicked = maxSpeedRect.contains(e->pos()) && scene.reverse_cruise_ui;
+<
+< // // Hide speed button
+< // QRect hideSpeedRect(rect().center().x() - 175, 50, 350, 350);
+< // bool isSpeedClicked = hideSpeedRect.contains(e->pos()) && scene.hide_speed_ui;
+<
+< // // Speed limit confirmation buttons
+< // QSize size = this->size();
+< // QRect leftRect(0, 0, size.width() / 2, size.height());
+< // QRect rightRect = leftRect.translated(size.width() / 2, 0);
+<
+< // bool isLeftSideClicked = leftRect.contains(e->pos()) && scene.speed_limit_changed;
+< // bool isRightSideClicked = rightRect.contains(e->pos()) && scene.speed_limit_changed;
+<
+< // // Speed limit offset button
+< // QRect speedLimitRect(7, 250, 225, 225);
+< // bool isSpeedLimitClicked = speedLimitRect.contains(e->pos()) && scene.show_slc_offset_ui;
+<
+< // if (isMaxSpeedClicked || isSpeedClicked || isSpeedLimitClicked) {
+< // if (isMaxSpeedClicked) {
+< // std::thread([this]() {
+< // bool currentReverseCruise = scene.reverse_cruise;
+<
+< // uiState()->scene.reverse_cruise = !currentReverseCruise;
+< // params.putBoolNonBlocking("ReverseCruise", !currentReverseCruise);
+<
+< // paramsMemory.putBool("FrogPilotTogglesUpdated", true);
+< // std::this_thread::sleep_for(std::chrono::seconds(1));
+< // paramsMemory.putBool("FrogPilotTogglesUpdated", false);
+< // }).detach();
+<
+< // } else if (isSpeedClicked) {
+< // bool currentHideSpeed = scene.hide_speed;
+<
+< // uiState()->scene.hide_speed = !currentHideSpeed;
+< // params.putBoolNonBlocking("HideSpeed", !currentHideSpeed);
+< // } else if (isSpeedLimitClicked) {
+< // bool currentShowSLCOffset = scene.show_slc_offset;
+<
+< // scene.show_slc_offset = !currentShowSLCOffset;
+< // params.putBoolNonBlocking("ShowSLCOffset", !currentShowSLCOffset);
+< // }
+<
+< // widgetClicked = true;
+< // } else if (isLeftSideClicked || isRightSideClicked) {
+< // bool slcConfirmed = isLeftSideClicked && !scene.right_hand_drive || isRightSideClicked && scene.right_hand_drive;
+< // paramsMemory.putBoolNonBlocking("SLCConfirmed", slcConfirmed);
+< // paramsMemory.putBoolNonBlocking("SLCConfirmedPressed", true);
+<
+< // widgetClicked = true;
+< // // If the click wasn't for anything specific, change the value of "ExperimentalMode"
+< // } else if (scene.experimental_mode_via_screen && e->pos() != timeoutPoint) {
+< // if (clickTimer.isActive()) {
+< // clickTimer.stop();
+<
+< // if (scene.conditional_experimental) {
+< // int override_value = (scene.conditional_status >= 1 && scene.conditional_status <= 6) ? 0 : scene.conditional_status >= 7 ? 5 : 6;
+< // paramsMemory.putIntNonBlocking("CEStatus", override_value);
+< // } else {
+< // bool experimentalMode = params.getBool("ExperimentalMode");
+< // params.putBoolNonBlocking("ExperimentalMode", !experimentalMode);
+< // }
+<
+< // } else {
+< // clickTimer.start(500);
+< // }
+< // widgetClicked = true;
+< // }
+---
+> // Change cruise control increments button
+> QRect maxSpeedRect(7, 25, 225, 225);
+> bool isMaxSpeedClicked = maxSpeedRect.contains(e->pos()) && scene.reverse_cruise_ui;
+>
+> // Hide speed button
+> QRect hideSpeedRect(rect().center().x() - 175, 50, 350, 350);
+> bool isSpeedClicked = hideSpeedRect.contains(e->pos()) && scene.hide_speed_ui;
+>
+> // Speed limit confirmation buttons
+> QSize size = this->size();
+> QRect leftRect(0, 0, size.width() / 2, size.height());
+> QRect rightRect = leftRect.translated(size.width() / 2, 0);
+>
+> bool isLeftSideClicked = leftRect.contains(e->pos()) && scene.speed_limit_changed;
+> bool isRightSideClicked = rightRect.contains(e->pos()) && scene.speed_limit_changed;
+>
+> // Speed limit offset button
+> QRect speedLimitRect(7, 250, 225, 225);
+> bool isSpeedLimitClicked = speedLimitRect.contains(e->pos()) && scene.show_slc_offset_ui;
+>
+> if (isMaxSpeedClicked || isSpeedClicked || isSpeedLimitClicked) {
+> if (isMaxSpeedClicked) {
+> std::thread([this]() {
+> bool currentReverseCruise = scene.reverse_cruise;
+>
+> uiState()->scene.reverse_cruise = !currentReverseCruise;
+> params.putBoolNonBlocking("ReverseCruise", !currentReverseCruise);
+>
+> paramsMemory.putBool("FrogPilotTogglesUpdated", true);
+> std::this_thread::sleep_for(std::chrono::seconds(1));
+> paramsMemory.putBool("FrogPilotTogglesUpdated", false);
+> }).detach();
+>
+> } else if (isSpeedClicked) {
+> bool currentHideSpeed = scene.hide_speed;
+>
+> uiState()->scene.hide_speed = !currentHideSpeed;
+> params.putBoolNonBlocking("HideSpeed", !currentHideSpeed);
+> } else if (isSpeedLimitClicked) {
+> bool currentShowSLCOffset = scene.show_slc_offset;
+>
+> scene.show_slc_offset = !currentShowSLCOffset;
+> params.putBoolNonBlocking("ShowSLCOffset", !currentShowSLCOffset);
+> }
+>
+> widgetClicked = true;
+> } else if (isLeftSideClicked || isRightSideClicked) {
+> bool slcConfirmed = isLeftSideClicked && !scene.right_hand_drive || isRightSideClicked && scene.right_hand_drive;
+> paramsMemory.putBoolNonBlocking("SLCConfirmed", slcConfirmed);
+> paramsMemory.putBoolNonBlocking("SLCConfirmedPressed", true);
+>
+> widgetClicked = true;
+> // If the click wasn't for anything specific, change the value of "ExperimentalMode"
+> } else if (scene.experimental_mode_via_screen && e->pos() != timeoutPoint) {
+> if (clickTimer.isActive()) {
+> clickTimer.stop();
+>
+> if (scene.conditional_experimental) {
+> int override_value = (scene.conditional_status >= 1 && scene.conditional_status <= 6) ? 0 : scene.conditional_status >= 7 ? 5 : 6;
+> paramsMemory.putIntNonBlocking("CEStatus", override_value);
+> } else {
+> bool experimentalMode = params.getBool("ExperimentalMode");
+> params.putBoolNonBlocking("ExperimentalMode", !experimentalMode);
+> }
+>
+> } else {
+> clickTimer.start(500);
+> }
+> widgetClicked = true;
+> }
+301,302c301,302
+< .arg(scene.acceleration_jerk_difference > 0 ? "-" : "", 0)
+< .arg(abs(scene.acceleration_jerk_difference), 0, 'f', 3)
+---
+> .arg(scene.acceleration_jerk_difference > 0 ? "-" : "+", 0)
+> .arg(scene.acceleration_jerk_difference, 0, 'f', 3)
+304,305c304,305
+< .arg(scene.ego_jerk_difference > 0 ? "-" : "", 0)
+< .arg(abs(scene.ego_jerk_difference), 0, 'f', 3);
+---
+> .arg(scene.ego_jerk_difference > 0 ? "-" : "+", 0)
+> .arg(scene.ego_jerk_difference, 0, 'f', 3);
+438,439c438,439
+< int override_value = (scene.conditional_status >= 1 && scene.conditional_status <= 4) ? 0 : scene.conditional_status >= 5 ? 5 : 6;
+< paramsMemory.putIntNonBlocking("ConditionalStatus", override_value);
+---
+> int override_value = (scene.conditional_status >= 1 && scene.conditional_status <= 6) ? 0 : scene.conditional_status >= 7 ? 5 : 6;
+> paramsMemory.putIntNonBlocking("CEStatus", override_value);
+555,556c555
+< recorder_btn->setVisible(false);
+< // buttons_layout->addWidget(recorder_btn);
+---
+> buttons_layout->addWidget(recorder_btn);
+559c558
+< // buttons_layout->addWidget(experimental_btn);
+---
+> buttons_layout->addWidget(experimental_btn);
+566c565
+< // top_right_layout->addWidget(pedal_icons, 0, Qt::AlignRight);
+---
+> top_right_layout->addWidget(pedal_icons, 0, Qt::AlignRight);
+620,621d618
+< // CLEARPILOT
+< experimental_btn->setVisible(false);
+771,773c768
+< // CLEARPILOT changes to 120 from ~176
+< // Maybe we want to hide this?
+< p.setFont(InterFont(140, QFont::Bold));
+---
+> p.setFont(InterFont(176, QFont::Bold));
+775,776c770
+< // CLEARPILOT changes to 40 from 66
+< p.setFont(InterFont(50));
+---
+> p.setFont(InterFont(66));
+826,836d819
+< // CLEARPILOT: color channel code rewriten to allow custom colors
+< // Center lane color
+< // This should be moved to ui.h
+< int base_red = 150;
+< int base_green = 150;
+< int base_blue = 150;
+< float path_alpha = 0.30; // 60% opacity
+< float other_alpha = 0.75; // 60% opacity
+<
+< QColor center_lane_color(base_red, base_green, base_blue);
+<
+841,845c824,828
+< // if (currentHolidayTheme != 0) {
+< // painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
+< // } else if (customColors != 0) {
+< // painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
+< // } else {
+---
+> if (currentHolidayTheme != 0) {
+> painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
+> } else if (customColors != 0) {
+> painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
+> } else {
+847c830
+< // }
+---
+> }
+853,857c836,840
+< // if (currentHolidayTheme != 0) {
+< // painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
+< // } else if (customColors != 0) {
+< // painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
+< // } else {
+---
+> if (currentHolidayTheme != 0) {
+> painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
+> } else if (customColors != 0) {
+> painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
+> } else {
+859c842
+< // }
+---
+> }
+877,881c860,872
+< try {
+< for (int i = 0; i < max_len; ++i) {
+< if (scene.track_vertices[i].y() < 0 || scene.track_vertices[i].y() > height()) continue;
+<
+< float lin_grad_point = (height() - scene.track_vertices[i].y()) / height();
+---
+> for (int i = 0; i < max_len; ++i) {
+> // Some points are out of frame
+> if (scene.track_vertices[i].y() < 0 || scene.track_vertices[i].y() > height()) continue;
+>
+> // Flip so 0 is bottom of frame
+> float lin_grad_point = (height() - scene.track_vertices[i].y()) / height();
+>
+> // If acceleration is between -0.25 and 0.25, resort to the theme color
+> if (std::abs(acceleration[i]) < 0.25 && (currentHolidayTheme != 0)) {
+> const auto &colorMap = std::get<2>(holidayThemeConfiguration[currentHolidayTheme]);
+> for (const auto &[position, brush] : colorMap) {
+> bg.setColorAt(position, brush.color());
+> }
+883,884c874,878
+< double _h, _s, _l; // Use double for compatibility with QColor::getHslF()
+< center_lane_color.getHslF(&_h, &_s, &_l);
+---
+> } else if (std::abs(acceleration[i]) < 0.25 && (customColors != 0)) {
+> const auto &colorMap = std::get<2>(themeConfiguration[customColors]);
+> for (const auto &[position, brush] : colorMap) {
+> bg.setColorAt(position, brush.color());
+> }
+886,888c880,889
+< // Calculate saturation and lightness based on acceleration
+< float adjusted_saturation = std::min(std::abs(acceleration[i] * 1.5f), 1.f);
+< float adjusted_lightness = util::map_val(adjusted_saturation, 0.f, 1.f, static_cast(_l), 0.95f); // Using base lightness as a starting point
+---
+> } else {
+> // speed up: 120, slow down: 0
+> float path_hue = fmax(fmin(60 + acceleration[i] * 35, 120), 0);
+> // FIXME: painter.drawPolygon can be slow if hue is not rounded
+> path_hue = int(path_hue * 100 + 0.5) / 100;
+>
+> float saturation = fmin(fabs(acceleration[i] * 1.5), 1);
+> float lightness = util::map_val(saturation, 0.0f, 1.0f, 0.95f, 0.62f); // lighter when grey
+> float alpha = util::map_val(lin_grad_point, 0.75f / 2.f, 0.75f, 0.4f, 0.0f); // matches previous alpha fade
+> bg.setColorAt(lin_grad_point, QColor::fromHslF(path_hue / 360., saturation, lightness, alpha));
+890,891c891,894
+< // Calculate dynamic alpha based on lin_grad_point
+< float dynamic_alpha = util::map_val(lin_grad_point, 0.75f / 2.f, 0.75f, path_alpha, 0.f);
+---
+> // Skip a point, unless next is last
+> i += (i + 2) < max_len ? 1 : 0;
+> }
+> }
+893,894c896,900
+< QColor final_color = QColor::fromHslF(static_cast(_h / 360.f), adjusted_saturation, adjusted_lightness, dynamic_alpha);
+< bg.setColorAt(lin_grad_point, final_color);
+---
+> } else if (currentHolidayTheme != 0) {
+> const auto &colorMap = std::get<2>(holidayThemeConfiguration[currentHolidayTheme]);
+> for (const auto &[position, brush] : colorMap) {
+> bg.setColorAt(position, brush.color());
+> }
+896,903c902,905
+< i += (i + 2) < max_len ? 1 : 0; // Skipping a point to optimize rendering
+< }
+< } catch (const std::exception& e) {
+< // Default shading if for some reason the above code fails
+< bg = QLinearGradient(0, height(), 0, 0);
+< bg.setColorAt(0.0, QColor(center_lane_color.red(), center_lane_color.green(), center_lane_color.blue(), static_cast(other_alpha * 255 * 0.4)));
+< bg.setColorAt(0.5, QColor(center_lane_color.red(), center_lane_color.green(), center_lane_color.blue(), static_cast(other_alpha * 255 * 0.35)));
+< bg.setColorAt(1.0, QColor(center_lane_color.red(), center_lane_color.green(), center_lane_color.blue(), static_cast(other_alpha * 255 * 0.0)));
+---
+> } else if (customColors != 0) {
+> const auto &colorMap = std::get<2>(themeConfiguration[customColors]);
+> for (const auto &[position, brush] : colorMap) {
+> bg.setColorAt(position, brush.color());
+904a907
+>
+906,908c909,911
+< bg.setColorAt(0.0, QColor(center_lane_color.red(), center_lane_color.green(), center_lane_color.blue(), static_cast(other_alpha * 255 * 0.4)));
+< bg.setColorAt(0.5, QColor(center_lane_color.red(), center_lane_color.green(), center_lane_color.blue(), static_cast(other_alpha * 255 * 0.35)));
+< bg.setColorAt(1.0, QColor(center_lane_color.red(), center_lane_color.green(), center_lane_color.blue(), static_cast(other_alpha * 255 * 0.0)));
+---
+> bg.setColorAt(0.0, QColor::fromHslF(148 / 360., 0.94, 0.51, 0.4));
+> bg.setColorAt(0.5, QColor::fromHslF(112 / 360., 1.0, 0.68, 0.35));
+> bg.setColorAt(1.0, QColor::fromHslF(112 / 360., 1.0, 0.68, 0.0));
+917,925c920,930
+< QColor color = bg_colors[STATUS_ALWAYS_ON_LATERAL_ACTIVE];
+< pe.setColorAt(0.0, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255)));
+< pe.setColorAt(0.5, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255 * 0.5)));
+< pe.setColorAt(1.0, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255 * 0.1)));
+< } else if (conditionalStatus == 1 || conditionalStatus == 3 || conditionalStatus == 5 || experimentalMode) {
+< QColor color = bg_colors[STATUS_EXPERIMENTAL_ACTIVE];
+< pe.setColorAt(0.0, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255)));
+< pe.setColorAt(0.5, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255 * 0.5)));
+< pe.setColorAt(1.0, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255 * 0.1)));
+---
+> pe.setColorAt(0.0, QColor::fromHslF(178 / 360., 0.90, 0.38, 1.0));
+> pe.setColorAt(0.5, QColor::fromHslF(178 / 360., 0.90, 0.38, 0.5));
+> pe.setColorAt(1.0, QColor::fromHslF(178 / 360., 0.90, 0.38, 0.1));
+> } else if (conditionalStatus == 1 || conditionalStatus == 3 || conditionalStatus == 5) {
+> pe.setColorAt(0.0, QColor::fromHslF(58 / 360., 1.00, 0.50, 1.0));
+> pe.setColorAt(0.5, QColor::fromHslF(58 / 360., 1.00, 0.50, 0.5));
+> pe.setColorAt(1.0, QColor::fromHslF(58 / 360., 1.00, 0.50, 0.1));
+> } else if (experimentalMode) {
+> pe.setColorAt(0.0, QColor::fromHslF(25 / 360., 0.71, 0.50, 1.0));
+> pe.setColorAt(0.5, QColor::fromHslF(25 / 360., 0.71, 0.50, 0.5));
+> pe.setColorAt(1.0, QColor::fromHslF(25 / 360., 0.71, 0.50, 0.1));
+933a939,950
+> } else if (currentHolidayTheme != 0) {
+> const auto &colorMap = std::get<2>(holidayThemeConfiguration[currentHolidayTheme]);
+> for (const auto &[position, brush] : colorMap) {
+> QColor darkerColor = brush.color().darker(120);
+> pe.setColorAt(position, darkerColor);
+> }
+> } else if (customColors != 0) {
+> const auto &colorMap = std::get<2>(themeConfiguration[customColors]);
+> for (const auto &[position, brush] : colorMap) {
+> QColor darkerColor = brush.color().darker(120);
+> pe.setColorAt(position, darkerColor);
+> }
+935,938c952,954
+< QColor color = bg_colors[STATUS_ENGAGED];
+< pe.setColorAt(0.0, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255)));
+< pe.setColorAt(0.5, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255 * 0.5)));
+< pe.setColorAt(1.0, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255 * 0.1)));
+---
+> pe.setColorAt(0.0, QColor::fromHslF(148 / 360., 0.94, 0.51, 1.0));
+> pe.setColorAt(0.5, QColor::fromHslF(112 / 360., 1.00, 0.68, 0.5));
+> pe.setColorAt(1.0, QColor::fromHslF(112 / 360., 1.00, 0.68, 0.1));
+1004c1020
+< // painter.save();
+---
+> painter.save();
+1006,1039c1022,1055
+< // // base icon
+< // int offset = UI_BORDER_SIZE + btn_size / 2;
+< // int x = rightHandDM ? width() - offset : offset;
+< // x += onroadDistanceButton ? 250 : 0;
+< // offset += showAlwaysOnLateralStatusBar || showConditionalExperimentalStatusBar || roadNameUI ? 25 : 0;
+< // int y = height() - offset;
+< // float opacity = dmActive ? 0.65 : 0.2;
+< // drawIcon(painter, QPoint(x, y), dm_img, blackColor(70), opacity);
+<
+< // // face
+< // QPointF face_kpts_draw[std::size(default_face_kpts_3d)];
+< // float kp;
+< // for (int i = 0; i < std::size(default_face_kpts_3d); ++i) {
+< // kp = (scene.face_kpts_draw[i].v[2] - 8) / 120 + 1.0;
+< // face_kpts_draw[i] = QPointF(scene.face_kpts_draw[i].v[0] * kp + x, scene.face_kpts_draw[i].v[1] * kp + y);
+< // }
+<
+< // painter.setPen(QPen(QColor::fromRgbF(1.0, 1.0, 1.0, opacity), 5.2, Qt::SolidLine, Qt::RoundCap));
+< // painter.drawPolyline(face_kpts_draw, std::size(default_face_kpts_3d));
+<
+< // // tracking arcs
+< // const int arc_l = 133;
+< // const float arc_t_default = 6.7;
+< // const float arc_t_extend = 12.0;
+< // QColor arc_color = QColor::fromRgbF(0.545 - 0.445 * s->engaged(),
+< // 0.545 + 0.4 * s->engaged(),
+< // 0.545 - 0.285 * s->engaged(),
+< // 0.4 * (1.0 - dm_fade_state));
+< // float delta_x = -scene.driver_pose_sins[1] * arc_l / 2;
+< // float delta_y = -scene.driver_pose_sins[0] * arc_l / 2;
+< // painter.setPen(QPen(arc_color, arc_t_default+arc_t_extend*fmin(1.0, scene.driver_pose_diff[1] * 5.0), Qt::SolidLine, Qt::RoundCap));
+< // painter.drawArc(QRectF(std::fmin(x + delta_x, x), y - arc_l / 2, fabs(delta_x), arc_l), (scene.driver_pose_sins[1]>0 ? 90 : -90) * 16, 180 * 16);
+< // painter.setPen(QPen(arc_color, arc_t_default+arc_t_extend*fmin(1.0, scene.driver_pose_diff[0] * 5.0), Qt::SolidLine, Qt::RoundCap));
+< // painter.drawArc(QRectF(x - arc_l / 2, std::fmin(y + delta_y, y), arc_l, fabs(delta_y)), (scene.driver_pose_sins[0]>0 ? 0 : 180) * 16, 180 * 16);
+---
+> // base icon
+> int offset = UI_BORDER_SIZE + btn_size / 2;
+> int x = rightHandDM ? width() - offset : offset;
+> x += onroadDistanceButton ? 250 : 0;
+> offset += showAlwaysOnLateralStatusBar || showConditionalExperimentalStatusBar || roadNameUI ? 25 : 0;
+> int y = height() - offset;
+> float opacity = dmActive ? 0.65 : 0.2;
+> drawIcon(painter, QPoint(x, y), dm_img, blackColor(70), opacity);
+>
+> // face
+> QPointF face_kpts_draw[std::size(default_face_kpts_3d)];
+> float kp;
+> for (int i = 0; i < std::size(default_face_kpts_3d); ++i) {
+> kp = (scene.face_kpts_draw[i].v[2] - 8) / 120 + 1.0;
+> face_kpts_draw[i] = QPointF(scene.face_kpts_draw[i].v[0] * kp + x, scene.face_kpts_draw[i].v[1] * kp + y);
+> }
+>
+> painter.setPen(QPen(QColor::fromRgbF(1.0, 1.0, 1.0, opacity), 5.2, Qt::SolidLine, Qt::RoundCap));
+> painter.drawPolyline(face_kpts_draw, std::size(default_face_kpts_3d));
+>
+> // tracking arcs
+> const int arc_l = 133;
+> const float arc_t_default = 6.7;
+> const float arc_t_extend = 12.0;
+> QColor arc_color = QColor::fromRgbF(0.545 - 0.445 * s->engaged(),
+> 0.545 + 0.4 * s->engaged(),
+> 0.545 - 0.285 * s->engaged(),
+> 0.4 * (1.0 - dm_fade_state));
+> float delta_x = -scene.driver_pose_sins[1] * arc_l / 2;
+> float delta_y = -scene.driver_pose_sins[0] * arc_l / 2;
+> painter.setPen(QPen(arc_color, arc_t_default+arc_t_extend*fmin(1.0, scene.driver_pose_diff[1] * 5.0), Qt::SolidLine, Qt::RoundCap));
+> painter.drawArc(QRectF(std::fmin(x + delta_x, x), y - arc_l / 2, fabs(delta_x), arc_l), (scene.driver_pose_sins[1]>0 ? 90 : -90) * 16, 180 * 16);
+> painter.setPen(QPen(arc_color, arc_t_default+arc_t_extend*fmin(1.0, scene.driver_pose_diff[0] * 5.0), Qt::SolidLine, Qt::RoundCap));
+> painter.drawArc(QRectF(x - arc_l / 2, std::fmin(y + delta_y, y), arc_l, fabs(delta_y)), (scene.driver_pose_sins[0]>0 ? 0 : 180) * 16, 180 * 16);
+1041c1057
+< // painter.restore();
+---
+> painter.restore();
+1074,1079c1090,1094
+< // CLEARPILOT disabling custom theme colors
+< // if (currentHolidayTheme != 0) {
+< // painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
+< // } else if (customColors != 0) {
+< // painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
+< // } else {
+---
+> if (currentHolidayTheme != 0) {
+> painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
+> } else if (customColors != 0) {
+> painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
+> } else {
+1081c1096
+< // }
+---
+> }
+1169c1184
+< if (s->scene.longitudinal_control && sm.rcv_frame("modelV2") > s->scene.started_frame) {
+---
+> if (s->scene.longitudinal_control && sm.rcv_frame("modelV2") > s->scene.started_frame && !s->scene.hide_lead_marker) {
+1218c1233
+< // bottom_layout->addWidget(distance_btn);
+---
+> bottom_layout->addWidget(distance_btn);
+1220,1221c1235,1236
+< // QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
+< // bottom_layout->addItem(spacer);
+---
+> QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
+> bottom_layout->addItem(spacer);
+1224c1239
+< // bottom_layout->addWidget(compass_img);
+---
+> bottom_layout->addWidget(compass_img);
+1285,1291c1300,1306
+< // QTimer *record_timer = new QTimer(this);
+< // connect(record_timer, &QTimer::timeout, this, [this]() {
+< // if (recorder_btn) {
+< // recorder_btn->update_screen();
+< // }
+< // });
+< // record_timer->start(1000 / UI_FREQ);
+---
+> QTimer *record_timer = new QTimer(this);
+> connect(record_timer, &QTimer::timeout, this, [this]() {
+> if (recorder_btn) {
+> recorder_btn->update_screen();
+> }
+> });
+> record_timer->start(1000 / UI_FREQ);
+1316c1331
+< // experimentalMode = scene.experimental_mode;
+---
+> experimentalMode = scene.experimental_mode;
+1387,1394c1402,1409
+< // if (customSignals != 0 && (turnSignalLeft || turnSignalRight) && !bigMapOpen) {
+< // if (!animationTimer->isActive()) {
+< // animationTimer->start(totalFrames * 11); // 440 milliseconds per loop; syncs up perfectly with my 2019 Lexus ES 350 turn signal clicks
+< // }
+< // drawTurnSignals(p);
+< // } else if (animationTimer->isActive()) {
+< // animationTimer->stop();
+< // }
+---
+> if (customSignals != 0 && (turnSignalLeft || turnSignalRight) && !bigMapOpen) {
+> if (!animationTimer->isActive()) {
+> animationTimer->start(totalFrames * 11); // 440 milliseconds per loop; syncs up perfectly with my 2019 Lexus ES 350 turn signal clicks
+> }
+> drawTurnSignals(p);
+> } else if (animationTimer->isActive()) {
+> animationTimer->stop();
+> }
+1404,1422c1419,1437
+< // bool enableCompass = compass && !hideBottomIcons;
+< // compass_img->setVisible(enableCompass);
+< // if (enableCompass) {
+< // compass_img->updateState();
+< // bottom_layout->setAlignment(compass_img, (rightHandDM ? Qt::AlignLeft : Qt::AlignRight));
+< // }
+<
+< // bool enableDistanceButton = onroadDistanceButton && !hideBottomIcons;
+< // distance_btn->setVisible(enableDistanceButton);
+< // if (enableDistanceButton) {
+< // distance_btn->updateState();
+< // bottom_layout->setAlignment(distance_btn, (rightHandDM ? Qt::AlignRight : Qt::AlignLeft));
+< // }
+<
+< // bool enablePedalIcons = scene.pedals_on_ui && !bigMapOpen;
+< // pedal_icons->setVisible(enablePedalIcons);
+< // if (enablePedalIcons) {
+< // pedal_icons->updateState();
+< // }
+---
+> bool enableCompass = compass && !hideBottomIcons;
+> compass_img->setVisible(enableCompass);
+> if (enableCompass) {
+> compass_img->updateState();
+> bottom_layout->setAlignment(compass_img, (rightHandDM ? Qt::AlignLeft : Qt::AlignRight));
+> }
+>
+> bool enableDistanceButton = onroadDistanceButton && !hideBottomIcons;
+> distance_btn->setVisible(enableDistanceButton);
+> if (enableDistanceButton) {
+> distance_btn->updateState();
+> bottom_layout->setAlignment(distance_btn, (rightHandDM ? Qt::AlignRight : Qt::AlignLeft));
+> }
+>
+> bool enablePedalIcons = scene.pedals_on_ui && !bigMapOpen;
+> pedal_icons->setVisible(enablePedalIcons);
+> if (enablePedalIcons) {
+> pedal_icons->updateState();
+> }
+1430,1431c1445
+< // recorder_btn->setVisible(scene.screen_recorder && !mapOpen);
+< recorder_btn->setVisible(false);
+---
+> recorder_btn->setVisible(scene.screen_recorder && !mapOpen);
+1435c1449
+< // setFixedSize(btn_size * 1.5, btn_size * 1.5);
+---
+> setFixedSize(btn_size * 1.5, btn_size * 1.5);
+1437,1440c1451,1454
+< // compassSize = btn_size;
+< // circleOffset = compassSize / 2;
+< // degreeLabelOffset = circleOffset + 25;
+< // innerCompass = compassSize / 2;
+---
+> compassSize = btn_size;
+> circleOffset = compassSize / 2;
+> degreeLabelOffset = circleOffset + 25;
+> innerCompass = compassSize / 2;
+1442,1443c1456,1457
+< // x = (btn_size * 1.5) / 2 + 20;
+< // y = (btn_size * 1.5) / 2;
+---
+> x = (btn_size * 1.5) / 2 + 20;
+> y = (btn_size * 1.5) / 2;
+1445c1459
+< // compassInnerImg = loadPixmap("../frogpilot/assets/other_images/compass_inner.png", QSize(compassSize / 1.75, compassSize / 1.75));
+---
+> compassInnerImg = loadPixmap("../frogpilot/assets/other_images/compass_inner.png", QSize(compassSize / 1.75, compassSize / 1.75));
+1447,1449c1461,1463
+< // staticElements = QPixmap(size());
+< // staticElements.fill(Qt::transparent);
+< // QPainter p(&staticElements);
+---
+> staticElements = QPixmap(size());
+> staticElements.fill(Qt::transparent);
+> QPainter p(&staticElements);
+1451c1465
+< // p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+---
+> p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+1453,1454c1467,1468
+< // QPen whitePen(Qt::white, 2);
+< // p.setPen(whitePen);
+---
+> QPen whitePen(Qt::white, 2);
+> p.setPen(whitePen);
+1456,1458c1470,1472
+< // p.setOpacity(1.0);
+< // p.setBrush(QColor(0, 0, 0, 100));
+< // p.drawEllipse(x - circleOffset, y - circleOffset, circleOffset * 2, circleOffset * 2);
+---
+> p.setOpacity(1.0);
+> p.setBrush(QColor(0, 0, 0, 100));
+> p.drawEllipse(x - circleOffset, y - circleOffset, circleOffset * 2, circleOffset * 2);
+1460,1462c1474,1476
+< // p.setBrush(Qt::NoBrush);
+< // p.drawEllipse(x - (innerCompass + 5), y - (innerCompass + 5), (innerCompass + 5) * 2, (innerCompass + 5) * 2);
+< // p.drawEllipse(x - degreeLabelOffset, y - degreeLabelOffset, degreeLabelOffset * 2, degreeLabelOffset * 2);
+---
+> p.setBrush(Qt::NoBrush);
+> p.drawEllipse(x - (innerCompass + 5), y - (innerCompass + 5), (innerCompass + 5) * 2, (innerCompass + 5) * 2);
+> p.drawEllipse(x - degreeLabelOffset, y - degreeLabelOffset, degreeLabelOffset * 2, degreeLabelOffset * 2);
+1464,1467c1478,1481
+< // QPainterPath outerCircle, innerCircle;
+< // outerCircle.addEllipse(x - degreeLabelOffset, y - degreeLabelOffset, degreeLabelOffset * 2, degreeLabelOffset * 2);
+< // innerCircle.addEllipse(x - circleOffset, y - circleOffset, compassSize, compassSize);
+< // p.fillPath(outerCircle.subtracted(innerCircle), Qt::black);
+---
+> QPainterPath outerCircle, innerCircle;
+> outerCircle.addEllipse(x - degreeLabelOffset, y - degreeLabelOffset, degreeLabelOffset * 2, degreeLabelOffset * 2);
+> innerCircle.addEllipse(x - circleOffset, y - circleOffset, compassSize, compassSize);
+> p.fillPath(outerCircle.subtracted(innerCircle), Qt::black);
+1471,1474c1485,1488
+< // if (bearingDeg != scene.bearing_deg) {
+< // update();
+< // bearingDeg = scene.bearing_deg;
+< // }
+---
+> if (bearingDeg != scene.bearing_deg) {
+> update();
+> bearingDeg = scene.bearing_deg;
+> }
+1478,1479c1492,1493
+< // QPainter p(this);
+< // p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+---
+> QPainter p(this);
+> p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+1481,1537c1495,1551
+< // bearingDeg = fmod(bearingDeg, 360);
+< // if (bearingDeg < 0) {
+< // bearingDeg += 360;
+< // }
+<
+< // p.drawPixmap(0, 0, staticElements);
+<
+< // p.translate(x, y);
+< // p.rotate(bearingDeg);
+< // p.drawPixmap(-compassInnerImg.width() / 2, -compassInnerImg.height() / 2, compassInnerImg);
+< // p.rotate(-bearingDeg);
+< // p.translate(-x, -y);
+<
+< // QFont font = InterFont(10, QFont::Normal);
+< // for (int i = 0; i < 360; i += 15) {
+< // bool isBold = abs(i - bearingDeg) <= 7;
+< // font.setWeight(isBold ? QFont::Bold : QFont::Normal);
+< // p.setFont(font);
+< // p.setPen(QPen(Qt::white, i % 90 == 0 ? 2 : 1));
+<
+< // p.save();
+< // p.translate(x, y);
+< // p.rotate(i);
+< // p.drawLine(0, -(compassSize / 2 - (i % 90 == 0 ? 12 : 8)), 0, -(compassSize / 2));
+< // p.translate(0, -(compassSize / 2 + 12));
+< // p.rotate(-i);
+< // p.drawText(QRect(-20, -10, 40, 20), Qt::AlignCenter, QString::number(i));
+< // p.restore();
+< // }
+<
+< // p.setFont(InterFont(20, QFont::Bold));
+< // std::map, int, QColor>> directionInfo = {
+< // {"N", {{292.5, 67.5}, Qt::AlignTop | Qt::AlignHCenter, Qt::white}},
+< // {"E", {{22.5, 157.5}, Qt::AlignRight | Qt::AlignVCenter, Qt::white}},
+< // {"S", {{112.5, 247.5}, Qt::AlignBottom | Qt::AlignHCenter, Qt::white}},
+< // {"W", {{202.5, 337.5}, Qt::AlignLeft | Qt::AlignVCenter, Qt::white}}
+< // };
+< // int directionOffset = 20;
+<
+< // for (auto &item : directionInfo) {
+< // QString direction = item.first;
+< // auto &[range, alignmentFlag, color] = item.second;
+< // auto &[minRange, maxRange] = range;
+<
+< // QRect textRect(x - innerCompass + directionOffset, y - innerCompass + directionOffset, innerCompass * 2 - 2 * directionOffset, innerCompass * 2 - 2 * directionOffset);
+<
+< // bool isInRange = false;
+< // if (minRange > maxRange) {
+< // isInRange = bearingDeg >= minRange || bearingDeg <= maxRange;
+< // } else {
+< // isInRange = bearingDeg >= minRange && bearingDeg <= maxRange;
+< // }
+<
+< // p.setOpacity(isInRange ? 1.0 : 0.2);
+< // p.setPen(QPen(color));
+< // p.drawText(textRect, alignmentFlag, direction);
+< // }
+---
+> bearingDeg = fmod(bearingDeg, 360);
+> if (bearingDeg < 0) {
+> bearingDeg += 360;
+> }
+>
+> p.drawPixmap(0, 0, staticElements);
+>
+> p.translate(x, y);
+> p.rotate(bearingDeg);
+> p.drawPixmap(-compassInnerImg.width() / 2, -compassInnerImg.height() / 2, compassInnerImg);
+> p.rotate(-bearingDeg);
+> p.translate(-x, -y);
+>
+> QFont font = InterFont(10, QFont::Normal);
+> for (int i = 0; i < 360; i += 15) {
+> bool isBold = abs(i - bearingDeg) <= 7;
+> font.setWeight(isBold ? QFont::Bold : QFont::Normal);
+> p.setFont(font);
+> p.setPen(QPen(Qt::white, i % 90 == 0 ? 2 : 1));
+>
+> p.save();
+> p.translate(x, y);
+> p.rotate(i);
+> p.drawLine(0, -(compassSize / 2 - (i % 90 == 0 ? 12 : 8)), 0, -(compassSize / 2));
+> p.translate(0, -(compassSize / 2 + 12));
+> p.rotate(-i);
+> p.drawText(QRect(-20, -10, 40, 20), Qt::AlignCenter, QString::number(i));
+> p.restore();
+> }
+>
+> p.setFont(InterFont(20, QFont::Bold));
+> std::map, int, QColor>> directionInfo = {
+> {"N", {{292.5, 67.5}, Qt::AlignTop | Qt::AlignHCenter, Qt::white}},
+> {"E", {{22.5, 157.5}, Qt::AlignRight | Qt::AlignVCenter, Qt::white}},
+> {"S", {{112.5, 247.5}, Qt::AlignBottom | Qt::AlignHCenter, Qt::white}},
+> {"W", {{202.5, 337.5}, Qt::AlignLeft | Qt::AlignVCenter, Qt::white}}
+> };
+> int directionOffset = 20;
+>
+> for (auto &item : directionInfo) {
+> QString direction = item.first;
+> auto &[range, alignmentFlag, color] = item.second;
+> auto &[minRange, maxRange] = range;
+>
+> QRect textRect(x - innerCompass + directionOffset, y - innerCompass + directionOffset, innerCompass * 2 - 2 * directionOffset, innerCompass * 2 - 2 * directionOffset);
+>
+> bool isInRange = false;
+> if (minRange > maxRange) {
+> isInRange = bearingDeg >= minRange || bearingDeg <= maxRange;
+> } else {
+> isInRange = bearingDeg >= minRange && bearingDeg <= maxRange;
+> }
+>
+> p.setOpacity(isInRange ? 1.0 : 0.2);
+> p.setPen(QPen(color));
+> p.drawText(textRect, alignmentFlag, direction);
+> }
+1541c1555,1562
+< // setFixedSize(btn_size * 1.5, btn_size * 1.5);
+---
+> setFixedSize(btn_size * 1.5, btn_size * 1.5);
+>
+> profile_data = {
+> {QPixmap("../frogpilot/assets/other_images/traffic.png"), "Traffic"},
+> {QPixmap("../frogpilot/assets/other_images/aggressive.png"), "Aggressive"},
+> {QPixmap("../frogpilot/assets/other_images/standard.png"), "Standard"},
+> {QPixmap("../frogpilot/assets/other_images/relaxed.png"), "Relaxed"}
+> };
+1543,1555c1564,1569
+< // profile_data = {
+< // {QPixmap("../frogpilot/assets/other_images/traffic.png"), "Traffic"},
+< // {QPixmap("../frogpilot/assets/other_images/aggressive.png"), "Aggressive"},
+< // {QPixmap("../frogpilot/assets/other_images/standard.png"), "Standard"},
+< // {QPixmap("../frogpilot/assets/other_images/relaxed.png"), "Relaxed"}
+< // };
+<
+< // profile_data_kaofui = {
+< // {QPixmap("../frogpilot/assets/other_images/traffic_kaofui.png"), "Traffic"},
+< // {QPixmap("../frogpilot/assets/other_images/aggressive_kaofui.png"), "Aggressive"},
+< // {QPixmap("../frogpilot/assets/other_images/standard_kaofui.png"), "Standard"},
+< // {QPixmap("../frogpilot/assets/other_images/relaxed_kaofui.png"), "Relaxed"}
+< // };
+---
+> profile_data_kaofui = {
+> {QPixmap("../frogpilot/assets/other_images/traffic_kaofui.png"), "Traffic"},
+> {QPixmap("../frogpilot/assets/other_images/aggressive_kaofui.png"), "Aggressive"},
+> {QPixmap("../frogpilot/assets/other_images/standard_kaofui.png"), "Standard"},
+> {QPixmap("../frogpilot/assets/other_images/relaxed_kaofui.png"), "Relaxed"}
+> };
+1557c1571
+< // transitionTimer.start();
+---
+> transitionTimer.start();
+1559,1560c1573,1574
+< // connect(this, &QPushButton::pressed, this, &DistanceButton::buttonPressed);
+< // connect(this, &QPushButton::released, this, &DistanceButton::buttonReleased);
+---
+> connect(this, &QPushButton::pressed, this, &DistanceButton::buttonPressed);
+> connect(this, &QPushButton::released, this, &DistanceButton::buttonReleased);
+1564c1578
+< // paramsMemory.putBool("OnroadDistanceButtonPressed", true);
+---
+> paramsMemory.putBool("OnroadDistanceButtonPressed", true);
+1568c1582
+< // paramsMemory.putBool("OnroadDistanceButtonPressed", false);
+---
+> paramsMemory.putBool("OnroadDistanceButtonPressed", false);
+1572,1574c1586,1588
+< // if (trafficModeActive != scene.traffic_mode_active || personality != static_cast(scene.personality) && !trafficModeActive) {
+< // transitionTimer.restart();
+< // }
+---
+> if (trafficModeActive != scene.traffic_mode_active || personality != static_cast(scene.personality) && !trafficModeActive) {
+> transitionTimer.restart();
+> }
+1576c1590
+< // personality = static_cast(scene.personality);
+---
+> personality = static_cast(scene.personality);
+1581,1582c1595,1606
+< // QPainter p(this);
+< // p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+---
+> QPainter p(this);
+> p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+>
+> constexpr qreal fadeDuration = 1000.0;
+> constexpr qreal textDuration = 3000.0;
+> int elapsed = transitionTimer.elapsed();
+>
+> qreal textOpacity = qBound(0.0, 1.0 - ((elapsed - textDuration) / fadeDuration), 1.0);
+> qreal imageOpacity = qBound(0.0, (elapsed - textDuration) / fadeDuration, 1.0);
+>
+> int profile = trafficModeActive ? 0 : personality + 1;
+> auto &[profileImage, profileText] = scene.use_kaofui_icons ? profile_data_kaofui[profile] : profile_data[profile];
+1584,1604c1608,1618
+< // constexpr qreal fadeDuration = 1000.0;
+< // constexpr qreal textDuration = 3000.0;
+< // int elapsed = transitionTimer.elapsed();
+<
+< // qreal textOpacity = qBound(0.0, 1.0 - ((elapsed - textDuration) / fadeDuration), 1.0);
+< // qreal imageOpacity = qBound(0.0, (elapsed - textDuration) / fadeDuration, 1.0);
+<
+< // int profile = trafficModeActive ? 0 : personality + 1;
+< // auto &[profileImage, profileText] = scene.use_kaofui_icons ? profile_data_kaofui[profile] : profile_data[profile];
+<
+< // if (textOpacity != 0.0) {
+< // p.setOpacity(textOpacity);
+< // p.setFont(InterFont(40, QFont::Bold));
+< // p.setPen(Qt::white);
+< // QRect textRect(-25, 0, width(), height() + 95);
+< // p.drawText(textRect, Qt::AlignCenter, profileText);
+< // }
+<
+< // if (imageOpacity != 0.0) {
+< // drawIcon(p, QPoint((btn_size / 2) * 1.25, btn_size / 2 + 95), profileImage, Qt::transparent, imageOpacity);
+< // }
+---
+> if (textOpacity != 0.0) {
+> p.setOpacity(textOpacity);
+> p.setFont(InterFont(40, QFont::Bold));
+> p.setPen(Qt::white);
+> QRect textRect(-25, 0, width(), height() + 95);
+> p.drawText(textRect, Qt::AlignCenter, profileText);
+> }
+>
+> if (imageOpacity != 0.0) {
+> drawIcon(p, QPoint((btn_size / 2) * 1.25, btn_size / 2 + 95), profileImage, Qt::transparent, imageOpacity);
+> }
+1729c1743
+< // acceleration = scene.acceleration;
+---
+> acceleration = scene.acceleration;
+1731,1732c1745,1746
+< // accelerating = acceleration > 0.25;
+< // decelerating = acceleration < -0.25;
+---
+> accelerating = acceleration > 0.25;
+> decelerating = acceleration < -0.25;
+1734,1736c1748,1750
+< // if (accelerating || decelerating) {
+< // update();
+< // }
+---
+> if (accelerating || decelerating) {
+> update();
+> }
+1740,1741c1754,1755
+< // QPainter p(this);
+< // p.setRenderHint(QPainter::Antialiasing);
+---
+> QPainter p(this);
+> p.setRenderHint(QPainter::Antialiasing);
+1743,1744c1757,1758
+< // int totalWidth = 2 * img_size;
+< // int startX = (width() - totalWidth) / 2;
+---
+> int totalWidth = 2 * img_size;
+> int startX = (width() - totalWidth) / 2;
+1746,1747c1760,1761
+< // int brakeX = startX + img_size / 2;
+< // int gasX = startX + img_size;
+---
+> int brakeX = startX + img_size / 2;
+> int gasX = startX + img_size;
+1749,1750c1763,1764
+< // float brakeOpacity = scene.standstill ? 1.0f : decelerating ? std::max(0.25f, std::abs(acceleration)) : 0.25f;
+< // float gasOpacity = accelerating ? std::max(0.25f, acceleration) : 0.25f;
+---
+> float brakeOpacity = scene.standstill ? 1.0f : decelerating ? std::max(0.25f, std::abs(acceleration)) : 0.25f;
+> float gasOpacity = accelerating ? std::max(0.25f, acceleration) : 0.25f;
+1752,1753c1766,1767
+< // p.setOpacity(brakeOpacity);
+< // p.drawPixmap(brakeX, (height() - img_size) / 2, brake_pedal_img);
+---
+> p.setOpacity(brakeOpacity);
+> p.drawPixmap(brakeX, (height() - img_size) / 2, brake_pedal_img);
+1755,1756c1769,1770
+< // p.setOpacity(gasOpacity);
+< // p.drawPixmap(gasX, (height() - img_size) / 2, gas_pedal_img);
+---
+> p.setOpacity(gasOpacity);
+> p.drawPixmap(gasX, (height() - img_size) / 2, gas_pedal_img);
+diff -r clearpilot/openpilot/selfdrive/ui/qt/onroad.h FrogPilot/openpilot/selfdrive/ui/qt/onroad.h
+53,59c53,59
+< // int bearingDeg;
+< // int circleOffset;
+< // int compassSize;
+< // int degreeLabelOffset;
+< // int innerCompass;
+< // int x;
+< // int y;
+---
+> int bearingDeg;
+> int circleOffset;
+> int compassSize;
+> int degreeLabelOffset;
+> int innerCompass;
+> int x;
+> int y;
+83c83
+< // int personality;
+---
+> int personality;
+Only in clearpilot/openpilot/selfdrive/ui/qt: ready.cc
+Only in clearpilot/openpilot/selfdrive/ui/qt: ready.h
+diff -r clearpilot/openpilot/selfdrive/ui/qt/sidebar.cc FrogPilot/openpilot/selfdrive/ui/qt/sidebar.cc
+79,81c79,81
+< {1, {"frog_theme", {QColor(255, 255, 255)}}},
+< {2, {"tesla_theme", {QColor(255, 255, 255)}}},
+< {3, {"stalin_theme", {QColor(255, 255, 255)}}}
+---
+> {1, {"frog_theme", {QColor(23, 134, 68)}}},
+> {2, {"tesla_theme", {QColor(0, 72, 255)}}},
+> {3, {"stalin_theme", {QColor(255, 0, 0)}}}
+Only in clearpilot/openpilot/selfdrive/ui/qt: spinner
+diff -r clearpilot/openpilot/selfdrive/ui/qt/util.cc FrogPilot/openpilot/selfdrive/ui/qt/util.cc
+29c29
+< return QObject::tr("ClearPilot");
+---
+> return QObject::tr("FrogPilot");
+diff -r clearpilot/openpilot/selfdrive/ui/qt/widgets/drive_stats.cc FrogPilot/openpilot/selfdrive/ui/qt/widgets/drive_stats.cc
+71,72c71,72
+< labels.routes->setText(QString::number(paramsStorage.getInt("FrogPilotDrives")));
+< labels.distance->setText(QString::number(int(paramsStorage.getFloat("FrogPilotKilometers") * (metric_ ? 1 : KM_TO_MILE))));
+---
+> labels.routes->setText(QString::number(params.getInt("FrogPilotDrives")));
+> labels.distance->setText(QString::number(int(params.getFloat("FrogPilotKilometers") * (metric_ ? 1 : KM_TO_MILE))));
+74c74
+< labels.hours->setText(QString::number(int(paramsStorage.getFloat("FrogPilotMinutes") / 60)));
+---
+> labels.hours->setText(QString::number(int(params.getFloat("FrogPilotMinutes") / 60)));
+diff -r clearpilot/openpilot/selfdrive/ui/qt/widgets/drive_stats.h FrogPilot/openpilot/selfdrive/ui/qt/widgets/drive_stats.h
+21d20
+< Params paramsStorage{"/persist/params"};
+diff -r clearpilot/openpilot/selfdrive/ui/SConscript FrogPilot/openpilot/selfdrive/ui/SConscript
+42d41
+< # CLEARPILOT added qt/ready.cc
+47,48c46
+< "../frogpilot/screenrecorder/omx_encoder.cc", "../frogpilot/screenrecorder/screenrecorder.cc",
+< "qt/ready.cc"]
+---
+> "../frogpilot/screenrecorder/omx_encoder.cc", "../frogpilot/screenrecorder/screenrecorder.cc"]
+83,85d80
+<
+< # Clearpilot tools
+< qt_env.Program("/data/openpilot/system/clearpilot/tools/qt_shell", ["/data/openpilot/system/clearpilot/tools/qt_shell.cc"], LIBS=qt_libs)
+diff -r clearpilot/openpilot/selfdrive/ui/soundd.py FrogPilot/openpilot/selfdrive/ui/soundd.py
+253,262c253,259
+< # Clearpilot: Impl theme switcher
+< # if current_holiday_theme != 0:
+< # theme_name = holiday_theme_configuration.get(current_holiday_theme)
+< # self.sound_directory = BASEDIR + ("/selfdrive/frogpilot/assets/holiday_themes/" + theme_name + "/sounds/")
+< # self.goat_scream = False
+< # else:
+< # theme_name = theme_configuration.get(custom_sounds)
+< # self.sound_directory = BASEDIR + ("/selfdrive/clearpilot/theme/" + theme_name + "/sounds/" if custom_sounds != 0 else "/selfdrive/assets/sounds/")
+<
+< self.sound_directory = BASEDIR + ("/selfdrive/clearpilot/theme/clearpilot/sounds/" if custom_sounds != 0 else "/selfdrive/assets/sounds/")
+---
+> if current_holiday_theme != 0:
+> theme_name = holiday_theme_configuration.get(current_holiday_theme)
+> self.sound_directory = BASEDIR + ("/selfdrive/frogpilot/assets/holiday_themes/" + theme_name + "/sounds/")
+> self.goat_scream = False
+> else:
+> theme_name = theme_configuration.get(custom_sounds)
+> self.sound_directory = BASEDIR + ("/selfdrive/frogpilot/assets/custom_themes/" + theme_name + "/sounds/" if custom_sounds != 0 else "/selfdrive/assets/sounds/")
+diff -r clearpilot/openpilot/selfdrive/ui/spinner FrogPilot/openpilot/selfdrive/ui/spinner
+3,4c3,4
+< if [ -f /TICI ] && [ ! -f qt/spinner ]; then
+< cp qt/spinner_larch64 qt/spinner
+---
+> if [ -f /TICI ] && [ ! -f _spinner ]; then
+> cp qt/spinner_larch64 _spinner
+7c7
+< exec ./qt/spinner "$1"
+---
+> exec ./_spinner "$1"
+diff -r clearpilot/openpilot/selfdrive/ui/translations/main_ar.ts FrogPilot/openpilot/selfdrive/ui/translations/main_ar.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+734,737d364
+<
+< Manage at %1
+<
+<
+940c567
+< openpilot
+---
+> openpilot
+991,994d617
+<
+< ClearPilot
+<
+<
+1041c664
+< ×
+---
+> ×
+1059,1078d681
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1272,1295d874
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1317c896
+< يتم تحميل التحديثات فقط عندما تكون السيارة متوقفة.
+---
+> يتم تحميل التحديثات فقط عندما تكون السيارة متوقفة.
+1371,1394d949
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< عرض
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1656,1663d1210
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/openpilot/selfdrive/ui/translations/main_de.ts FrogPilot/openpilot/selfdrive/ui/translations/main_de.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+730,733d360
+<
+< Manage at %1
+<
+<
+935c562
+< openpilot
+---
+> openpilot
+974,977d600
+<
+< ClearPilot
+<
+<
+1023c646
+< x
+---
+> x
+1041,1060d663
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1255,1278d857
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1301c880
+< Updates werden nur heruntergeladen, wenn das Auto aus ist.
+---
+> Updates werden nur heruntergeladen, wenn das Auto aus ist.
+1355,1378d933
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< ANSEHEN
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1641,1648d1195
+<
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+diff -r clearpilot/openpilot/selfdrive/ui/translations/main_fr.ts FrogPilot/openpilot/selfdrive/ui/translations/main_fr.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+730,733d360
+<
+< Manage at %1
+<
+<
+936c563
+< openpilot
+---
+> openpilot
+975,978d601
+<
+< ClearPilot
+<
+<
+1025c648
+< ×
+---
+> ×
+1043,1062d665
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1256,1279d858
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1285c864
+< Les MàJ sont téléchargées uniquement si la voiture est éteinte.
+---
+> Les MàJ sont téléchargées uniquement si la voiture est éteinte.
+1355,1378d933
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< VOIR
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1640,1647d1194
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/openpilot/selfdrive/ui/translations/main_ja.ts FrogPilot/openpilot/selfdrive/ui/translations/main_ja.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+729,732d359
+<
+< Manage at %1
+<
+<
+934c561
+< openpilot
+---
+> openpilot
+970,973d596
+<
+< ClearPilot
+<
+<
+1019c642
+< ×
+---
+> ×
+1037,1056d659
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1250,1273d852
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1279c858
+< 車の電源がオフの間のみ、アップデートのダウンロードが行われます。
+---
+> 車の電源がオフの間のみ、アップデートのダウンロードが行われます。
+1349,1372d927
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< FrogPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< 見る
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1633,1640d1187
+<
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+diff -r clearpilot/openpilot/selfdrive/ui/translations/main_ko.ts FrogPilot/openpilot/selfdrive/ui/translations/main_ko.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+729,732d359
+<
+< Manage at %1
+<
+<
+935c562
+< openpilot
+---
+> openpilot
+971,974d597
+<
+< ClearPilot
+<
+<
+1021c644
+< ×
+---
+> ×
+1039,1058d661
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1252,1275d854
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1281c860
+< 업데이트는 차량 시동이 꺼졌을 때 다운로드됩니다.
+---
+> 업데이트는 차량 시동이 꺼졌을 때 다운로드됩니다.
+1351,1374d929
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< 보기
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1636,1643d1190
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/openpilot/selfdrive/ui/translations/main_pt-BR.ts FrogPilot/openpilot/selfdrive/ui/translations/main_pt-BR.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+730,733d360
+<
+< Manage at %1
+<
+<
+936c563
+< openpilot
+---
+> openpilot
+975,978d601
+<
+< ClearPilot
+<
+<
+1025c648
+< ×
+---
+> ×
+1043,1062d665
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1256,1279d858
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1285c864
+< Atualizações baixadas durante o motor desligado.
+---
+> Atualizações baixadas durante o motor desligado.
+1355,1378d933
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< VER
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1640,1647d1194
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/openpilot/selfdrive/ui/translations/main_th.ts FrogPilot/openpilot/selfdrive/ui/translations/main_th.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+729,732d359
+<
+< Manage at %1
+<
+<
+935c562
+< openpilot
+---
+> openpilot
+971,974d597
+<
+< ClearPilot
+<
+<
+1021c644
+< ×
+---
+> ×
+1039,1058d661
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1252,1275d854
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1297c876
+< ตัวอัปเดตจะดำเนินการดาวน์โหลดเมื่อรถดับเครื่องยนต์อยู่เท่านั้น
+---
+> ตัวอัปเดตจะดำเนินการดาวน์โหลดเมื่อรถดับเครื่องยนต์อยู่เท่านั้น
+1351,1374d929
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< ดู
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1636,1643d1190
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/openpilot/selfdrive/ui/translations/main_tr.ts FrogPilot/openpilot/selfdrive/ui/translations/main_tr.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+729,732d359
+<
+< Manage at %1
+<
+<
+934c561
+< openpilot
+---
+> openpilot
+970,973d596
+<
+< ClearPilot
+<
+<
+1019c642
+< x
+---
+> x
+1037,1056d659
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1250,1273d852
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1293a873,876
+> Updates are only downloaded while the car is off.
+>
+>
+>
+1345,1368d927
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< BAK
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1629,1636d1187
+<
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+diff -r clearpilot/openpilot/selfdrive/ui/translations/main_zh-CHS.ts FrogPilot/openpilot/selfdrive/ui/translations/main_zh-CHS.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+729,732d359
+<
+< Manage at %1
+<
+<
+935c562
+< openpilot
+---
+> openpilot
+971,974d597
+<
+< ClearPilot
+<
+<
+1021c644
+< ×
+---
+> ×
+1039,1058d661
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1252,1275d854
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1281c860
+< 车辆熄火时才能下载升级文件。
+---
+> 车辆熄火时才能下载升级文件。
+1351,1374d929
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< 查看
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1636,1643d1190
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/openpilot/selfdrive/ui/translations/main_zh-CHT.ts FrogPilot/openpilot/selfdrive/ui/translations/main_zh-CHT.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+729,732d359
+<
+< Manage at %1
+<
+<
+935c562
+< openpilot
+---
+> openpilot
+971,974d597
+<
+< ClearPilot
+<
+<
+1021c644
+< ×
+---
+> ×
+1039,1058d661
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1252,1275d854
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1281c860
+< 系統更新只會在熄火時下載。
+---
+> 系統更新只會在熄火時下載。
+1351,1374d929
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< 觀看
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1636,1643d1190
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/openpilot/selfdrive/ui/ui.cc FrogPilot/openpilot/selfdrive/ui/ui.cc
+361,363c361,362
+< // CLEARPILOT
+< scene.lane_line_width = /* params.getInt("LaneLinesWidth") */ 2 * (scene.is_metric ? 1.0f : INCH_TO_CM) / 200.0f;
+< scene.path_edge_width = /* params.getInt("PathEdgeWidth"); */ 16;
+---
+> scene.lane_line_width = params.getInt("LaneLinesWidth") * (scene.is_metric ? 1.0f : INCH_TO_CM) / 200.0f;
+> scene.path_edge_width = params.getInt("PathEdgeWidth");
+394c393
+< scene.screen_timeout = screen_management ? params.getInt("ScreenTimeout") : 120;
+---
+> scene.screen_timeout = screen_management ? params.getInt("ScreenTimeout") : 30;
+diff -r clearpilot/openpilot/selfdrive/ui/ui.h FrogPilot/openpilot/selfdrive/ui/ui.h
+21c21
+< const int UI_BORDER_SIZE = 16; // clearpilot
+---
+> const int UI_BORDER_SIZE = 30;
+29c29
+< const float MAX_DRAW_DISTANCE = 100.0;
+---
+> const float MAX_DRAW_DISTANCE = 100.0;
+109a110,120
+> typedef enum UIStatus {
+> STATUS_DISENGAGED,
+> STATUS_OVERRIDE,
+> STATUS_ENGAGED,
+>
+> // FrogPilot statuses
+> STATUS_ALWAYS_ON_LATERAL_ACTIVE,
+> STATUS_TRAFFIC_MODE_ACTIVE,
+>
+> } UIStatus;
+>
+119,128d129
+<
+< // Clearpilot redefined these.
+< typedef enum UIStatus {
+< STATUS_DISENGAGED,
+< STATUS_OVERRIDE,
+< STATUS_ENGAGED,
+< STATUS_ALWAYS_ON_LATERAL_ACTIVE,
+< STATUS_TRAFFIC_MODE_ACTIVE,
+< STATUS_EXPERIMENTAL_ACTIVE,
+< } UIStatus;
+130d130
+< // Clearpilot custom colors
+133,137c133,138
+< [STATUS_OVERRIDE] = QColor(64, 85, 245, 0xd1), // When you nudge the steering wheel while engaged
+< [STATUS_ENGAGED] = QColor(64, 85, 245, 0xd1), // Orange
+< [STATUS_ALWAYS_ON_LATERAL_ACTIVE] = QColor(162, 221, 235, 0xd1), // Gray
+< [STATUS_TRAFFIC_MODE_ACTIVE] = QColor(0xc9, 0x22, 0x31, 0xd1), // ? unused?
+< [STATUS_EXPERIMENTAL_ACTIVE] = QColor(201, 41, 204, 0xd1), // Magenta
+---
+> [STATUS_OVERRIDE] = QColor(0x91, 0x9b, 0x95, 0xf1),
+> [STATUS_ENGAGED] = QColor(0x17, 0x86, 0x44, 0xf1),
+>
+> // FrogPilot colors
+> [STATUS_ALWAYS_ON_LATERAL_ACTIVE] = QColor(0x0a, 0xba, 0xb5, 0xf1),
+> [STATUS_TRAFFIC_MODE_ACTIVE] = QColor(0xc9, 0x22, 0x31, 0xf1),
+142c143
+< {cereal::ControlsState::AlertStatus::USER_PROMPT, QColor(4, 64, 11, 0xf1)}, // CLEARPILOT changed to a shade of dark blue
+---
+> {cereal::ControlsState::AlertStatus::USER_PROMPT, QColor(0xDA, 0x6F, 0x25, 0xf1)},
+144c145
+< {cereal::ControlsState::AlertStatus::FROGPILOT, QColor(47, 158, 238, 0xf1)}, // CLEARPILOT changed to light blue
+---
+> {cereal::ControlsState::AlertStatus::FROGPILOT, QColor(0x17, 0x86, 0x44, 0xf1)},
+diff -r clearpilot/openpilot/selfdrive/updated/updated.py FrogPilot/openpilot/selfdrive/updated/updated.py
+89,90d88
+< # CLEARPILOT
+< return b""
+134,135c132
+< # CLEARPILOT
+< return
+---
+>
+Only in clearpilot/openpilot/system: clearpilot
+diff -r clearpilot/openpilot/system/hardware/base.h FrogPilot/openpilot/system/hardware/base.h
+29d28
+< static void soft_reboot() {}
+diff -r clearpilot/openpilot/system/hardware/base.py FrogPilot/openpilot/system/hardware/base.py
+33,36d32
+< def soft_reboot(self):
+< pass
+<
+< @abstractmethod
+diff -r clearpilot/openpilot/system/hardware/pc/hardware.py FrogPilot/openpilot/system/hardware/pc/hardware.py
+23,25d22
+< def soft_reboot(self):
+< print("SOFT REBOOT!")
+<
+diff -r clearpilot/openpilot/system/hardware/tici/hardware.h FrogPilot/openpilot/system/hardware/tici/hardware.h
+53,69d52
+< static void soft_reboot() {
+< const std::vector commands = {
+< "rm -f /tmp/safe_staging_overlay.lock",
+< "tmux new -s commatmp -d '/data/continue.sh'",
+< "tmux kill-session -t comma",
+< "tmux rename comma"
+< };
+< for (const auto& cmd : commands) {
+< int result;
+< do {
+< result = std::system(cmd.c_str());
+< } while (result != 0);
+< if (result != 0) {
+< reboot();
+< }
+< }
+< }
+diff -r clearpilot/openpilot/system/hardware/tici/hardware.py FrogPilot/openpilot/system/hardware/tici/hardware.py
+135,144d134
+< def soft_reboot(self):
+< commands = [
+< ['rm', '-f', '/tmp/safe_staging_overlay.lock'],
+< ['tmux', 'new', '-s', 'commatmp', '-d', '/data/continue.sh'],
+< ['tmux', 'kill-session', '-t', 'comma'],
+< ['tmux', 'rename', 'comma'],
+< ]
+< for command in commands:
+< subprocess.run(command, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
+<
+diff -r clearpilot/openpilot/system/loggerd/uploader.py FrogPilot/openpilot/system/loggerd/uploader.py
+17d16
+< import openpilot.selfdrive.sentry as sentry
+255,256c254
+< openpilot_crashed = os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt'))
+< if network_type == NetworkType.none or not at_home or openpilot_crashed:
+---
+> if network_type == NetworkType.none or not at_home:
+diff -r clearpilot/openpilot/system/qcomgpsd/nmeaport.py FrogPilot/openpilot/system/qcomgpsd/nmeaport.py
+96c96
+< with open(device, "r") as nmeaport:
+---
+> with open(device) as nmeaport:
+diff -r clearpilot/openpilot/system/qcomgpsd/qcomgpsd.py FrogPilot/openpilot/system/qcomgpsd/qcomgpsd.py
+13c13
+< from typing import NoReturn, Optional
+---
+> from typing import NoReturn
+93c93
+< def at_cmd(cmd: str) -> Optional[str]:
+---
+> def at_cmd(cmd: str) -> str | None:
+208c208
+< def wait_for_modem():
+---
+> def wait_for_modem(cmd="AT+QGPS?"):
+211c211
+< ret = subprocess.call("mmcli -m any --timeout 10 --command=\"AT+QGPS?\"", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True)
+---
+> ret = subprocess.call(f"mmcli -m any --timeout 10 --command=\"{cmd}\"", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True)
+345c345
+< dt_timestamp = (datetime.datetime(1980, 1, 6, 0, 0, 0, 0, datetime.timezone.utc) +
+---
+> dt_timestamp = (datetime.datetime(1980, 1, 6, 0, 0, 0, 0, datetime.UTC) +
+355,356c355,356
+< gps.flags = 1 if gps.verticalAccuracy != 500 else 0
+< if gps.flags:
+---
+> gps.hasFix = gps.verticalAccuracy != 500
+> if gps.hasFix:
+Only in FrogPilot/openpilot/system/tests: __init__.py
+Only in FrogPilot/openpilot/system/tests: test_logmessaged.py
+diff -r clearpilot/openpilot/system/timed.py FrogPilot/openpilot/system/timed.py
+59d58
+< tf = TimezoneFinder()
+Only in FrogPilot/openpilot/system: ugpsd.py
+diff -r clearpilot/openpilot/system/version.py FrogPilot/openpilot/system/version.py
+4c4,5
+< from typing import List, Callable, TypeVar
+---
+> from typing import TypeVar
+> from collections.abc import Callable
+21c22
+< def run_cmd(cmd: List[str]) -> str:
+---
+> def run_cmd(cmd: list[str]) -> str:
+25c26
+< def run_cmd_default(cmd: List[str], default: str = "") -> str:
+---
+> def run_cmd_default(cmd: list[str], default: str = "") -> str:
+diff -r clearpilot/openpilot/system/webrtc/device/audio.py FrogPilot/openpilot/system/webrtc/device/audio.py
+3d2
+< from typing import Optional, List, Tuple
+20c19
+< def __init__(self, audio_format: int = pyaudio.paInt16, rate: int = 16000, channels: int = 1, packet_time: float = 0.020, device_index: Optional[int] = None):
+---
+> def __init__(self, audio_format: int = pyaudio.paInt16, rate: int = 16000, channels: int = 1, packet_time: float = 0.020, device_index: int = None):
+52c51
+< def __init__(self, audio_format: int = pyaudio.paInt16, rate: int = 48000, channels: int = 2, packet_time: float = 0.2, device_index: Optional[int] = None):
+---
+> def __init__(self, audio_format: int = pyaudio.paInt16, rate: int = 48000, channels: int = 2, packet_time: float = 0.2, device_index: int = None):
+65c64
+< self.tracks_and_tasks: List[Tuple[aiortc.MediaStreamTrack, Optional[asyncio.Task]]] = []
+---
+> self.tracks_and_tasks: list[tuple[aiortc.MediaStreamTrack, asyncio.Task | None]] = []
+diff -r clearpilot/openpilot/system/webrtc/device/video.py FrogPilot/openpilot/system/webrtc/device/video.py
+2d1
+< from typing import Optional
+43c42
+< def codec_preference(self) -> Optional[str]:
+---
+> def codec_preference(self) -> str | None:
+diff -r clearpilot/openpilot/system/webrtc/schema.py FrogPilot/openpilot/system/webrtc/schema.py
+2c2
+< from typing import Union, List, Dict, Any
+---
+> from typing import Any
+5c5
+< def generate_type(type_walker, schema_walker) -> Union[str, List[Any], Dict[str, Any]]:
+---
+> def generate_type(type_walker, schema_walker) -> str | list[Any] | dict[str, Any]:
+18c18
+< def generate_struct(schema: capnp.lib.capnp._StructSchema) -> Dict[str, Any]:
+---
+> def generate_struct(schema: capnp.lib.capnp._StructSchema) -> dict[str, Any]:
+22c22
+< def generate_field(field: capnp.lib.capnp._StructSchemaField) -> Union[str, List[Any], Dict[str, Any]]:
+---
+> def generate_field(field: capnp.lib.capnp._StructSchemaField) -> str | list[Any] | dict[str, Any]:
+Only in FrogPilot/openpilot/system/webrtc/tests: test_stream_session.py
+Only in FrogPilot/openpilot/system/webrtc/tests: test_webrtcd.py
+diff -r clearpilot/openpilot/system/webrtc/webrtcd.py FrogPilot/openpilot/system/webrtc/webrtcd.py
+9c9
+< from typing import Any, List, Optional, Union, TYPE_CHECKING
+---
+> from typing import Any, TYPE_CHECKING
+27c27
+< self.channels: List['RTCDataChannel'] = []
+---
+> self.channels: list['RTCDataChannel'] = []
+104a105,116
+> class DynamicPubMaster(messaging.PubMaster):
+> def __init__(self, *args, **kwargs):
+> super().__init__(*args, **kwargs)
+> self.lock = asyncio.Lock()
+>
+> async def add_services_if_needed(self, services):
+> async with self.lock:
+> for service in services:
+> if service not in self.sock:
+> self.sock[service] = messaging.pub_sock(service)
+>
+>
+106c118,120
+< def __init__(self, sdp: str, cameras: List[str], incoming_services: List[str], outgoing_services: List[str], debug_mode: bool = False):
+---
+> shared_pub_master = DynamicPubMaster([])
+>
+> def __init__(self, sdp: str, cameras: list[str], incoming_services: list[str], outgoing_services: list[str], debug_mode: bool = False):
+131,133c145,153
+< self.outgoing_bridge = CerealOutgoingMessageProxy(messaging.SubMaster(outgoing_services))
+< self.incoming_bridge = CerealIncomingMessageProxy(messaging.PubMaster(incoming_services))
+< self.outgoing_bridge_runner = CerealProxyRunner(self.outgoing_bridge)
+---
+> self.incoming_bridge: CerealIncomingMessageProxy | None = None
+> self.incoming_bridge_services = incoming_services
+> self.outgoing_bridge: CerealOutgoingMessageProxy | None = None
+> self.outgoing_bridge_runner: CerealProxyRunner | None = None
+> if len(incoming_services) > 0:
+> self.incoming_bridge = CerealIncomingMessageProxy(self.shared_pub_master)
+> if len(outgoing_services) > 0:
+> self.outgoing_bridge = CerealOutgoingMessageProxy(messaging.SubMaster(outgoing_services))
+> self.outgoing_bridge_runner = CerealProxyRunner(self.outgoing_bridge)
+135,136c155,156
+< self.audio_output: Optional[Union[AudioOutputSpeaker, MediaBlackhole]] = None
+< self.run_task: Optional[asyncio.Task] = None
+---
+> self.audio_output: AudioOutputSpeaker | MediaBlackhole | None = None
+> self.run_task: asyncio.Task | None = None
+154a175
+> assert self.incoming_bridge is not None
+164,167c185,191
+< self.stream.set_message_handler(self.message_handler)
+< channel = self.stream.get_messaging_channel()
+< self.outgoing_bridge_runner.proxy.add_channel(channel)
+< self.outgoing_bridge_runner.start()
+---
+> if self.incoming_bridge is not None:
+> await self.shared_pub_master.add_services_if_needed(self.incoming_bridge_services)
+> self.stream.set_message_handler(self.message_handler)
+> if self.outgoing_bridge_runner is not None:
+> channel = self.stream.get_messaging_channel()
+> self.outgoing_bridge_runner.proxy.add_channel(channel)
+> self.outgoing_bridge_runner.start()
+184c208,209
+< self.outgoing_bridge_runner.stop()
+---
+> if self.outgoing_bridge is not None:
+> self.outgoing_bridge_runner.stop()
+192,194c217,219
+< cameras: List[str]
+< bridge_services_in: List[str] = field(default_factory=list)
+< bridge_services_out: List[str] = field(default_factory=list)
+---
+> cameras: list[str]
+> bridge_services_in: list[str] = field(default_factory=list)
+> bridge_services_out: list[str] = field(default_factory=list)
+Only in FrogPilot/openpilot/tools/bodyteleop: .gitignore
+diff -r clearpilot/openpilot/tools/bodyteleop/web.py FrogPilot/openpilot/tools/bodyteleop/web.py
+59c59
+< stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+---
+> capture_output=True, shell=True)
+80c80
+< with open(os.path.join(TELEOPDIR, "static", "index.html"), "r") as f:
+---
+> with open(os.path.join(TELEOPDIR, "static", "index.html")) as f:
+Only in FrogPilot/openpilot/tools/cabana/assets: assets.qrc
+Only in FrogPilot/openpilot/tools/cabana/assets: cabana-icon.png
+Only in FrogPilot/openpilot/tools/cabana/assets: .gitignore
+Only in FrogPilot/openpilot/tools/cabana: binaryview.cc
+Only in FrogPilot/openpilot/tools/cabana: binaryview.h
+Only in FrogPilot/openpilot/tools/cabana: cabana.cc
+Only in FrogPilot/openpilot/tools/cabana/chart: chart.cc
+Only in FrogPilot/openpilot/tools/cabana/chart: chart.h
+Only in FrogPilot/openpilot/tools/cabana/chart: chartswidget.cc
+Only in FrogPilot/openpilot/tools/cabana/chart: chartswidget.h
+Only in FrogPilot/openpilot/tools/cabana/chart: signalselector.cc
+Only in FrogPilot/openpilot/tools/cabana/chart: signalselector.h
+Only in FrogPilot/openpilot/tools/cabana/chart: sparkline.cc
+Only in FrogPilot/openpilot/tools/cabana/chart: sparkline.h
+Only in FrogPilot/openpilot/tools/cabana/chart: tiplabel.cc
+Only in FrogPilot/openpilot/tools/cabana/chart: tiplabel.h
+Only in FrogPilot/openpilot/tools/cabana: commands.cc
+Only in FrogPilot/openpilot/tools/cabana: commands.h
+Only in FrogPilot/openpilot/tools/cabana/dbc: dbc.cc
+Only in FrogPilot/openpilot/tools/cabana/dbc: dbcfile.cc
+Only in FrogPilot/openpilot/tools/cabana/dbc: dbcfile.h
+Only in FrogPilot/openpilot/tools/cabana/dbc: dbc.h
+Only in FrogPilot/openpilot/tools/cabana/dbc: dbcmanager.cc
+Only in FrogPilot/openpilot/tools/cabana/dbc: dbcmanager.h
+Only in FrogPilot/openpilot/tools/cabana/dbc: generate_dbc_json.py
+Only in FrogPilot/openpilot/tools/cabana: detailwidget.cc
+Only in FrogPilot/openpilot/tools/cabana: detailwidget.h
+Only in FrogPilot/openpilot/tools/cabana: .gitignore
+Only in FrogPilot/openpilot/tools/cabana: historylog.cc
+Only in FrogPilot/openpilot/tools/cabana: historylog.h
+Only in FrogPilot/openpilot/tools/cabana: mainwin.cc
+Only in FrogPilot/openpilot/tools/cabana: mainwin.h
+Only in FrogPilot/openpilot/tools/cabana: messageswidget.cc
+Only in FrogPilot/openpilot/tools/cabana: messageswidget.h
+Only in FrogPilot/openpilot/tools/cabana: README.md
+Only in FrogPilot/openpilot/tools/cabana: SConscript
+Only in FrogPilot/openpilot/tools/cabana: settings.cc
+Only in FrogPilot/openpilot/tools/cabana: settings.h
+Only in FrogPilot/openpilot/tools/cabana: signalview.cc
+Only in FrogPilot/openpilot/tools/cabana: signalview.h
+Only in FrogPilot/openpilot/tools/cabana/streams: abstractstream.cc
+Only in FrogPilot/openpilot/tools/cabana/streams: abstractstream.h
+Only in FrogPilot/openpilot/tools/cabana/streams: devicestream.cc
+Only in FrogPilot/openpilot/tools/cabana/streams: devicestream.h
+Only in FrogPilot/openpilot/tools/cabana/streams: livestream.cc
+Only in FrogPilot/openpilot/tools/cabana/streams: livestream.h
+Only in FrogPilot/openpilot/tools/cabana/streams: pandastream.cc
+Only in FrogPilot/openpilot/tools/cabana/streams: pandastream.h
+Only in FrogPilot/openpilot/tools/cabana/streams: replaystream.cc
+Only in FrogPilot/openpilot/tools/cabana/streams: replaystream.h
+Only in FrogPilot/openpilot/tools/cabana/streams: socketcanstream.cc
+Only in FrogPilot/openpilot/tools/cabana/streams: socketcanstream.h
+Only in FrogPilot/openpilot/tools/cabana: streamselector.cc
+Only in FrogPilot/openpilot/tools/cabana: streamselector.h
+Only in FrogPilot/openpilot/tools/cabana/tests: test_cabana.cc
+Only in FrogPilot/openpilot/tools/cabana/tests: test_runner.cc
+Only in FrogPilot/openpilot/tools/cabana/tools: findsignal.cc
+Only in FrogPilot/openpilot/tools/cabana/tools: findsignal.h
+Only in FrogPilot/openpilot/tools/cabana/tools: findsimilarbits.cc
+Only in FrogPilot/openpilot/tools/cabana/tools: findsimilarbits.h
+Only in FrogPilot/openpilot/tools/cabana/utils: export.cc
+Only in FrogPilot/openpilot/tools/cabana/utils: export.h
+Only in FrogPilot/openpilot/tools/cabana/utils: util.cc
+Only in FrogPilot/openpilot/tools/cabana/utils: util.h
+Only in FrogPilot/openpilot/tools/cabana: videowidget.cc
+Only in FrogPilot/openpilot/tools/cabana: videowidget.h
+Only in FrogPilot/openpilot/tools/camerastream: compressed_vipc.py
+Only in FrogPilot/openpilot/tools/camerastream: README.md
+Only in FrogPilot/openpilot/tools/car_porting: auto_fingerprint.py
+Only in FrogPilot/openpilot/tools/car_porting/examples: ford_vin_fingerprint.ipynb
+Only in FrogPilot/openpilot/tools/car_porting/examples: subaru_fuzzy_fingerprint.ipynb
+Only in FrogPilot/openpilot/tools/car_porting/examples: subaru_long_accel.ipynb
+Only in FrogPilot/openpilot/tools/car_porting/examples: subaru_steer_temp_fault.ipynb
+Only in FrogPilot/openpilot/tools/car_porting: README.md
+Only in FrogPilot/openpilot/tools/car_porting: test_car_model.py
+Only in FrogPilot/openpilot/tools: CTF.md
+Only in FrogPilot/openpilot/tools: install_python_dependencies.sh
+Only in FrogPilot/openpilot/tools: install_ubuntu_dependencies.sh
+Only in FrogPilot/openpilot/tools/latencylogger: latency_logger.py
+Only in FrogPilot/openpilot/tools/latencylogger: README.md
+diff -r clearpilot/openpilot/tools/lib/auth.py FrogPilot/openpilot/tools/lib/auth.py
+29c29
+< from typing import Any, Dict
+---
+> from typing import Any
+39c39
+< query_params: Dict[str, Any] = {}
+---
+> query_params: dict[str, Any] = {}
+diff -r clearpilot/openpilot/tools/lib/azure_container.py FrogPilot/openpilot/tools/lib/azure_container.py
+5c5
+< from typing import IO, Union
+---
+> from typing import IO
+60c60
+< def upload_bytes(self, data: Union[bytes, IO], blob_name: str) -> str:
+---
+> def upload_bytes(self, data: bytes | IO, blob_name: str) -> str:
+72c72
+< def upload_file(self, path: Union[str, os.PathLike], blob_name: str) -> str:
+---
+> def upload_file(self, path: str | os.PathLike, blob_name: str) -> str:
+diff -r clearpilot/openpilot/tools/lib/bootlog.py FrogPilot/openpilot/tools/lib/bootlog.py
+3d2
+< from typing import List, Optional
+47c46
+< def get_bootlog_from_id(bootlog_id: str) -> Optional[Bootlog]:
+---
+> def get_bootlog_from_id(bootlog_id: str) -> Bootlog | None:
+55c54
+< def get_bootlogs(dongle_id: str) -> List[Bootlog]:
+---
+> def get_bootlogs(dongle_id: str) -> list[Bootlog]:
+diff -r clearpilot/openpilot/tools/lib/helpers.py FrogPilot/openpilot/tools/lib/helpers.py
+12,14c12,14
+< LOG_ID = r'(?P(?:{}|{}))'.format(TIMESTAMP, LOG_ID_V2)
+< ROUTE_NAME = r'(?P{}[|_/]{})'.format(DONGLE_ID, LOG_ID)
+< SEGMENT_NAME = r'{}(?:--|/)(?P[0-9]+)'.format(ROUTE_NAME)
+---
+> LOG_ID = fr'(?P(?:{TIMESTAMP}|{LOG_ID_V2}))'
+> ROUTE_NAME = fr'(?P{DONGLE_ID}[|_/]{LOG_ID})'
+> SEGMENT_NAME = fr'{ROUTE_NAME}(?:--|/)(?P[0-9]+)'
+17,18c17,18
+< SLICE = r'(?P{})?:?(?P{})?:?(?P{})?'.format(INDEX, INDEX, INDEX)
+< SEGMENT_RANGE = r'{}(?:(--|/)(?P({})))?(?:/(?P([qras])))?'.format(ROUTE_NAME, SLICE)
+---
+> SLICE = fr'(?P{INDEX})?:?(?P{INDEX})?:?(?P{INDEX})?'
+> SEGMENT_RANGE = fr'{ROUTE_NAME}(?:(--|/)(?P({SLICE})))?(?:/(?P([qras])))?'
+22,23c22,23
+< EXPLORER_FILE = r'^(?P{})--(?P[a-z]+\.[a-z0-9]+)$'.format(SEGMENT_NAME)
+< OP_SEGMENT_DIR = r'^(?P{})$'.format(SEGMENT_NAME)
+---
+> EXPLORER_FILE = fr'^(?P{SEGMENT_NAME})--(?P[a-z]+\.[a-z0-9]+)$'
+> OP_SEGMENT_DIR = fr'^(?P{SEGMENT_NAME})$'
+diff -r clearpilot/openpilot/tools/lib/live_logreader.py FrogPilot/openpilot/tools/lib/live_logreader.py
+2d1
+< from typing import List
+11c10
+< def raw_live_logreader(services: List[str] = ALL_SERVICES, addr: str = '127.0.0.1') -> RawLogIterable:
+---
+> def raw_live_logreader(services: list[str] = ALL_SERVICES, addr: str = '127.0.0.1') -> RawLogIterable:
+28c27
+< def live_logreader(services: List[str] = ALL_SERVICES, addr: str = '127.0.0.1') -> LogIterable:
+---
+> def live_logreader(services: list[str] = ALL_SERVICES, addr: str = '127.0.0.1') -> LogIterable:
+diff -r clearpilot/openpilot/tools/lib/logreader.py FrogPilot/openpilot/tools/lib/logreader.py
+14c14
+< from typing import Callable, Dict, Iterable, Iterator, List, Optional, Type
+---
+> from collections.abc import Callable, Iterable, Iterator
+24c24
+< LogMessage = Type[capnp._DynamicStructReader]
+---
+> LogMessage = type[capnp._DynamicStructReader]
+79,80c79,80
+< LogPath = Optional[str]
+< LogPaths = List[LogPath]
+---
+> LogPath = str | None
+> LogPaths = list[LogPath]
+92c92
+< if any(rlog is None or not valid_file(rlog) for rlog in rlog_paths):
+---
+> if any(rlog is None or not valid_file(rlog) for rlog in rlog_paths) and all(qlog is not None and valid_file(qlog) for qlog in qlog_paths):
+173c173
+< SOURCES: List[Source] = [internal_source, openpilotci_source, comma_api_source, comma_car_segments_source,]
+---
+> SOURCES: list[Source] = [internal_source, openpilotci_source, comma_api_source, comma_car_segments_source,]
+174a175,183
+>
+> # for automatic fallback modes, auto_source needs to first check if rlogs exist for any source
+> if mode in [ReadMode.AUTO, ReadMode.AUTO_INTERACTIVE]:
+> for source in SOURCES:
+> try:
+> return check_source(source, sr, ReadMode.RLOG)
+> except Exception:
+> pass
+>
+215c224
+< def _parse_identifiers(self, identifier: str | List[str]):
+---
+> def _parse_identifiers(self, identifier: str | list[str]):
+237c246
+< def __init__(self, identifier: str | List[str], default_mode: ReadMode = ReadMode.RLOG,
+---
+> def __init__(self, identifier: str | list[str], default_mode: ReadMode = ReadMode.RLOG,
+246c255
+< self.__lrs: Dict[int, _LogFileReader] = {}
+---
+> self.__lrs: dict[int, _LogFileReader] = {}
+251c260
+< self.__lrs[i] = _LogFileReader(self.logreader_identifiers[i])
+---
+> self.__lrs[i] = _LogFileReader(self.logreader_identifiers[i], sort_by_time=self.sort_by_time, only_union_types=self.only_union_types)
+diff -r clearpilot/openpilot/tools/lib/README.md FrogPilot/openpilot/tools/lib/README.md
+37c37
+< We also support a new format called a "segment range", where you can specify which segments from a route to load.
+---
+> We also support a new format called a "segment range":
+39c39,44
+< ```python
+---
+> ```
+> 344c5c15b34f2d8a / 2024-01-03--09-37-12 / 2:6 / q
+> [ dongle id ] [ timestamp ] [ selector ] [ query type]
+> ```
+>
+> you can specify which segments from a route to load
+40a46
+> ```python
+diff -r clearpilot/openpilot/tools/lib/route.py FrogPilot/openpilot/tools/lib/route.py
+7c7
+< from typing import Optional, cast
+---
+> from typing import cast
+234c234
+< def data_dir(self) -> Optional[str]: return self._data_dir
+---
+> def data_dir(self) -> str | None: return self._data_dir
+266a267,270
+> def log_id(self) -> str:
+> return self.m.group("log_id")
+>
+> @property
+294c298
+< return f"{self.dongle_id}/{self.timestamp}" + (f"/{self.slice}" if self.slice else "") + (f"/{self.selector}" if self.selector else "")
+---
+> return f"{self.dongle_id}/{self.log_id}" + (f"/{self.slice}" if self.slice else "") + (f"/{self.selector}" if self.selector else "")
+diff -r clearpilot/openpilot/tools/lib/tests/test_caching.py FrogPilot/openpilot/tools/lib/tests/test_caching.py
+4a5,6
+> import shutil
+> import socket
+8,9c10,11
+< from openpilot.selfdrive.athena.tests.helpers import with_http_server
+<
+---
+> from openpilot.selfdrive.test.helpers import with_http_server
+> from openpilot.system.hardware.hw import Paths
+18c20
+< self.send_response(200, b'1234')
+---
+> self.send_response(206 if "Range" in self.headers else 200, b'1234')
+35a38,65
+>
+> @with_caching_server
+> def test_pipeline_defaults(self, host):
+> # TODO: parameterize the defaults so we don't rely on hard-coded values in xx
+>
+> self.assertEqual(URLFile.pool_manager().pools._maxsize, 10) # PoolManager num_pools param
+> pool_manager_defaults = {
+> "maxsize": 100,
+> "socket_options": [(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),],
+> }
+> for k, v in pool_manager_defaults.items():
+> self.assertEqual(URLFile.pool_manager().connection_pool_kw.get(k), v)
+>
+> retry_defaults = {
+> "total": 5,
+> "backoff_factor": 0.5,
+> "status_forcelist": [409, 429, 503, 504],
+> }
+> for k, v in retry_defaults.items():
+> self.assertEqual(getattr(URLFile.pool_manager().connection_pool_kw["retries"], k), v)
+>
+> # ensure caching off by default and cache dir doesn't get created
+> os.environ.pop("FILEREADER_CACHE", None)
+> if os.path.exists(Paths.download_cache_root()):
+> shutil.rmtree(Paths.download_cache_root())
+> URLFile(f"{host}/test.txt").get_length()
+> URLFile(f"{host}/test.txt").read()
+> self.assertEqual(os.path.exists(Paths.download_cache_root()), False)
+diff -r clearpilot/openpilot/tools/lib/tests/test_comma_car_segments.py FrogPilot/openpilot/tools/lib/tests/test_comma_car_segments.py
+1,2c1
+<
+<
+---
+> import pytest
+10a10
+> @pytest.mark.skip(reason="huggingface is flaky, run this test manually to check for issues")
+diff -r clearpilot/openpilot/tools/lib/tests/test_logreader.py FrogPilot/openpilot/tools/lib/tests/test_logreader.py
+1a2
+> import capnp
+13a15
+> from cereal import log as capnp_log
+217a220,256
+>
+> @pytest.mark.slow
+> def test_sort_by_time(self):
+> msgs = list(LogReader(f"{TEST_ROUTE}/0/q"))
+> self.assertNotEqual(msgs, sorted(msgs, key=lambda m: m.logMonoTime))
+>
+> msgs = list(LogReader(f"{TEST_ROUTE}/0/q", sort_by_time=True))
+> self.assertEqual(msgs, sorted(msgs, key=lambda m: m.logMonoTime))
+>
+> def test_only_union_types(self):
+> with tempfile.NamedTemporaryFile() as qlog:
+> # write valid Event messages
+> num_msgs = 100
+> with open(qlog.name, "wb") as f:
+> f.write(b"".join(capnp_log.Event.new_message().to_bytes() for _ in range(num_msgs)))
+>
+> msgs = list(LogReader(qlog.name))
+> self.assertEqual(len(msgs), num_msgs)
+> [m.which() for m in msgs]
+>
+> # append non-union Event message
+> event_msg = capnp_log.Event.new_message()
+> non_union_bytes = bytearray(event_msg.to_bytes())
+> non_union_bytes[event_msg.total_size.word_count * 8] = 0xff # set discriminant value out of range using Event word offset
+> with open(qlog.name, "ab") as f:
+> f.write(non_union_bytes)
+>
+> # ensure new message is added, but is not a union type
+> msgs = list(LogReader(qlog.name))
+> self.assertEqual(len(msgs), num_msgs + 1)
+> with self.assertRaises(capnp.KjException):
+> [m.which() for m in msgs]
+>
+> # should not be added when only_union_types=True
+> msgs = list(LogReader(qlog.name, only_union_types=True))
+> self.assertEqual(len(msgs), num_msgs)
+> [m.which() for m in msgs]
+diff -r clearpilot/openpilot/tools/lib/vidindex.py FrogPilot/openpilot/tools/lib/vidindex.py
+6d5
+< from typing import Tuple
+123c122
+< def get_ue(dat: bytes, start_idx: int, skip_bits: int) -> Tuple[int, int]:
+---
+> def get_ue(dat: bytes, start_idx: int, skip_bits: int) -> tuple[int, int]:
+187c186
+< def get_hevc_slice_type(dat: bytes, nal_unit_start: int, nal_unit_type: HevcNalUnitType) -> Tuple[int, bool]:
+---
+> def get_hevc_slice_type(dat: bytes, nal_unit_start: int, nal_unit_type: HevcNalUnitType) -> tuple[int, bool]:
+262c261
+< def hevc_index(hevc_file_name: str, allow_corrupt: bool=False) -> Tuple[list, int, bytes]:
+---
+> def hevc_index(hevc_file_name: str, allow_corrupt: bool=False) -> tuple[list, int, bytes]:
+Only in FrogPilot/openpilot/tools: mac_setup.sh
+Only in FrogPilot/openpilot/tools/plotjuggler: .gitignore
+Only in FrogPilot/openpilot/tools/plotjuggler: juggle.py
+Only in FrogPilot/openpilot/tools/plotjuggler/layouts: camera-timings.xml
+Only in FrogPilot/openpilot/tools/plotjuggler/layouts: CAN-bus-debug.xml
+Only in FrogPilot/openpilot/tools/plotjuggler/layouts: can-states.xml
+Only in FrogPilot/openpilot/tools/plotjuggler/layouts: controls_mismatch_debug.xml
+Only in FrogPilot/openpilot/tools/plotjuggler/layouts: demo.xml
+Only in FrogPilot/openpilot/tools/plotjuggler/layouts: gps_vs_llk.xml
+Only in FrogPilot/openpilot/tools/plotjuggler/layouts: longitudinal.xml
+Only in FrogPilot/openpilot/tools/plotjuggler/layouts: max-torque-debug.xml
+Only in FrogPilot/openpilot/tools/plotjuggler/layouts: system_lag_debug.xml
+Only in FrogPilot/openpilot/tools/plotjuggler/layouts: thermal_debug.xml
+Only in FrogPilot/openpilot/tools/plotjuggler/layouts: torque-controller.xml
+Only in FrogPilot/openpilot/tools/plotjuggler/layouts: tuning.xml
+Only in FrogPilot/openpilot/tools/plotjuggler/layouts: ublox-debug.xml
+Only in FrogPilot/openpilot/tools/plotjuggler: README.md
+Only in FrogPilot/openpilot/tools/plotjuggler: test_plotjuggler.py
+Only in FrogPilot/openpilot/tools/profiling/clpeak: build.sh
+Only in FrogPilot/openpilot/tools/profiling/clpeak: .gitignore
+Only in FrogPilot/openpilot/tools/profiling/clpeak: no_print.patch
+Only in FrogPilot/openpilot/tools/profiling/clpeak: run_continuously.patch
+Only in FrogPilot/openpilot/tools/profiling: ftrace.sh
+Only in FrogPilot/openpilot/tools/profiling/palanteer: .gitignore
+Only in FrogPilot/openpilot/tools/profiling/palanteer: setup.sh
+Only in FrogPilot/openpilot/tools/profiling/perfetto: build.sh
+Only in FrogPilot/openpilot/tools/profiling/perfetto: copy.sh
+Only in FrogPilot/openpilot/tools/profiling/perfetto: .gitignore
+Only in FrogPilot/openpilot/tools/profiling/perfetto: record.sh
+Only in FrogPilot/openpilot/tools/profiling/perfetto: server.sh
+Only in FrogPilot/openpilot/tools/profiling/perfetto: traces.sh
+Only in FrogPilot/openpilot/tools/profiling/py-spy: profile.sh
+Only in FrogPilot/openpilot/tools/profiling/snapdragon: .gitignore
+Only in FrogPilot/openpilot/tools/profiling/snapdragon: README.md
+Only in FrogPilot/openpilot/tools/profiling/snapdragon: setup-agnos.sh
+Only in FrogPilot/openpilot/tools/profiling/snapdragon: setup-profiler.sh
+Only in FrogPilot/openpilot/tools/profiling: watch-irqs.sh
+Only in FrogPilot/openpilot/tools: README.md
+Only in FrogPilot/openpilot/tools/replay: camera.cc
+Only in FrogPilot/openpilot/tools/replay: camera.h
+Only in FrogPilot/openpilot/tools/replay: can_replay.py
+Only in FrogPilot/openpilot/tools/replay: consoleui.cc
+Only in FrogPilot/openpilot/tools/replay: consoleui.h
+Only in FrogPilot/openpilot/tools/replay: filereader.cc
+Only in FrogPilot/openpilot/tools/replay: filereader.h
+Only in FrogPilot/openpilot/tools/replay: framereader.cc
+Only in FrogPilot/openpilot/tools/replay: framereader.h
+Only in FrogPilot/openpilot/tools/replay: .gitignore
+Only in FrogPilot/openpilot/tools/replay: __init__.py
+Only in FrogPilot/openpilot/tools/replay/lib: __init__.py
+Only in FrogPilot/openpilot/tools/replay/lib: ui_helpers.py
+Only in FrogPilot/openpilot/tools/replay: logreader.cc
+Only in FrogPilot/openpilot/tools/replay: logreader.h
+Only in FrogPilot/openpilot/tools/replay: main.cc
+Only in FrogPilot/openpilot/tools/replay: README.md
+Only in FrogPilot/openpilot/tools/replay: replay.cc
+Only in FrogPilot/openpilot/tools/replay: replay.h
+Only in FrogPilot/openpilot/tools/replay: route.cc
+Only in FrogPilot/openpilot/tools/replay: route.h
+Only in FrogPilot/openpilot/tools/replay: SConscript
+Only in FrogPilot/openpilot/tools/replay/tests: test_replay.cc
+Only in FrogPilot/openpilot/tools/replay/tests: test_runner.cc
+Only in FrogPilot/openpilot/tools/replay: ui.py
+Only in FrogPilot/openpilot/tools/replay: unlog_ci_segment.py
+Only in FrogPilot/openpilot/tools/replay: util.cc
+Only in FrogPilot/openpilot/tools/replay: util.h
+Only in FrogPilot/openpilot/tools/scripts: fetch_image_from_route.py
+Only in FrogPilot/openpilot/tools/scripts: save_ubloxraw_stream.py
+Only in FrogPilot/openpilot/tools/scripts: setup_ssh_keys.py
+Only in FrogPilot/openpilot/tools/serial: connect.sh
+Only in FrogPilot/openpilot/tools/serial: README.md
+Only in FrogPilot/openpilot/tools/sim/bridge: common.py
+Only in FrogPilot/openpilot/tools/sim/bridge: __init__.py
+Only in FrogPilot/openpilot/tools/sim/bridge/metadrive: metadrive_bridge.py
+Only in FrogPilot/openpilot/tools/sim/bridge/metadrive: metadrive_common.py
+Only in FrogPilot/openpilot/tools/sim/bridge/metadrive: metadrive_process.py
+Only in FrogPilot/openpilot/tools/sim/bridge/metadrive: metadrive_world.py
+Only in FrogPilot/openpilot/tools/sim: build_container.sh
+Only in FrogPilot/openpilot/tools/sim: Dockerfile.sim
+Only in FrogPilot/openpilot/tools/sim: Dockerfile.sim_nvidia
+Only in FrogPilot/openpilot/tools/sim: __init__.py
+Only in FrogPilot/openpilot/tools/sim: launch_openpilot.sh
+Only in FrogPilot/openpilot/tools/sim/lib: camerad.py
+Only in FrogPilot/openpilot/tools/sim/lib: common.py
+Only in FrogPilot/openpilot/tools/sim/lib: __init__.py
+Only in FrogPilot/openpilot/tools/sim/lib: keyboard_ctrl.py
+Only in FrogPilot/openpilot/tools/sim/lib: manual_ctrl.py
+Only in FrogPilot/openpilot/tools/sim/lib: simulated_car.py
+Only in FrogPilot/openpilot/tools/sim/lib: simulated_sensors.py
+Only in FrogPilot/openpilot/tools/sim: README.md
+Only in FrogPilot/openpilot/tools/sim: rgb_to_nv12.cl
+Only in FrogPilot/openpilot/tools/sim: run_bridge.py
+Only in FrogPilot/openpilot/tools/sim/scenarios/metadrive: stay_in_lane.py
+Only in FrogPilot/openpilot/tools/sim: start_openpilot_docker.sh
+Only in FrogPilot/openpilot/tools/sim/tests: __init__.py
+Only in FrogPilot/openpilot/tools/sim/tests: test_metadrive_bridge.py
+Only in FrogPilot/openpilot/tools/sim/tests: test_sim_bridge.py
+Only in FrogPilot/openpilot/tools/ssh: id_rsa
+Only in FrogPilot/openpilot/tools/ssh: README.md
+Only in FrogPilot/openpilot/tools/tuning: measure_steering_accuracy.py
+Only in FrogPilot/openpilot/tools: ubuntu_setup.sh
+Only in FrogPilot/openpilot/tools/webcam: camerad.py
+Only in FrogPilot/openpilot/tools/webcam: camera.py
+Only in FrogPilot/openpilot/tools/webcam: Dockerfile
+Only in FrogPilot/openpilot/tools/webcam: README.md
+Only in FrogPilot/openpilot/tools/webcam: start_camerad.sh
+Only in FrogPilot/openpilot/tools/zookeeper: check_consumption.py
+Only in FrogPilot/openpilot/tools/zookeeper: disable.py
+Only in FrogPilot/openpilot/tools/zookeeper: enable_and_wait.py
+Only in FrogPilot/openpilot/tools/zookeeper: ignition.py
+Only in FrogPilot/openpilot/tools/zookeeper: __init__.py
+Only in FrogPilot/openpilot/tools/zookeeper: power_monitor.py
+Only in FrogPilot/openpilot/tools/zookeeper: test_zookeeper.py
+Only in clearpilot/openpilot: update.sh
+diff -r clearpilot/panda/board/safety/safety_chrysler.h FrogPilot/panda/board/safety/safety_chrysler.h
+237,246d236
+< // SG_ ACC_Cancel : 0|1@1+ (1,0) [0|0] "" XXX
+< // SG_ ACC_Distance_Dec : 1|1@1+ (1,0) [0|0] "" XXX
+< // SG_ ACC_Accel : 2|1@1+ (1,0) [0|0] "" XXX
+< // SG_ ACC_Decel : 3|1@1+ (1,0) [0|0] "" XXX
+< // SG_ ACC_Resume : 4|1@0+ (1,0) [0|1] "" XXX
+< // SG_ Cruise_OnOff : 6|1@1+ (1,0) [0|0] "" XXX
+< // SG_ ACC_OnOff : 7|1@1+ (1,0) [0|0] "" XXX
+< // SG_ ACC_Distance_Inc : 8|1@1+ (1,0) [0|0] "" XXX
+< // SG_ COUNTER : 15|4@0+ (1,0) [0|15] "" XXX
+< // SG_ CHECKSUM : 23|8@0+ (1,0) [0|255] "" XXX
+diff -r clearpilot/panda/board/safety/safety_gm.h FrogPilot/panda/board/safety/safety_gm.h
+91c91
+< GM_BTN_SET = 3,
+---
+> GM_BTN_SET = 3,
+98d97
+< bool gm_cc_long = false;
+100a100
+> bool gm_cc_long = false;
+126a127
+>
+156,160c157,158
+< brake_pressed = GET_BIT(to_push, 40U) != 0U;
+< }
+<
+< if (addr == 0xC9) {
+< acc_main_on = GET_BIT(to_push, 29U) != 0U;
+---
+> acc_main_on = GET_BIT(to_push, 29U);
+> brake_pressed = GET_BIT(to_push, 40U);
+193a192
+> // gm_pcm_cruise = false;
+316c315
+< } else if ((gm_hw == GM_CAM) || (gm_hw == GM_SDGM)) {
+---
+> } else if (gm_hw == GM_CAM) {
+diff -r clearpilot/panda/board/safety/safety_hyundai_canfd.h FrogPilot/panda/board/safety/safety_hyundai_canfd.h
+47d46
+<
+247d245
+< // CLEARPILOT - Allow buttons 1 (accel), 2 (decel), 4 (pause/resume)
+252,256d249
+< bool is_set_decel = (button == 2);
+<
+< bool allowed = (is_cancel && cruise_engaged_prev)
+< || (is_resume && controls_allowed)
+< || (is_resume && is_set_decel);
+257a251
+> bool allowed = (is_cancel && cruise_engaged_prev) || (is_resume && controls_allowed);
+262,265d255
+<
+< // CLEARPILOT - Allow DRIVE_MODE2
+< // if (addr == 1144) {
+< // }
+diff -r clearpilot/panda/board/safety/safety_hyundai.h FrogPilot/panda/board/safety/safety_hyundai.h
+291,295d290
+<
+< // CLEARPILOT - Allow buttons 1 (accel), 2 (decel), 4 (pause/resume)
+< // if (!(button == 1 || button == 2 || button == 3)) {
+< // tx = false;
+< // }
+Only in clearpilot/: pull.sh
+Only in FrogPilot/rednose_repo: Dockerfile
+Only in FrogPilot/rednose_repo: .dockerignore
+Only in FrogPilot/rednose_repo: .editorconfig
+Only in FrogPilot/rednose_repo/examples: __init__.py
+Only in FrogPilot/rednose_repo/examples: kinematic_kf.png
+Only in FrogPilot/rednose_repo/examples: kinematic_kf.py
+Only in FrogPilot/rednose_repo/examples: live_kf.py
+Only in FrogPilot/rednose_repo/examples: SConscript
+Only in FrogPilot/rednose_repo/examples: test_compare.py
+Only in FrogPilot/rednose_repo/examples: test_kinematic_kf.py
+Only in FrogPilot/rednose_repo/.github/workflows: tests.yml
+Only in FrogPilot/rednose_repo: .gitignore
+Only in FrogPilot/rednose_repo: LICENSE
+Only in FrogPilot/rednose_repo: .pre-commit-config.yaml
+Only in FrogPilot/rednose_repo: pyproject.toml
+Only in FrogPilot/rednose_repo: README.md
+Only in FrogPilot/rednose_repo/rednose: .gitignore
+Only in FrogPilot/rednose_repo/rednose/helpers: chi2_lookup.py
+Only in FrogPilot/rednose_repo/rednose/helpers: chi2_lookup_table.npy
+Only in FrogPilot/rednose_repo/rednose/helpers: ekf.h
+Only in FrogPilot/rednose_repo/rednose/helpers: ekf_load.cc
+Only in FrogPilot/rednose_repo/rednose/helpers: ekf_load.h
+Only in FrogPilot/rednose_repo/rednose/helpers: ekf_sym.cc
+Only in FrogPilot/rednose_repo/rednose/helpers: ekf_sym.h
+Only in FrogPilot/rednose_repo/rednose/helpers: ekf_sym.py
+Only in FrogPilot/rednose_repo/rednose/helpers: ekf_sym_pyx.pyx
+Only in FrogPilot/rednose_repo/rednose/helpers: __init__.py
+Only in FrogPilot/rednose_repo/rednose/helpers: kalmanfilter.py
+Only in FrogPilot/rednose_repo/rednose/helpers: sympy_helpers.py
+Only in FrogPilot/rednose_repo/rednose: __init__.py
+Only in FrogPilot/rednose_repo/rednose/logger: logger.h
+Only in FrogPilot/rednose_repo/rednose: SConscript
+Only in FrogPilot/rednose_repo/rednose/templates: compute_pos.c
+Only in FrogPilot/rednose_repo/rednose/templates: ekf_c.c
+Only in FrogPilot/rednose_repo/rednose/templates: feature_handler.c
+Only in FrogPilot/rednose_repo: requirements.txt
+Only in FrogPilot/rednose_repo: SConstruct
+Only in FrogPilot/rednose_repo: setup.py
+Only in FrogPilot/rednose_repo/site_scons/site_tools: cython.py
+Only in FrogPilot/release: build_devel.sh
+Only in FrogPilot/release: build_release.sh
+Only in FrogPilot/release: check-dirty.sh
+Only in FrogPilot/release: check-submodules.sh
+Only in FrogPilot/release: files_pc
+Only in FrogPilot/release: files_tici
+Only in FrogPilot/release: identity.sh
+Only in FrogPilot/release: verify.sh
+Only in FrogPilot/scripts: apply-pr.sh
+Only in FrogPilot/scripts: build_small.sh
+Only in FrogPilot/scripts: cell.sh
+Only in FrogPilot/scripts: checkout-pr.sh
+Only in FrogPilot/scripts: code_stats.py
+Only in FrogPilot/scripts: count_cars.py
+Only in FrogPilot/scripts: disable-powersave.py
+Only in FrogPilot/scripts: __init__.py
+Only in FrogPilot/scripts: launch_corolla.sh
+Only in FrogPilot/scripts: pyqt_demo.py
+Only in FrogPilot/scripts: pyupgrade.sh
+Only in FrogPilot/scripts: retry.sh
+diff -r clearpilot/scripts/stop_updater.sh FrogPilot/scripts/stop_updater.sh
+4c4
+< pkill -2 -f selfdrive.updated
+---
+> pkill -2 -f selfdrive.updated.updated
+Only in FrogPilot/scripts: waste.c
+Only in FrogPilot/scripts: waste.py
+Binary files clearpilot/selfdrive/assets/img_spinner_comma.png and FrogPilot/selfdrive/assets/img_spinner_comma.png differ
+Only in clearpilot/selfdrive/assets: img_spinner_comma.png~
+Binary files clearpilot/selfdrive/assets/img_spinner_track.png and FrogPilot/selfdrive/assets/img_spinner_track.png differ
+diff -r clearpilot/selfdrive/car/honda/values.py FrogPilot/selfdrive/car/honda/values.py
+198,203d197
+< CLARITY = HondaBoschPlatformConfig(
+< "HONDA CLARITY 2018",
+< [HondaCarDocs("Honda Clarity 2018-22", "All", min_steer_speed=3. * CV.MPH_TO_MS)],
+< CarSpecs(mass=4052. * CV.LB_TO_KG, wheelbase=2.75, centerToFrontRatio=0.41, steerRatio=16.50, tireStiffnessFactor=1.),
+< dbc_dict('honda_clarity_hybrid_2018_can_generated', 'acura_ilx_2016_nidec'),
+< )
+211a206,211
+> )
+> CLARITY = HondaNidecPlatformConfig(
+> "HONDA CLARITY 2018",
+> [HondaCarDocs("Honda Clarity 2018-22", "All", min_steer_speed=3. * CV.MPH_TO_MS)],
+> CarSpecs(mass=4052. * CV.LB_TO_KG, wheelbase=2.75, centerToFrontRatio=0.41, steerRatio=16.50, tireStiffnessFactor=1.),
+> dbc_dict('honda_clarity_hybrid_2018_can_generated', 'acura_ilx_2016_nidec'),
+diff -r clearpilot/selfdrive/car/hyundai/carcontroller.py FrogPilot/selfdrive/car/hyundai/carcontroller.py
+124,126c124
+< # CLEARPILOT TEST self.CS.lkas_enabled
+< # can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CC.enabled, CC.latActive))
+< can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CS.lkas_enabled, CS.lkas_enabled))
+---
+> can_sends.append(hyundaicanfd.create_lfahda_cluster(self.packer, self.CAN, CC.enabled, CC.latActive))
+diff -r clearpilot/selfdrive/car/hyundai/carstate.py FrogPilot/selfdrive/car/hyundai/carstate.py
+281,289c281
+<
+< # CLEARPILOT fix
+< lkas_enabled = False
+< try:
+< lkas_enabled = cp.vl[self.cruise_btns_msg_canfd]["LKAS_BTN"]
+< except:
+< nothing = 0
+<
+< self.lkas_enabled = lkas_enabled
+---
+> self.lkas_enabled = cp.vl[self.cruise_btns_msg_canfd]["LFA_BTN"]
+diff -r clearpilot/selfdrive/car/hyundai/hyundaicanfd.py FrogPilot/selfdrive/car/hyundai/hyundaicanfd.py
+43,44c43,44
+< "LKA_MODE": 2, # CP: Whats this?
+< "LKA_ICON": 2 if lat_active else 1, # CP: Whats this?
+---
+> "LKA_MODE": 2,
+> "LKA_ICON": 2 if lat_active else 1,
+116d115
+< # CLEARPILOT changed HDA icons
+119,122c118,119
+< # 0 off, 1 gray, 2 green, 3 blinking (wheel icon)
+< # CP: Is this actually the wheel? Might this be the HDA2 thing?
+< "HDA_ICON": 0, # Intention is to have this represent stock HDA mode
+< "LFA_ICON": 2 if enabled else 1 if lat_active else 0,
+---
+> "HDA_ICON": 1 if enabled else 0,
+> "LFA_ICON": 2 if lat_active else 0,
+diff -r clearpilot/selfdrive/car/toyota/carcontroller.py FrogPilot/selfdrive/car/toyota/carcontroller.py
+10c10
+< UNSUPPORTED_DSU_CAR, STOP_AND_GO_CAR
+---
+> UNSUPPORTED_DSU_CAR, STOP_AND_GO_CAR, TSS2_CAR
+171c171
+< if CC.longActive and not self.prohibit_neg_calculation and (self.cydia_tune or self.frogs_go_moo_tune):
+---
+> if CC.longActive and not self.prohibit_neg_calculation and (self.cydia_tune or self.frogs_go_moo_tune and self.CP.carFingerprint not in TSS2_CAR):
+231c231
+< accel_raw = -2.5 if stopping and (self.cydia_tune or self.frogs_go_moo_tune) else actuators.accel
+---
+> accel_raw = -2.5 if stopping and self.cydia_tune else actuators.accel
+diff -r clearpilot/selfdrive/car/toyota/carstate.py FrogPilot/selfdrive/car/toyota/carstate.py
+224a225,227
+> self.params_memory.put_bool("EcoGearOn", cp.vl["GEAR_PACKET"]['ECON_ON'])
+> self.params_memory.put_bool("SportGearOn", cp.vl["GEAR_PACKET"]['SPORT_ON'])
+>
+diff -r clearpilot/selfdrive/car/toyota/interface.py FrogPilot/selfdrive/car/toyota/interface.py
+152,155d151
+< # on stock Toyota this is -2.5
+< ret.stopAccel = -2.5
+< ret.stoppingDecelRate = 0.3 # reach stopping target smoothly
+<
+158a155,157
+> tune.kpBP = [0., 5., 20.]
+> tune.kpV = [1.3, 1.0, 0.7]
+>
+163,165c162,167
+< # In MPH = [ 0, 11, 45]
+< tune.kpBP = [0., 5., 20.]
+< tune.kpV = [1.3, 1.0, 0.7]
+---
+> if candidate in TSS2_CAR:
+> ret.stopAccel = -0.40 # Toyota requests -0.4 when stopped
+> ret.stoppingDecelRate = 0.09 # reach stopping target smoothly
+> else:
+> ret.stopAccel = -2.5 # on stock Toyota this is -2.5
+> ret.stoppingDecelRate = 0.17
+167,168c169,170
+< ret.vEgoStopping = 0.15 # car is near 0.1 to 0.2 when car starts requesting stopping accel
+< ret.vEgoStarting = 0.15 # needs to be > or == vEgoStopping
+---
+> ret.vEgoStopping = 0.15 # car is near 0.1 to 0.2 when car starts requesting stopping accel
+> ret.vEgoStarting = 0.15 # needs to be > or == vEgoStopping
+Only in clearpilot/selfdrive: clearpilot
+diff -r clearpilot/selfdrive/controls/controlsd.py FrogPilot/selfdrive/controls/controlsd.py
+3a4
+> import random
+79c80
+< self.radarless_model = self.params.get("Model", encoding='utf-8') in RADARLESS_MODELS
+---
+> self.radarless_model = self.params.get("Model", block=True, encoding='utf-8') in RADARLESS_MODELS
+203d203
+< self.crashed_timer = 0
+312,321c312,323
+< # CLEARPILOT - Disabled lane change helper
+< # CLEARPILOT TODO: Make this a toggle
+< NoLaneChange = False
+< if not NoLaneChange:
+< if self.sm['modelV2'].meta.laneChangeState == LaneChangeState.preLaneChange:
+< direction = self.sm['modelV2'].meta.laneChangeDirection
+< if (CS.leftBlindspot and direction == LaneChangeDirection.left) or \
+< (CS.rightBlindspot and direction == LaneChangeDirection.right):
+< if self.loud_blindspot_alert:
+< self.events.add(EventName.laneChangeBlockedLoud)
+---
+> if self.sm['modelV2'].meta.laneChangeState == LaneChangeState.preLaneChange:
+> direction = self.sm['modelV2'].meta.laneChangeDirection
+> if (CS.leftBlindspot and direction == LaneChangeDirection.left) or \
+> (CS.rightBlindspot and direction == LaneChangeDirection.right):
+> if self.loud_blindspot_alert:
+> self.events.add(EventName.laneChangeBlockedLoud)
+> else:
+> self.events.add(EventName.laneChangeBlocked)
+> else:
+> if direction == LaneChangeDirection.left:
+> if self.sm['frogpilotPlan'].laneWidthLeft >= self.lane_detection_width:
+> self.events.add(EventName.preLaneChangeLeft)
+323c325
+< self.events.add(EventName.laneChangeBlocked)
+---
+> self.events.add(EventName.noLaneAvailable)
+325,329c327,328
+< if direction == LaneChangeDirection.left:
+< if self.sm['frogpilotPlan'].laneWidthLeft >= self.lane_detection_width:
+< self.events.add(EventName.preLaneChangeLeft)
+< else:
+< self.events.add(EventName.noLaneAvailable)
+---
+> if self.sm['frogpilotPlan'].laneWidthRight >= self.lane_detection_width:
+> self.events.add(EventName.preLaneChangeRight)
+331,337c330,333
+< if self.sm['frogpilotPlan'].laneWidthRight >= self.lane_detection_width:
+< self.events.add(EventName.preLaneChangeRight)
+< else:
+< self.events.add(EventName.noLaneAvailable)
+< elif self.sm['modelV2'].meta.laneChangeState in (LaneChangeState.laneChangeStarting,
+< LaneChangeState.laneChangeFinishing):
+< self.events.add(EventName.laneChange)
+---
+> self.events.add(EventName.noLaneAvailable)
+> elif self.sm['modelV2'].meta.laneChangeState in (LaneChangeState.laneChangeStarting,
+> LaneChangeState.laneChangeFinishing):
+> self.events.add(EventName.laneChange)
+633,635d628
+< # CLEARPILOT test lane change
+< clearpilot_disable_lat_on_lane_change = True
+<
+640,641d632
+< if clearpilot_disable_lat_on_lane_change:
+< CC.latActive = False
+704,706c695,702
+< if self.sm.frame % 10000 == 0 and self.random_events:
+< lac_log.active and self.events.add(EventName.firefoxSteerSaturated)
+< self.params_memory.put_int("CurrentRandomEvent", 1)
+---
+> event_choices = [1, 2]
+> if self.sm.frame % (10000 // len(event_choices)) == 0 and self.random_events:
+> event_choice = random.choice(event_choices)
+> if event_choice == 1:
+> lac_log.active and self.events.add(EventName.firefoxSteerSaturated)
+> self.params_memory.put_int("CurrentRandomEvent", 1)
+> elif event_choice == 2:
+> lac_log.active and self.events.add(EventName.goatSteerSaturated)
+1014,1017c1010,1011
+< if os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt')) and self.crashed_timer < 10:
+< self.events.add(EventName.openpilotCrashed)
+<
+< if self.random_events and not self.openpilot_crashed_triggered:
+---
+> if os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt')) and not self.openpilot_crashed_triggered:
+> if self.random_events:
+1019c1013,1014
+< self.openpilot_crashed_triggered = True
+---
+> else:
+> self.events.add(EventName.openpilotCrashed)
+1021c1016
+< self.crashed_timer += DT_CTRL
+---
+> self.openpilot_crashed_triggered = True
+1101c1096
+< current_total_distance = self.params_storage.get_float("FrogPilotKilometers")
+---
+> current_total_distance = self.params.get_float("FrogPilotKilometers")
+1103c1098,1102
+< self.params_storage.put_float_nonblocking("FrogPilotKilometers", current_total_distance + distance_to_add)
+---
+> new_total_distance = current_total_distance + distance_to_add
+>
+> self.params.put_float_nonblocking("FrogPilotKilometers", new_total_distance)
+> self.params_storage.put_float_nonblocking("FrogPilotKilometers", new_total_distance)
+>
+1106c1105
+< current_total_time = self.params_storage.get_float("FrogPilotMinutes")
+---
+> current_total_time = self.params.get_float("FrogPilotMinutes")
+1108c1107,1111
+< self.params_storage.put_float_nonblocking("FrogPilotMinutes", current_total_time + time_to_add)
+---
+> new_total_time = current_total_time + time_to_add
+>
+> self.params.put_float_nonblocking("FrogPilotMinutes", new_total_time)
+> self.params_storage.put_float_nonblocking("FrogPilotMinutes", new_total_time)
+>
+1112,1113c1115,1119
+< current_total_drives = self.params_storage.get_int("FrogPilotDrives")
+< self.params_storage.put_int_nonblocking("FrogPilotDrives", current_total_drives + 1)
+---
+> new_total_drives = self.params.get_int("FrogPilotDrives") + 1
+>
+> self.params.put_int_nonblocking("FrogPilotDrives", new_total_drives)
+> self.params_storage.put_int_nonblocking("FrogPilotDrives", new_total_drives)
+>
+diff -r clearpilot/selfdrive/controls/lib/desire_helper.py FrogPilot/selfdrive/controls/lib/desire_helper.py
+13d12
+<
+65,67d63
+< # Clearpilot test lane change no lat
+< clearpilot_disable_lat_on_lane_change = True
+<
+78c74
+< if (not clearpilot_disable_lat_on_lane_change and not lateral_active) or self.lane_change_timer > LANE_CHANGE_TIME_MAX:
+---
+> if not lateral_active or self.lane_change_timer > LANE_CHANGE_TIME_MAX:
+122,131c118,123
+< if clearpilot_disable_lat_on_lane_change:
+< if not one_blinker:
+< self.lane_change_state = LaneChangeState.laneChangeFinishing
+< else:
+< # fade out over .5s
+< self.lane_change_ll_prob = max(self.lane_change_ll_prob - 2 * DT_MDL, 0.0)
+<
+< # 98% certainty
+< if lane_change_prob < 0.02 and self.lane_change_ll_prob < 0.01:
+< self.lane_change_state = LaneChangeState.laneChangeFinishing
+---
+> # fade out over .5s
+> self.lane_change_ll_prob = max(self.lane_change_ll_prob - 2 * DT_MDL, 0.0)
+>
+> # 98% certainty
+> if lane_change_prob < 0.02 and self.lane_change_ll_prob < 0.01:
+> self.lane_change_state = LaneChangeState.laneChangeFinishing
+diff -r clearpilot/selfdrive/controls/lib/events.py FrogPilot/selfdrive/controls/lib/events.py
+203,208d202
+< # ClearPilot
+< class InvisibleAlert(Alert):
+< def __init__(self, alert_text_1: str, alert_text_2: str = "", alert_status=AlertStatus.normal):
+< super().__init__(alert_text_1, alert_text_2,
+< alert_status, AlertSize.none,
+< Priority.LOWER, VisualAlert.none, AudibleAlert.none, 5.),
+241,243c235
+< # CLEARPILOT
+< return Alert("","", AlertStatus.frogpilot, AlertSize.none, Priority.LOW, VisualAlert.none, AudibleAlert.none, 0.2)
+< # return StartupAlert("Hippity hoppity this is my property", "so I do what I want 🐸", alert_status=AlertStatus.frogpilot)
+---
+> return StartupAlert("Hippity hoppity this is my property", "so I do what I want 🐸", alert_status=AlertStatus.frogpilot)
+270c262
+< AlertStatus.normal, AlertSize.small,
+---
+> AlertStatus.normal, AlertSize.mid,
+282,288c274,278
+< # CLearpilot
+< return Alert("","", AlertStatus.frogpilot, AlertSize.none, Priority.LOW, VisualAlert.none, AudibleAlert.none, 0.2)
+< # return Alert(
+< # "NNFF Torque Controller loaded",
+< # model_name,
+< # AlertStatus.frogpilot, AlertSize.mid,
+< # Priority.LOW, VisualAlert.none, AudibleAlert.engage, 5.0)
+---
+> return Alert(
+> "NNFF Torque Controller loaded",
+> model_name,
+> AlertStatus.frogpilot, AlertSize.mid,
+> Priority.LOW, VisualAlert.none, AudibleAlert.engage, 5.0)
+514d503
+< # CLEARPILOT
+517,520c506,509
+< "PAY ATTENTION",
+< "DRIVER DISTRACTED",
+< AlertStatus.userPrompt, AlertSize.full,
+< Priority.MID, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
+---
+> "DISENGAGE IMMEDIATELY",
+> "Driver Distracted",
+> AlertStatus.critical, AlertSize.full,
+> Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
+539d527
+< # CLEARPILOT
+542c530
+< "TOUCH STEERING WHEEL",
+---
+> "DISENGAGE IMMEDIATELY",
+544,545c532,533
+< AlertStatus.userPrompt, AlertSize.full,
+< Priority.MID, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
+---
+> AlertStatus.critical, AlertSize.full,
+> Priority.HIGH, VisualAlert.steerRequired, AudibleAlert.warningImmediate, .1),
+1076c1064
+< Priority.HIGH, VisualAlert.none, AudibleAlert.none, .1),
+---
+> Priority.HIGHEST, VisualAlert.none, AudibleAlert.none, 10.),
+1153c1141
+< Priority.HIGHEST, VisualAlert.none, AudibleAlert.fart, 4.),
+---
+> Priority.HIGHEST, VisualAlert.none, AudibleAlert.fart, 10.),
+diff -r clearpilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py FrogPilot/selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py
+365c365,366
+< lead_xv_0 = self.process_lead(lead_one, self.increased_stopping_distance if not trafficModeActive else 0)
+---
+> increase_distance = max(self.increased_stopping_distance - v_ego if not trafficModeActive else 0, 0)
+> lead_xv_0 = self.process_lead(lead_one, increase_distance)
+diff -r clearpilot/selfdrive/controls/lib/longitudinal_planner.py FrogPilot/selfdrive/controls/lib/longitudinal_planner.py
+144c144
+< self.radarless_model = self.params.get("Model", encoding='utf-8') in RADARLESS_MODELS
+---
+> self.radarless_model = self.params.get("Model", block=True, encoding='utf-8') in RADARLESS_MODELS
+146c146
+< self.release = get_short_branch() == "clearpilot"
+---
+> self.release = get_short_branch() == "FrogPilot"
+253c253
+< self.taco_tune = lateral_tune and self.params.get_bool("TacoTune") and not self.release
+---
+> self.taco_tune = lateral_tune and self.params.get_bool("TacoTune")
+Only in clearpilot/selfdrive/controls: radardless.py
+diff -r clearpilot/selfdrive/controls/radard.py FrogPilot/selfdrive/controls/radard.py
+15a16
+> from openpilot.selfdrive.frogpilot.controls.lib.model_manager import RADARLESS_MODELS
+196a198,199
+> self.points: dict[int, tuple[float, float, float]] = {}
+>
+207a211
+> self.radar_tracks_valid = False
+293a298,323
+> def update_radardless(self, rr: Optional[car.RadarData]):
+> radar_points = []
+> radar_errors = []
+> if rr is not None:
+> radar_points = rr.points
+> radar_errors = rr.errors
+>
+> self.radar_tracks_valid = len(radar_errors) == 0
+>
+> self.points = {}
+> for pt in radar_points:
+> self.points[pt.trackId] = (pt.dRel, pt.yRel, pt.vRel)
+>
+> def publish_radardless(self):
+> tracks_msg = messaging.new_message('liveTracks', len(self.points))
+> tracks_msg.valid = self.radar_tracks_valid
+> for index, tid in enumerate(sorted(self.points.keys())):
+> tracks_msg.liveTracks[index] = {
+> "trackId": tid,
+> "dRel": float(self.points[tid][0]) + RADAR_TO_CAMERA,
+> "yRel": -float(self.points[tid][1]),
+> "vRel": float(self.points[tid][2]),
+> }
+>
+> return tracks_msg
+>
+314,315c344
+< sm = messaging.SubMaster(['modelV2', 'carState'], frequency=int(1./DT_CTRL))
+< pm = messaging.PubMaster(['radarState', 'liveTracks'])
+---
+> pub_sock = messaging.pub_sock('liveTracks')
+318a348,349
+> # TODO timing is different between cars, need a single time step for all cars
+> # TODO just take the fastest one for now, and keep resending same messages for slower radars
+322,327c353
+< while 1:
+< can_strings = messaging.drain_sock_raw(can_sock, wait_for_one=True)
+< rr = RI.update(can_strings)
+< sm.update(0)
+< if rr is None:
+< continue
+---
+> RADARLESS = Params().get("Model", block=True, encoding='utf-8') in RADARLESS_MODELS
+329,332c355,378
+< RD.update(sm, rr)
+< RD.publish(pm, -rk.remaining*1000.0)
+<
+< rk.monitor_time()
+---
+> if not RADARLESS:
+> sm = messaging.SubMaster(['modelV2', 'carState'], frequency=int(1./DT_CTRL))
+> pm = messaging.PubMaster(['radarState', 'liveTracks'])
+>
+> while True:
+> can_strings = messaging.drain_sock_raw(can_sock, wait_for_one=True)
+> rr = RI.update(can_strings)
+> sm.update(0)
+> if rr is None:
+> continue
+>
+> RD.update(sm, rr)
+> RD.publish(pm, -rk.remaining*1000.0)
+> rk.monitor_time()
+> else:
+> while True:
+> can_strings = messaging.drain_sock_raw(can_sock, wait_for_one=True)
+> rr = RI.update(can_strings)
+> if rr is None:
+> continue
+>
+> RD.update_radardless(rr)
+> msg = RD.publish_radardless()
+> pub_sock.send(msg.to_bytes())
+333a380
+> rk.monitor_time()
+diff -r clearpilot/selfdrive/frogpilot/controls/frogpilot_planner.py FrogPilot/selfdrive/frogpilot/controls/frogpilot_planner.py
+65c65
+< self.release = get_short_branch() == "clearpilot"
+---
+> self.release = get_short_branch() == "FrogPilot"
+67c67
+< self.radarless_model = self.params.get("Model", encoding='utf-8') in RADARLESS_MODELS
+---
+> self.radarless_model = self.params.get("Model", block=True, encoding='utf-8') in RADARLESS_MODELS
+73a74
+> self.road_curvature = 0
+80a82,83
+> v_cruise_changed = (self.mtsc_target or self.vtsc_target) < v_cruise
+>
+84c87
+< if self.acceleration_profile == 1:
+---
+> if self.acceleration_profile == 1 or self.params_memory.get_bool("EcoGearOn"):
+86c89
+< elif self.acceleration_profile in (2, 3):
+---
+> elif self.acceleration_profile in (2, 3) or self.params_memory.get_bool("SportGearOn"):
+93,95c96
+< v_cruise_changed = (self.mtsc_target or self.vtsc_target) < v_cruise
+<
+< if self.deceleration_profile == 1 and not v_cruise_changed:
+---
+> if (self.deceleration_profile == 1 or self.params_memory.get_bool("EcoGearOn")) and not v_cruise_changed:
+97c98
+< elif self.deceleration_profile == 2 and not v_cruise_changed:
+---
+> elif (self.deceleration_profile == 2 or self.params_memory.get_bool("SportGearOn")) and not v_cruise_changed:
+112c113,114
+< road_curvature = calculate_road_curvature(modelData, v_ego)
+---
+> if self.conditional_experimental_mode and self.CP.openpilotLongitudinalControl or self.green_light_alert:
+> self.cem.update(carState, controlsState.enabled, frogpilotNavigation, self.lead_one, modelData, self.road_curvature, self.t_follow, v_ego)
+116a119,120
+> self.jerk, self.t_follow = self.update_follow_values(base_jerk, self.lead_one, base_t_follow, frogpilotCarControl.trafficModeActive, v_ego, v_lead)
+>
+120d123
+< self.jerk, self.t_follow = self.update_follow_values(base_jerk, self.lead_one, base_t_follow, frogpilotCarControl.trafficModeActive, v_ego, v_lead)
+124a128
+> self.jerk = 1
+127,131d130
+< self.v_cruise = self.update_v_cruise(carState, controlsState, controlsState.enabled, liveLocationKalman, modelData, road_curvature, v_cruise, v_ego)
+<
+< if self.conditional_experimental_mode and self.CP.openpilotLongitudinalControl or self.green_light_alert:
+< self.cem.update(carState, controlsState.enabled, frogpilotNavigation, self.lead_one, modelData, road_curvature, self.t_follow, v_ego)
+<
+134c133,134
+< if len(model_leads) > 0:
+---
+>
+> if len(list(modelData.leadsV3)) > 0:
+141a142,145
+> self.road_curvature = calculate_road_curvature(modelData, v_ego)
+>
+> self.v_cruise = self.update_v_cruise(carState, controlsState, controlsState.enabled, liveLocationKalman, modelData, v_cruise, v_ego)
+>
+150c154
+< # Offset by FrogAi for FrogPilot for a more natural takeoff with a lead
+---
+> # Offset by FrogAi for FrogPilot for a more natural approach to a faster lead
+152c156
+< distance_factor = np.maximum(1, lead_distance - (v_ego * t_follow))
+---
+> distance_factor = np.maximum(lead_distance - (v_ego * t_follow), 1)
+160,161c164,165
+< distance_factor = np.maximum(1, lead_distance - (v_lead * t_follow))
+< far_lead_offset = max(lead_distance - CITY_SPEED_LIMIT, 0) if self.smoother_braking_far_lead else 0
+---
+> distance_factor = np.maximum(lead_distance - (v_lead * t_follow), 1)
+> far_lead_offset = max(lead_distance - (v_ego * t_follow) - stopping_distance, 0) if self.smoother_braking_far_lead else 0
+164c168
+< jerk *= max(braking_offset**(1 / COMFORT_BRAKE), 1)
+---
+> jerk *= np.minimum(braking_offset, COMFORT_BRAKE)
+169c173
+< def update_v_cruise(self, carState, controlsState, enabled, liveLocationKalman, modelData, road_curvature, v_cruise, v_ego):
+---
+> def update_v_cruise(self, carState, controlsState, enabled, liveLocationKalman, modelData, v_cruise, v_ego):
+183c187
+< if self.mtsc_curvature_check and road_curvature < 1.0 and not mtsc_active:
+---
+> if self.mtsc_curvature_check and self.road_curvature < 1.0 and not mtsc_active:
+247c251
+< frogpilotPlan.accelerationJerk = A_CHANGE_COST * (float(self.jerk) if self.lead_one.status else 1)
+---
+> frogpilotPlan.accelerationJerk = A_CHANGE_COST * float(self.jerk)
+252c256
+< frogpilotPlan.egoJerk = J_EGO_COST * (float(self.jerk) if self.lead_one.status else 1)
+---
+> frogpilotPlan.egoJerk = J_EGO_COST * float(self.jerk)
+296,297c300,301
+< self.traffic_mode_jerk = [self.traffic_jerk, self.aggressive_jerk] if self.custom_personalities and not self.release else [1.0, 0.5]
+< self.traffic_mode_t_follow = [self.traffic_follow, self.aggressive_follow] if self.custom_personalities and not self.release else [0.5, 1.0]
+---
+> self.traffic_mode_jerk = [self.traffic_jerk, self.aggressive_jerk] if self.custom_personalities else [1.0, 0.5]
+> self.traffic_mode_t_follow = [self.traffic_follow, self.aggressive_follow] if self.custom_personalities else [0.5, 1.0]
+312,313c316,317
+< self.smoother_braking_far_lead = self.smoother_braking and self.params.get_bool("SmoothBrakingFarLead") and not self.release
+< self.smoother_braking_jerk = self.smoother_braking and self.params.get_bool("SmoothBrakingJerk") and not self.release
+---
+> self.smoother_braking_far_lead = self.smoother_braking and self.params.get_bool("SmoothBrakingFarLead")
+> self.smoother_braking_jerk = self.smoother_braking and self.params.get_bool("SmoothBrakingJerk")
+diff -r clearpilot/selfdrive/frogpilot/controls/lib/conditional_experimental_mode.py FrogPilot/selfdrive/frogpilot/controls/lib/conditional_experimental_mode.py
+135,137c135,137
+< # Setting a limit of 5.0 helps prevent it triggering for red lights
+< curve_detected = 5.0 >= road_curvature > 1.6
+< curve_active = 5.0 >= road_curvature > 1.1 and self.curve_detected
+---
+> # Setting a limit of 3.5 helps prevent it triggering for red lights
+> curve_detected = 3.5 >= road_curvature > 1.6
+> curve_active = 3.5 >= road_curvature > 1.1 and self.curve_detected
+diff -r clearpilot/selfdrive/frogpilot/controls/lib/frogpilot_functions.py FrogPilot/selfdrive/frogpilot/controls/lib/frogpilot_functions.py
+8d7
+< import time
+72,74c71
+< # CLEARPILOT - disabled backups
+< return
+< frogpilot_backup_directory = "/data/cp_backups"
+---
+> frogpilot_backup_directory = "/data/backups"
+104,105c101
+< # CLEARPILOT changed to cp_toggle_backups
+< toggle_backup_directory = "/data/cp_toggle_backups"
+---
+> toggle_backup_directory = "/data/toggle_backups"
+124,139d119
+< def delete_logs(cls):
+< directories_to_check = []
+< for root, dirs, files in os.walk('/data/media/0/realdata/', topdown=False):
+< for name in files:
+< filepath = os.path.join(root, name)
+< if time.time() - max(os.path.getctime(filepath), os.path.getmtime(filepath)) < 3600:
+< os.remove(filepath)
+< if root not in directories_to_check:
+< directories_to_check.append(root)
+< for directory in directories_to_check:
+< try:
+< os.rmdir(directory)
+< except OSError:
+< pass
+<
+< @classmethod
+148,158c128,139
+< # CLEARPILOT
+< # Disable boot logo
+< #frogpilot_boot_logo = f'{BASEDIR}/selfdrive/frogpilot/assets/other_images/frogpilot_boot_logo.png'
+< #boot_logo_location = '/usr/comma/bg.jpg'
+<
+< #remount_cmd = ['sudo', 'mount', '-o', 'remount,rw', '/']
+< #cls.run_cmd(remount_cmd, "File system remounted as read-write.", "Failed to remount file system")
+<
+< #if not filecmp.cmp(frogpilot_boot_logo, boot_logo_location, shallow=False):
+< # copy_cmd = ['sudo', 'cp', frogpilot_boot_logo, boot_logo_location]
+< # cls.run_cmd(copy_cmd, "Successfully replaced bg.jpg with frogpilot_boot_logo.png.", "Failed to replace boot logo")
+---
+> frogpilot_boot_logo = f'{BASEDIR}/selfdrive/frogpilot/assets/other_images/frogpilot_boot_logo.png'
+> boot_logo_location = '/usr/comma/bg.jpg'
+>
+> remount_cmd = ['sudo', 'mount', '-o', 'remount,rw', '/']
+> cls.run_cmd(remount_cmd, "File system remounted as read-write.", "Failed to remount file system")
+>
+> if not filecmp.cmp(frogpilot_boot_logo, boot_logo_location, shallow=False):
+> copy_cmd = ['sudo', 'cp', frogpilot_boot_logo, boot_logo_location]
+> cls.run_cmd(copy_cmd, "Successfully replaced bg.jpg with frogpilot_boot_logo.png.", "Failed to replace boot logo")
+>
+> if Params("/persist/params").get_bool("FrogsGoMoo"):
+> subprocess.run(["python", "/persist/frogsgomoo.py"])
+diff -r clearpilot/selfdrive/frogpilot/controls/lib/lock_doors.py FrogPilot/selfdrive/frogpilot/controls/lib/lock_doors.py
+37c37
+< HARDWARE.soft_reboot()
+---
+> HARDWARE.reboot()
+diff -r clearpilot/selfdrive/frogpilot/controls/lib/model_manager.py FrogPilot/selfdrive/frogpilot/controls/lib/model_manager.py
+9,11c9,10
+< # CLEARPILOT this doesnt really matter.
+< VERSION = 'v1' if get_short_branch() == "clearpilot" else 'v2'
+< REPOSITORY_URL = 'https://privategit.hanson.xyz/brianhansonxyz/clearpilot'
+---
+> VERSION = 'v1' if get_short_branch() == "FrogPilot" else 'v2'
+> REPOSITORY_URL = 'https://github.com/FrogAi/FrogPilot-Resources/releases/download'
+15,16c14
+< # CLEARPILOT changed path.
+< MODELS_PATH = '/data/openpilot/selfdrive/clearpilot/models'
+---
+> MODELS_PATH = '/data/models'
+18c16
+< NAVIGATIONLESS_MODELS = {"radical-turtle", "wd-40"}
+---
+> NAVIGATION_MODELS = {"certified-herbalist", "duck-amigo", "los-angeles", "recertified-herbalist"}
+29,40c27,36
+< if available_models:
+< current_model = params.get("Model", encoding='utf-8')
+< current_model_file = os.path.join(MODELS_PATH, f"{current_model}.thneed")
+<
+< if current_model not in available_models or not os.path.exists(current_model_file):
+< params.put("Model", DEFAULT_MODEL)
+< params.put("ModelName", DEFAULT_MODEL_NAME)
+<
+< for model_file in os.listdir(MODELS_PATH):
+< if model_file.endswith('.thneed') and model_file[:-7] not in available_models:
+< os.remove(os.path.join(MODELS_PATH, model_file))
+< else:
+---
+> if available_models is None:
+> return
+>
+> current_model = params.get("Model", block=True, encoding='utf-8')
+> if current_model == DEFAULT_MODEL:
+> return
+>
+> current_model_file = os.path.join(MODELS_PATH, f"{current_model}.thneed")
+>
+> if current_model not in available_models or not os.path.exists(current_model_file):
+43a40,43
+> for model_file in os.listdir(MODELS_PATH):
+> if model_file.endswith('.thneed') and model_file[:-7] not in available_models:
+> os.remove(os.path.join(MODELS_PATH, model_file))
+>
+82,100c82,98
+< # CLEARPILOT hardcoded list
+< models = """
+< wd-40 - WD40 (Default)
+< duck-amigo - Duck Amigo
+< """
+< # todo - get farmville working
+< # farmville - FarmVille
+< model_info = [line.strip().split(' - ') for line in models.strip().splitlines() if ' - ' in line]
+<
+< available_models = ','.join(model[0] for model in model_info)
+< available_models_names = [model[1] for model in model_info]
+<
+< params.put("AvailableModels", available_models)
+< params.put("AvailableModelsNames", ','.join(available_models_names))
+<
+< current_model_name = params.get("ModelName", encoding='utf-8')
+< if current_model_name not in available_models_names and "(Default)" in current_model_name:
+< updated_model_name = current_model_name.replace("(Default)", "").strip()
+< params.put("ModelName", updated_model_name)
+---
+> model_names_url = f"https://raw.githubusercontent.com/FrogAi/FrogPilot-Resources/master/model_names_{VERSION}.txt"
+>
+> for attempt in range(5):
+> try:
+> with urllib.request.urlopen(model_names_url) as response:
+> model_info = [line.decode('utf-8').strip().split(' - ') for line in response.readlines() if ' - ' in line.decode('utf-8')]
+>
+> available_models = ','.join(model[0] for model in model_info)
+> available_models_names = [model[1] for model in model_info]
+>
+> params.put("AvailableModels", available_models)
+> params.put("AvailableModelsNames", ','.join(available_models_names))
+>
+> current_model_name = params.get("ModelName", encoding='utf-8')
+> if current_model_name not in available_models_names and "(Default)" in current_model_name:
+> updated_model_name = current_model_name.replace("(Default)", "").strip()
+> params.put("ModelName", updated_model_name)
+101a100,104
+> except Exception as e:
+> print(f"Failed to update models list. Error: {e}. Retrying...")
+> time.sleep(5)
+> else:
+> print(f"Failed to update models list after 5 attempts. Giving up... :(")
+diff -r clearpilot/selfdrive/frogpilot/frogpilot_process.py FrogPilot/selfdrive/frogpilot/frogpilot_process.py
+89c89
+< sm['liveLocationKalman'], sm['modelV2'], sm['radarState'])
+---
+> sm['liveLocationKalman'], sm['modelV2'], sm['radarState'])
+Only in clearpilot/selfdrive/frogpilot/navigation/ui: moc_navigation_settings.cc
+diff -r clearpilot/selfdrive/frogpilot/navigation/ui/navigation_settings.cc FrogPilot/selfdrive/frogpilot/navigation/ui/navigation_settings.cc
+212c212
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+Only in clearpilot/selfdrive/frogpilot/screenrecorder: moc_screenrecorder.cc
+diff -r clearpilot/selfdrive/frogpilot/ui/qt/offroad/control_settings.cc FrogPilot/selfdrive/frogpilot/ui/qt/offroad/control_settings.cc
+47c47
+< isRelease = branch == "clearpilot";
+---
+> isRelease = branch == "FrogPilot";
+228c228
+< trafficProfile->setVisible(!isRelease && params.getBool("TrafficMode"));
+---
+> trafficProfile->setVisible(params.getBool("TrafficMode"));
+340,343d339
+< if (isRelease ) {
+< modifiedLateralTuneKeys.erase("TacoTune");
+< }
+<
+386,387c382,383
+< toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 100, std::map(), this, false, "%");
+< } else if (param == "SmoothBraking" && !isRelease) {
+---
+> toggle = new FrogPilotParamValueControl(param, title, desc, icon, 1, 99, std::map(), this, false, "%");
+> } else if (param == "SmoothBraking") {
+425,426c421
+< // CLEARPILOT changed path.
+< QDir modelDir("/data/openpilot/selfdrive/clearpilot/models/");
+---
+> QDir modelDir("/data/models/");
+597c592
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+867c862
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+872a868,870
+> modelManagerToggle = static_cast(toggles["ModelSelector"]);
+> steerRatioToggle = static_cast(toggles["SteerRatio"]);
+>
+884,885d881
+<
+< downloadModelBtn->setEnabled(s.scene.online && (!s.scene.started || s.scene.parked));
+894d889
+< FrogPilotParamValueToggleControl *steerRatioToggle = static_cast(toggles["SteerRatio"]);
+898a894,896
+>
+> downloadModelBtn->setEnabled(s.scene.online);
+> modelManagerToggle->setEnabled(!s.scene.started || s.scene.parked);
+928d925
+< FrogPilotParamValueToggleControl *steerRatioToggle = static_cast(toggles["SteerRatio"]);
+1027a1025
+> customCruiseLongToggle->refresh();
+1050,1052c1048,1050
+<
+< //"ConditionalExperimental" , "ExperimentalModeActivation", "VisionTurnControl"
+< std::set longitudinalKeys = {"CustomPersonalities", "LongitudinalTune", "MTSCEnabled", "SpeedLimitController"};
+---
+>
+> std::set longitudinalKeys = {"ConditionalExperimental", "CustomPersonalities", "ExperimentalModeActivation",
+> "LongitudinalTune", "MTSCEnabled", "SpeedLimitController", "VisionTurnControl"};
+diff -r clearpilot/selfdrive/frogpilot/ui/qt/offroad/control_settings.h FrogPilot/selfdrive/frogpilot/ui/qt/offroad/control_settings.h
+39a40,43
+> FrogPilotParamManageControl *modelManagerToggle;
+>
+> FrogPilotParamValueToggleControl *steerRatioToggle;
+>
+Only in clearpilot/selfdrive/frogpilot/ui/qt/offroad: moc_control_settings.cc
+Only in clearpilot/selfdrive/frogpilot/ui/qt/offroad: moc_vehicle_settings.cc
+Only in clearpilot/selfdrive/frogpilot/ui/qt/offroad: moc_visual_settings.cc
+diff -r clearpilot/selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.cc FrogPilot/selfdrive/frogpilot/ui/qt/offroad/vehicle_settings.cc
+141c141
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+173c173
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+diff -r clearpilot/selfdrive/frogpilot/ui/qt/offroad/visual_settings.cc FrogPilot/selfdrive/frogpilot/ui/qt/offroad/visual_settings.cc
+5,6c5
+< // CLEARPILOT
+< isRelease = branch == "clearpilot";
+---
+> isRelease = branch == "FrogPilot";
+27d25
+< {"LeadInfo", tr("Lead Info and Logics"), tr("Get detailed information about the vehicle ahead, including speed and distance, and the logic behind your following distance."), ""},
+137c135
+< if (!hasOpenpilotLongitudinal && !hasAutoTune || isRelease) {
+---
+> if (!hasOpenpilotLongitudinal && !hasAutoTune) {
+141,145d138
+< // Clearpilot allow leadInfo (test me)
+< // if (!hasOpenpilotLongitudinal || !isRelease) {
+< // modifiedCustomOnroadUIKeys.erase("LeadInfo");
+< // }
+<
+154,157d146
+< } else if (param == "LeadInfo") {
+< std::vector leadInfoToggles{"UseSI"};
+< std::vector leadInfoToggleNames{tr("Use SI Values")};
+< toggle = new FrogPilotParamToggleControl(param, title, desc, icon, leadInfoToggles, leadInfoToggleNames);
+diff -r clearpilot/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.h FrogPilot/selfdrive/frogpilot/ui/qt/widgets/frogpilot_controls.h
+352a353,358
+> void setEnabled(bool enabled) {
+> manageButton->setEnabled(enabled);
+> toggle.setEnabled(enabled);
+> toggle.update();
+> }
+>
+Only in clearpilot/selfdrive/frogpilot/ui/qt/widgets: moc_frogpilot_controls.cc
+diff -r clearpilot/selfdrive/locationd/locationd.cc FrogPilot/selfdrive/locationd/locationd.cc
+750c750
+< }
+\ No newline at end of file
+---
+> }
+diff -r clearpilot/selfdrive/locationd/paramsd.py FrogPilot/selfdrive/locationd/paramsd.py
+274c274
+< main()
+\ No newline at end of file
+---
+> main()
+diff -r clearpilot/selfdrive/manager/build.py FrogPilot/selfdrive/manager/build.py
+56d55
+< Path('/data/openpilot/prebuilt').touch()
+diff -r clearpilot/selfdrive/manager/manager.py FrogPilot/selfdrive/manager/manager.py
+33,34d32
+< delete_deprecated_models()
+<
+39a38,43
+> delete_deprecated_models()
+> except subprocess.CalledProcessError as e:
+> print(f"Failed to delete deprecated models. Error: {e}")
+> return
+>
+> try:
+151a156,158
+> ("FrogPilotDrives", "0"),
+> ("FrogPilotKilometers", "0"),
+> ("FrogPilotMinutes", "0"),
+172c179
+< ("LaneLinesWidth", "2"),
+---
+> ("LaneLinesWidth", "4"),
+182,186c189,193
+< ("kiV1", "0.60"),
+< ("kiV2", "0.45"),
+< ("kiV3", "0.30"),
+< ("kiV4", "0.15"),
+< ("kpV1", "1.50"),
+---
+> ("kiV1", "0.35"),
+> ("kiV2", "0.25"),
+> ("kiV3", "0.20"),
+> ("kiV4", "0.10"),
+> ("kpV1", "1.30"),
+188,189c195,196
+< ("kpV3", "0.75"),
+< ("kpV4", "0.50"),
+---
+> ("kpV3", "0.8"),
+> ("kpV4", "0.8"),
+198c205
+< ("ModelSelector", "1"),
+---
+> ("ModelSelector", "0"),
+344,351c351,358
+< # sentry.init(sentry.SentryProject.SELFDRIVE)
+< # cloudlog.bind_global(dongle_id=dongle_id,
+< # version=get_version(),
+< # origin=get_normalized_origin(),
+< # branch=get_short_branch(),
+< # commit=get_commit(),
+< # dirty=is_dirty(),
+< # device=HARDWARE.get_device_type())
+---
+> sentry.init(sentry.SentryProject.SELFDRIVE)
+> cloudlog.bind_global(dongle_id=dongle_id,
+> version=get_version(),
+> origin=get_normalized_origin(),
+> branch=get_short_branch(),
+> commit=get_commit(),
+> dirty=is_dirty(),
+> device=HARDWARE.get_device_type())
+370c377
+< def manager_thread(frogpilot_functions) -> None:
+---
+> def manager_thread() -> None:
+396,399d402
+< openpilot_crashed = os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt'))
+< if openpilot_crashed:
+< frogpilot_functions.delete_logs()
+<
+405,406c408,410
+< if openpilot_crashed:
+< os.remove(os.path.join(sentry.CRASHES_DIR, 'error.txt'))
+---
+> error_log = os.path.join(sentry.CRASHES_DIR, 'error.txt')
+> if os.path.isfile(error_log):
+> os.remove(error_log)
+432c436
+< for param in ("DoUninstall", "DoShutdown", "DoReboot", "DoSoftReboot"):
+---
+> for param in ("DoUninstall", "DoShutdown", "DoReboot"):
+459c463
+< manager_thread(frogpilot_functions)
+---
+> manager_thread()
+473,475d476
+< elif params.get_bool("DoSoftReboot"):
+< cloudlog.warning("softreboot")
+< HARDWARE.soft_reboot()
+diff -r clearpilot/selfdrive/manager/process_config.py FrogPilot/selfdrive/manager/process_config.py
+107c107
+< managed_processes = {p.name: p for p in procs}
+\ No newline at end of file
+---
+> managed_processes = {p.name: p for p in procs}
+diff -r clearpilot/selfdrive/modeld/modeld.py FrogPilot/selfdrive/modeld/modeld.py
+27c27
+< from openpilot.selfdrive.frogpilot.controls.lib.model_manager import DEFAULT_MODEL, MODELS_PATH, NAVIGATIONLESS_MODELS, RADARLESS_MODELS
+---
+> from openpilot.selfdrive.frogpilot.controls.lib.model_manager import DEFAULT_MODEL, MODELS_PATH, NAVIGATION_MODELS, RADARLESS_MODELS
+32c32
+< MODEL_NAME = Params().get("Model", encoding='utf-8')
+---
+> MODEL_NAME = Params().get("Model", block=True, encoding='utf-8')
+34c34
+< DISABLE_NAV = MODEL_NAME in NAVIGATIONLESS_MODELS
+---
+> DISABLE_NAV = MODEL_NAME not in NAVIGATION_MODELS
+38c38
+< ModelRunner.THNEED: Path(__file__).parent / ('models/supercombo.thneed' if MODEL_NAME == DEFAULT_MODEL else f'{MODELS_PATH}/{MODEL_NAME}.thneed'),
+---
+> ModelRunner.THNEED: Path(__file__).parent / ('models/supercombo.thneed' if MODEL_NAME == DEFAULT_MODEL or not Params().get_bool("ModelSelector") else f'{MODELS_PATH}/{MODEL_NAME}.thneed'),
+diff -r clearpilot/selfdrive/monitoring/driver_monitor.py FrogPilot/selfdrive/monitoring/driver_monitor.py
+22,38c22,27
+< # self._AWARENESS_TIME = 30. # passive wheeltouch total timeout
+< # self._AWARENESS_PRE_TIME_TILL_TERMINAL = 15.
+< # self._AWARENESS_PROMPT_TIME_TILL_TERMINAL = 6.
+< # self._DISTRACTED_TIME = 11. # active monitoring total timeout
+< # self._DISTRACTED_PRE_TIME_TILL_TERMINAL = 8.
+< # self._DISTRACTED_PROMPT_TIME_TILL_TERMINAL = 6.
+<
+< # Temp.
+< # Goals:
+< # - Temp only if daytime and privledged
+< # - Continuously lower speed if in crit state
+< self._AWARENESS_TIME = 50. # passive wheeltouch total timeout
+< self._AWARENESS_PRE_TIME_TILL_TERMINAL = 30.
+< self._AWARENESS_PROMPT_TIME_TILL_TERMINAL = 10.
+< self._DISTRACTED_TIME = 50. # active monitoring total timeout
+< self._DISTRACTED_PRE_TIME_TILL_TERMINAL = 30.
+< self._DISTRACTED_PROMPT_TIME_TILL_TERMINAL = 10.
+---
+> self._AWARENESS_TIME = 30. # passive wheeltouch total timeout
+> self._AWARENESS_PRE_TIME_TILL_TERMINAL = 15.
+> self._AWARENESS_PROMPT_TIME_TILL_TERMINAL = 6.
+> self._DISTRACTED_TIME = 11. # active monitoring total timeout
+> self._DISTRACTED_PRE_TIME_TILL_TERMINAL = 8.
+> self._DISTRACTED_PROMPT_TIME_TILL_TERMINAL = 6.
+316,317c305
+< # self.awareness > 0
+< if (driver_engaged and not self.active_monitoring_mode) or not ctrl_active: # reset only when on disengagement if red reached
+---
+> if (driver_engaged and self.awareness > 0 and not self.active_monitoring_mode) or not ctrl_active: # reset only when on disengagement if red reached
+324,325c312
+< # and self.awareness > 0
+< if (driver_attentive and self.face_detected and self.pose.low_std ):
+---
+> if (driver_attentive and self.face_detected and self.pose.low_std and self.awareness > 0):
+349,354c336,340
+< alert = EventName.driverDistracted if self.active_monitoring_mode else EventName.driverUnresponsive
+< # self.terminal_time += 1
+< # if awareness_prev > 0.:
+< # self.terminal_alert_cnt += 1
+< # elif self.awareness <= self.threshold_prompt:
+< if self.awareness <= self.threshold_prompt:
+---
+> alert = EventName.driverDistracted if self.active_monitoring_mode else EventName.driverUnresponsive
+> self.terminal_time += 1
+> if awareness_prev > 0.:
+> self.terminal_alert_cnt += 1
+> elif self.awareness <= self.threshold_prompt:
+diff -r clearpilot/selfdrive/sentry.py FrogPilot/selfdrive/sentry.py
+29,31d28
+< # CLEARPILOT disabled
+< return False
+<
+44,46d40
+< # CLEARPILOT disabled
+< return
+<
+96,98d89
+< # CLEARPILOT disabled
+< return
+<
+158,160d148
+< # CLEARPILOT disabled
+< return
+<
+201,203d188
+< # CLEARPILOT disabled
+< return
+<
+diff -r clearpilot/selfdrive/ui/qt/home.cc FrogPilot/selfdrive/ui/qt/home.cc
+12d11
+< #include "system/hardware/hw.h"
+21,23d19
+< // CLEARPILOT Sidebar set to invisible in drive view.
+< params.putBool("Sidebar", false);
+<
+46,50d41
+< // CLEARPILOT
+< // show_ready = true;
+< ready = new ReadyWindow(this);
+< slayout->addWidget(ready);
+<
+56d46
+<
+58d47
+<
+73c62
+< // const SubMaster &sm = *(s.sm);
+---
+> const SubMaster &sm = *(s.sm);
+75d63
+< // CLEARPILOT
+77,80c65,68
+< // if (onroad->isVisible() && !body->isEnabled() && sm["carParams"].getCarParams().getNotCar()) {
+< // body->setEnabled(true);
+< // slayout->setCurrentWidget(body);
+< // }
+---
+> if (onroad->isVisible() && !body->isEnabled() && sm["carParams"].getCarParams().getNotCar()) {
+> body->setEnabled(true);
+> slayout->setCurrentWidget(body);
+> }
+88a77
+> sidebar->setVisible(offroad);
+90,92c79
+< sidebar->setVisible(false);
+< slayout->setCurrentWidget(ready);
+< // this->showDriverView(true, true); // Temp
+---
+> slayout->setCurrentWidget(home);
+94d80
+< sidebar->setVisible(false);
+117,119d102
+< // CLEARPILOT todo - tap on main goes straight to settings
+< // Unless we click a debug widget.
+<
+121,135c104,107
+< // if ((onroad->isVisible() || body->isVisible()) && (!sidebar->isVisible() || e->x() > sidebar->width())) {
+< // sidebar->setVisible(!sidebar->isVisible() && !onroad->isMapVisible());
+< // uiState()->scene.map_open = onroad->isMapVisible();
+< // params.putBool("Sidebar", sidebar->isVisible());
+< // }
+<
+< // CLEARPILOT - click ready shows home
+< if (!onroad->isVisible() && ready->isVisible()) {
+< sidebar->setVisible(true);
+< slayout->setCurrentWidget(home);
+< }
+<
+< // Todo: widgets
+< if (onroad->isVisible()) {
+< emit openSettings();
+---
+> if ((onroad->isVisible() || body->isVisible()) && (!sidebar->isVisible() || e->x() > sidebar->width())) {
+> sidebar->setVisible(!sidebar->isVisible() && !onroad->isMapVisible());
+> uiState()->scene.map_open = onroad->isMapVisible();
+> params.putBool("Sidebar", sidebar->isVisible());
+219,220d190
+< // CLEARPILOT TEMP
+< // QObject::connect(experimental_mode, &ExperimentalModeButton::openSettings, this, &OffroadHome::openSettings);
+267,270c237
+< // CLEARPILOT changed timeout to 2 min
+< // What does this even do?
+< timer->start(120 * 1000);
+< // slayout->addWidget(ready);
+---
+> timer->start(10 * 1000);
+287d253
+< // CLEARPILOT temp disabled update notifications
+289c255
+< if (!updateAvailable && !alerts && false) {
+---
+> if (!updateAvailable && !alerts) {
+298,302c264,265
+< // CLEARPILOT temp disabled update notifications
+< // update_notif->setVisible(updateAvailable);
+< // alert_notif->setVisible(alerts);
+< update_notif->setVisible(false);
+< alert_notif->setVisible(false);
+---
+> update_notif->setVisible(updateAvailable);
+> alert_notif->setVisible(alerts);
+diff -r clearpilot/selfdrive/ui/qt/home.h FrogPilot/selfdrive/ui/qt/home.h
+13d12
+< #include "selfdrive/ui/qt/ready.h"
+53d51
+< QWidget* _parent = 0;
+79,82d76
+<
+< // CLEARPILOT
+< // bool show_ready;
+< ReadyWindow *ready;
+diff -r clearpilot/selfdrive/ui/qt/offroad/settings.cc FrogPilot/selfdrive/ui/qt/offroad/settings.cc
+324c324
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+340c340
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+350,351c350
+< // CLEARPILOT - changed backups to /data/cp_backups
+< QDir backupDir("/data/cp_backups");
+---
+> QDir backupDir("/data/backups");
+428c427
+< Hardware::soft_reboot();
+---
+> Hardware::reboot();
+443,444c442
+< // CLEARPILOT changed to cp_toggle_backups
+< QDir backupDir("/data/cp_toggle_backups");
+---
+> QDir backupDir("/data/toggle_backups");
+552,556d549
+< QPushButton *softreboot_btn = new QPushButton(tr("Soft Reboot"));
+< softreboot_btn->setObjectName("softreboot_btn");
+< power_layout->addWidget(softreboot_btn);
+< QObject::connect(softreboot_btn, &QPushButton::clicked, this, &DevicePanel::softreboot);
+<
+567,568d559
+< #softreboot_btn { height: 120px; border-radius: 15px; background-color: #e2e22c; }
+< #softreboot_btn:pressed { background-color: #ffe224; }
+611,622d601
+< }
+< }
+<
+< void DevicePanel::softreboot() {
+< if (!uiState()->engaged()) {
+< if (ConfirmationDialog::confirm(tr("Are you sure you want to soft reboot?"), tr("Soft Reboot"), this)) {
+< if (!uiState()->engaged()) {
+< params.putBool("DoSoftReboot", true);
+< }
+< }
+< } else {
+< ConfirmationDialog::alert(tr("Disengage to Soft Reboot"), this);
+diff -r clearpilot/selfdrive/ui/qt/offroad/settings.h FrogPilot/selfdrive/ui/qt/offroad/settings.h
+67d66
+< void softreboot();
+diff -r clearpilot/selfdrive/ui/qt/offroad/software_settings.cc FrogPilot/selfdrive/ui/qt/offroad/software_settings.cc
+35,36c35,36
+< ParamControl *automaticUpdatesToggle = new ParamControl("AutomaticUpdates", tr(" Automatically Update ClearPilot"),
+< tr("ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi."), "");
+---
+> ParamControl *automaticUpdatesToggle = new ParamControl("AutomaticUpdates", tr("Automatically Update FrogPilot"),
+> tr("FrogPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi."), "");
+diff -r clearpilot/selfdrive/ui/qt/onroad.cc FrogPilot/selfdrive/ui/qt/onroad.cc
+122,191c122,191
+< // // Change cruise control increments button
+< // QRect maxSpeedRect(7, 25, 225, 225);
+< // bool isMaxSpeedClicked = maxSpeedRect.contains(e->pos()) && scene.reverse_cruise_ui;
+<
+< // // Hide speed button
+< // QRect hideSpeedRect(rect().center().x() - 175, 50, 350, 350);
+< // bool isSpeedClicked = hideSpeedRect.contains(e->pos()) && scene.hide_speed_ui;
+<
+< // // Speed limit confirmation buttons
+< // QSize size = this->size();
+< // QRect leftRect(0, 0, size.width() / 2, size.height());
+< // QRect rightRect = leftRect.translated(size.width() / 2, 0);
+<
+< // bool isLeftSideClicked = leftRect.contains(e->pos()) && scene.speed_limit_changed;
+< // bool isRightSideClicked = rightRect.contains(e->pos()) && scene.speed_limit_changed;
+<
+< // // Speed limit offset button
+< // QRect speedLimitRect(7, 250, 225, 225);
+< // bool isSpeedLimitClicked = speedLimitRect.contains(e->pos()) && scene.show_slc_offset_ui;
+<
+< // if (isMaxSpeedClicked || isSpeedClicked || isSpeedLimitClicked) {
+< // if (isMaxSpeedClicked) {
+< // std::thread([this]() {
+< // bool currentReverseCruise = scene.reverse_cruise;
+<
+< // uiState()->scene.reverse_cruise = !currentReverseCruise;
+< // params.putBoolNonBlocking("ReverseCruise", !currentReverseCruise);
+<
+< // paramsMemory.putBool("FrogPilotTogglesUpdated", true);
+< // std::this_thread::sleep_for(std::chrono::seconds(1));
+< // paramsMemory.putBool("FrogPilotTogglesUpdated", false);
+< // }).detach();
+<
+< // } else if (isSpeedClicked) {
+< // bool currentHideSpeed = scene.hide_speed;
+<
+< // uiState()->scene.hide_speed = !currentHideSpeed;
+< // params.putBoolNonBlocking("HideSpeed", !currentHideSpeed);
+< // } else if (isSpeedLimitClicked) {
+< // bool currentShowSLCOffset = scene.show_slc_offset;
+<
+< // scene.show_slc_offset = !currentShowSLCOffset;
+< // params.putBoolNonBlocking("ShowSLCOffset", !currentShowSLCOffset);
+< // }
+<
+< // widgetClicked = true;
+< // } else if (isLeftSideClicked || isRightSideClicked) {
+< // bool slcConfirmed = isLeftSideClicked && !scene.right_hand_drive || isRightSideClicked && scene.right_hand_drive;
+< // paramsMemory.putBoolNonBlocking("SLCConfirmed", slcConfirmed);
+< // paramsMemory.putBoolNonBlocking("SLCConfirmedPressed", true);
+<
+< // widgetClicked = true;
+< // // If the click wasn't for anything specific, change the value of "ExperimentalMode"
+< // } else if (scene.experimental_mode_via_screen && e->pos() != timeoutPoint) {
+< // if (clickTimer.isActive()) {
+< // clickTimer.stop();
+<
+< // if (scene.conditional_experimental) {
+< // int override_value = (scene.conditional_status >= 1 && scene.conditional_status <= 6) ? 0 : scene.conditional_status >= 7 ? 5 : 6;
+< // paramsMemory.putIntNonBlocking("CEStatus", override_value);
+< // } else {
+< // bool experimentalMode = params.getBool("ExperimentalMode");
+< // params.putBoolNonBlocking("ExperimentalMode", !experimentalMode);
+< // }
+<
+< // } else {
+< // clickTimer.start(500);
+< // }
+< // widgetClicked = true;
+< // }
+---
+> // Change cruise control increments button
+> QRect maxSpeedRect(7, 25, 225, 225);
+> bool isMaxSpeedClicked = maxSpeedRect.contains(e->pos()) && scene.reverse_cruise_ui;
+>
+> // Hide speed button
+> QRect hideSpeedRect(rect().center().x() - 175, 50, 350, 350);
+> bool isSpeedClicked = hideSpeedRect.contains(e->pos()) && scene.hide_speed_ui;
+>
+> // Speed limit confirmation buttons
+> QSize size = this->size();
+> QRect leftRect(0, 0, size.width() / 2, size.height());
+> QRect rightRect = leftRect.translated(size.width() / 2, 0);
+>
+> bool isLeftSideClicked = leftRect.contains(e->pos()) && scene.speed_limit_changed;
+> bool isRightSideClicked = rightRect.contains(e->pos()) && scene.speed_limit_changed;
+>
+> // Speed limit offset button
+> QRect speedLimitRect(7, 250, 225, 225);
+> bool isSpeedLimitClicked = speedLimitRect.contains(e->pos()) && scene.show_slc_offset_ui;
+>
+> if (isMaxSpeedClicked || isSpeedClicked || isSpeedLimitClicked) {
+> if (isMaxSpeedClicked) {
+> std::thread([this]() {
+> bool currentReverseCruise = scene.reverse_cruise;
+>
+> uiState()->scene.reverse_cruise = !currentReverseCruise;
+> params.putBoolNonBlocking("ReverseCruise", !currentReverseCruise);
+>
+> paramsMemory.putBool("FrogPilotTogglesUpdated", true);
+> std::this_thread::sleep_for(std::chrono::seconds(1));
+> paramsMemory.putBool("FrogPilotTogglesUpdated", false);
+> }).detach();
+>
+> } else if (isSpeedClicked) {
+> bool currentHideSpeed = scene.hide_speed;
+>
+> uiState()->scene.hide_speed = !currentHideSpeed;
+> params.putBoolNonBlocking("HideSpeed", !currentHideSpeed);
+> } else if (isSpeedLimitClicked) {
+> bool currentShowSLCOffset = scene.show_slc_offset;
+>
+> scene.show_slc_offset = !currentShowSLCOffset;
+> params.putBoolNonBlocking("ShowSLCOffset", !currentShowSLCOffset);
+> }
+>
+> widgetClicked = true;
+> } else if (isLeftSideClicked || isRightSideClicked) {
+> bool slcConfirmed = isLeftSideClicked && !scene.right_hand_drive || isRightSideClicked && scene.right_hand_drive;
+> paramsMemory.putBoolNonBlocking("SLCConfirmed", slcConfirmed);
+> paramsMemory.putBoolNonBlocking("SLCConfirmedPressed", true);
+>
+> widgetClicked = true;
+> // If the click wasn't for anything specific, change the value of "ExperimentalMode"
+> } else if (scene.experimental_mode_via_screen && e->pos() != timeoutPoint) {
+> if (clickTimer.isActive()) {
+> clickTimer.stop();
+>
+> if (scene.conditional_experimental) {
+> int override_value = (scene.conditional_status >= 1 && scene.conditional_status <= 6) ? 0 : scene.conditional_status >= 7 ? 5 : 6;
+> paramsMemory.putIntNonBlocking("CEStatus", override_value);
+> } else {
+> bool experimentalMode = params.getBool("ExperimentalMode");
+> params.putBoolNonBlocking("ExperimentalMode", !experimentalMode);
+> }
+>
+> } else {
+> clickTimer.start(500);
+> }
+> widgetClicked = true;
+> }
+301,302c301,302
+< .arg(scene.acceleration_jerk_difference > 0 ? "-" : "", 0)
+< .arg(abs(scene.acceleration_jerk_difference), 0, 'f', 3)
+---
+> .arg(scene.acceleration_jerk_difference > 0 ? "-" : "+", 0)
+> .arg(scene.acceleration_jerk_difference, 0, 'f', 3)
+304,305c304,305
+< .arg(scene.ego_jerk_difference > 0 ? "-" : "", 0)
+< .arg(abs(scene.ego_jerk_difference), 0, 'f', 3);
+---
+> .arg(scene.ego_jerk_difference > 0 ? "-" : "+", 0)
+> .arg(scene.ego_jerk_difference, 0, 'f', 3);
+438,439c438,439
+< int override_value = (scene.conditional_status >= 1 && scene.conditional_status <= 4) ? 0 : scene.conditional_status >= 5 ? 5 : 6;
+< paramsMemory.putIntNonBlocking("ConditionalStatus", override_value);
+---
+> int override_value = (scene.conditional_status >= 1 && scene.conditional_status <= 6) ? 0 : scene.conditional_status >= 7 ? 5 : 6;
+> paramsMemory.putIntNonBlocking("CEStatus", override_value);
+555,556c555
+< recorder_btn->setVisible(false);
+< // buttons_layout->addWidget(recorder_btn);
+---
+> buttons_layout->addWidget(recorder_btn);
+559c558
+< // buttons_layout->addWidget(experimental_btn);
+---
+> buttons_layout->addWidget(experimental_btn);
+566c565
+< // top_right_layout->addWidget(pedal_icons, 0, Qt::AlignRight);
+---
+> top_right_layout->addWidget(pedal_icons, 0, Qt::AlignRight);
+620,621d618
+< // CLEARPILOT
+< experimental_btn->setVisible(false);
+771,773c768
+< // CLEARPILOT changes to 120 from ~176
+< // Maybe we want to hide this?
+< p.setFont(InterFont(140, QFont::Bold));
+---
+> p.setFont(InterFont(176, QFont::Bold));
+775,776c770
+< // CLEARPILOT changes to 40 from 66
+< p.setFont(InterFont(50));
+---
+> p.setFont(InterFont(66));
+826,836d819
+< // CLEARPILOT: color channel code rewriten to allow custom colors
+< // Center lane color
+< // This should be moved to ui.h
+< int base_red = 150;
+< int base_green = 150;
+< int base_blue = 150;
+< float path_alpha = 0.30; // 60% opacity
+< float other_alpha = 0.75; // 60% opacity
+<
+< QColor center_lane_color(base_red, base_green, base_blue);
+<
+841,845c824,828
+< // if (currentHolidayTheme != 0) {
+< // painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
+< // } else if (customColors != 0) {
+< // painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
+< // } else {
+---
+> if (currentHolidayTheme != 0) {
+> painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
+> } else if (customColors != 0) {
+> painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
+> } else {
+847c830
+< // }
+---
+> }
+853,857c836,840
+< // if (currentHolidayTheme != 0) {
+< // painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
+< // } else if (customColors != 0) {
+< // painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
+< // } else {
+---
+> if (currentHolidayTheme != 0) {
+> painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
+> } else if (customColors != 0) {
+> painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
+> } else {
+859c842
+< // }
+---
+> }
+877,881c860,872
+< try {
+< for (int i = 0; i < max_len; ++i) {
+< if (scene.track_vertices[i].y() < 0 || scene.track_vertices[i].y() > height()) continue;
+<
+< float lin_grad_point = (height() - scene.track_vertices[i].y()) / height();
+---
+> for (int i = 0; i < max_len; ++i) {
+> // Some points are out of frame
+> if (scene.track_vertices[i].y() < 0 || scene.track_vertices[i].y() > height()) continue;
+>
+> // Flip so 0 is bottom of frame
+> float lin_grad_point = (height() - scene.track_vertices[i].y()) / height();
+>
+> // If acceleration is between -0.25 and 0.25, resort to the theme color
+> if (std::abs(acceleration[i]) < 0.25 && (currentHolidayTheme != 0)) {
+> const auto &colorMap = std::get<2>(holidayThemeConfiguration[currentHolidayTheme]);
+> for (const auto &[position, brush] : colorMap) {
+> bg.setColorAt(position, brush.color());
+> }
+883,884c874,878
+< double _h, _s, _l; // Use double for compatibility with QColor::getHslF()
+< center_lane_color.getHslF(&_h, &_s, &_l);
+---
+> } else if (std::abs(acceleration[i]) < 0.25 && (customColors != 0)) {
+> const auto &colorMap = std::get<2>(themeConfiguration[customColors]);
+> for (const auto &[position, brush] : colorMap) {
+> bg.setColorAt(position, brush.color());
+> }
+886,888c880,889
+< // Calculate saturation and lightness based on acceleration
+< float adjusted_saturation = std::min(std::abs(acceleration[i] * 1.5f), 1.f);
+< float adjusted_lightness = util::map_val(adjusted_saturation, 0.f, 1.f, static_cast(_l), 0.95f); // Using base lightness as a starting point
+---
+> } else {
+> // speed up: 120, slow down: 0
+> float path_hue = fmax(fmin(60 + acceleration[i] * 35, 120), 0);
+> // FIXME: painter.drawPolygon can be slow if hue is not rounded
+> path_hue = int(path_hue * 100 + 0.5) / 100;
+>
+> float saturation = fmin(fabs(acceleration[i] * 1.5), 1);
+> float lightness = util::map_val(saturation, 0.0f, 1.0f, 0.95f, 0.62f); // lighter when grey
+> float alpha = util::map_val(lin_grad_point, 0.75f / 2.f, 0.75f, 0.4f, 0.0f); // matches previous alpha fade
+> bg.setColorAt(lin_grad_point, QColor::fromHslF(path_hue / 360., saturation, lightness, alpha));
+890,891c891,894
+< // Calculate dynamic alpha based on lin_grad_point
+< float dynamic_alpha = util::map_val(lin_grad_point, 0.75f / 2.f, 0.75f, path_alpha, 0.f);
+---
+> // Skip a point, unless next is last
+> i += (i + 2) < max_len ? 1 : 0;
+> }
+> }
+893,894c896,900
+< QColor final_color = QColor::fromHslF(static_cast(_h / 360.f), adjusted_saturation, adjusted_lightness, dynamic_alpha);
+< bg.setColorAt(lin_grad_point, final_color);
+---
+> } else if (currentHolidayTheme != 0) {
+> const auto &colorMap = std::get<2>(holidayThemeConfiguration[currentHolidayTheme]);
+> for (const auto &[position, brush] : colorMap) {
+> bg.setColorAt(position, brush.color());
+> }
+896,903c902,905
+< i += (i + 2) < max_len ? 1 : 0; // Skipping a point to optimize rendering
+< }
+< } catch (const std::exception& e) {
+< // Default shading if for some reason the above code fails
+< bg = QLinearGradient(0, height(), 0, 0);
+< bg.setColorAt(0.0, QColor(center_lane_color.red(), center_lane_color.green(), center_lane_color.blue(), static_cast(other_alpha * 255 * 0.4)));
+< bg.setColorAt(0.5, QColor(center_lane_color.red(), center_lane_color.green(), center_lane_color.blue(), static_cast(other_alpha * 255 * 0.35)));
+< bg.setColorAt(1.0, QColor(center_lane_color.red(), center_lane_color.green(), center_lane_color.blue(), static_cast(other_alpha * 255 * 0.0)));
+---
+> } else if (customColors != 0) {
+> const auto &colorMap = std::get<2>(themeConfiguration[customColors]);
+> for (const auto &[position, brush] : colorMap) {
+> bg.setColorAt(position, brush.color());
+904a907
+>
+906,908c909,911
+< bg.setColorAt(0.0, QColor(center_lane_color.red(), center_lane_color.green(), center_lane_color.blue(), static_cast(other_alpha * 255 * 0.4)));
+< bg.setColorAt(0.5, QColor(center_lane_color.red(), center_lane_color.green(), center_lane_color.blue(), static_cast(other_alpha * 255 * 0.35)));
+< bg.setColorAt(1.0, QColor(center_lane_color.red(), center_lane_color.green(), center_lane_color.blue(), static_cast(other_alpha * 255 * 0.0)));
+---
+> bg.setColorAt(0.0, QColor::fromHslF(148 / 360., 0.94, 0.51, 0.4));
+> bg.setColorAt(0.5, QColor::fromHslF(112 / 360., 1.0, 0.68, 0.35));
+> bg.setColorAt(1.0, QColor::fromHslF(112 / 360., 1.0, 0.68, 0.0));
+917,925c920,930
+< QColor color = bg_colors[STATUS_ALWAYS_ON_LATERAL_ACTIVE];
+< pe.setColorAt(0.0, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255)));
+< pe.setColorAt(0.5, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255 * 0.5)));
+< pe.setColorAt(1.0, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255 * 0.1)));
+< } else if (conditionalStatus == 1 || conditionalStatus == 3 || conditionalStatus == 5 || experimentalMode) {
+< QColor color = bg_colors[STATUS_EXPERIMENTAL_ACTIVE];
+< pe.setColorAt(0.0, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255)));
+< pe.setColorAt(0.5, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255 * 0.5)));
+< pe.setColorAt(1.0, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255 * 0.1)));
+---
+> pe.setColorAt(0.0, QColor::fromHslF(178 / 360., 0.90, 0.38, 1.0));
+> pe.setColorAt(0.5, QColor::fromHslF(178 / 360., 0.90, 0.38, 0.5));
+> pe.setColorAt(1.0, QColor::fromHslF(178 / 360., 0.90, 0.38, 0.1));
+> } else if (conditionalStatus == 1 || conditionalStatus == 3 || conditionalStatus == 5) {
+> pe.setColorAt(0.0, QColor::fromHslF(58 / 360., 1.00, 0.50, 1.0));
+> pe.setColorAt(0.5, QColor::fromHslF(58 / 360., 1.00, 0.50, 0.5));
+> pe.setColorAt(1.0, QColor::fromHslF(58 / 360., 1.00, 0.50, 0.1));
+> } else if (experimentalMode) {
+> pe.setColorAt(0.0, QColor::fromHslF(25 / 360., 0.71, 0.50, 1.0));
+> pe.setColorAt(0.5, QColor::fromHslF(25 / 360., 0.71, 0.50, 0.5));
+> pe.setColorAt(1.0, QColor::fromHslF(25 / 360., 0.71, 0.50, 0.1));
+933a939,950
+> } else if (currentHolidayTheme != 0) {
+> const auto &colorMap = std::get<2>(holidayThemeConfiguration[currentHolidayTheme]);
+> for (const auto &[position, brush] : colorMap) {
+> QColor darkerColor = brush.color().darker(120);
+> pe.setColorAt(position, darkerColor);
+> }
+> } else if (customColors != 0) {
+> const auto &colorMap = std::get<2>(themeConfiguration[customColors]);
+> for (const auto &[position, brush] : colorMap) {
+> QColor darkerColor = brush.color().darker(120);
+> pe.setColorAt(position, darkerColor);
+> }
+935,938c952,954
+< QColor color = bg_colors[STATUS_ENGAGED];
+< pe.setColorAt(0.0, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255)));
+< pe.setColorAt(0.5, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255 * 0.5)));
+< pe.setColorAt(1.0, QColor(color.red(), color.green(), color.blue(), static_cast(other_alpha * 255 * 0.1)));
+---
+> pe.setColorAt(0.0, QColor::fromHslF(148 / 360., 0.94, 0.51, 1.0));
+> pe.setColorAt(0.5, QColor::fromHslF(112 / 360., 1.00, 0.68, 0.5));
+> pe.setColorAt(1.0, QColor::fromHslF(112 / 360., 1.00, 0.68, 0.1));
+1004c1020
+< // painter.save();
+---
+> painter.save();
+1006,1039c1022,1055
+< // // base icon
+< // int offset = UI_BORDER_SIZE + btn_size / 2;
+< // int x = rightHandDM ? width() - offset : offset;
+< // x += onroadDistanceButton ? 250 : 0;
+< // offset += showAlwaysOnLateralStatusBar || showConditionalExperimentalStatusBar || roadNameUI ? 25 : 0;
+< // int y = height() - offset;
+< // float opacity = dmActive ? 0.65 : 0.2;
+< // drawIcon(painter, QPoint(x, y), dm_img, blackColor(70), opacity);
+<
+< // // face
+< // QPointF face_kpts_draw[std::size(default_face_kpts_3d)];
+< // float kp;
+< // for (int i = 0; i < std::size(default_face_kpts_3d); ++i) {
+< // kp = (scene.face_kpts_draw[i].v[2] - 8) / 120 + 1.0;
+< // face_kpts_draw[i] = QPointF(scene.face_kpts_draw[i].v[0] * kp + x, scene.face_kpts_draw[i].v[1] * kp + y);
+< // }
+<
+< // painter.setPen(QPen(QColor::fromRgbF(1.0, 1.0, 1.0, opacity), 5.2, Qt::SolidLine, Qt::RoundCap));
+< // painter.drawPolyline(face_kpts_draw, std::size(default_face_kpts_3d));
+<
+< // // tracking arcs
+< // const int arc_l = 133;
+< // const float arc_t_default = 6.7;
+< // const float arc_t_extend = 12.0;
+< // QColor arc_color = QColor::fromRgbF(0.545 - 0.445 * s->engaged(),
+< // 0.545 + 0.4 * s->engaged(),
+< // 0.545 - 0.285 * s->engaged(),
+< // 0.4 * (1.0 - dm_fade_state));
+< // float delta_x = -scene.driver_pose_sins[1] * arc_l / 2;
+< // float delta_y = -scene.driver_pose_sins[0] * arc_l / 2;
+< // painter.setPen(QPen(arc_color, arc_t_default+arc_t_extend*fmin(1.0, scene.driver_pose_diff[1] * 5.0), Qt::SolidLine, Qt::RoundCap));
+< // painter.drawArc(QRectF(std::fmin(x + delta_x, x), y - arc_l / 2, fabs(delta_x), arc_l), (scene.driver_pose_sins[1]>0 ? 90 : -90) * 16, 180 * 16);
+< // painter.setPen(QPen(arc_color, arc_t_default+arc_t_extend*fmin(1.0, scene.driver_pose_diff[0] * 5.0), Qt::SolidLine, Qt::RoundCap));
+< // painter.drawArc(QRectF(x - arc_l / 2, std::fmin(y + delta_y, y), arc_l, fabs(delta_y)), (scene.driver_pose_sins[0]>0 ? 0 : 180) * 16, 180 * 16);
+---
+> // base icon
+> int offset = UI_BORDER_SIZE + btn_size / 2;
+> int x = rightHandDM ? width() - offset : offset;
+> x += onroadDistanceButton ? 250 : 0;
+> offset += showAlwaysOnLateralStatusBar || showConditionalExperimentalStatusBar || roadNameUI ? 25 : 0;
+> int y = height() - offset;
+> float opacity = dmActive ? 0.65 : 0.2;
+> drawIcon(painter, QPoint(x, y), dm_img, blackColor(70), opacity);
+>
+> // face
+> QPointF face_kpts_draw[std::size(default_face_kpts_3d)];
+> float kp;
+> for (int i = 0; i < std::size(default_face_kpts_3d); ++i) {
+> kp = (scene.face_kpts_draw[i].v[2] - 8) / 120 + 1.0;
+> face_kpts_draw[i] = QPointF(scene.face_kpts_draw[i].v[0] * kp + x, scene.face_kpts_draw[i].v[1] * kp + y);
+> }
+>
+> painter.setPen(QPen(QColor::fromRgbF(1.0, 1.0, 1.0, opacity), 5.2, Qt::SolidLine, Qt::RoundCap));
+> painter.drawPolyline(face_kpts_draw, std::size(default_face_kpts_3d));
+>
+> // tracking arcs
+> const int arc_l = 133;
+> const float arc_t_default = 6.7;
+> const float arc_t_extend = 12.0;
+> QColor arc_color = QColor::fromRgbF(0.545 - 0.445 * s->engaged(),
+> 0.545 + 0.4 * s->engaged(),
+> 0.545 - 0.285 * s->engaged(),
+> 0.4 * (1.0 - dm_fade_state));
+> float delta_x = -scene.driver_pose_sins[1] * arc_l / 2;
+> float delta_y = -scene.driver_pose_sins[0] * arc_l / 2;
+> painter.setPen(QPen(arc_color, arc_t_default+arc_t_extend*fmin(1.0, scene.driver_pose_diff[1] * 5.0), Qt::SolidLine, Qt::RoundCap));
+> painter.drawArc(QRectF(std::fmin(x + delta_x, x), y - arc_l / 2, fabs(delta_x), arc_l), (scene.driver_pose_sins[1]>0 ? 90 : -90) * 16, 180 * 16);
+> painter.setPen(QPen(arc_color, arc_t_default+arc_t_extend*fmin(1.0, scene.driver_pose_diff[0] * 5.0), Qt::SolidLine, Qt::RoundCap));
+> painter.drawArc(QRectF(x - arc_l / 2, std::fmin(y + delta_y, y), arc_l, fabs(delta_y)), (scene.driver_pose_sins[0]>0 ? 0 : 180) * 16, 180 * 16);
+1041c1057
+< // painter.restore();
+---
+> painter.restore();
+1074,1079c1090,1094
+< // CLEARPILOT disabling custom theme colors
+< // if (currentHolidayTheme != 0) {
+< // painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
+< // } else if (customColors != 0) {
+< // painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
+< // } else {
+---
+> if (currentHolidayTheme != 0) {
+> painter.setBrush(std::get<2>(holidayThemeConfiguration[currentHolidayTheme]).begin()->second);
+> } else if (customColors != 0) {
+> painter.setBrush(std::get<2>(themeConfiguration[customColors]).begin()->second);
+> } else {
+1081c1096
+< // }
+---
+> }
+1169c1184
+< if (s->scene.longitudinal_control && sm.rcv_frame("modelV2") > s->scene.started_frame) {
+---
+> if (s->scene.longitudinal_control && sm.rcv_frame("modelV2") > s->scene.started_frame && !s->scene.hide_lead_marker) {
+1218c1233
+< // bottom_layout->addWidget(distance_btn);
+---
+> bottom_layout->addWidget(distance_btn);
+1220,1221c1235,1236
+< // QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
+< // bottom_layout->addItem(spacer);
+---
+> QSpacerItem *spacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Minimum);
+> bottom_layout->addItem(spacer);
+1224c1239
+< // bottom_layout->addWidget(compass_img);
+---
+> bottom_layout->addWidget(compass_img);
+1285,1291c1300,1306
+< // QTimer *record_timer = new QTimer(this);
+< // connect(record_timer, &QTimer::timeout, this, [this]() {
+< // if (recorder_btn) {
+< // recorder_btn->update_screen();
+< // }
+< // });
+< // record_timer->start(1000 / UI_FREQ);
+---
+> QTimer *record_timer = new QTimer(this);
+> connect(record_timer, &QTimer::timeout, this, [this]() {
+> if (recorder_btn) {
+> recorder_btn->update_screen();
+> }
+> });
+> record_timer->start(1000 / UI_FREQ);
+1316c1331
+< // experimentalMode = scene.experimental_mode;
+---
+> experimentalMode = scene.experimental_mode;
+1387,1394c1402,1409
+< // if (customSignals != 0 && (turnSignalLeft || turnSignalRight) && !bigMapOpen) {
+< // if (!animationTimer->isActive()) {
+< // animationTimer->start(totalFrames * 11); // 440 milliseconds per loop; syncs up perfectly with my 2019 Lexus ES 350 turn signal clicks
+< // }
+< // drawTurnSignals(p);
+< // } else if (animationTimer->isActive()) {
+< // animationTimer->stop();
+< // }
+---
+> if (customSignals != 0 && (turnSignalLeft || turnSignalRight) && !bigMapOpen) {
+> if (!animationTimer->isActive()) {
+> animationTimer->start(totalFrames * 11); // 440 milliseconds per loop; syncs up perfectly with my 2019 Lexus ES 350 turn signal clicks
+> }
+> drawTurnSignals(p);
+> } else if (animationTimer->isActive()) {
+> animationTimer->stop();
+> }
+1404,1422c1419,1437
+< // bool enableCompass = compass && !hideBottomIcons;
+< // compass_img->setVisible(enableCompass);
+< // if (enableCompass) {
+< // compass_img->updateState();
+< // bottom_layout->setAlignment(compass_img, (rightHandDM ? Qt::AlignLeft : Qt::AlignRight));
+< // }
+<
+< // bool enableDistanceButton = onroadDistanceButton && !hideBottomIcons;
+< // distance_btn->setVisible(enableDistanceButton);
+< // if (enableDistanceButton) {
+< // distance_btn->updateState();
+< // bottom_layout->setAlignment(distance_btn, (rightHandDM ? Qt::AlignRight : Qt::AlignLeft));
+< // }
+<
+< // bool enablePedalIcons = scene.pedals_on_ui && !bigMapOpen;
+< // pedal_icons->setVisible(enablePedalIcons);
+< // if (enablePedalIcons) {
+< // pedal_icons->updateState();
+< // }
+---
+> bool enableCompass = compass && !hideBottomIcons;
+> compass_img->setVisible(enableCompass);
+> if (enableCompass) {
+> compass_img->updateState();
+> bottom_layout->setAlignment(compass_img, (rightHandDM ? Qt::AlignLeft : Qt::AlignRight));
+> }
+>
+> bool enableDistanceButton = onroadDistanceButton && !hideBottomIcons;
+> distance_btn->setVisible(enableDistanceButton);
+> if (enableDistanceButton) {
+> distance_btn->updateState();
+> bottom_layout->setAlignment(distance_btn, (rightHandDM ? Qt::AlignRight : Qt::AlignLeft));
+> }
+>
+> bool enablePedalIcons = scene.pedals_on_ui && !bigMapOpen;
+> pedal_icons->setVisible(enablePedalIcons);
+> if (enablePedalIcons) {
+> pedal_icons->updateState();
+> }
+1430,1431c1445
+< // recorder_btn->setVisible(scene.screen_recorder && !mapOpen);
+< recorder_btn->setVisible(false);
+---
+> recorder_btn->setVisible(scene.screen_recorder && !mapOpen);
+1435c1449
+< // setFixedSize(btn_size * 1.5, btn_size * 1.5);
+---
+> setFixedSize(btn_size * 1.5, btn_size * 1.5);
+1437,1440c1451,1454
+< // compassSize = btn_size;
+< // circleOffset = compassSize / 2;
+< // degreeLabelOffset = circleOffset + 25;
+< // innerCompass = compassSize / 2;
+---
+> compassSize = btn_size;
+> circleOffset = compassSize / 2;
+> degreeLabelOffset = circleOffset + 25;
+> innerCompass = compassSize / 2;
+1442,1443c1456,1457
+< // x = (btn_size * 1.5) / 2 + 20;
+< // y = (btn_size * 1.5) / 2;
+---
+> x = (btn_size * 1.5) / 2 + 20;
+> y = (btn_size * 1.5) / 2;
+1445c1459
+< // compassInnerImg = loadPixmap("../frogpilot/assets/other_images/compass_inner.png", QSize(compassSize / 1.75, compassSize / 1.75));
+---
+> compassInnerImg = loadPixmap("../frogpilot/assets/other_images/compass_inner.png", QSize(compassSize / 1.75, compassSize / 1.75));
+1447,1449c1461,1463
+< // staticElements = QPixmap(size());
+< // staticElements.fill(Qt::transparent);
+< // QPainter p(&staticElements);
+---
+> staticElements = QPixmap(size());
+> staticElements.fill(Qt::transparent);
+> QPainter p(&staticElements);
+1451c1465
+< // p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+---
+> p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+1453,1454c1467,1468
+< // QPen whitePen(Qt::white, 2);
+< // p.setPen(whitePen);
+---
+> QPen whitePen(Qt::white, 2);
+> p.setPen(whitePen);
+1456,1458c1470,1472
+< // p.setOpacity(1.0);
+< // p.setBrush(QColor(0, 0, 0, 100));
+< // p.drawEllipse(x - circleOffset, y - circleOffset, circleOffset * 2, circleOffset * 2);
+---
+> p.setOpacity(1.0);
+> p.setBrush(QColor(0, 0, 0, 100));
+> p.drawEllipse(x - circleOffset, y - circleOffset, circleOffset * 2, circleOffset * 2);
+1460,1462c1474,1476
+< // p.setBrush(Qt::NoBrush);
+< // p.drawEllipse(x - (innerCompass + 5), y - (innerCompass + 5), (innerCompass + 5) * 2, (innerCompass + 5) * 2);
+< // p.drawEllipse(x - degreeLabelOffset, y - degreeLabelOffset, degreeLabelOffset * 2, degreeLabelOffset * 2);
+---
+> p.setBrush(Qt::NoBrush);
+> p.drawEllipse(x - (innerCompass + 5), y - (innerCompass + 5), (innerCompass + 5) * 2, (innerCompass + 5) * 2);
+> p.drawEllipse(x - degreeLabelOffset, y - degreeLabelOffset, degreeLabelOffset * 2, degreeLabelOffset * 2);
+1464,1467c1478,1481
+< // QPainterPath outerCircle, innerCircle;
+< // outerCircle.addEllipse(x - degreeLabelOffset, y - degreeLabelOffset, degreeLabelOffset * 2, degreeLabelOffset * 2);
+< // innerCircle.addEllipse(x - circleOffset, y - circleOffset, compassSize, compassSize);
+< // p.fillPath(outerCircle.subtracted(innerCircle), Qt::black);
+---
+> QPainterPath outerCircle, innerCircle;
+> outerCircle.addEllipse(x - degreeLabelOffset, y - degreeLabelOffset, degreeLabelOffset * 2, degreeLabelOffset * 2);
+> innerCircle.addEllipse(x - circleOffset, y - circleOffset, compassSize, compassSize);
+> p.fillPath(outerCircle.subtracted(innerCircle), Qt::black);
+1471,1474c1485,1488
+< // if (bearingDeg != scene.bearing_deg) {
+< // update();
+< // bearingDeg = scene.bearing_deg;
+< // }
+---
+> if (bearingDeg != scene.bearing_deg) {
+> update();
+> bearingDeg = scene.bearing_deg;
+> }
+1478,1479c1492,1493
+< // QPainter p(this);
+< // p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+---
+> QPainter p(this);
+> p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+1481,1537c1495,1551
+< // bearingDeg = fmod(bearingDeg, 360);
+< // if (bearingDeg < 0) {
+< // bearingDeg += 360;
+< // }
+<
+< // p.drawPixmap(0, 0, staticElements);
+<
+< // p.translate(x, y);
+< // p.rotate(bearingDeg);
+< // p.drawPixmap(-compassInnerImg.width() / 2, -compassInnerImg.height() / 2, compassInnerImg);
+< // p.rotate(-bearingDeg);
+< // p.translate(-x, -y);
+<
+< // QFont font = InterFont(10, QFont::Normal);
+< // for (int i = 0; i < 360; i += 15) {
+< // bool isBold = abs(i - bearingDeg) <= 7;
+< // font.setWeight(isBold ? QFont::Bold : QFont::Normal);
+< // p.setFont(font);
+< // p.setPen(QPen(Qt::white, i % 90 == 0 ? 2 : 1));
+<
+< // p.save();
+< // p.translate(x, y);
+< // p.rotate(i);
+< // p.drawLine(0, -(compassSize / 2 - (i % 90 == 0 ? 12 : 8)), 0, -(compassSize / 2));
+< // p.translate(0, -(compassSize / 2 + 12));
+< // p.rotate(-i);
+< // p.drawText(QRect(-20, -10, 40, 20), Qt::AlignCenter, QString::number(i));
+< // p.restore();
+< // }
+<
+< // p.setFont(InterFont(20, QFont::Bold));
+< // std::map, int, QColor>> directionInfo = {
+< // {"N", {{292.5, 67.5}, Qt::AlignTop | Qt::AlignHCenter, Qt::white}},
+< // {"E", {{22.5, 157.5}, Qt::AlignRight | Qt::AlignVCenter, Qt::white}},
+< // {"S", {{112.5, 247.5}, Qt::AlignBottom | Qt::AlignHCenter, Qt::white}},
+< // {"W", {{202.5, 337.5}, Qt::AlignLeft | Qt::AlignVCenter, Qt::white}}
+< // };
+< // int directionOffset = 20;
+<
+< // for (auto &item : directionInfo) {
+< // QString direction = item.first;
+< // auto &[range, alignmentFlag, color] = item.second;
+< // auto &[minRange, maxRange] = range;
+<
+< // QRect textRect(x - innerCompass + directionOffset, y - innerCompass + directionOffset, innerCompass * 2 - 2 * directionOffset, innerCompass * 2 - 2 * directionOffset);
+<
+< // bool isInRange = false;
+< // if (minRange > maxRange) {
+< // isInRange = bearingDeg >= minRange || bearingDeg <= maxRange;
+< // } else {
+< // isInRange = bearingDeg >= minRange && bearingDeg <= maxRange;
+< // }
+<
+< // p.setOpacity(isInRange ? 1.0 : 0.2);
+< // p.setPen(QPen(color));
+< // p.drawText(textRect, alignmentFlag, direction);
+< // }
+---
+> bearingDeg = fmod(bearingDeg, 360);
+> if (bearingDeg < 0) {
+> bearingDeg += 360;
+> }
+>
+> p.drawPixmap(0, 0, staticElements);
+>
+> p.translate(x, y);
+> p.rotate(bearingDeg);
+> p.drawPixmap(-compassInnerImg.width() / 2, -compassInnerImg.height() / 2, compassInnerImg);
+> p.rotate(-bearingDeg);
+> p.translate(-x, -y);
+>
+> QFont font = InterFont(10, QFont::Normal);
+> for (int i = 0; i < 360; i += 15) {
+> bool isBold = abs(i - bearingDeg) <= 7;
+> font.setWeight(isBold ? QFont::Bold : QFont::Normal);
+> p.setFont(font);
+> p.setPen(QPen(Qt::white, i % 90 == 0 ? 2 : 1));
+>
+> p.save();
+> p.translate(x, y);
+> p.rotate(i);
+> p.drawLine(0, -(compassSize / 2 - (i % 90 == 0 ? 12 : 8)), 0, -(compassSize / 2));
+> p.translate(0, -(compassSize / 2 + 12));
+> p.rotate(-i);
+> p.drawText(QRect(-20, -10, 40, 20), Qt::AlignCenter, QString::number(i));
+> p.restore();
+> }
+>
+> p.setFont(InterFont(20, QFont::Bold));
+> std::map, int, QColor>> directionInfo = {
+> {"N", {{292.5, 67.5}, Qt::AlignTop | Qt::AlignHCenter, Qt::white}},
+> {"E", {{22.5, 157.5}, Qt::AlignRight | Qt::AlignVCenter, Qt::white}},
+> {"S", {{112.5, 247.5}, Qt::AlignBottom | Qt::AlignHCenter, Qt::white}},
+> {"W", {{202.5, 337.5}, Qt::AlignLeft | Qt::AlignVCenter, Qt::white}}
+> };
+> int directionOffset = 20;
+>
+> for (auto &item : directionInfo) {
+> QString direction = item.first;
+> auto &[range, alignmentFlag, color] = item.second;
+> auto &[minRange, maxRange] = range;
+>
+> QRect textRect(x - innerCompass + directionOffset, y - innerCompass + directionOffset, innerCompass * 2 - 2 * directionOffset, innerCompass * 2 - 2 * directionOffset);
+>
+> bool isInRange = false;
+> if (minRange > maxRange) {
+> isInRange = bearingDeg >= minRange || bearingDeg <= maxRange;
+> } else {
+> isInRange = bearingDeg >= minRange && bearingDeg <= maxRange;
+> }
+>
+> p.setOpacity(isInRange ? 1.0 : 0.2);
+> p.setPen(QPen(color));
+> p.drawText(textRect, alignmentFlag, direction);
+> }
+1541c1555,1562
+< // setFixedSize(btn_size * 1.5, btn_size * 1.5);
+---
+> setFixedSize(btn_size * 1.5, btn_size * 1.5);
+>
+> profile_data = {
+> {QPixmap("../frogpilot/assets/other_images/traffic.png"), "Traffic"},
+> {QPixmap("../frogpilot/assets/other_images/aggressive.png"), "Aggressive"},
+> {QPixmap("../frogpilot/assets/other_images/standard.png"), "Standard"},
+> {QPixmap("../frogpilot/assets/other_images/relaxed.png"), "Relaxed"}
+> };
+1543,1555c1564,1569
+< // profile_data = {
+< // {QPixmap("../frogpilot/assets/other_images/traffic.png"), "Traffic"},
+< // {QPixmap("../frogpilot/assets/other_images/aggressive.png"), "Aggressive"},
+< // {QPixmap("../frogpilot/assets/other_images/standard.png"), "Standard"},
+< // {QPixmap("../frogpilot/assets/other_images/relaxed.png"), "Relaxed"}
+< // };
+<
+< // profile_data_kaofui = {
+< // {QPixmap("../frogpilot/assets/other_images/traffic_kaofui.png"), "Traffic"},
+< // {QPixmap("../frogpilot/assets/other_images/aggressive_kaofui.png"), "Aggressive"},
+< // {QPixmap("../frogpilot/assets/other_images/standard_kaofui.png"), "Standard"},
+< // {QPixmap("../frogpilot/assets/other_images/relaxed_kaofui.png"), "Relaxed"}
+< // };
+---
+> profile_data_kaofui = {
+> {QPixmap("../frogpilot/assets/other_images/traffic_kaofui.png"), "Traffic"},
+> {QPixmap("../frogpilot/assets/other_images/aggressive_kaofui.png"), "Aggressive"},
+> {QPixmap("../frogpilot/assets/other_images/standard_kaofui.png"), "Standard"},
+> {QPixmap("../frogpilot/assets/other_images/relaxed_kaofui.png"), "Relaxed"}
+> };
+1557c1571
+< // transitionTimer.start();
+---
+> transitionTimer.start();
+1559,1560c1573,1574
+< // connect(this, &QPushButton::pressed, this, &DistanceButton::buttonPressed);
+< // connect(this, &QPushButton::released, this, &DistanceButton::buttonReleased);
+---
+> connect(this, &QPushButton::pressed, this, &DistanceButton::buttonPressed);
+> connect(this, &QPushButton::released, this, &DistanceButton::buttonReleased);
+1564c1578
+< // paramsMemory.putBool("OnroadDistanceButtonPressed", true);
+---
+> paramsMemory.putBool("OnroadDistanceButtonPressed", true);
+1568c1582
+< // paramsMemory.putBool("OnroadDistanceButtonPressed", false);
+---
+> paramsMemory.putBool("OnroadDistanceButtonPressed", false);
+1572,1574c1586,1588
+< // if (trafficModeActive != scene.traffic_mode_active || personality != static_cast(scene.personality) && !trafficModeActive) {
+< // transitionTimer.restart();
+< // }
+---
+> if (trafficModeActive != scene.traffic_mode_active || personality != static_cast(scene.personality) && !trafficModeActive) {
+> transitionTimer.restart();
+> }
+1576c1590
+< // personality = static_cast(scene.personality);
+---
+> personality = static_cast(scene.personality);
+1581,1582c1595,1606
+< // QPainter p(this);
+< // p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+---
+> QPainter p(this);
+> p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
+>
+> constexpr qreal fadeDuration = 1000.0;
+> constexpr qreal textDuration = 3000.0;
+> int elapsed = transitionTimer.elapsed();
+>
+> qreal textOpacity = qBound(0.0, 1.0 - ((elapsed - textDuration) / fadeDuration), 1.0);
+> qreal imageOpacity = qBound(0.0, (elapsed - textDuration) / fadeDuration, 1.0);
+>
+> int profile = trafficModeActive ? 0 : personality + 1;
+> auto &[profileImage, profileText] = scene.use_kaofui_icons ? profile_data_kaofui[profile] : profile_data[profile];
+1584,1604c1608,1618
+< // constexpr qreal fadeDuration = 1000.0;
+< // constexpr qreal textDuration = 3000.0;
+< // int elapsed = transitionTimer.elapsed();
+<
+< // qreal textOpacity = qBound(0.0, 1.0 - ((elapsed - textDuration) / fadeDuration), 1.0);
+< // qreal imageOpacity = qBound(0.0, (elapsed - textDuration) / fadeDuration, 1.0);
+<
+< // int profile = trafficModeActive ? 0 : personality + 1;
+< // auto &[profileImage, profileText] = scene.use_kaofui_icons ? profile_data_kaofui[profile] : profile_data[profile];
+<
+< // if (textOpacity != 0.0) {
+< // p.setOpacity(textOpacity);
+< // p.setFont(InterFont(40, QFont::Bold));
+< // p.setPen(Qt::white);
+< // QRect textRect(-25, 0, width(), height() + 95);
+< // p.drawText(textRect, Qt::AlignCenter, profileText);
+< // }
+<
+< // if (imageOpacity != 0.0) {
+< // drawIcon(p, QPoint((btn_size / 2) * 1.25, btn_size / 2 + 95), profileImage, Qt::transparent, imageOpacity);
+< // }
+---
+> if (textOpacity != 0.0) {
+> p.setOpacity(textOpacity);
+> p.setFont(InterFont(40, QFont::Bold));
+> p.setPen(Qt::white);
+> QRect textRect(-25, 0, width(), height() + 95);
+> p.drawText(textRect, Qt::AlignCenter, profileText);
+> }
+>
+> if (imageOpacity != 0.0) {
+> drawIcon(p, QPoint((btn_size / 2) * 1.25, btn_size / 2 + 95), profileImage, Qt::transparent, imageOpacity);
+> }
+1729c1743
+< // acceleration = scene.acceleration;
+---
+> acceleration = scene.acceleration;
+1731,1732c1745,1746
+< // accelerating = acceleration > 0.25;
+< // decelerating = acceleration < -0.25;
+---
+> accelerating = acceleration > 0.25;
+> decelerating = acceleration < -0.25;
+1734,1736c1748,1750
+< // if (accelerating || decelerating) {
+< // update();
+< // }
+---
+> if (accelerating || decelerating) {
+> update();
+> }
+1740,1741c1754,1755
+< // QPainter p(this);
+< // p.setRenderHint(QPainter::Antialiasing);
+---
+> QPainter p(this);
+> p.setRenderHint(QPainter::Antialiasing);
+1743,1744c1757,1758
+< // int totalWidth = 2 * img_size;
+< // int startX = (width() - totalWidth) / 2;
+---
+> int totalWidth = 2 * img_size;
+> int startX = (width() - totalWidth) / 2;
+1746,1747c1760,1761
+< // int brakeX = startX + img_size / 2;
+< // int gasX = startX + img_size;
+---
+> int brakeX = startX + img_size / 2;
+> int gasX = startX + img_size;
+1749,1750c1763,1764
+< // float brakeOpacity = scene.standstill ? 1.0f : decelerating ? std::max(0.25f, std::abs(acceleration)) : 0.25f;
+< // float gasOpacity = accelerating ? std::max(0.25f, acceleration) : 0.25f;
+---
+> float brakeOpacity = scene.standstill ? 1.0f : decelerating ? std::max(0.25f, std::abs(acceleration)) : 0.25f;
+> float gasOpacity = accelerating ? std::max(0.25f, acceleration) : 0.25f;
+1752,1753c1766,1767
+< // p.setOpacity(brakeOpacity);
+< // p.drawPixmap(brakeX, (height() - img_size) / 2, brake_pedal_img);
+---
+> p.setOpacity(brakeOpacity);
+> p.drawPixmap(brakeX, (height() - img_size) / 2, brake_pedal_img);
+1755,1756c1769,1770
+< // p.setOpacity(gasOpacity);
+< // p.drawPixmap(gasX, (height() - img_size) / 2, gas_pedal_img);
+---
+> p.setOpacity(gasOpacity);
+> p.drawPixmap(gasX, (height() - img_size) / 2, gas_pedal_img);
+diff -r clearpilot/selfdrive/ui/qt/onroad.h FrogPilot/selfdrive/ui/qt/onroad.h
+53,59c53,59
+< // int bearingDeg;
+< // int circleOffset;
+< // int compassSize;
+< // int degreeLabelOffset;
+< // int innerCompass;
+< // int x;
+< // int y;
+---
+> int bearingDeg;
+> int circleOffset;
+> int compassSize;
+> int degreeLabelOffset;
+> int innerCompass;
+> int x;
+> int y;
+83c83
+< // int personality;
+---
+> int personality;
+Only in clearpilot/selfdrive/ui/qt: ready.cc
+Only in clearpilot/selfdrive/ui/qt: ready.h
+diff -r clearpilot/selfdrive/ui/qt/sidebar.cc FrogPilot/selfdrive/ui/qt/sidebar.cc
+79,81c79,81
+< {1, {"frog_theme", {QColor(255, 255, 255)}}},
+< {2, {"tesla_theme", {QColor(255, 255, 255)}}},
+< {3, {"stalin_theme", {QColor(255, 255, 255)}}}
+---
+> {1, {"frog_theme", {QColor(23, 134, 68)}}},
+> {2, {"tesla_theme", {QColor(0, 72, 255)}}},
+> {3, {"stalin_theme", {QColor(255, 0, 0)}}}
+Only in clearpilot/selfdrive/ui/qt: spinner
+diff -r clearpilot/selfdrive/ui/qt/util.cc FrogPilot/selfdrive/ui/qt/util.cc
+29c29
+< return QObject::tr("ClearPilot");
+---
+> return QObject::tr("FrogPilot");
+diff -r clearpilot/selfdrive/ui/qt/widgets/drive_stats.cc FrogPilot/selfdrive/ui/qt/widgets/drive_stats.cc
+71,72c71,72
+< labels.routes->setText(QString::number(paramsStorage.getInt("FrogPilotDrives")));
+< labels.distance->setText(QString::number(int(paramsStorage.getFloat("FrogPilotKilometers") * (metric_ ? 1 : KM_TO_MILE))));
+---
+> labels.routes->setText(QString::number(params.getInt("FrogPilotDrives")));
+> labels.distance->setText(QString::number(int(params.getFloat("FrogPilotKilometers") * (metric_ ? 1 : KM_TO_MILE))));
+74c74
+< labels.hours->setText(QString::number(int(paramsStorage.getFloat("FrogPilotMinutes") / 60)));
+---
+> labels.hours->setText(QString::number(int(params.getFloat("FrogPilotMinutes") / 60)));
+diff -r clearpilot/selfdrive/ui/qt/widgets/drive_stats.h FrogPilot/selfdrive/ui/qt/widgets/drive_stats.h
+21d20
+< Params paramsStorage{"/persist/params"};
+diff -r clearpilot/selfdrive/ui/SConscript FrogPilot/selfdrive/ui/SConscript
+42d41
+< # CLEARPILOT added qt/ready.cc
+47,48c46
+< "../frogpilot/screenrecorder/omx_encoder.cc", "../frogpilot/screenrecorder/screenrecorder.cc",
+< "qt/ready.cc"]
+---
+> "../frogpilot/screenrecorder/omx_encoder.cc", "../frogpilot/screenrecorder/screenrecorder.cc"]
+83,85d80
+<
+< # Clearpilot tools
+< qt_env.Program("/data/openpilot/system/clearpilot/tools/qt_shell", ["/data/openpilot/system/clearpilot/tools/qt_shell.cc"], LIBS=qt_libs)
+diff -r clearpilot/selfdrive/ui/soundd.py FrogPilot/selfdrive/ui/soundd.py
+253,262c253,259
+< # Clearpilot: Impl theme switcher
+< # if current_holiday_theme != 0:
+< # theme_name = holiday_theme_configuration.get(current_holiday_theme)
+< # self.sound_directory = BASEDIR + ("/selfdrive/frogpilot/assets/holiday_themes/" + theme_name + "/sounds/")
+< # self.goat_scream = False
+< # else:
+< # theme_name = theme_configuration.get(custom_sounds)
+< # self.sound_directory = BASEDIR + ("/selfdrive/clearpilot/theme/" + theme_name + "/sounds/" if custom_sounds != 0 else "/selfdrive/assets/sounds/")
+<
+< self.sound_directory = BASEDIR + ("/selfdrive/clearpilot/theme/clearpilot/sounds/" if custom_sounds != 0 else "/selfdrive/assets/sounds/")
+---
+> if current_holiday_theme != 0:
+> theme_name = holiday_theme_configuration.get(current_holiday_theme)
+> self.sound_directory = BASEDIR + ("/selfdrive/frogpilot/assets/holiday_themes/" + theme_name + "/sounds/")
+> self.goat_scream = False
+> else:
+> theme_name = theme_configuration.get(custom_sounds)
+> self.sound_directory = BASEDIR + ("/selfdrive/frogpilot/assets/custom_themes/" + theme_name + "/sounds/" if custom_sounds != 0 else "/selfdrive/assets/sounds/")
+diff -r clearpilot/selfdrive/ui/spinner FrogPilot/selfdrive/ui/spinner
+3,4c3,4
+< if [ -f /TICI ] && [ ! -f qt/spinner ]; then
+< cp qt/spinner_larch64 qt/spinner
+---
+> if [ -f /TICI ] && [ ! -f _spinner ]; then
+> cp qt/spinner_larch64 _spinner
+7c7
+< exec ./qt/spinner "$1"
+---
+> exec ./_spinner "$1"
+diff -r clearpilot/selfdrive/ui/translations/main_ar.ts FrogPilot/selfdrive/ui/translations/main_ar.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+734,737d364
+<
+< Manage at %1
+<
+<
+940c567
+< openpilot
+---
+> openpilot
+991,994d617
+<
+< ClearPilot
+<
+<
+1041c664
+< ×
+---
+> ×
+1059,1078d681
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1272,1295d874
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1317c896
+< يتم تحميل التحديثات فقط عندما تكون السيارة متوقفة.
+---
+> يتم تحميل التحديثات فقط عندما تكون السيارة متوقفة.
+1371,1394d949
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< عرض
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1656,1663d1210
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/selfdrive/ui/translations/main_de.ts FrogPilot/selfdrive/ui/translations/main_de.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+730,733d360
+<
+< Manage at %1
+<
+<
+935c562
+< openpilot
+---
+> openpilot
+974,977d600
+<
+< ClearPilot
+<
+<
+1023c646
+< x
+---
+> x
+1041,1060d663
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1255,1278d857
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1301c880
+< Updates werden nur heruntergeladen, wenn das Auto aus ist.
+---
+> Updates werden nur heruntergeladen, wenn das Auto aus ist.
+1355,1378d933
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< ANSEHEN
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1641,1648d1195
+<
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+diff -r clearpilot/selfdrive/ui/translations/main_fr.ts FrogPilot/selfdrive/ui/translations/main_fr.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+730,733d360
+<
+< Manage at %1
+<
+<
+936c563
+< openpilot
+---
+> openpilot
+975,978d601
+<
+< ClearPilot
+<
+<
+1025c648
+< ×
+---
+> ×
+1043,1062d665
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1256,1279d858
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1285c864
+< Les MàJ sont téléchargées uniquement si la voiture est éteinte.
+---
+> Les MàJ sont téléchargées uniquement si la voiture est éteinte.
+1355,1378d933
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< VOIR
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1640,1647d1194
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/selfdrive/ui/translations/main_ja.ts FrogPilot/selfdrive/ui/translations/main_ja.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+729,732d359
+<
+< Manage at %1
+<
+<
+934c561
+< openpilot
+---
+> openpilot
+970,973d596
+<
+< ClearPilot
+<
+<
+1019c642
+< ×
+---
+> ×
+1037,1056d659
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1250,1273d852
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1279c858
+< 車の電源がオフの間のみ、アップデートのダウンロードが行われます。
+---
+> 車の電源がオフの間のみ、アップデートのダウンロードが行われます。
+1349,1372d927
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< FrogPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< 見る
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1633,1640d1187
+<
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+diff -r clearpilot/selfdrive/ui/translations/main_ko.ts FrogPilot/selfdrive/ui/translations/main_ko.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+729,732d359
+<
+< Manage at %1
+<
+<
+935c562
+< openpilot
+---
+> openpilot
+971,974d597
+<
+< ClearPilot
+<
+<
+1021c644
+< ×
+---
+> ×
+1039,1058d661
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1252,1275d854
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1281c860
+< 업데이트는 차량 시동이 꺼졌을 때 다운로드됩니다.
+---
+> 업데이트는 차량 시동이 꺼졌을 때 다운로드됩니다.
+1351,1374d929
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< 보기
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1636,1643d1190
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/selfdrive/ui/translations/main_pt-BR.ts FrogPilot/selfdrive/ui/translations/main_pt-BR.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+730,733d360
+<
+< Manage at %1
+<
+<
+936c563
+< openpilot
+---
+> openpilot
+975,978d601
+<
+< ClearPilot
+<
+<
+1025c648
+< ×
+---
+> ×
+1043,1062d665
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1256,1279d858
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1285c864
+< Atualizações baixadas durante o motor desligado.
+---
+> Atualizações baixadas durante o motor desligado.
+1355,1378d933
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< VER
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1640,1647d1194
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/selfdrive/ui/translations/main_th.ts FrogPilot/selfdrive/ui/translations/main_th.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+729,732d359
+<
+< Manage at %1
+<
+<
+935c562
+< openpilot
+---
+> openpilot
+971,974d597
+<
+< ClearPilot
+<
+<
+1021c644
+< ×
+---
+> ×
+1039,1058d661
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1252,1275d854
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1297c876
+< ตัวอัปเดตจะดำเนินการดาวน์โหลดเมื่อรถดับเครื่องยนต์อยู่เท่านั้น
+---
+> ตัวอัปเดตจะดำเนินการดาวน์โหลดเมื่อรถดับเครื่องยนต์อยู่เท่านั้น
+1351,1374d929
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< ดู
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1636,1643d1190
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/selfdrive/ui/translations/main_tr.ts FrogPilot/selfdrive/ui/translations/main_tr.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+729,732d359
+<
+< Manage at %1
+<
+<
+934c561
+< openpilot
+---
+> openpilot
+970,973d596
+<
+< ClearPilot
+<
+<
+1019c642
+< x
+---
+> x
+1037,1056d659
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1250,1273d852
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1293a873,876
+> Updates are only downloaded while the car is off.
+>
+>
+>
+1345,1368d927
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< BAK
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1629,1636d1187
+<
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+diff -r clearpilot/selfdrive/ui/translations/main_zh-CHS.ts FrogPilot/selfdrive/ui/translations/main_zh-CHS.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+729,732d359
+<
+< Manage at %1
+<
+<
+935c562
+< openpilot
+---
+> openpilot
+971,974d597
+<
+< ClearPilot
+<
+<
+1021c644
+< ×
+---
+> ×
+1039,1058d661
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1252,1275d854
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1281c860
+< 车辆熄火时才能下载升级文件。
+---
+> 车辆熄火时才能下载升级文件。
+1351,1374d929
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< 查看
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1636,1643d1190
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/selfdrive/ui/translations/main_zh-CHT.ts FrogPilot/selfdrive/ui/translations/main_zh-CHT.ts
+18,21d17
+<
+< Disable Internet Check
+<
+<
+116,289d111
+<
+< meters
+<
+<
+<
+< feet
+<
+<
+<
+< Vehicle in blind spot
+<
+<
+<
+< m/s²
+<
+<
+<
+< m/s
+<
+<
+<
+< kph
+<
+<
+<
+< ft/s²
+<
+<
+<
+< Accel: %1%2
+<
+<
+<
+< - Max: %1%2
+<
+<
+<
+< | Obstacle:
+<
+<
+<
+< | Obstacle Factor:
+<
+<
+<
+< - Stop:
+<
+<
+<
+< - Stop Factor:
+<
+<
+<
+< Follow:
+<
+<
+<
+< Follow Distance:
+<
+<
+<
+< Confirm speed limit
+<
+<
+<
+<
+< Ignore speed limit
+<
+<
+<
+<
+< Conditional Experimental Mode ready
+<
+<
+<
+< Conditional Experimental overridden
+<
+<
+<
+< Experimental Mode manually activated
+<
+<
+<
+< Experimental Mode activated for
+<
+<
+<
+< intersection
+<
+<
+<
+< upcoming intersection
+<
+<
+<
+< turn
+<
+<
+<
+< upcoming turn
+<
+<
+<
+< Experimental Mode activated due to
+<
+<
+<
+< SLC
+<
+<
+<
+< no speed limit set
+<
+<
+<
+< speed
+<
+<
+<
+< speed being less than
+<
+<
+<
+< kph
+<
+<
+<
+< mph
+<
+<
+<
+< Experimental Mode activated for slower lead
+<
+<
+<
+< Experimental Mode activated for turn
+<
+<
+<
+< / lane change
+<
+<
+<
+< Experimental Mode activated for curve
+<
+<
+<
+< Experimental Mode activated for stop
+<
+<
+<
+< sign / stop light
+<
+<
+<
+< Always On Lateral active
+<
+<
+<
+< . Press the "Cruise Control" button to disable
+<
+<
+<
+< . Long press the "distance" button to revert
+<
+<
+<
+< . Double press the "LKAS" button to revert
+<
+<
+<
+< . Double tap the screen to revert
+<
+<
+474,664d295
+<
+< Delete Driving Data
+<
+<
+<
+< DELETE
+<
+<
+<
+< This button provides a swift and secure way to permanently delete all stored driving footage and data from your device. Ideal for maintaining privacy or freeing up space.
+<
+<
+<
+< Are you sure you want to permanently delete all of your driving footage and data?
+<
+<
+<
+< Delete
+<
+<
+<
+< Deleting footage...
+<
+<
+<
+< Deleted!
+<
+<
+<
+< Flash Panda
+<
+<
+<
+< FLASH
+<
+<
+<
+< Use this button to troubleshoot and update the Panda device's firmware.
+<
+<
+<
+< Are you sure you want to flash the Panda?
+<
+<
+<
+< Flash
+<
+<
+<
+< Flashing...
+<
+<
+<
+< Reset Toggle Settings
+<
+<
+<
+< Reset your toggle settings back to default.
+<
+<
+<
+< Are you sure you want to completely reset your toggle settings? This is irreversible!
+<
+<
+<
+< Resetting toggles...
+<
+<
+<
+< Backup
+<
+<
+<
+< Restore
+<
+<
+<
+< FrogPilot Backups
+<
+<
+<
+< Backup, delete, or restore your FrogPilot backups.
+<
+<
+<
+< Name your backup
+<
+<
+<
+< Backing up...
+<
+<
+<
+< Success!
+<
+<
+<
+< Failed...
+<
+<
+<
+< Select a backup to delete
+<
+<
+<
+< Are you sure you want to delete this backup?
+<
+<
+<
+< Deleting...
+<
+<
+<
+< Select a restore point
+<
+<
+<
+< Are you sure you want to restore this version of FrogPilot?
+<
+<
+<
+< Restoring...
+<
+<
+<
+< Toggle Backups
+<
+<
+<
+< Backup, delete, or restore your toggle backups.
+<
+<
+<
+< Are you sure you want to restore this toggle backup?
+<
+<
+<
+< Lock Doors
+<
+<
+<
+< LOCK
+<
+<
+<
+< Use this button to lock the doors on Toyota/Lexus vehicles.
+<
+<
+<
+< Soft Reboot
+<
+<
+<
+< Are you sure you want to soft reboot?
+<
+<
+<
+< Disengage to Soft Reboot
+<
+<
+<
+<
+< DriveStats
+<
+< Drives
+<
+<
+<
+< Hours
+<
+<
+<
+< ALL TIME
+<
+<
+<
+< PAST WEEK
+<
+<
+<
+< FROGPILOT
+<
+<
+<
+< KM
+<
+<
+<
+< Miles
+<
+<
+729,732d359
+<
+< Manage at %1
+<
+<
+935c562
+< openpilot
+---
+> openpilot
+971,974d597
+<
+< ClearPilot
+<
+<
+1021c644
+< ×
+---
+> ×
+1039,1058d661
+<
+< ← Back
+<
+<
+<
+< Controls
+<
+<
+<
+< Navigation
+<
+<
+<
+< Vehicles
+<
+<
+<
+< Visuals
+<
+<
+1252,1275d854
+<
+< GPU
+<
+<
+<
+< CPU
+<
+<
+<
+< GB
+<
+<
+<
+< MEMORY
+<
+<
+<
+< LEFT
+<
+<
+<
+< USED
+<
+<
+1281c860
+< 系統更新只會在熄火時下載。
+---
+> 系統更新只會在熄火時下載。
+1351,1374d929
+<
+< Updates are only downloaded while the car is off or in park.
+<
+<
+<
+< Automatically Update ClearPilot
+<
+<
+<
+< ClearPilot will automatically update itself and it's assets when you're offroad and connected to Wi-Fi.
+<
+<
+<
+< Error Log
+<
+<
+<
+< VIEW
+< 觀看
+<
+<
+< View the error log for openpilot crashes.
+<
+<
+1636,1643d1190
+<
+<
+< Uploading disabled
+<
+<
+<
+< Toggle off the 'Disable Uploading' toggle to enable uploads.
+<
+diff -r clearpilot/selfdrive/ui/ui.cc FrogPilot/selfdrive/ui/ui.cc
+361,363c361,362
+< // CLEARPILOT
+< scene.lane_line_width = /* params.getInt("LaneLinesWidth") */ 2 * (scene.is_metric ? 1.0f : INCH_TO_CM) / 200.0f;
+< scene.path_edge_width = /* params.getInt("PathEdgeWidth"); */ 16;
+---
+> scene.lane_line_width = params.getInt("LaneLinesWidth") * (scene.is_metric ? 1.0f : INCH_TO_CM) / 200.0f;
+> scene.path_edge_width = params.getInt("PathEdgeWidth");
+394c393
+< scene.screen_timeout = screen_management ? params.getInt("ScreenTimeout") : 120;
+---
+> scene.screen_timeout = screen_management ? params.getInt("ScreenTimeout") : 30;
+diff -r clearpilot/selfdrive/ui/ui.h FrogPilot/selfdrive/ui/ui.h
+21c21
+< const int UI_BORDER_SIZE = 16; // clearpilot
+---
+> const int UI_BORDER_SIZE = 30;
+29c29
+< const float MAX_DRAW_DISTANCE = 100.0;
+---
+> const float MAX_DRAW_DISTANCE = 100.0;
+109a110,120
+> typedef enum UIStatus {
+> STATUS_DISENGAGED,
+> STATUS_OVERRIDE,
+> STATUS_ENGAGED,
+>
+> // FrogPilot statuses
+> STATUS_ALWAYS_ON_LATERAL_ACTIVE,
+> STATUS_TRAFFIC_MODE_ACTIVE,
+>
+> } UIStatus;
+>
+119,128d129
+<
+< // Clearpilot redefined these.
+< typedef enum UIStatus {
+< STATUS_DISENGAGED,
+< STATUS_OVERRIDE,
+< STATUS_ENGAGED,
+< STATUS_ALWAYS_ON_LATERAL_ACTIVE,
+< STATUS_TRAFFIC_MODE_ACTIVE,
+< STATUS_EXPERIMENTAL_ACTIVE,
+< } UIStatus;
+130d130
+< // Clearpilot custom colors
+133,137c133,138
+< [STATUS_OVERRIDE] = QColor(64, 85, 245, 0xd1), // When you nudge the steering wheel while engaged
+< [STATUS_ENGAGED] = QColor(64, 85, 245, 0xd1), // Orange
+< [STATUS_ALWAYS_ON_LATERAL_ACTIVE] = QColor(162, 221, 235, 0xd1), // Gray
+< [STATUS_TRAFFIC_MODE_ACTIVE] = QColor(0xc9, 0x22, 0x31, 0xd1), // ? unused?
+< [STATUS_EXPERIMENTAL_ACTIVE] = QColor(201, 41, 204, 0xd1), // Magenta
+---
+> [STATUS_OVERRIDE] = QColor(0x91, 0x9b, 0x95, 0xf1),
+> [STATUS_ENGAGED] = QColor(0x17, 0x86, 0x44, 0xf1),
+>
+> // FrogPilot colors
+> [STATUS_ALWAYS_ON_LATERAL_ACTIVE] = QColor(0x0a, 0xba, 0xb5, 0xf1),
+> [STATUS_TRAFFIC_MODE_ACTIVE] = QColor(0xc9, 0x22, 0x31, 0xf1),
+142c143
+< {cereal::ControlsState::AlertStatus::USER_PROMPT, QColor(4, 64, 11, 0xf1)}, // CLEARPILOT changed to a shade of dark blue
+---
+> {cereal::ControlsState::AlertStatus::USER_PROMPT, QColor(0xDA, 0x6F, 0x25, 0xf1)},
+144c145
+< {cereal::ControlsState::AlertStatus::FROGPILOT, QColor(47, 158, 238, 0xf1)}, // CLEARPILOT changed to light blue
+---
+> {cereal::ControlsState::AlertStatus::FROGPILOT, QColor(0x17, 0x86, 0x44, 0xf1)},
+diff -r clearpilot/selfdrive/updated/updated.py FrogPilot/selfdrive/updated/updated.py
+89,90d88
+< # CLEARPILOT
+< return b""
+134,135c132
+< # CLEARPILOT
+< return
+---
+>
+Only in clearpilot/system: clearpilot
+diff -r clearpilot/system/hardware/base.h FrogPilot/system/hardware/base.h
+29d28
+< static void soft_reboot() {}
+diff -r clearpilot/system/hardware/base.py FrogPilot/system/hardware/base.py
+33,36d32
+< def soft_reboot(self):
+< pass
+<
+< @abstractmethod
+diff -r clearpilot/system/hardware/pc/hardware.py FrogPilot/system/hardware/pc/hardware.py
+23,25d22
+< def soft_reboot(self):
+< print("SOFT REBOOT!")
+<
+diff -r clearpilot/system/hardware/tici/hardware.h FrogPilot/system/hardware/tici/hardware.h
+53,69d52
+< static void soft_reboot() {
+< const std::vector commands = {
+< "rm -f /tmp/safe_staging_overlay.lock",
+< "tmux new -s commatmp -d '/data/continue.sh'",
+< "tmux kill-session -t comma",
+< "tmux rename comma"
+< };
+< for (const auto& cmd : commands) {
+< int result;
+< do {
+< result = std::system(cmd.c_str());
+< } while (result != 0);
+< if (result != 0) {
+< reboot();
+< }
+< }
+< }
+diff -r clearpilot/system/hardware/tici/hardware.py FrogPilot/system/hardware/tici/hardware.py
+135,144d134
+< def soft_reboot(self):
+< commands = [
+< ['rm', '-f', '/tmp/safe_staging_overlay.lock'],
+< ['tmux', 'new', '-s', 'commatmp', '-d', '/data/continue.sh'],
+< ['tmux', 'kill-session', '-t', 'comma'],
+< ['tmux', 'rename', 'comma'],
+< ]
+< for command in commands:
+< subprocess.run(command, stderr=subprocess.DEVNULL, stdout=subprocess.DEVNULL)
+<
+diff -r clearpilot/system/loggerd/uploader.py FrogPilot/system/loggerd/uploader.py
+17d16
+< import openpilot.selfdrive.sentry as sentry
+255,256c254
+< openpilot_crashed = os.path.isfile(os.path.join(sentry.CRASHES_DIR, 'error.txt'))
+< if network_type == NetworkType.none or not at_home or openpilot_crashed:
+---
+> if network_type == NetworkType.none or not at_home:
+diff -r clearpilot/system/qcomgpsd/nmeaport.py FrogPilot/system/qcomgpsd/nmeaport.py
+96c96
+< with open(device, "r") as nmeaport:
+---
+> with open(device) as nmeaport:
+diff -r clearpilot/system/qcomgpsd/qcomgpsd.py FrogPilot/system/qcomgpsd/qcomgpsd.py
+13c13
+< from typing import NoReturn, Optional
+---
+> from typing import NoReturn
+93c93
+< def at_cmd(cmd: str) -> Optional[str]:
+---
+> def at_cmd(cmd: str) -> str | None:
+208c208
+< def wait_for_modem():
+---
+> def wait_for_modem(cmd="AT+QGPS?"):
+211c211
+< ret = subprocess.call("mmcli -m any --timeout 10 --command=\"AT+QGPS?\"", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True)
+---
+> ret = subprocess.call(f"mmcli -m any --timeout 10 --command=\"{cmd}\"", stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL, shell=True)
+345c345
+< dt_timestamp = (datetime.datetime(1980, 1, 6, 0, 0, 0, 0, datetime.timezone.utc) +
+---
+> dt_timestamp = (datetime.datetime(1980, 1, 6, 0, 0, 0, 0, datetime.UTC) +
+355,356c355,356
+< gps.flags = 1 if gps.verticalAccuracy != 500 else 0
+< if gps.flags:
+---
+> gps.hasFix = gps.verticalAccuracy != 500
+> if gps.hasFix:
+Only in FrogPilot/system/tests: __init__.py
+Only in FrogPilot/system/tests: test_logmessaged.py
+diff -r clearpilot/system/timed.py FrogPilot/system/timed.py
+59d58
+< tf = TimezoneFinder()
+Only in FrogPilot/system: ugpsd.py
+diff -r clearpilot/system/version.py FrogPilot/system/version.py
+4c4,5
+< from typing import List, Callable, TypeVar
+---
+> from typing import TypeVar
+> from collections.abc import Callable
+21c22
+< def run_cmd(cmd: List[str]) -> str:
+---
+> def run_cmd(cmd: list[str]) -> str:
+25c26
+< def run_cmd_default(cmd: List[str], default: str = "") -> str:
+---
+> def run_cmd_default(cmd: list[str], default: str = "") -> str:
+diff -r clearpilot/system/webrtc/device/audio.py FrogPilot/system/webrtc/device/audio.py
+3d2
+< from typing import Optional, List, Tuple
+20c19
+< def __init__(self, audio_format: int = pyaudio.paInt16, rate: int = 16000, channels: int = 1, packet_time: float = 0.020, device_index: Optional[int] = None):
+---
+> def __init__(self, audio_format: int = pyaudio.paInt16, rate: int = 16000, channels: int = 1, packet_time: float = 0.020, device_index: int = None):
+52c51
+< def __init__(self, audio_format: int = pyaudio.paInt16, rate: int = 48000, channels: int = 2, packet_time: float = 0.2, device_index: Optional[int] = None):
+---
+> def __init__(self, audio_format: int = pyaudio.paInt16, rate: int = 48000, channels: int = 2, packet_time: float = 0.2, device_index: int = None):
+65c64
+< self.tracks_and_tasks: List[Tuple[aiortc.MediaStreamTrack, Optional[asyncio.Task]]] = []
+---
+> self.tracks_and_tasks: list[tuple[aiortc.MediaStreamTrack, asyncio.Task | None]] = []
+diff -r clearpilot/system/webrtc/device/video.py FrogPilot/system/webrtc/device/video.py
+2d1
+< from typing import Optional
+43c42
+< def codec_preference(self) -> Optional[str]:
+---
+> def codec_preference(self) -> str | None:
+diff -r clearpilot/system/webrtc/schema.py FrogPilot/system/webrtc/schema.py
+2c2
+< from typing import Union, List, Dict, Any
+---
+> from typing import Any
+5c5
+< def generate_type(type_walker, schema_walker) -> Union[str, List[Any], Dict[str, Any]]:
+---
+> def generate_type(type_walker, schema_walker) -> str | list[Any] | dict[str, Any]:
+18c18
+< def generate_struct(schema: capnp.lib.capnp._StructSchema) -> Dict[str, Any]:
+---
+> def generate_struct(schema: capnp.lib.capnp._StructSchema) -> dict[str, Any]:
+22c22
+< def generate_field(field: capnp.lib.capnp._StructSchemaField) -> Union[str, List[Any], Dict[str, Any]]:
+---
+> def generate_field(field: capnp.lib.capnp._StructSchemaField) -> str | list[Any] | dict[str, Any]:
+Only in FrogPilot/system/webrtc/tests: test_stream_session.py
+Only in FrogPilot/system/webrtc/tests: test_webrtcd.py
+diff -r clearpilot/system/webrtc/webrtcd.py FrogPilot/system/webrtc/webrtcd.py
+9c9
+< from typing import Any, List, Optional, Union, TYPE_CHECKING
+---
+> from typing import Any, TYPE_CHECKING
+27c27
+< self.channels: List['RTCDataChannel'] = []
+---
+> self.channels: list['RTCDataChannel'] = []
+104a105,116
+> class DynamicPubMaster(messaging.PubMaster):
+> def __init__(self, *args, **kwargs):
+> super().__init__(*args, **kwargs)
+> self.lock = asyncio.Lock()
+>
+> async def add_services_if_needed(self, services):
+> async with self.lock:
+> for service in services:
+> if service not in self.sock:
+> self.sock[service] = messaging.pub_sock(service)
+>
+>
+106c118,120
+< def __init__(self, sdp: str, cameras: List[str], incoming_services: List[str], outgoing_services: List[str], debug_mode: bool = False):
+---
+> shared_pub_master = DynamicPubMaster([])
+>
+> def __init__(self, sdp: str, cameras: list[str], incoming_services: list[str], outgoing_services: list[str], debug_mode: bool = False):
+131,133c145,153
+< self.outgoing_bridge = CerealOutgoingMessageProxy(messaging.SubMaster(outgoing_services))
+< self.incoming_bridge = CerealIncomingMessageProxy(messaging.PubMaster(incoming_services))
+< self.outgoing_bridge_runner = CerealProxyRunner(self.outgoing_bridge)
+---
+> self.incoming_bridge: CerealIncomingMessageProxy | None = None
+> self.incoming_bridge_services = incoming_services
+> self.outgoing_bridge: CerealOutgoingMessageProxy | None = None
+> self.outgoing_bridge_runner: CerealProxyRunner | None = None
+> if len(incoming_services) > 0:
+> self.incoming_bridge = CerealIncomingMessageProxy(self.shared_pub_master)
+> if len(outgoing_services) > 0:
+> self.outgoing_bridge = CerealOutgoingMessageProxy(messaging.SubMaster(outgoing_services))
+> self.outgoing_bridge_runner = CerealProxyRunner(self.outgoing_bridge)
+135,136c155,156
+< self.audio_output: Optional[Union[AudioOutputSpeaker, MediaBlackhole]] = None
+< self.run_task: Optional[asyncio.Task] = None
+---
+> self.audio_output: AudioOutputSpeaker | MediaBlackhole | None = None
+> self.run_task: asyncio.Task | None = None
+154a175
+> assert self.incoming_bridge is not None
+164,167c185,191
+< self.stream.set_message_handler(self.message_handler)
+< channel = self.stream.get_messaging_channel()
+< self.outgoing_bridge_runner.proxy.add_channel(channel)
+< self.outgoing_bridge_runner.start()
+---
+> if self.incoming_bridge is not None:
+> await self.shared_pub_master.add_services_if_needed(self.incoming_bridge_services)
+> self.stream.set_message_handler(self.message_handler)
+> if self.outgoing_bridge_runner is not None:
+> channel = self.stream.get_messaging_channel()
+> self.outgoing_bridge_runner.proxy.add_channel(channel)
+> self.outgoing_bridge_runner.start()
+184c208,209
+< self.outgoing_bridge_runner.stop()
+---
+> if self.outgoing_bridge is not None:
+> self.outgoing_bridge_runner.stop()
+192,194c217,219
+< cameras: List[str]
+< bridge_services_in: List[str] = field(default_factory=list)
+< bridge_services_out: List[str] = field(default_factory=list)
+---
+> cameras: list[str]
+> bridge_services_in: list[str] = field(default_factory=list)
+> bridge_services_out: list[str] = field(default_factory=list)
+diff -r clearpilot/teleoprtc/builder.py FrogPilot/teleoprtc/builder.py
+2d1
+< from typing import List, Dict
+19c18
+< self.requested_camera_types: List[str] = []
+---
+> self.requested_camera_types: list[str] = []
+21c20
+< self.audio_tracks: List[aiortc.MediaStreamTrack] = []
+---
+> self.audio_tracks: list[aiortc.MediaStreamTrack] = []
+52c51
+< self.video_tracks: Dict[str, aiortc.MediaStreamTrack] = dict()
+---
+> self.video_tracks: dict[str, aiortc.MediaStreamTrack] = dict()
+54c53
+< self.audio_tracks: List[aiortc.MediaStreamTrack] = []
+---
+> self.audio_tracks: list[aiortc.MediaStreamTrack] = []
+diff -r clearpilot/teleoprtc/info.py FrogPilot/teleoprtc/info.py
+1d0
+<
+diff -r clearpilot/teleoprtc/stream.py FrogPilot/teleoprtc/stream.py
+5c5,6
+< from typing import Callable, Awaitable, Dict, List, Any, Optional
+---
+> from typing import Any
+> from collections.abc import Callable, Awaitable
+16c17
+< video: List[str]
+---
+> video: list[str]
+25c26
+< consumed_camera_types: List[str],
+---
+> consumed_camera_types: list[str],
+27,28c28,29
+< video_producer_tracks: List[aiortc.MediaStreamTrack],
+< audio_producer_tracks: List[aiortc.MediaStreamTrack],
+---
+> video_producer_tracks: list[aiortc.MediaStreamTrack],
+> audio_producer_tracks: list[aiortc.MediaStreamTrack],
+34c35
+< self.expected_number_of_incoming_media: Optional[int] = None
+---
+> self.expected_number_of_incoming_media: int | None = None
+36,39c37,40
+< self.incoming_camera_tracks: Dict[str, aiortc.MediaStreamTrack] = dict()
+< self.incoming_audio_tracks: List[aiortc.MediaStreamTrack] = []
+< self.outgoing_video_tracks: List[aiortc.MediaStreamTrack] = video_producer_tracks
+< self.outgoing_audio_tracks: List[aiortc.MediaStreamTrack] = audio_producer_tracks
+---
+> self.incoming_camera_tracks: dict[str, aiortc.MediaStreamTrack] = dict()
+> self.incoming_audio_tracks: list[aiortc.MediaStreamTrack] = []
+> self.outgoing_video_tracks: list[aiortc.MediaStreamTrack] = video_producer_tracks
+> self.outgoing_audio_tracks: list[aiortc.MediaStreamTrack] = audio_producer_tracks
+42,43c43,44
+< self.messaging_channel: Optional[aiortc.RTCDataChannel] = None
+< self.incoming_message_handlers: List[MessageHandler] = []
+---
+> self.messaging_channel: aiortc.RTCDataChannel | None = None
+> self.incoming_message_handlers: list[MessageHandler] = []
+72c73
+< def _find_trackless_transceiver(self, kind: str) -> Optional[aiortc.RTCRtpTransceiver]:
+---
+> def _find_trackless_transceiver(self, kind: str) -> aiortc.RTCRtpTransceiver | None:
+99c100
+< def _add_messaging_channel(self, channel: Optional[aiortc.RTCDataChannel] = None):
+---
+> def _add_messaging_channel(self, channel: aiortc.RTCDataChannel | None = None):
+202c203
+< self.expected_number_of_incoming_media != 0 and self.incoming_media_ready_event.is_set()
+---
+> (self.expected_number_of_incoming_media == 0 or self.incoming_media_ready_event.is_set())
+215c216
+< assert self.is_connected_and_ready
+---
+> assert self.is_connected_and_ready, "Stream is not connected/ready yet (make sure wait_for_connection was awaited)"
+258c259
+< def _probe_video_codecs(self) -> List[str]:
+---
+> def _probe_video_codecs(self) -> list[str]:
+266c267
+< def _override_incoming_video_codecs(self, remote_sdp: str, codecs: List[str]) -> str:
+---
+> def _override_incoming_video_codecs(self, remote_sdp: str, codecs: list[str]) -> str:
+273c274
+< preferred_codecs: List[aiortc.RTCRtpCodecParameters] = [c for c in m.rtp.codecs if c.mimeType in codec_mimes]
+---
+> preferred_codecs: list[aiortc.RTCRtpCodecParameters] = [c for c in m.rtp.codecs if c.mimeType in codec_mimes]
+diff -r clearpilot/teleoprtc/tracks.py FrogPilot/teleoprtc/tracks.py
+5c5
+< from typing import Optional, Tuple, Any
+---
+> from typing import Any
+15c15
+< def parse_video_track_id(track_id: str) -> Tuple[str, str]:
+---
+> def parse_video_track_id(track_id: str) -> tuple[str, str]:
+38c38
+< self._start: Optional[float] = None
+---
+> self._start: float | None = None
+56c56
+< def codec_preference(self) -> Optional[str]:
+---
+> def codec_preference(self) -> str | None:
+Only in FrogPilot/teleoprtc_repo/examples/face_detection: face_detection.py
+Only in FrogPilot/teleoprtc_repo/examples/face_detection: README.md
+Only in FrogPilot/teleoprtc_repo/examples/videostream_cli: cli.py
+Only in FrogPilot/teleoprtc_repo/examples/videostream_cli: README.md
+Only in FrogPilot/teleoprtc_repo/.github/workflows: release.yaml
+Only in FrogPilot/teleoprtc_repo/.github/workflows: tests.yaml
+Only in FrogPilot/teleoprtc_repo: .gitignore
+Only in FrogPilot/teleoprtc_repo: LICENSE
+Only in FrogPilot/teleoprtc_repo: .pre-commit-config.yaml
+Only in FrogPilot/teleoprtc_repo: pyproject.toml
+Only in FrogPilot/teleoprtc_repo: README.md
+Only in FrogPilot/teleoprtc_repo/scripts: bump_tag.sh
+Only in FrogPilot/teleoprtc_repo/scripts: publish_pypi.sh
+Only in FrogPilot/teleoprtc_repo/teleoprtc: builder.py
+Only in FrogPilot/teleoprtc_repo/teleoprtc: info.py
+Only in FrogPilot/teleoprtc_repo/teleoprtc: __init__.py
+Only in FrogPilot/teleoprtc_repo/teleoprtc: stream.py
+Only in FrogPilot/teleoprtc_repo/teleoprtc: tracks.py
+Only in FrogPilot/teleoprtc_repo/tests: test_info.py
+Only in FrogPilot/teleoprtc_repo/tests: test_integration.py
+Only in FrogPilot/teleoprtc_repo/tests: test_stream.py
+Only in FrogPilot/teleoprtc_repo/tests: test_track.py
+Only in FrogPilot/tinygrad_repo: compile.sh
+Only in FrogPilot/tinygrad_repo: CONTRIBUTING.md
+Only in FrogPilot/tinygrad_repo/disassemblers/adreno: disasm-a3xx.c
+Only in FrogPilot/tinygrad_repo/disassemblers/adreno: .gitignore
+Only in FrogPilot/tinygrad_repo/disassemblers/adreno: __init__.py
+Only in FrogPilot/tinygrad_repo/disassemblers/adreno: instr-a3xx.h
+Only in FrogPilot/tinygrad_repo/disassemblers/adreno: ir3.h
+Only in FrogPilot/tinygrad_repo/disassemblers/adreno: README
+Only in FrogPilot/tinygrad_repo/disassemblers/adreno: shader_enums.h
+Only in FrogPilot/tinygrad_repo/disassemblers/adreno/util: bitscan.h
+Only in FrogPilot/tinygrad_repo/disassemblers/adreno/util: bitset.h
+Only in FrogPilot/tinygrad_repo/disassemblers/adreno/util: list.h
+Only in FrogPilot/tinygrad_repo/disassemblers/adreno/util: macros.h
+Only in FrogPilot/tinygrad_repo/docs: abstractions.py
+Only in FrogPilot/tinygrad_repo/docs: adding_new_accelerators.md
+Only in FrogPilot/tinygrad_repo/docs: DESIGNv2.md
+Only in FrogPilot/tinygrad_repo/docs: env_vars.md
+Only in FrogPilot/tinygrad_repo/docs: logo.png
+Only in FrogPilot/tinygrad_repo/docs: quickstart.md
+Only in FrogPilot/tinygrad_repo/docs: README.md
+Only in FrogPilot/tinygrad_repo/docs/showcase: mnist_by_tinygrad.jpg
+Only in FrogPilot/tinygrad_repo/docs/showcase: stable_diffusion_by_tinygrad.jpg
+Only in FrogPilot/tinygrad_repo/docs/showcase: yolo_by_tinygrad.jpg
+Only in FrogPilot/tinygrad_repo/docs/showcase: yolov8_showcase_image.png
+Only in FrogPilot/tinygrad_repo/docs: showcase.md
+Only in FrogPilot/tinygrad_repo: .editorconfig
+Only in FrogPilot/tinygrad_repo/examples: benchmark_train_efficientnet.py
+Only in FrogPilot/tinygrad_repo/examples: compile_efficientnet.py
+Only in FrogPilot/tinygrad_repo/examples: compile_tensorflow.py
+Only in FrogPilot/tinygrad_repo/examples: efficientnet.py
+Only in FrogPilot/tinygrad_repo/examples: f16_w_uint32.py
+Only in FrogPilot/tinygrad_repo/examples: gpt2.py
+Only in FrogPilot/tinygrad_repo/examples: handcode_resnet50_opt.py
+Only in FrogPilot/tinygrad_repo/examples: hlb_cifar10.py
+Only in FrogPilot/tinygrad_repo/examples: index.html
+Only in FrogPilot/tinygrad_repo/examples: __init__.py
+Only in FrogPilot/tinygrad_repo/examples: llama.py
+Only in FrogPilot/tinygrad_repo/examples: mask_rcnn.py
+Only in FrogPilot/tinygrad_repo/examples/mlperf: helpers.py
+Only in FrogPilot/tinygrad_repo/examples/mlperf: metrics.py
+Only in FrogPilot/tinygrad_repo/examples/mlperf: model_eval.py
+Only in FrogPilot/tinygrad_repo/examples/mlperf: model_spec.py
+Only in FrogPilot/tinygrad_repo/examples/mlperf: model_train.py
+Only in FrogPilot/tinygrad_repo/examples/mlperf: README
+Only in FrogPilot/tinygrad_repo/examples: mnist_gan.py
+Only in FrogPilot/tinygrad_repo/examples: serious_mnist.py
+Only in FrogPilot/tinygrad_repo/examples: simple_conv_bn.py
+Only in FrogPilot/tinygrad_repo/examples/sovits_helpers: preprocess.py
+Only in FrogPilot/tinygrad_repo/examples: so_vits_svc.py
+Only in FrogPilot/tinygrad_repo/examples: stable_diffusion.py
+Only in FrogPilot/tinygrad_repo/examples: train_efficientnet.py
+Only in FrogPilot/tinygrad_repo/examples: train_resnet.py
+Only in FrogPilot/tinygrad_repo/examples: transformer.py
+Only in FrogPilot/tinygrad_repo/examples/vgg7_helpers: waifu2x.py
+Only in FrogPilot/tinygrad_repo/examples: vgg7.py
+Only in FrogPilot/tinygrad_repo/examples: vit.py
+Only in FrogPilot/tinygrad_repo/examples: vits.py
+Only in FrogPilot/tinygrad_repo/examples/webgpu/stable_diffusion: compile.py
+Only in FrogPilot/tinygrad_repo/examples/webgpu/stable_diffusion: f16_to_f32.js
+Only in FrogPilot/tinygrad_repo/examples/webgpu/stable_diffusion: index.html
+Only in FrogPilot/tinygrad_repo/examples: whisper.py
+Only in FrogPilot/tinygrad_repo/examples: yolov3.py
+Only in FrogPilot/tinygrad_repo/examples: yolov8-onnx.py
+Only in FrogPilot/tinygrad_repo/examples: yolov8.py
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/1_build: coreml_ane.py
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/1_build: .gitignore
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/1_build: run.swift
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/1_build: test.mlmodel
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: ane.py
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: aneregs.json
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: compile.m
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: compile.mm
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: compile.sh
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: dcompile.py
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: .gitignore
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: hwx_parse.py
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: min_uint8.weights
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: min.weights
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: model.espresso.weights
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: model.hwx.golden
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: net.additional.weights
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: net.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/plists: broadcast.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/plists: concat.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/plists: gemm.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/plists: goc.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/plists: inputview.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/plists: neuron.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/plists: reshape.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/plists: scaled.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/plists: sum.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/simple: concat.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/simple: convneuron.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/simple: conv.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/simple: convuint8.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/simple: doubleconv.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/simple: doubleconvrev.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/simple: doubleconvsout.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/simple: doubleneuron.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/simple: gemm.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/simple: goc.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/simple: neuron.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/simple: quadconv.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile/simple: reshape.plist
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: struct_recover.py
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/2_compile: twos.weights
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/3_run: build.sh
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/3_run: entitlements.xml
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/3_run: h11ane.h
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/3_run: test.mm
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/amfi: new_patch.py
+Only in FrogPilot/tinygrad_repo/extra/accel/ane: aneregs
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/lib: ane.mm
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/lib: ane.py
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/lib: aneregs.json
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/lib: build.sh
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/lib: entitlements.xml
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/lib: .gitignore
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/lib: h11ane.h
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/lib: sign_python.sh
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/lib: testconv.py
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/ops: concat.hwx
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/ops: conv.hwx
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/ops: gemm.hwx
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/ops: relu.hwx
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/ops: sigmoid.hwx
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/ops: sum.hwx
+Only in FrogPilot/tinygrad_repo/extra/accel/ane: README.md
+Only in FrogPilot/tinygrad_repo/extra/accel/ane: README.old
+Only in FrogPilot/tinygrad_repo/extra/accel/ane/tinygrad: ops_ane.py
+Only in FrogPilot/tinygrad_repo/extra/accel: MAPPING
+Only in FrogPilot/tinygrad_repo/extra/accel: README
+Only in FrogPilot/tinygrad_repo/extra/accel/tpu/logs: tpu_driver.t1v-n-852cd0d5-w-0.taylor.log.INFO.20210619-062914.26926.gz
+Only in FrogPilot/tinygrad_repo/extra/accel/tpu: README.md
+Only in FrogPilot/tinygrad_repo/extra/accel/tpu/tfexample: libtpu_client.c
+Only in FrogPilot/tinygrad_repo/extra/accel/tpu/tfexample: libtpu.h
+Only in FrogPilot/tinygrad_repo/extra: archprobe.py
+Only in FrogPilot/tinygrad_repo/extra/assembly: assembly_arm64.py
+Only in FrogPilot/tinygrad_repo/extra/assembly: assembly_ptx.py
+Only in FrogPilot/tinygrad_repo/extra/assembly: assembly.py
+Only in FrogPilot/tinygrad_repo/extra/assembly: assembly_rdna.py
+Only in FrogPilot/tinygrad_repo/extra: augment.py
+Only in FrogPilot/tinygrad_repo/extra/datasets: coco.py
+Only in FrogPilot/tinygrad_repo/extra/datasets: imagenet_download.py
+Only in FrogPilot/tinygrad_repo/extra/datasets: imagenet.py
+Only in FrogPilot/tinygrad_repo/extra/datasets: __init__.py
+Only in FrogPilot/tinygrad_repo/extra/datasets: kits19.py
+Only in FrogPilot/tinygrad_repo/extra/datasets: librispeech.py
+Only in FrogPilot/tinygrad_repo/extra/datasets/mnist: t10k-images-idx3-ubyte.gz
+Only in FrogPilot/tinygrad_repo/extra/datasets/mnist: t10k-labels-idx1-ubyte.gz
+Only in FrogPilot/tinygrad_repo/extra/datasets/mnist: train-images-idx3-ubyte.gz
+Only in FrogPilot/tinygrad_repo/extra/datasets/mnist: train-labels-idx1-ubyte.gz
+Only in FrogPilot/tinygrad_repo/extra/datasets: openimages.py
+Only in FrogPilot/tinygrad_repo/extra/datasets: preprocess_imagenet.py
+Only in FrogPilot/tinygrad_repo/extra/datasets: sops.gz
+Only in FrogPilot/tinygrad_repo/extra/datasets: squad.py
+Only in FrogPilot/tinygrad_repo/extra/disk: .gitignore
+Only in FrogPilot/tinygrad_repo/extra/disk: test.cc
+Only in FrogPilot/tinygrad_repo/extra/dist: collectives.py
+Only in FrogPilot/tinygrad_repo/extra/dist: __init__.py
+Only in FrogPilot/tinygrad_repo/extra/dist: world.py
+Only in FrogPilot/tinygrad_repo/extra: dump_cache.py
+Only in FrogPilot/tinygrad_repo/extra: export_model.py
+Only in FrogPilot/tinygrad_repo/extra/fastvits: conv1_reorder.cl
+Only in FrogPilot/tinygrad_repo/extra/fastvits: fastvits_speed.py
+Only in FrogPilot/tinygrad_repo/extra/gemm: amx.py
+Only in FrogPilot/tinygrad_repo/extra/gemm: cuda_matmul.py
+Only in FrogPilot/tinygrad_repo/extra/gemm: gemm.c
+Only in FrogPilot/tinygrad_repo/extra/gemm: gemm.py
+Only in FrogPilot/tinygrad_repo/extra/gemm: gemv_845.py
+Only in FrogPilot/tinygrad_repo/extra/gemm: .gitignore
+Only in FrogPilot/tinygrad_repo/extra/gemm: hip_matmul.py
+Only in FrogPilot/tinygrad_repo/extra/gemm: metal_conv.py
+Only in FrogPilot/tinygrad_repo/extra/gemm: metal_matmul.py
+Only in FrogPilot/tinygrad_repo/extra/gemm: metal_matvec.py
+Only in FrogPilot/tinygrad_repo/extra/gemm: simple_matmul.py
+Only in FrogPilot/tinygrad_repo/extra/gemm: tf_gemm.py
+Only in FrogPilot/tinygrad_repo/extra/gemm: torch_gemm.py
+Only in FrogPilot/tinygrad_repo/extra/gemm: tvm_gemm.py
+Only in FrogPilot/tinygrad_repo/extra: gradcheck.py
+Only in FrogPilot/tinygrad_repo/extra: helpers.py
+Only in FrogPilot/tinygrad_repo/extra: hip_wrapper.py
+Only in FrogPilot/tinygrad_repo/extra/intel: benchmark_matmul.py
+Only in FrogPilot/tinygrad_repo/extra/intel: .gitignore
+Only in FrogPilot/tinygrad_repo/extra/intel: go.sh
+Only in FrogPilot/tinygrad_repo/extra/intel: joint_matrix_bfloat16.cpp
+Only in FrogPilot/tinygrad_repo/extra/intel: README
+Only in FrogPilot/tinygrad_repo/extra: introspection.py
+Only in FrogPilot/tinygrad_repo/extra: lib_test_ast.py
+Only in FrogPilot/tinygrad_repo/extra: lr_scheduler.py
+Only in FrogPilot/tinygrad_repo/extra/optimization: extract_policynet.py
+Only in FrogPilot/tinygrad_repo/extra/optimization: extract_sa_pairs.py
+Only in FrogPilot/tinygrad_repo/extra/optimization: generate_dataset.sh
+Only in FrogPilot/tinygrad_repo/extra/optimization: get_action_space.py
+Only in FrogPilot/tinygrad_repo/extra/optimization: helpers.py
+Only in FrogPilot/tinygrad_repo/extra/optimization: pretrain_valuenet.py
+Only in FrogPilot/tinygrad_repo/extra/optimization: rl.py
+Only in FrogPilot/tinygrad_repo/extra/optimization: run_qnet.py
+Only in FrogPilot/tinygrad_repo/extra/optimization: test_beam_search.py
+Only in FrogPilot/tinygrad_repo/extra/optimization: test_net.py
+Only in FrogPilot/tinygrad_repo/extra/optimization: test_time_linearizer.py
+Only in FrogPilot/tinygrad_repo/extra/ptx: test.py
+Only in FrogPilot/tinygrad_repo/extra/rocm: .gitignore
+Only in FrogPilot/tinygrad_repo/extra/rocm/kernel_crashes: dump
+Only in FrogPilot/tinygrad_repo/extra/rocm/kernel_crashes: dump2
+Only in FrogPilot/tinygrad_repo/extra/rocm/kernel_crashes: dump3
+Only in FrogPilot/tinygrad_repo/extra/rocm/kernel_crashes: dump4
+Only in FrogPilot/tinygrad_repo/extra/rocm: NOTES
+Only in FrogPilot/tinygrad_repo/extra/rocm/rdna3: asm.py
+Only in FrogPilot/tinygrad_repo/extra/rocm/rdna3: prog.s
+Only in FrogPilot/tinygrad_repo/extra/rocm: rocm_clone.sh
+Only in FrogPilot/tinygrad_repo/extra/rocm: rocm_from_scratch.sh
+Only in FrogPilot/tinygrad_repo/extra/rocm: rocm_setup.sh
+Only in FrogPilot/tinygrad_repo/extra/rocm/sniffer: build.sh
+Only in FrogPilot/tinygrad_repo/extra/rocm/sniffer: sniff.cc
+Only in FrogPilot/tinygrad_repo/extra: training.py
+Only in FrogPilot/tinygrad_repo/extra/triton: test.py
+Only in FrogPilot/tinygrad_repo: .flake8
+Only in FrogPilot/tinygrad_repo/.github/workflows: benchmark.yml
+Only in FrogPilot/tinygrad_repo/.github/workflows: python-publish.yml
+Only in FrogPilot/tinygrad_repo/.github/workflows: szdiff.yml
+Only in FrogPilot/tinygrad_repo/.github/workflows: test.yml
+Only in FrogPilot/tinygrad_repo: .gitignore
+Only in FrogPilot/tinygrad_repo: LICENSE
+Only in FrogPilot/tinygrad_repo/models: bert.py
+Only in FrogPilot/tinygrad_repo/models: convnext.py
+Only in FrogPilot/tinygrad_repo/models: efficientnet.py
+Only in FrogPilot/tinygrad_repo/models: mask_rcnn.py
+Only in FrogPilot/tinygrad_repo/models: resnet.py
+Only in FrogPilot/tinygrad_repo/models: retinanet.py
+Only in FrogPilot/tinygrad_repo/models: rnnt.py
+Only in FrogPilot/tinygrad_repo/models: transformer.py
+Only in FrogPilot/tinygrad_repo/models: unet3d.py
+Only in FrogPilot/tinygrad_repo/models: vit.py
+Only in FrogPilot/tinygrad_repo: mypy.ini
+Only in FrogPilot/tinygrad_repo/openpilot: compile.py
+Only in FrogPilot/tinygrad_repo/openpilot: go.sh
+Only in FrogPilot/tinygrad_repo: .pre-commit-config.yaml
+Only in FrogPilot/tinygrad_repo: push_pypi.sh
+Only in FrogPilot/tinygrad_repo: .pylintrc
+Only in FrogPilot/tinygrad_repo: pytest.ini
+Only in FrogPilot/tinygrad_repo: README.md
+Only in FrogPilot/tinygrad_repo: rmso.sh
+Only in FrogPilot/tinygrad_repo: ruff.toml
+Only in FrogPilot/tinygrad_repo: run_multibackend.sh
+Only in FrogPilot/tinygrad_repo: setup.py
+Only in FrogPilot/tinygrad_repo: strip_whitespace.sh
+Only in FrogPilot/tinygrad_repo: sz.py
+Only in FrogPilot/tinygrad_repo/test: Dockerfile
+Only in FrogPilot/tinygrad_repo/test/external/dist: test_collectives.py
+Only in FrogPilot/tinygrad_repo/test/external/dist: test_world.py
+Only in FrogPilot/tinygrad_repo/test/external: external_copy_benchmark.py
+Only in FrogPilot/tinygrad_repo/test/external: external_llama_eval.py
+Only in FrogPilot/tinygrad_repo/test/external: external_model_benchmark.py
+Only in FrogPilot/tinygrad_repo/test/external: external_multi_gpu.py
+Only in FrogPilot/tinygrad_repo/test/external: external_osx_profiling.py
+Only in FrogPilot/tinygrad_repo/test/external: external_test_allocator_on_models.py
+Only in FrogPilot/tinygrad_repo/test/external: external_test_embedding.py
+Only in FrogPilot/tinygrad_repo/test/external: external_test_gpu_ast.py
+Only in FrogPilot/tinygrad_repo/test/external: external_test_image.py
+Only in FrogPilot/tinygrad_repo/test/external: external_test_jit_on_models.py
+Only in FrogPilot/tinygrad_repo/test/external: external_test_onnx_backend.py
+Only in FrogPilot/tinygrad_repo/test/external: external_test_optim.py
+Only in FrogPilot/tinygrad_repo/test/external: external_test_opt.py
+Only in FrogPilot/tinygrad_repo/test/external: external_test_speed_llama.py
+Only in FrogPilot/tinygrad_repo/test/external: external_test_uops_graphing.py
+Only in FrogPilot/tinygrad_repo/test/external: external_test_yolo.py
+Only in FrogPilot/tinygrad_repo/test/external: external_test_yolov8.py
+Only in FrogPilot/tinygrad_repo/test/external: fuzz_shapetracker.py
+Only in FrogPilot/tinygrad_repo/test/external: fuzz_symbolic.py
+Only in FrogPilot/tinygrad_repo/test/external: graph_batchnorm.py
+Only in FrogPilot/tinygrad_repo/test/external: test_example.py
+Only in FrogPilot/tinygrad_repo/test/extra: test_export_model.py
+Only in FrogPilot/tinygrad_repo/test/extra: test_extra_helpers.py
+Only in FrogPilot/tinygrad_repo/test/extra: test_lr_scheduler.py
+Only in FrogPilot/tinygrad_repo/test/extra: test_utils.py
+Only in FrogPilot/tinygrad_repo/test: helpers.py
+Only in FrogPilot/tinygrad_repo/test: __init__.py
+Only in FrogPilot/tinygrad_repo/test/models/efficientnet: car.jpg
+Only in FrogPilot/tinygrad_repo/test/models/efficientnet: Chicken.jpg
+Only in FrogPilot/tinygrad_repo/test/models: test_bert.py
+Only in FrogPilot/tinygrad_repo/test/models: test_efficientnet.py
+Only in FrogPilot/tinygrad_repo/test/models: test_end2end.py
+Only in FrogPilot/tinygrad_repo/test/models: test_mnist.py
+Only in FrogPilot/tinygrad_repo/test/models: test_onnx.py
+Only in FrogPilot/tinygrad_repo/test/models: test_real_world.py
+Only in FrogPilot/tinygrad_repo/test/models: test_rnnt.py
+Only in FrogPilot/tinygrad_repo/test/models: test_train.py
+Only in FrogPilot/tinygrad_repo/test/models: test_waifu2x.py
+Only in FrogPilot/tinygrad_repo/test/models: test_whisper.py
+Only in FrogPilot/tinygrad_repo/test/models/waifu2x: input.png
+Only in FrogPilot/tinygrad_repo/test/models/waifu2x: output.png
+Only in FrogPilot/tinygrad_repo/test/models/whisper: test.wav
+Only in FrogPilot/tinygrad_repo/test: test_allocators.py
+Only in FrogPilot/tinygrad_repo/test: test_assign.py
+Only in FrogPilot/tinygrad_repo/test: test_conv.py
+Only in FrogPilot/tinygrad_repo/test: test_conv_shapetracker.py
+Only in FrogPilot/tinygrad_repo/test: test_custom_function.py
+Only in FrogPilot/tinygrad_repo/test: test_dtype.py
+Only in FrogPilot/tinygrad_repo/test: test_gc.py
+Only in FrogPilot/tinygrad_repo/test: test_jit.py
+Only in FrogPilot/tinygrad_repo/test: test_kernel_cache.py
+Only in FrogPilot/tinygrad_repo/test: test_lazybuffer.py
+Only in FrogPilot/tinygrad_repo/test: test_lazyop.py
+Only in FrogPilot/tinygrad_repo/test: test_linearizer_failures.py
+Only in FrogPilot/tinygrad_repo/test: test_linearizer.py
+Only in FrogPilot/tinygrad_repo/test: test_net_speed.py
+Only in FrogPilot/tinygrad_repo/test: test_nn.py
+Only in FrogPilot/tinygrad_repo/test: test_ops.py
+Only in FrogPilot/tinygrad_repo/test: test_optim.py
+Only in FrogPilot/tinygrad_repo/test: test_randomness.py
+Only in FrogPilot/tinygrad_repo/test: test_schedule.py
+Only in FrogPilot/tinygrad_repo/test: test_search.py
+Only in FrogPilot/tinygrad_repo/test: test_specific_conv.py
+Only in FrogPilot/tinygrad_repo/test: test_speed_v_torch.py
+Only in FrogPilot/tinygrad_repo/test: test_symbolic_jit.py
+Only in FrogPilot/tinygrad_repo/test: test_symbolic_ops.py
+Only in FrogPilot/tinygrad_repo/test: test_symbolic_shapetracker.py
+Only in FrogPilot/tinygrad_repo/test: test_tensor.py
+Only in FrogPilot/tinygrad_repo/test: test_uops.py
+Only in FrogPilot/tinygrad_repo/test: test_webgpu.js
+Only in FrogPilot/tinygrad_repo/test: test_winograd.py
+Only in FrogPilot/tinygrad_repo/test/unit: test_disk_cache.py
+Only in FrogPilot/tinygrad_repo/test/unit: test_disk_tensor.py
+Only in FrogPilot/tinygrad_repo/test/unit: test_flopcounter.py
+Only in FrogPilot/tinygrad_repo/test/unit: test_helpers.py
+Only in FrogPilot/tinygrad_repo/test/unit: test_shapetracker.py
+Only in FrogPilot/tinygrad_repo/test/unit: test_shm_tensor.py
+Only in FrogPilot/tinygrad_repo/test/unit: test_symbolic.py
+Only in FrogPilot/tinygrad_repo/tinygrad/renderer: cuda.py
+Only in FrogPilot/tinygrad_repo/tinygrad/renderer: llvmir.py
+Only in FrogPilot/tinygrad_repo/tinygrad/renderer: metal.py
+Only in FrogPilot/tinygrad_repo/tinygrad/renderer: triton.py
+Only in FrogPilot/tinygrad_repo/tinygrad/renderer: wgsl.py
+Only in FrogPilot/tinygrad_repo/tinygrad/runtime: ops_clang.py
+Only in FrogPilot/tinygrad_repo/tinygrad/runtime: ops_cuda.py
+Only in FrogPilot/tinygrad_repo/tinygrad/runtime: ops_hip.py
+Only in FrogPilot/tinygrad_repo/tinygrad/runtime: ops_llvm.py
+Only in FrogPilot/tinygrad_repo/tinygrad/runtime: ops_metal.py
+Only in FrogPilot/tinygrad_repo/tinygrad/runtime: ops_shm.py
+Only in FrogPilot/tinygrad_repo/tinygrad/runtime: ops_torch.py
+Only in FrogPilot/tinygrad_repo/tinygrad/runtime: ops_webgpu.py
+Only in FrogPilot/tinygrad_repo: .tokeignore
+Only in FrogPilot/tools/bodyteleop: .gitignore
+diff -r clearpilot/tools/bodyteleop/web.py FrogPilot/tools/bodyteleop/web.py
+59c59
+< stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+---
+> capture_output=True, shell=True)
+80c80
+< with open(os.path.join(TELEOPDIR, "static", "index.html"), "r") as f:
+---
+> with open(os.path.join(TELEOPDIR, "static", "index.html")) as f:
+Only in FrogPilot/tools/cabana/assets: assets.qrc
+Only in FrogPilot/tools/cabana/assets: cabana-icon.png
+Only in FrogPilot/tools/cabana/assets: .gitignore
+Only in FrogPilot/tools/cabana: binaryview.cc
+Only in FrogPilot/tools/cabana: binaryview.h
+Only in FrogPilot/tools/cabana: cabana.cc
+Only in FrogPilot/tools/cabana/chart: chart.cc
+Only in FrogPilot/tools/cabana/chart: chart.h
+Only in FrogPilot/tools/cabana/chart: chartswidget.cc
+Only in FrogPilot/tools/cabana/chart: chartswidget.h
+Only in FrogPilot/tools/cabana/chart: signalselector.cc
+Only in FrogPilot/tools/cabana/chart: signalselector.h
+Only in FrogPilot/tools/cabana/chart: sparkline.cc
+Only in FrogPilot/tools/cabana/chart: sparkline.h
+Only in FrogPilot/tools/cabana/chart: tiplabel.cc
+Only in FrogPilot/tools/cabana/chart: tiplabel.h
+Only in FrogPilot/tools/cabana: commands.cc
+Only in FrogPilot/tools/cabana: commands.h
+Only in FrogPilot/tools/cabana/dbc: dbc.cc
+Only in FrogPilot/tools/cabana/dbc: dbcfile.cc
+Only in FrogPilot/tools/cabana/dbc: dbcfile.h
+Only in FrogPilot/tools/cabana/dbc: dbc.h
+Only in FrogPilot/tools/cabana/dbc: dbcmanager.cc
+Only in FrogPilot/tools/cabana/dbc: dbcmanager.h
+Only in FrogPilot/tools/cabana/dbc: generate_dbc_json.py
+Only in FrogPilot/tools/cabana: detailwidget.cc
+Only in FrogPilot/tools/cabana: detailwidget.h
+Only in FrogPilot/tools/cabana: .gitignore
+Only in FrogPilot/tools/cabana: historylog.cc
+Only in FrogPilot/tools/cabana: historylog.h
+Only in FrogPilot/tools/cabana: mainwin.cc
+Only in FrogPilot/tools/cabana: mainwin.h
+Only in FrogPilot/tools/cabana: messageswidget.cc
+Only in FrogPilot/tools/cabana: messageswidget.h
+Only in FrogPilot/tools/cabana: README.md
+Only in FrogPilot/tools/cabana: SConscript
+Only in FrogPilot/tools/cabana: settings.cc
+Only in FrogPilot/tools/cabana: settings.h
+Only in FrogPilot/tools/cabana: signalview.cc
+Only in FrogPilot/tools/cabana: signalview.h
+Only in FrogPilot/tools/cabana/streams: abstractstream.cc
+Only in FrogPilot/tools/cabana/streams: abstractstream.h
+Only in FrogPilot/tools/cabana/streams: devicestream.cc
+Only in FrogPilot/tools/cabana/streams: devicestream.h
+Only in FrogPilot/tools/cabana/streams: livestream.cc
+Only in FrogPilot/tools/cabana/streams: livestream.h
+Only in FrogPilot/tools/cabana/streams: pandastream.cc
+Only in FrogPilot/tools/cabana/streams: pandastream.h
+Only in FrogPilot/tools/cabana/streams: replaystream.cc
+Only in FrogPilot/tools/cabana/streams: replaystream.h
+Only in FrogPilot/tools/cabana/streams: socketcanstream.cc
+Only in FrogPilot/tools/cabana/streams: socketcanstream.h
+Only in FrogPilot/tools/cabana: streamselector.cc
+Only in FrogPilot/tools/cabana: streamselector.h
+Only in FrogPilot/tools/cabana/tests: test_cabana.cc
+Only in FrogPilot/tools/cabana/tests: test_runner.cc
+Only in FrogPilot/tools/cabana/tools: findsignal.cc
+Only in FrogPilot/tools/cabana/tools: findsignal.h
+Only in FrogPilot/tools/cabana/tools: findsimilarbits.cc
+Only in FrogPilot/tools/cabana/tools: findsimilarbits.h
+Only in FrogPilot/tools/cabana/utils: export.cc
+Only in FrogPilot/tools/cabana/utils: export.h
+Only in FrogPilot/tools/cabana/utils: util.cc
+Only in FrogPilot/tools/cabana/utils: util.h
+Only in FrogPilot/tools/cabana: videowidget.cc
+Only in FrogPilot/tools/cabana: videowidget.h
+Only in FrogPilot/tools/camerastream: compressed_vipc.py
+Only in FrogPilot/tools/camerastream: README.md
+Only in FrogPilot/tools/car_porting: auto_fingerprint.py
+Only in FrogPilot/tools/car_porting/examples: ford_vin_fingerprint.ipynb
+Only in FrogPilot/tools/car_porting/examples: subaru_fuzzy_fingerprint.ipynb
+Only in FrogPilot/tools/car_porting/examples: subaru_long_accel.ipynb
+Only in FrogPilot/tools/car_porting/examples: subaru_steer_temp_fault.ipynb
+Only in FrogPilot/tools/car_porting: README.md
+Only in FrogPilot/tools/car_porting: test_car_model.py
+Only in FrogPilot/tools: CTF.md
+Only in FrogPilot/tools: install_python_dependencies.sh
+Only in FrogPilot/tools: install_ubuntu_dependencies.sh
+Only in FrogPilot/tools/latencylogger: latency_logger.py
+Only in FrogPilot/tools/latencylogger: README.md
+diff -r clearpilot/tools/lib/auth.py FrogPilot/tools/lib/auth.py
+29c29
+< from typing import Any, Dict
+---
+> from typing import Any
+39c39
+< query_params: Dict[str, Any] = {}
+---
+> query_params: dict[str, Any] = {}
+diff -r clearpilot/tools/lib/azure_container.py FrogPilot/tools/lib/azure_container.py
+5c5
+< from typing import IO, Union
+---
+> from typing import IO
+60c60
+< def upload_bytes(self, data: Union[bytes, IO], blob_name: str) -> str:
+---
+> def upload_bytes(self, data: bytes | IO, blob_name: str) -> str:
+72c72
+< def upload_file(self, path: Union[str, os.PathLike], blob_name: str) -> str:
+---
+> def upload_file(self, path: str | os.PathLike, blob_name: str) -> str:
+diff -r clearpilot/tools/lib/bootlog.py FrogPilot/tools/lib/bootlog.py
+3d2
+< from typing import List, Optional
+47c46
+< def get_bootlog_from_id(bootlog_id: str) -> Optional[Bootlog]:
+---
+> def get_bootlog_from_id(bootlog_id: str) -> Bootlog | None:
+55c54
+< def get_bootlogs(dongle_id: str) -> List[Bootlog]:
+---
+> def get_bootlogs(dongle_id: str) -> list[Bootlog]:
+diff -r clearpilot/tools/lib/helpers.py FrogPilot/tools/lib/helpers.py
+12,14c12,14
+< LOG_ID = r'(?P(?:{}|{}))'.format(TIMESTAMP, LOG_ID_V2)
+< ROUTE_NAME = r'(?P{}[|_/]{})'.format(DONGLE_ID, LOG_ID)
+< SEGMENT_NAME = r'{}(?:--|/)(?P[0-9]+)'.format(ROUTE_NAME)
+---
+> LOG_ID = fr'(?P(?:{TIMESTAMP}|{LOG_ID_V2}))'
+> ROUTE_NAME = fr'(?P{DONGLE_ID}[|_/]{LOG_ID})'
+> SEGMENT_NAME = fr'{ROUTE_NAME}(?:--|/)(?P[0-9]+)'
+17,18c17,18
+< SLICE = r'(?P{})?:?(?P{})?:?(?P{})?'.format(INDEX, INDEX, INDEX)
+< SEGMENT_RANGE = r'{}(?:(--|/)(?P({})))?(?:/(?P([qras])))?'.format(ROUTE_NAME, SLICE)
+---
+> SLICE = fr'(?P{INDEX})?:?(?P{INDEX})?:?(?P{INDEX})?'
+> SEGMENT_RANGE = fr'{ROUTE_NAME}(?:(--|/)(?P({SLICE})))?(?:/(?P([qras])))?'
+22,23c22,23
+< EXPLORER_FILE = r'^(?P{})--(?P[a-z]+\.[a-z0-9]+)$'.format(SEGMENT_NAME)
+< OP_SEGMENT_DIR = r'^(?P{})$'.format(SEGMENT_NAME)
+---
+> EXPLORER_FILE = fr'^(?P{SEGMENT_NAME})--(?P[a-z]+\.[a-z0-9]+)$'
+> OP_SEGMENT_DIR = fr'^(?P{SEGMENT_NAME})$'
+diff -r clearpilot/tools/lib/live_logreader.py FrogPilot/tools/lib/live_logreader.py
+2d1
+< from typing import List
+11c10
+< def raw_live_logreader(services: List[str] = ALL_SERVICES, addr: str = '127.0.0.1') -> RawLogIterable:
+---
+> def raw_live_logreader(services: list[str] = ALL_SERVICES, addr: str = '127.0.0.1') -> RawLogIterable:
+28c27
+< def live_logreader(services: List[str] = ALL_SERVICES, addr: str = '127.0.0.1') -> LogIterable:
+---
+> def live_logreader(services: list[str] = ALL_SERVICES, addr: str = '127.0.0.1') -> LogIterable:
+diff -r clearpilot/tools/lib/logreader.py FrogPilot/tools/lib/logreader.py
+14c14
+< from typing import Callable, Dict, Iterable, Iterator, List, Optional, Type
+---
+> from collections.abc import Callable, Iterable, Iterator
+24c24
+< LogMessage = Type[capnp._DynamicStructReader]
+---
+> LogMessage = type[capnp._DynamicStructReader]
+79,80c79,80
+< LogPath = Optional[str]
+< LogPaths = List[LogPath]
+---
+> LogPath = str | None
+> LogPaths = list[LogPath]
+92c92
+< if any(rlog is None or not valid_file(rlog) for rlog in rlog_paths):
+---
+> if any(rlog is None or not valid_file(rlog) for rlog in rlog_paths) and all(qlog is not None and valid_file(qlog) for qlog in qlog_paths):
+173c173
+< SOURCES: List[Source] = [internal_source, openpilotci_source, comma_api_source, comma_car_segments_source,]
+---
+> SOURCES: list[Source] = [internal_source, openpilotci_source, comma_api_source, comma_car_segments_source,]
+174a175,183
+>
+> # for automatic fallback modes, auto_source needs to first check if rlogs exist for any source
+> if mode in [ReadMode.AUTO, ReadMode.AUTO_INTERACTIVE]:
+> for source in SOURCES:
+> try:
+> return check_source(source, sr, ReadMode.RLOG)
+> except Exception:
+> pass
+>
+215c224
+< def _parse_identifiers(self, identifier: str | List[str]):
+---
+> def _parse_identifiers(self, identifier: str | list[str]):
+237c246
+< def __init__(self, identifier: str | List[str], default_mode: ReadMode = ReadMode.RLOG,
+---
+> def __init__(self, identifier: str | list[str], default_mode: ReadMode = ReadMode.RLOG,
+246c255
+< self.__lrs: Dict[int, _LogFileReader] = {}
+---
+> self.__lrs: dict[int, _LogFileReader] = {}
+251c260
+< self.__lrs[i] = _LogFileReader(self.logreader_identifiers[i])
+---
+> self.__lrs[i] = _LogFileReader(self.logreader_identifiers[i], sort_by_time=self.sort_by_time, only_union_types=self.only_union_types)
+diff -r clearpilot/tools/lib/README.md FrogPilot/tools/lib/README.md
+37c37
+< We also support a new format called a "segment range", where you can specify which segments from a route to load.
+---
+> We also support a new format called a "segment range":
+39c39,44
+< ```python
+---
+> ```
+> 344c5c15b34f2d8a / 2024-01-03--09-37-12 / 2:6 / q
+> [ dongle id ] [ timestamp ] [ selector ] [ query type]
+> ```
+>
+> you can specify which segments from a route to load
+40a46
+> ```python
+diff -r clearpilot/tools/lib/route.py FrogPilot/tools/lib/route.py
+7c7
+< from typing import Optional, cast
+---
+> from typing import cast
+234c234
+< def data_dir(self) -> Optional[str]: return self._data_dir
+---
+> def data_dir(self) -> str | None: return self._data_dir
+266a267,270
+> def log_id(self) -> str:
+> return self.m.group("log_id")
+>
+> @property
+294c298
+< return f"{self.dongle_id}/{self.timestamp}" + (f"/{self.slice}" if self.slice else "") + (f"/{self.selector}" if self.selector else "")
+---
+> return f"{self.dongle_id}/{self.log_id}" + (f"/{self.slice}" if self.slice else "") + (f"/{self.selector}" if self.selector else "")
+diff -r clearpilot/tools/lib/tests/test_caching.py FrogPilot/tools/lib/tests/test_caching.py
+4a5,6
+> import shutil
+> import socket
+8,9c10,11
+< from openpilot.selfdrive.athena.tests.helpers import with_http_server
+<
+---
+> from openpilot.selfdrive.test.helpers import with_http_server
+> from openpilot.system.hardware.hw import Paths
+18c20
+< self.send_response(200, b'1234')
+---
+> self.send_response(206 if "Range" in self.headers else 200, b'1234')
+35a38,65
+>
+> @with_caching_server
+> def test_pipeline_defaults(self, host):
+> # TODO: parameterize the defaults so we don't rely on hard-coded values in xx
+>
+> self.assertEqual(URLFile.pool_manager().pools._maxsize, 10) # PoolManager num_pools param
+> pool_manager_defaults = {
+> "maxsize": 100,
+> "socket_options": [(socket.SOL_SOCKET, socket.SO_KEEPALIVE, 1),],
+> }
+> for k, v in pool_manager_defaults.items():
+> self.assertEqual(URLFile.pool_manager().connection_pool_kw.get(k), v)
+>
+> retry_defaults = {
+> "total": 5,
+> "backoff_factor": 0.5,
+> "status_forcelist": [409, 429, 503, 504],
+> }
+> for k, v in retry_defaults.items():
+> self.assertEqual(getattr(URLFile.pool_manager().connection_pool_kw["retries"], k), v)
+>
+> # ensure caching off by default and cache dir doesn't get created
+> os.environ.pop("FILEREADER_CACHE", None)
+> if os.path.exists(Paths.download_cache_root()):
+> shutil.rmtree(Paths.download_cache_root())
+> URLFile(f"{host}/test.txt").get_length()
+> URLFile(f"{host}/test.txt").read()
+> self.assertEqual(os.path.exists(Paths.download_cache_root()), False)
+diff -r clearpilot/tools/lib/tests/test_comma_car_segments.py FrogPilot/tools/lib/tests/test_comma_car_segments.py
+1,2c1
+<
+<
+---
+> import pytest
+10a10
+> @pytest.mark.skip(reason="huggingface is flaky, run this test manually to check for issues")
+diff -r clearpilot/tools/lib/tests/test_logreader.py FrogPilot/tools/lib/tests/test_logreader.py
+1a2
+> import capnp
+13a15
+> from cereal import log as capnp_log
+217a220,256
+>
+> @pytest.mark.slow
+> def test_sort_by_time(self):
+> msgs = list(LogReader(f"{TEST_ROUTE}/0/q"))
+> self.assertNotEqual(msgs, sorted(msgs, key=lambda m: m.logMonoTime))
+>
+> msgs = list(LogReader(f"{TEST_ROUTE}/0/q", sort_by_time=True))
+> self.assertEqual(msgs, sorted(msgs, key=lambda m: m.logMonoTime))
+>
+> def test_only_union_types(self):
+> with tempfile.NamedTemporaryFile() as qlog:
+> # write valid Event messages
+> num_msgs = 100
+> with open(qlog.name, "wb") as f:
+> f.write(b"".join(capnp_log.Event.new_message().to_bytes() for _ in range(num_msgs)))
+>
+> msgs = list(LogReader(qlog.name))
+> self.assertEqual(len(msgs), num_msgs)
+> [m.which() for m in msgs]
+>
+> # append non-union Event message
+> event_msg = capnp_log.Event.new_message()
+> non_union_bytes = bytearray(event_msg.to_bytes())
+> non_union_bytes[event_msg.total_size.word_count * 8] = 0xff # set discriminant value out of range using Event word offset
+> with open(qlog.name, "ab") as f:
+> f.write(non_union_bytes)
+>
+> # ensure new message is added, but is not a union type
+> msgs = list(LogReader(qlog.name))
+> self.assertEqual(len(msgs), num_msgs + 1)
+> with self.assertRaises(capnp.KjException):
+> [m.which() for m in msgs]
+>
+> # should not be added when only_union_types=True
+> msgs = list(LogReader(qlog.name, only_union_types=True))
+> self.assertEqual(len(msgs), num_msgs)
+> [m.which() for m in msgs]
+diff -r clearpilot/tools/lib/vidindex.py FrogPilot/tools/lib/vidindex.py
+6d5
+< from typing import Tuple
+123c122
+< def get_ue(dat: bytes, start_idx: int, skip_bits: int) -> Tuple[int, int]:
+---
+> def get_ue(dat: bytes, start_idx: int, skip_bits: int) -> tuple[int, int]:
+187c186
+< def get_hevc_slice_type(dat: bytes, nal_unit_start: int, nal_unit_type: HevcNalUnitType) -> Tuple[int, bool]:
+---
+> def get_hevc_slice_type(dat: bytes, nal_unit_start: int, nal_unit_type: HevcNalUnitType) -> tuple[int, bool]:
+262c261
+< def hevc_index(hevc_file_name: str, allow_corrupt: bool=False) -> Tuple[list, int, bytes]:
+---
+> def hevc_index(hevc_file_name: str, allow_corrupt: bool=False) -> tuple[list, int, bytes]:
+Only in FrogPilot/tools: mac_setup.sh
+Only in FrogPilot/tools/plotjuggler: .gitignore
+Only in FrogPilot/tools/plotjuggler: juggle.py
+Only in FrogPilot/tools/plotjuggler/layouts: camera-timings.xml
+Only in FrogPilot/tools/plotjuggler/layouts: CAN-bus-debug.xml
+Only in FrogPilot/tools/plotjuggler/layouts: can-states.xml
+Only in FrogPilot/tools/plotjuggler/layouts: controls_mismatch_debug.xml
+Only in FrogPilot/tools/plotjuggler/layouts: demo.xml
+Only in FrogPilot/tools/plotjuggler/layouts: gps_vs_llk.xml
+Only in FrogPilot/tools/plotjuggler/layouts: longitudinal.xml
+Only in FrogPilot/tools/plotjuggler/layouts: max-torque-debug.xml
+Only in FrogPilot/tools/plotjuggler/layouts: system_lag_debug.xml
+Only in FrogPilot/tools/plotjuggler/layouts: thermal_debug.xml
+Only in FrogPilot/tools/plotjuggler/layouts: torque-controller.xml
+Only in FrogPilot/tools/plotjuggler/layouts: tuning.xml
+Only in FrogPilot/tools/plotjuggler/layouts: ublox-debug.xml
+Only in FrogPilot/tools/plotjuggler: README.md
+Only in FrogPilot/tools/plotjuggler: test_plotjuggler.py
+Only in FrogPilot/tools/profiling/clpeak: build.sh
+Only in FrogPilot/tools/profiling/clpeak: .gitignore
+Only in FrogPilot/tools/profiling/clpeak: no_print.patch
+Only in FrogPilot/tools/profiling/clpeak: run_continuously.patch
+Only in FrogPilot/tools/profiling: ftrace.sh
+Only in FrogPilot/tools/profiling/palanteer: .gitignore
+Only in FrogPilot/tools/profiling/palanteer: setup.sh
+Only in FrogPilot/tools/profiling/perfetto: build.sh
+Only in FrogPilot/tools/profiling/perfetto: copy.sh
+Only in FrogPilot/tools/profiling/perfetto: .gitignore
+Only in FrogPilot/tools/profiling/perfetto: record.sh
+Only in FrogPilot/tools/profiling/perfetto: server.sh
+Only in FrogPilot/tools/profiling/perfetto: traces.sh
+Only in FrogPilot/tools/profiling/py-spy: profile.sh
+Only in FrogPilot/tools/profiling/snapdragon: .gitignore
+Only in FrogPilot/tools/profiling/snapdragon: README.md
+Only in FrogPilot/tools/profiling/snapdragon: setup-agnos.sh
+Only in FrogPilot/tools/profiling/snapdragon: setup-profiler.sh
+Only in FrogPilot/tools/profiling: watch-irqs.sh
+Only in FrogPilot/tools: README.md
+Only in FrogPilot/tools/replay: camera.cc
+Only in FrogPilot/tools/replay: camera.h
+Only in FrogPilot/tools/replay: can_replay.py
+Only in FrogPilot/tools/replay: consoleui.cc
+Only in FrogPilot/tools/replay: consoleui.h
+Only in FrogPilot/tools/replay: filereader.cc
+Only in FrogPilot/tools/replay: filereader.h
+Only in FrogPilot/tools/replay: framereader.cc
+Only in FrogPilot/tools/replay: framereader.h
+Only in FrogPilot/tools/replay: .gitignore
+Only in FrogPilot/tools/replay: __init__.py
+Only in FrogPilot/tools/replay/lib: __init__.py
+Only in FrogPilot/tools/replay/lib: ui_helpers.py
+Only in FrogPilot/tools/replay: logreader.cc
+Only in FrogPilot/tools/replay: logreader.h
+Only in FrogPilot/tools/replay: main.cc
+Only in FrogPilot/tools/replay: README.md
+Only in FrogPilot/tools/replay: replay.cc
+Only in FrogPilot/tools/replay: replay.h
+Only in FrogPilot/tools/replay: route.cc
+Only in FrogPilot/tools/replay: route.h
+Only in FrogPilot/tools/replay: SConscript
+Only in FrogPilot/tools/replay/tests: test_replay.cc
+Only in FrogPilot/tools/replay/tests: test_runner.cc
+Only in FrogPilot/tools/replay: ui.py
+Only in FrogPilot/tools/replay: unlog_ci_segment.py
+Only in FrogPilot/tools/replay: util.cc
+Only in FrogPilot/tools/replay: util.h
+Only in FrogPilot/tools/scripts: fetch_image_from_route.py
+Only in FrogPilot/tools/scripts: save_ubloxraw_stream.py
+Only in FrogPilot/tools/scripts: setup_ssh_keys.py
+Only in FrogPilot/tools/serial: connect.sh
+Only in FrogPilot/tools/serial: README.md
+Only in FrogPilot/tools/sim/bridge: common.py
+Only in FrogPilot/tools/sim/bridge: __init__.py
+Only in FrogPilot/tools/sim/bridge/metadrive: metadrive_bridge.py
+Only in FrogPilot/tools/sim/bridge/metadrive: metadrive_common.py
+Only in FrogPilot/tools/sim/bridge/metadrive: metadrive_process.py
+Only in FrogPilot/tools/sim/bridge/metadrive: metadrive_world.py
+Only in FrogPilot/tools/sim: build_container.sh
+Only in FrogPilot/tools/sim: Dockerfile.sim
+Only in FrogPilot/tools/sim: Dockerfile.sim_nvidia
+Only in FrogPilot/tools/sim: __init__.py
+Only in FrogPilot/tools/sim: launch_openpilot.sh
+Only in FrogPilot/tools/sim/lib: camerad.py
+Only in FrogPilot/tools/sim/lib: common.py
+Only in FrogPilot/tools/sim/lib: __init__.py
+Only in FrogPilot/tools/sim/lib: keyboard_ctrl.py
+Only in FrogPilot/tools/sim/lib: manual_ctrl.py
+Only in FrogPilot/tools/sim/lib: simulated_car.py
+Only in FrogPilot/tools/sim/lib: simulated_sensors.py
+Only in FrogPilot/tools/sim: README.md
+Only in FrogPilot/tools/sim: rgb_to_nv12.cl
+Only in FrogPilot/tools/sim: run_bridge.py
+Only in FrogPilot/tools/sim/scenarios/metadrive: stay_in_lane.py
+Only in FrogPilot/tools/sim: start_openpilot_docker.sh
+Only in FrogPilot/tools/sim/tests: __init__.py
+Only in FrogPilot/tools/sim/tests: test_metadrive_bridge.py
+Only in FrogPilot/tools/sim/tests: test_sim_bridge.py
+Only in FrogPilot/tools/ssh: id_rsa
+Only in FrogPilot/tools/ssh: README.md
+Only in FrogPilot/tools/tuning: measure_steering_accuracy.py
+Only in FrogPilot/tools: ubuntu_setup.sh
+Only in FrogPilot/tools/webcam: camerad.py
+Only in FrogPilot/tools/webcam: camera.py
+Only in FrogPilot/tools/webcam: Dockerfile
+Only in FrogPilot/tools/webcam: README.md
+Only in FrogPilot/tools/webcam: start_camerad.sh
+Only in FrogPilot/tools/zookeeper: check_consumption.py
+Only in FrogPilot/tools/zookeeper: disable.py
+Only in FrogPilot/tools/zookeeper: enable_and_wait.py
+Only in FrogPilot/tools/zookeeper: ignition.py
+Only in FrogPilot/tools/zookeeper: __init__.py
+Only in FrogPilot/tools/zookeeper: power_monitor.py
+Only in FrogPilot/tools/zookeeper: test_zookeeper.py
+Only in clearpilot/: update_and_launch.sh
+Only in clearpilot/: update.sh
+Only in FrogPilot/.vscode: extensions.json
+Only in FrogPilot/.vscode: launch.json
+diff -r clearpilot/.vscode/settings.json FrogPilot/.vscode/settings.json
+1a2,10
+> "editor.tabSize": 2,
+> "editor.insertSpaces": true,
+> "editor.renderWhitespace": "trailing",
+> "files.trimTrailingWhitespace": true,
+> "search.exclude": {
+> "**/.git": true,
+> "**/.venv": true,
+> "**/__pycache__": true
+> },
+3,5c12,14
+< "selfdrive/": true,
+< "openpilot/system/": true,
+< "tools/": true
+---
+> "**/.git": true,
+> "**/.venv": true,
+> "**/__pycache__": true
+7,11c16,26
+< "search.exclude": {
+< "selfdrive/": true,
+< "openpilot/system/": true,
+< "tools/": true
+< }
+---
+> "python.analysis.exclude": [
+> "**/.git",
+> "**/.venv",
+> "**/__pycache__",
+> // exclude directories that should be using the symlinked version
+> "common/**",
+> "selfdrive/**",
+> "system/**",
+> "third_party/**",
+> "tools/**",
+> ]
diff --git a/selfdrive/car/hyundai/hyundaicanfd.py b/selfdrive/car/hyundai/hyundaicanfd.py
index 6d4d2a4..760a497 100644
--- a/selfdrive/car/hyundai/hyundaicanfd.py
+++ b/selfdrive/car/hyundai/hyundaicanfd.py
@@ -41,7 +41,7 @@ def create_steering_messages(packer, CP, CAN, enabled, lat_active, apply_steer):
values = {
"LKA_MODE": 2, # CP: Whats this?
- "LKA_ICON": 2 if lat_active else 1, # CP: Whats this?
+ "LKA_ICON": 2 if enabled else 1 if lat_active else 0, # CP: Whats this?
"TORQUE_REQUEST": apply_steer,
"LKA_ASSIST": 0,
"STEER_REQ": 1 if lat_active else 0,
@@ -114,12 +114,13 @@ def create_acc_cancel(packer, CP, CAN, cruise_info_copy):
return packer.make_can_msg("SCC_CONTROL", CAN.ECAN, values)
# CLEARPILOT changed HDA icons
+# This doesn't appear to do anything on my tucson
def create_lfahda_cluster(packer, CAN, enabled, lat_active):
values = {
# 0 off, 1 gray, 2 green, 3 blinking (wheel icon)
# CP: Is this actually the wheel? Might this be the HDA2 thing?
"HDA_ICON": 0, # Intention is to have this represent stock HDA mode
- "LFA_ICON": 2 if enabled else 1 if lat_active else 0,
+ "LFA_ICON": 2 if enabled else 1 if lat_active else 0,
}
return packer.make_can_msg("LFAHDA_CLUSTER", CAN.ECAN, values)
diff --git a/system/qcomgpsd/nmeaport.py b/system/qcomgpsd/nmeaport.py
index 231096f..caff7af 100644
--- a/system/qcomgpsd/nmeaport.py
+++ b/system/qcomgpsd/nmeaport.py
@@ -93,7 +93,7 @@ def nmea_checksum_ok(s):
def process_nmea_port_messages(device:str="/dev/ttyUSB1") -> NoReturn:
while True:
try:
- with open(device, "r") as nmeaport:
+ with open(device) as nmeaport:
for line in nmeaport:
line = line.strip()
if DEBUG: