mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-08-20 02:53:44 +08:00
Merge remote-tracking branch 'sunnypilot/sunnypilot/master' into hkg-angle-steering-2025
# Conflicts: # opendbc_repo
This commit is contained in:
@@ -132,7 +132,6 @@ jobs:
|
||||
|
||||
process_replay:
|
||||
name: process replay
|
||||
if: false # disable process_replay for forks
|
||||
runs-on: ${{
|
||||
(github.repository == 'commaai/openpilot') &&
|
||||
((github.event_name != 'pull_request') ||
|
||||
@@ -169,14 +168,14 @@ jobs:
|
||||
name: diff_report_${{ github.event.number }}
|
||||
path: openpilot/selfdrive/test/process_replay/diff_report.txt
|
||||
- name: Checkout ci-artifacts
|
||||
if: github.repository == 'commaai/openpilot' && github.ref == 'refs/heads/master'
|
||||
if: github.repository == 'sunnypilot/sunnypilot' && github.ref == 'refs/heads/master'
|
||||
uses: actions/checkout@v7
|
||||
with:
|
||||
repository: commaai/ci-artifacts
|
||||
repository: sunnypilot/ci-artifacts
|
||||
ssh-key: ${{ secrets.CI_ARTIFACTS_DEPLOY_KEY }}
|
||||
path: ${{ github.workspace }}/ci-artifacts
|
||||
- name: Prepare refs
|
||||
if: github.repository == 'commaai/openpilot' && github.ref == 'refs/heads/master'
|
||||
if: github.repository == 'sunnypilot/sunnypilot' && github.ref == 'refs/heads/master'
|
||||
working-directory: ${{ github.workspace }}/ci-artifacts
|
||||
run: |
|
||||
git config user.name "GitHub Actions Bot"
|
||||
@@ -188,7 +187,7 @@ jobs:
|
||||
git add .
|
||||
git commit -m "process-replay refs for ${{ github.repository }}@${{ github.sha }}" || echo "No changes to commit"
|
||||
- name: Push refs
|
||||
if: github.repository == 'commaai/openpilot' && github.ref == 'refs/heads/master'
|
||||
if: github.repository == 'sunnypilot/sunnypilot' && github.ref == 'refs/heads/master'
|
||||
uses: nick-fields/retry@ad984534de44a9489a53aefd81eb77f87c70dc60
|
||||
with:
|
||||
timeout_minutes: 2
|
||||
|
||||
+8
-7
@@ -1,10 +1,10 @@
|
||||
<!--- AUTOGENERATED FROM selfdrive/car/CARS_template.md, DO NOT EDIT. --->
|
||||
<!--- AUTOGENERATED FROM openpilot/selfdrive/car/CARS_template.md, DO NOT EDIT. --->
|
||||
|
||||
# Supported Cars
|
||||
|
||||
A supported vehicle is one that just works when you install a comma device. All supported cars provide a better experience than any stock system. Supported vehicles reference the US market unless otherwise specified.
|
||||
|
||||
# 341 Supported Cars
|
||||
# 342 Supported Cars
|
||||
|
||||
|Make|Model|Supported Package|ACC|No ACC accel below|No ALC below|Steering Torque|Resume from stop|<a href="##"><img width=2000></a>Hardware Needed<br> |Video|Setup Video|
|
||||
|---|---|---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
|
||||
@@ -78,8 +78,8 @@ A supported vehicle is one that just works when you install a comma device. All
|
||||
|Honda|Accord 2018-22|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord 2018-22">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=mrUwlj3Mi58" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||
|Honda|Accord 2023-25|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord 2023-25">Buy Here</a></sub></details>|||
|
||||
|Honda|Accord Hybrid 2018-22|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|3 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord Hybrid 2018-22">Buy Here</a></sub></details>|||
|
||||
|Honda|Accord Hybrid 2023-25|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord Hybrid 2023-25">Buy Here</a></sub></details>|||
|
||||
|Honda|City (Brazil only) 2023|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|14 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda City (Brazil only) 2023">Buy Here</a></sub></details>|||
|
||||
|Honda|Accord Hybrid 2023-26|All|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch C connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Accord Hybrid 2023-26">Buy Here</a></sub></details>|||
|
||||
|Honda|City (Brazil only) 2023-25|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|14 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda City (Brazil only) 2023-25">Buy Here</a></sub></details>|||
|
||||
|Honda|Civic 2016-18|Honda Sensing|openpilot|0 mph|12 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Nidec connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic 2016-18">Buy Here</a></sub></details>|<a href="https://youtu.be/-IkImTe1NYE" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||
|Honda|Civic 2019-21|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|2 mph[<sup>4</sup>](#footnotes)|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic 2019-21">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=4Iz1Mz5LGF8" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||
|Honda|Civic 2022-24|All|openpilot available[<sup>1,5</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Honda Bosch B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Honda Civic 2022-24">Buy Here</a></sub></details>|<a href="https://youtu.be/ytiOT5lcp6Q" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||
@@ -187,7 +187,7 @@ A supported vehicle is one that just works when you install a comma device. All
|
||||
|Kia|Niro Plug-in Hybrid 2022|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai F connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Niro Plug-in Hybrid 2022">Buy Here</a></sub></details>|||
|
||||
|Kia|Optima 2017|Advanced Smart Cruise Control|Stock|0 mph|32 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Optima 2017">Buy Here</a></sub></details>|||
|
||||
|Kia|Optima 2019-20|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai G connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Optima 2019-20">Buy Here</a></sub></details>|||
|
||||
|Kia|Optima Hybrid 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Optima Hybrid 2019">Buy Here</a></sub></details>|||
|
||||
|Kia|Optima Hybrid 2019|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai H connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Optima Hybrid 2019">Buy Here</a></sub></details>|||
|
||||
|Kia|Seltos 2021|Smart Cruise Control (SCC)|openpilot available[<sup>1</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Seltos 2021">Buy Here</a></sub></details>|||
|
||||
|Kia|Sorento 2018|Advanced Smart Cruise Control & LKAS|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento 2018">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=Fkh3s6WHJz8" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||
|Kia|Sorento 2019|Smart Cruise Control (SCC)|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Hyundai E connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Kia Sorento 2019">Buy Here</a></sub></details>|<a href="https://www.youtube.com/watch?v=Fkh3s6WHJz8" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||
@@ -230,14 +230,15 @@ A supported vehicle is one that just works when you install a comma device. All
|
||||
|Mazda|CX-9 2021-23|All|Stock|0 mph|28 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Mazda connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Mazda CX-9 2021-23">Buy Here</a></sub></details>|<a href="https://youtu.be/dA3duO4a0O4" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||
|Nissan[<sup>6</sup>](#footnotes)|Altima 2019-24|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan B connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Altima 2019-24">Buy Here</a></sub></details>|||
|
||||
|Nissan[<sup>6</sup>](#footnotes)|Leaf 2018-23|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Leaf 2018-23">Buy Here</a></sub></details>|<a href="https://youtu.be/vaMbtAh_0cY" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||
|Nissan[<sup>6</sup>](#footnotes)|Leaf IC 2018-23|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Leaf IC 2018-23">Buy Here</a></sub></details>|<a href="https://youtu.be/vaMbtAh_0cY" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>||
|
||||
|Nissan[<sup>6</sup>](#footnotes)|Rogue 2018-20|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan Rogue 2018-20">Buy Here</a></sub></details>|||
|
||||
|Nissan[<sup>6</sup>](#footnotes)|X-Trail 2017|ProPILOT Assist|Stock|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 Nissan A connector<br>- 1 OBD-C cable (2 ft)<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Nissan X-Trail 2017">Buy Here</a></sub></details>|||
|
||||
|Ram|1500 2019-24|Adaptive Cruise Control (ACC)|Stock|32 mph|1 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Ram connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ram 1500 2019-24">Buy Here</a></sub></details>|||
|
||||
|Ram|2500 2020-24|Adaptive Cruise Control (ACC)|Stock|0 mph|36 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Ram connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ram 2500 2020-24">Buy Here</a></sub></details>|||
|
||||
|Ram|3500 2019-22|Adaptive Cruise Control (ACC)|Stock|0 mph|36 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Ram connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Ram 3500 2019-22">Buy Here</a></sub></details>|||
|
||||
|Rivian|R1S 2022-24|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1S 2022-24">Buy Here</a></sub></details>||<a href="https://youtu.be/uaISd1j7Z4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>|
|
||||
|Rivian|R1S 2022-24|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1S 2022-24">Buy Here</a></sub></details>|<a href="https://youtu.be/dflSSGQwYNc" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>|<a href="https://youtu.be/uaISd1j7Z4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>|
|
||||
|Rivian|R1S 2025|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian B connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1S 2025">Buy Here</a></sub></details>|||
|
||||
|Rivian|R1T 2022-24|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1T 2022-24">Buy Here</a></sub></details>||<a href="https://youtu.be/uaISd1j7Z4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>|
|
||||
|Rivian|R1T 2022-24|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian A connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1T 2022-24">Buy Here</a></sub></details>|<a href="https://youtu.be/dflSSGQwYNc" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>|<a href="https://youtu.be/uaISd1j7Z4U" target="_blank"><img height="18px" src="assets/icon-youtube.svg" /></a>|
|
||||
|Rivian|R1T 2025|All|openpilot|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 Rivian B connector<br>- 1 comma four<br>- 1 comma power v3<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=Rivian R1T 2025">Buy Here</a></sub></details>|||
|
||||
|SEAT[<sup>12</sup>](#footnotes)|Ateca 2016-23|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=SEAT Ateca 2016-23">Buy Here</a></sub></details>|||
|
||||
|SEAT[<sup>12</sup>](#footnotes)|Leon 2014-20|Adaptive Cruise Control (ACC) & Lane Assist|openpilot available[<sup>1,16</sup>](#footnotes)|0 mph|0 mph|[](##)|[](##)|<details><summary>Parts</summary><sub>- 1 OBD-C cable (2 ft)<br>- 1 VW J533 connector<br>- 1 comma four<br>- 1 harness box<br>- 1 long OBD-C cable (9.5 ft)<br>- 1 mount<br><a href="https://comma.ai/shop/comma-3x?harness=SEAT Leon 2014-20">Buy Here</a></sub></details>|||
|
||||
|
||||
+1
-1
Submodule opendbc_repo updated: 86d3b68483...e7a6defadd
@@ -273,6 +273,7 @@ inline static std::unordered_map<std::string, ParamKeyAttributes> keys = {
|
||||
// Torque lateral control custom params
|
||||
{"CustomTorqueParams", {PERSISTENT | BACKUP , BOOL}},
|
||||
{"EnforceTorqueControl", {PERSISTENT | BACKUP, BOOL}},
|
||||
{"LateralJerkTorqueController", {PERSISTENT | BACKUP, BOOL, "0"}},
|
||||
{"LiveTorqueParamsToggle", {PERSISTENT | BACKUP , BOOL}},
|
||||
{"LiveTorqueParamsRelaxedToggle", {PERSISTENT | BACKUP , BOOL}},
|
||||
{"TorqueControlTune", {PERSISTENT | BACKUP, FLOAT, "0.0"}},
|
||||
|
||||
@@ -56,6 +56,9 @@ class CarSpecificEvents:
|
||||
if self.CP.minEnableSpeed > 0 and CS.vEgo < 0.001:
|
||||
events.add(EventName.manualRestart)
|
||||
|
||||
if CS.brakeHoldActive and CS.blockPcmEnable: # set by Nidec Hybrid which cannot resume from brakehold
|
||||
events.add(EventName.belowEngageSpeed)
|
||||
|
||||
elif self.CP.brand == 'toyota':
|
||||
# TODO: when we check for unexpected disengagement, check gear not S1, S2, S3
|
||||
if self.CP.openpilotLongitudinalControl:
|
||||
|
||||
@@ -25,6 +25,8 @@ from openpilot.tools.lib.logreader import LogReader, LogsUnavailable, openpilotc
|
||||
from openpilot.tools.lib.file_sources import Source
|
||||
from openpilot.tools.lib.route import SegmentName
|
||||
|
||||
from openpilot.sunnypilot.tools.lib.sunnypilot_car_segments import sunnypilot_car_segments_source
|
||||
|
||||
SafetyModel = car.CarParams.SafetyModel
|
||||
SteerControlType = structs.CarParams.SteerControlType
|
||||
|
||||
@@ -132,7 +134,7 @@ class TestCarModelBase(unittest.TestCase):
|
||||
segment_range = f"{cls.test_route.route}/{seg}"
|
||||
|
||||
try:
|
||||
sources: list[Source] = [internal_source] if len(INTERNAL_SEG_LIST) else [openpilotci_source, comma_api_source]
|
||||
sources: list[Source] = [internal_source] if len(INTERNAL_SEG_LIST) else [openpilotci_source, comma_api_source, sunnypilot_car_segments_source]
|
||||
lr = LogReader(segment_range, sources=sources, sort_by_time=True)
|
||||
return cls.get_testing_data_from_logreader(lr)
|
||||
except (LogsUnavailable, AssertionError):
|
||||
|
||||
@@ -23,7 +23,7 @@ def main():
|
||||
cloudlog.info("plannerd got CarParamsSP")
|
||||
|
||||
gps_location_service = get_gps_location_service(params)
|
||||
ignore_services = ["liveMapDataSP", gps_location_service]
|
||||
ignore_services = ["liveMapDataSP", "carStateSP", "selfdriveStateSP", gps_location_service]
|
||||
|
||||
ldw = LaneDepartureWarning()
|
||||
longitudinal_planner = LongitudinalPlanner(CP, CP_SP)
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"severity": 1
|
||||
},
|
||||
"Offroad_CarUnrecognized": {
|
||||
"text": "sunnypilot was unable to identify your car. Your car is either unsupported or its ECUs are not recognized. Please submit a pull request to add the firmware versions to the proper vehicle. Need help? Join discord.comma.ai.",
|
||||
"text": "sunnypilot was unable to identify your car. Your car is either unsupported or its ECUs are not recognized. Please select your vehicle manually at https://www.sunnylink.ai/. Need help? Visit https://community.sunnypilot.ai/",
|
||||
"severity": 0
|
||||
},
|
||||
"Offroad_Recalibration": {
|
||||
@@ -42,7 +42,7 @@
|
||||
"severity": 0
|
||||
},
|
||||
"Offroad_ExcessiveActuation": {
|
||||
"text": "Excessive %1 actuation detected on your last drive. Please contact support at https://comma.ai/support and share your device's Dongle ID for troubleshooting.",
|
||||
"text": "Excessive %1 actuation detected on your last drive. Please visit https://community.sunnypilot.ai/ and share your device's Dongle ID for troubleshooting.",
|
||||
"severity": 1,
|
||||
"_comment": "Set extra field to lateral or longitudinal."
|
||||
},
|
||||
|
||||
@@ -93,7 +93,7 @@ class SelfdriveD(CruiseHelper):
|
||||
# TODO: de-couple selfdrived with card/conflate on carState without introducing controls mismatches
|
||||
self.car_state_sock = messaging.sub_sock('carState', timeout=20)
|
||||
|
||||
ignore = self.sensor_packets + self.gps_packets + ['alertDebug', 'lateralManeuverPlan'] + ['modelDataV2SP']
|
||||
ignore = self.sensor_packets + self.gps_packets + ['alertDebug', 'lateralManeuverPlan'] + ['modelDataV2SP', 'longitudinalPlanSP']
|
||||
if SIMULATION:
|
||||
ignore += ['driverCameraState', 'managerState']
|
||||
if REPLAY:
|
||||
|
||||
@@ -500,7 +500,7 @@ CONFIGS = [
|
||||
),
|
||||
ProcessConfig(
|
||||
proc_name="dmonitoringd",
|
||||
pubs=["driverStateV2", "liveCalibration", "carState", "modelV2", "selfdriveState"],
|
||||
pubs=["driverStateV2", "liveCalibration", "carState", "modelV2", "selfdriveState", "carControl"],
|
||||
subs=["driverMonitoringState"],
|
||||
ignore=["logMonoTime"],
|
||||
should_recv_callback=MessageBasedRcvCallback("driverStateV2"),
|
||||
@@ -511,7 +511,7 @@ CONFIGS = [
|
||||
pubs=[
|
||||
"cameraOdometry", "accelerometer", "gyroscope", "liveCalibration", "carState"
|
||||
],
|
||||
subs=["liveLocationKalman", "livePose"],
|
||||
subs=["livePose"],
|
||||
ignore=["logMonoTime"],
|
||||
should_recv_callback=MessageBasedRcvCallback("cameraOdometry"),
|
||||
tolerance=NUMPY_TOLERANCE,
|
||||
|
||||
@@ -66,7 +66,7 @@ segments = [
|
||||
# dashcamOnly makes don't need to be tested until a full port is done
|
||||
excluded_interfaces = ["mock", "body", "psa"]
|
||||
|
||||
BASE_URL = "https://raw.githubusercontent.com/commaai/ci-artifacts/refs/heads/process-replay/"
|
||||
BASE_URL = "https://raw.githubusercontent.com/sunnypilot/ci-artifacts/refs/heads/process-replay/"
|
||||
REF_COMMIT_FN = os.path.join(PROC_REPLAY_DIR, "ref_commit")
|
||||
EXCLUDED_PROCS = {"modeld", "dmonitoringmodeld"}
|
||||
|
||||
|
||||
@@ -139,7 +139,8 @@ class SteeringLayout(Widget):
|
||||
self._nnlc_toggle.action_item.set_state(False)
|
||||
enforce_torque_enabled = False
|
||||
nnlc_enabled = False
|
||||
self._nnlc_toggle.action_item.set_enabled(ui_state.is_offroad() and torque_allowed and not enforce_torque_enabled)
|
||||
jerk_aware_enabled = ui_state.params.get_bool("LateralJerkTorqueController")
|
||||
self._nnlc_toggle.action_item.set_enabled(ui_state.is_offroad() and torque_allowed and not enforce_torque_enabled and not jerk_aware_enabled)
|
||||
self._torque_control_toggle.action_item.set_enabled(ui_state.is_offroad() and torque_allowed and not nnlc_enabled)
|
||||
self._torque_customization_button.action_item.set_enabled(self._torque_control_toggle.action_item.get_state())
|
||||
|
||||
|
||||
+10
@@ -40,6 +40,13 @@ class TorqueSettingsLayout(Widget):
|
||||
self.cached_torque_versions = json.load(f)
|
||||
|
||||
def _initialize_items(self):
|
||||
self._jerk_aware_toggle = toggle_item_sp(
|
||||
param="LateralJerkTorqueController",
|
||||
title=lambda: tr("Lateral Jerk Torque Controller"),
|
||||
description=lambda: tr("Looks ahead at planned steering to reduce sudden corrections, so the wheel moves " +
|
||||
"more smoothly through turns. Works with Self-Tune and custom tuning. " +
|
||||
"Thanks to @twilsonco for the implementation."),
|
||||
)
|
||||
self._torque_control_versions = ListItemSP(
|
||||
title=tr("Torque Control Tune Version"),
|
||||
description="Select the version of Torque Control Tune to use.",
|
||||
@@ -95,6 +102,7 @@ class TorqueSettingsLayout(Widget):
|
||||
)
|
||||
|
||||
items = [
|
||||
self._jerk_aware_toggle,
|
||||
self._torque_control_versions,
|
||||
self._self_tune_toggle,
|
||||
self._relaxed_tune_toggle,
|
||||
@@ -107,6 +115,8 @@ class TorqueSettingsLayout(Widget):
|
||||
|
||||
def _update_state(self):
|
||||
super()._update_state()
|
||||
nnlc_enabled = ui_state.params.get_bool("NeuralNetworkLateralControl")
|
||||
self._jerk_aware_toggle.action_item.set_enabled(ui_state.is_offroad() and not nnlc_enabled)
|
||||
if not ui_state.params.get_bool("LiveTorqueParamsToggle"):
|
||||
ui_state.params.remove("LiveTorqueParamsRelaxedToggle")
|
||||
self._relaxed_tune_toggle.action_item.set_state(False)
|
||||
|
||||
@@ -184,10 +184,15 @@ class UIStateSP:
|
||||
self.params.put_bool("EnforceTorqueControl", False, block=True)
|
||||
self.params.put_bool("NeuralNetworkLateralControl", False, block=True)
|
||||
|
||||
if self.params.get_bool("LateralJerkTorqueController") and self.params.get_bool("NeuralNetworkLateralControl"):
|
||||
self.params.put_bool("LateralJerkTorqueController", False, block=True)
|
||||
self.params.put_bool("NeuralNetworkLateralControl", False, block=True)
|
||||
|
||||
# Angle steering: no torque-based lateral controls
|
||||
if CP.steerControlType == car.CarParams.SteerControlType.angle:
|
||||
self.params.remove("EnforceTorqueControl")
|
||||
self.params.remove("NeuralNetworkLateralControl")
|
||||
self.params.remove("LateralJerkTorqueController")
|
||||
|
||||
# Alpha longitudinal: clear if not available
|
||||
if not CP.alphaLongitudinalAvailable:
|
||||
@@ -200,6 +205,7 @@ class UIStateSP:
|
||||
# No CarParams: clear all car-dependent params as safety default
|
||||
self.params.remove("EnforceTorqueControl")
|
||||
self.params.remove("NeuralNetworkLateralControl")
|
||||
self.params.remove("LateralJerkTorqueController")
|
||||
self.params.remove("AlphaLongitudinalEnabled")
|
||||
|
||||
# No longitudinal control: no experimental mode or DEC
|
||||
|
||||
@@ -73,10 +73,16 @@ def _cleanup_unsupported_params(CP: structs.CarParams, CP_SP: structs.CarParamsS
|
||||
if params is None:
|
||||
params = Params()
|
||||
|
||||
if params.get_bool("LateralJerkTorqueController") and params.get_bool("NeuralNetworkLateralControl"):
|
||||
cloudlog.warning("LateralJerkTorqueController and NeuralNetworkLateralControl both enabled, disabling both")
|
||||
params.put_bool("LateralJerkTorqueController", False, block=True)
|
||||
params.put_bool("NeuralNetworkLateralControl", False, block=True)
|
||||
|
||||
if CP.steerControlType == structs.CarParams.SteerControlType.angle:
|
||||
cloudlog.warning("SteerControlType is angle, cleaning up params")
|
||||
params.remove("NeuralNetworkLateralControl")
|
||||
params.remove("EnforceTorqueControl")
|
||||
params.remove("LateralJerkTorqueController")
|
||||
|
||||
if not CP_SP.intelligentCruiseButtonManagementAvailable or CP.openpilotLongitudinalControl:
|
||||
cloudlog.warning("ICBM not available or openpilot Longitudinal Control enabled, cleaning up params")
|
||||
|
||||
@@ -33,6 +33,7 @@ class LatControlTorqueExt(NeuralNetworkLateralControl, LatControlTorqueExtOverri
|
||||
self._output_torque = output_torque
|
||||
|
||||
self.update_calculations(CS, VM, desired_lateral_accel)
|
||||
self.update_jerk_aware_torque_control(CS, roll_compensation, gravity_adjusted_lateral_accel)
|
||||
self.update_neural_network_feedforward(CS, params, calibrated_pose)
|
||||
|
||||
return self._pid_log, self._output_torque
|
||||
|
||||
@@ -132,3 +132,10 @@ class LatControlTorqueExtBase:
|
||||
self.lat_accel_friction_factor = 1.0
|
||||
self.lateral_jerk_setpoint = self.lat_jerk_friction_factor * self.lookahead_lateral_jerk
|
||||
self.lateral_jerk_measurement = self.lat_jerk_friction_factor * self.actual_lateral_jerk
|
||||
|
||||
def update_output_torque(self, CS):
|
||||
freeze_integrator = self._steer_limited_by_safety or CS.steeringPressed or CS.vEgo < 5
|
||||
self._output_torque = self._pid.update(self._pid_log.error,
|
||||
feedforward=self._ff,
|
||||
speed=CS.vEgo,
|
||||
freeze_integrator=freeze_integrator)
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
"""
|
||||
Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||
|
||||
This file is part of sunnypilot and is licensed under the MIT License.
|
||||
See the LICENSE.md file in the root directory for more details.
|
||||
"""
|
||||
from opendbc.car.lateral import FRICTION_THRESHOLD
|
||||
from opendbc.sunnypilot.car.interfaces import LatControlInputs
|
||||
from opendbc.sunnypilot.car.lateral_ext import get_friction as get_friction_in_torque_space
|
||||
from openpilot.common.params import Params
|
||||
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.latcontrol_torque_ext_base import LatControlTorqueExtBase
|
||||
|
||||
|
||||
class LatControlTorqueJerkAware(LatControlTorqueExtBase):
|
||||
def __init__(self, lac_torque, CP, CP_SP, CI):
|
||||
super().__init__(lac_torque, CP, CP_SP, CI)
|
||||
self.params = Params()
|
||||
self._jerk_aware_enabled = self.params.get_bool("LateralJerkTorqueController")
|
||||
|
||||
def update_limits(self):
|
||||
if not self._jerk_aware_enabled:
|
||||
return
|
||||
self._pid.set_limits(self.lac_torque.steer_max, -self.lac_torque.steer_max)
|
||||
|
||||
def update_jerk_aware_torque_control(self, CS, roll_compensation, gravity_adjusted_lateral_accel):
|
||||
if not self._jerk_aware_enabled:
|
||||
return
|
||||
|
||||
torque_from_setpoint = self.torque_from_lateral_accel_in_torque_space(
|
||||
LatControlInputs(self._setpoint, roll_compensation, CS.vEgo, CS.aEgo), self.torque_params, gravity_adjusted=False
|
||||
)
|
||||
torque_from_measurement = self.torque_from_lateral_accel_in_torque_space(
|
||||
LatControlInputs(self._measurement, roll_compensation, CS.vEgo, CS.aEgo), self.torque_params, gravity_adjusted=False
|
||||
)
|
||||
|
||||
self._pid_log.error = float(torque_from_setpoint - torque_from_measurement) # ty: ignore[invalid-assignment]
|
||||
self._ff = self.torque_from_lateral_accel_in_torque_space(
|
||||
LatControlInputs(gravity_adjusted_lateral_accel, roll_compensation, CS.vEgo, CS.aEgo), self.torque_params, gravity_adjusted=True
|
||||
)
|
||||
|
||||
friction_input = self.update_friction_input(self._desired_lateral_accel, self._actual_lateral_accel)
|
||||
self._ff += get_friction_in_torque_space(friction_input, self._lateral_accel_deadzone, FRICTION_THRESHOLD, self.torque_params)
|
||||
|
||||
self.update_output_torque(CS)
|
||||
@@ -82,7 +82,7 @@ class LatControlTorque(LatControl):
|
||||
future_desired_lateral_accel = desired_curvature * CS.vEgo ** 2
|
||||
self.lat_accel_request_buffer.append(future_desired_lateral_accel)
|
||||
gravity_adjusted_future_lateral_accel = future_desired_lateral_accel - roll_compensation
|
||||
desired_lateral_jerk = (future_desired_lateral_accel - expected_lateral_accel) / lat_delay
|
||||
desired_lateral_jerk = (future_desired_lateral_accel - expected_lateral_accel) / max(lat_delay, self.dt)
|
||||
|
||||
measurement = measured_curvature * CS.vEgo ** 2
|
||||
measurement_rate = self.measurement_rate_filter.update((measurement - self.previous_measurement) / self.dt)
|
||||
|
||||
@@ -14,7 +14,8 @@ from opendbc.sunnypilot.car.lateral_ext import get_friction as get_friction_in_t
|
||||
from openpilot.common.filter_simple import FirstOrderFilter
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.selfdrive.modeld.constants import ModelConstants
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.latcontrol_torque_ext_base import LatControlTorqueExtBase, sign
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.latcontrol_torque_ext_base import sign
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.latcontrol_torque_jerk_aware import LatControlTorqueJerkAware
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.nnlc.helpers import MOCK_MODEL_PATH
|
||||
from openpilot.sunnypilot.selfdrive.controls.lib.nnlc.model import NNTorqueModel
|
||||
|
||||
@@ -31,17 +32,18 @@ def roll_pitch_adjust(roll, pitch):
|
||||
return roll * math.cos(pitch)
|
||||
|
||||
|
||||
class NeuralNetworkLateralControl(LatControlTorqueExtBase):
|
||||
class NeuralNetworkLateralControl(LatControlTorqueJerkAware):
|
||||
def __init__(self, lac_torque, CP, CP_SP, CI):
|
||||
super().__init__(lac_torque, CP, CP_SP, CI)
|
||||
self.params = Params()
|
||||
self.enabled = self.params.get_bool("NeuralNetworkLateralControl")
|
||||
self.has_nn_model = CP_SP.neuralNetworkLateralControl.model.path != MOCK_MODEL_PATH
|
||||
model_path = CP_SP.neuralNetworkLateralControl.model.path
|
||||
self.has_nn_model = model_path not in (MOCK_MODEL_PATH, '')
|
||||
|
||||
# NN model takes current v_ego, lateral_accel, lat accel/jerk error, roll, and past/future/planned data
|
||||
# of lat accel and roll
|
||||
# Past value is computed using previous desired lat accel and observed roll
|
||||
self.model = NNTorqueModel(CP_SP.neuralNetworkLateralControl.model.path)
|
||||
self.model = NNTorqueModel(model_path) if self.has_nn_model else None
|
||||
|
||||
self.pitch = FirstOrderFilter(0.0, 0.5, 0.01)
|
||||
self.pitch_last = 0.0
|
||||
@@ -64,6 +66,7 @@ class NeuralNetworkLateralControl(LatControlTorqueExtBase):
|
||||
return self.enabled and self.model_valid and self.has_nn_model
|
||||
|
||||
def update_limits(self):
|
||||
super().update_limits()
|
||||
if not self._nnlc_enabled:
|
||||
return
|
||||
|
||||
@@ -84,13 +87,6 @@ class NeuralNetworkLateralControl(LatControlTorqueExtBase):
|
||||
self._ff += get_friction_in_torque_space(self._desired_lateral_accel - self._actual_lateral_accel, self._lateral_accel_deadzone,
|
||||
FRICTION_THRESHOLD, self.torque_params)
|
||||
|
||||
def update_output_torque(self, CS):
|
||||
freeze_integrator = self._steer_limited_by_safety or CS.steeringPressed or CS.vEgo < 5
|
||||
self._output_torque = self._pid.update(self._pid_log.error,
|
||||
feedforward=self._ff,
|
||||
speed=CS.vEgo,
|
||||
freeze_integrator=freeze_integrator)
|
||||
|
||||
def update_neural_network_feedforward(self, CS, params, calibrated_pose) -> None:
|
||||
if not self._nnlc_enabled:
|
||||
return
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
"""
|
||||
Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||
|
||||
This file is part of sunnypilot and is licensed under the MIT License.
|
||||
See the LICENSE.md file in the root directory for more details.
|
||||
"""
|
||||
import numpy as np
|
||||
|
||||
from openpilot.cereal import log, messaging
|
||||
from opendbc.car.structs import car
|
||||
from opendbc.car.car_helpers import interfaces
|
||||
from opendbc.car.honda.values import CAR as HONDA
|
||||
from opendbc.car.vehicle_model import VehicleModel
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.common.realtime import DT_CTRL
|
||||
from openpilot.selfdrive.car.helpers import convert_to_capnp
|
||||
from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque
|
||||
from openpilot.selfdrive.locationd.helpers import Pose
|
||||
from openpilot.common.mock.generators import generate_livePose
|
||||
from openpilot.sunnypilot.selfdrive.car import interfaces as sunnypilot_interfaces
|
||||
from openpilot.selfdrive.modeld.constants import ModelConstants
|
||||
|
||||
|
||||
def _make_controller(enhanced=False, nnlc=False):
|
||||
params = Params()
|
||||
params.put_bool("EnforceTorqueControl", True, block=True)
|
||||
params.put_bool("LateralJerkTorqueController", enhanced, block=True)
|
||||
params.put_bool("NeuralNetworkLateralControl", nnlc, block=True)
|
||||
|
||||
car_name = HONDA.HONDA_CIVIC
|
||||
CarInterface = interfaces[car_name]
|
||||
CP = CarInterface.get_non_essential_params(car_name)
|
||||
CP_SP = CarInterface.get_non_essential_params_sp(CP, car_name)
|
||||
CI = CarInterface(CP, CP_SP)
|
||||
sunnypilot_interfaces.setup_interfaces(CI, params)
|
||||
CP_SP = convert_to_capnp(CP_SP)
|
||||
VM = VehicleModel(CP)
|
||||
controller = LatControlTorque(CP.as_reader(), CP_SP.as_reader(), CI, DT_CTRL)
|
||||
return controller, VM, CP
|
||||
|
||||
|
||||
def _make_model_v2():
|
||||
model = messaging.new_message('modelV2')
|
||||
position = log.XYZTData.new_message()
|
||||
position.x = [float(x) for x in 30.0 * np.array(ModelConstants.T_IDXS)]
|
||||
model.modelV2.position = position
|
||||
orientation = log.XYZTData.new_message()
|
||||
orientation.x = [0.0 for _ in ModelConstants.T_IDXS]
|
||||
orientation.y = [0.0 for _ in ModelConstants.T_IDXS]
|
||||
model.modelV2.orientation = orientation
|
||||
velocity = log.XYZTData.new_message()
|
||||
velocity.x = [30.0 for _ in ModelConstants.T_IDXS]
|
||||
model.modelV2.velocity = velocity
|
||||
acceleration = log.XYZTData.new_message()
|
||||
acceleration.x = [0.0 for _ in ModelConstants.T_IDXS]
|
||||
acceleration.y = [0.0 for _ in ModelConstants.T_IDXS]
|
||||
model.modelV2.acceleration = acceleration
|
||||
return model
|
||||
|
||||
|
||||
def _run_update(controller, VM):
|
||||
CS = car.CarState.new_message()
|
||||
CS.vEgo = 30
|
||||
CS.steeringPressed = False
|
||||
lp = generate_livePose()
|
||||
pose = Pose.from_live_pose(lp.livePose)
|
||||
params = log.LiveParametersData.new_message()
|
||||
model_v2 = _make_model_v2().modelV2
|
||||
controller.extension.update_model_v2(model_v2)
|
||||
controller.extension.update_lateral_lag(0.2)
|
||||
return controller.update(True, CS, VM, params, False, 0.5, pose, False, 0.2)
|
||||
|
||||
|
||||
class TestLatControlTorqueExt:
|
||||
def test_init_enhanced_only(self):
|
||||
controller, VM, _ = _make_controller(enhanced=True, nnlc=False)
|
||||
assert controller.extension._jerk_aware_enabled
|
||||
assert not controller.extension.enabled # NNLC disabled
|
||||
|
||||
def test_init_nnlc_only(self):
|
||||
controller, VM, _ = _make_controller(enhanced=False, nnlc=True)
|
||||
assert not controller.extension._jerk_aware_enabled
|
||||
assert controller.extension.enabled
|
||||
|
||||
def test_init_neither(self):
|
||||
controller, VM, _ = _make_controller(enhanced=False, nnlc=False)
|
||||
assert not controller.extension._jerk_aware_enabled
|
||||
assert not controller.extension.enabled
|
||||
|
||||
def test_init_both_no_crash(self):
|
||||
controller, VM, _ = _make_controller(enhanced=True, nnlc=True)
|
||||
assert not controller.extension._jerk_aware_enabled
|
||||
assert not controller.extension.enabled
|
||||
|
||||
def test_update_enhanced_only(self):
|
||||
controller, VM, _ = _make_controller(enhanced=True, nnlc=False)
|
||||
output_torque, _, pid_log = _run_update(controller, VM)
|
||||
assert pid_log.active
|
||||
|
||||
def test_update_neither(self):
|
||||
controller, VM, _ = _make_controller(enhanced=False, nnlc=False)
|
||||
output_torque, _, pid_log = _run_update(controller, VM)
|
||||
assert pid_log.active
|
||||
|
||||
def test_update_both_no_crash(self):
|
||||
controller, VM, _ = _make_controller(enhanced=True, nnlc=True)
|
||||
output_torque, _, pid_log = _run_update(controller, VM)
|
||||
assert pid_log.active
|
||||
@@ -323,6 +323,32 @@
|
||||
"equals": true
|
||||
},
|
||||
"items": [
|
||||
{
|
||||
"key": "LateralJerkTorqueController",
|
||||
"widget": "toggle",
|
||||
"title": "Lateral Jerk Torque Controller",
|
||||
"description": "Looks ahead at planned steering to reduce sudden corrections, so the wheel moves more smoothly through turns. Works with Self-Tune and custom tuning. Thanks to @twilsonco for the implementation.",
|
||||
"visibility": [
|
||||
{
|
||||
"type": "not",
|
||||
"condition": {
|
||||
"type": "capability",
|
||||
"field": "steer_control_type",
|
||||
"equals": "angle"
|
||||
}
|
||||
}
|
||||
],
|
||||
"enablement": [
|
||||
{
|
||||
"type": "offroad_only"
|
||||
},
|
||||
{
|
||||
"type": "param",
|
||||
"key": "NeuralNetworkLateralControl",
|
||||
"equals": false
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"key": "LiveTorqueParamsToggle",
|
||||
"widget": "toggle",
|
||||
@@ -2037,6 +2063,11 @@
|
||||
"type": "param",
|
||||
"key": "EnforceTorqueControl",
|
||||
"equals": false
|
||||
},
|
||||
{
|
||||
"type": "param",
|
||||
"key": "LateralJerkTorqueController",
|
||||
"equals": false
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -73,6 +73,9 @@ sections:
|
||||
- type: param
|
||||
key: EnforceTorqueControl
|
||||
equals: false
|
||||
- type: param
|
||||
key: LateralJerkTorqueController
|
||||
equals: false
|
||||
- id: camera
|
||||
title: Camera
|
||||
description: Camera position and calibration
|
||||
|
||||
@@ -127,6 +127,21 @@ sections:
|
||||
key: EnforceTorqueControl
|
||||
equals: true
|
||||
items:
|
||||
- key: LateralJerkTorqueController
|
||||
widget: toggle
|
||||
title: Lateral Jerk Torque Controller
|
||||
description: Looks ahead at planned steering to reduce sudden corrections, so the wheel moves more smoothly through turns. Works with Self-Tune and custom tuning. Thanks to @twilsonco for the implementation.
|
||||
visibility:
|
||||
- type: not
|
||||
condition:
|
||||
type: capability
|
||||
field: steer_control_type
|
||||
equals: angle
|
||||
enablement:
|
||||
- $ref: '#/macros/offroad'
|
||||
- type: param
|
||||
key: NeuralNetworkLateralControl
|
||||
equals: false
|
||||
- key: LiveTorqueParamsToggle
|
||||
widget: toggle
|
||||
title: Self-Tune
|
||||
|
||||
@@ -257,20 +257,26 @@ class TestKnownPanels:
|
||||
assert "mads_settings" in sub_ids
|
||||
|
||||
def test_mutual_exclusion_torque_nnlc(self, schema):
|
||||
"""EnforceTorqueControl and NNLC must reference each other in enablement."""
|
||||
torque = nnlc = None
|
||||
"""EnforceTorqueControl, EnhancedLatAccel, and NNLC must reference each other in enablement."""
|
||||
torque = nnlc = enhanced = None
|
||||
for panel in schema["panels"]:
|
||||
for item in _iter_panel_items(panel):
|
||||
if item["key"] == "EnforceTorqueControl":
|
||||
torque = item
|
||||
elif item["key"] == "NeuralNetworkLateralControl":
|
||||
nnlc = item
|
||||
elif item["key"] == "LateralJerkTorqueController":
|
||||
enhanced = item
|
||||
assert torque is not None, "EnforceTorqueControl item missing"
|
||||
assert nnlc is not None, "NeuralNetworkLateralControl item missing"
|
||||
assert enhanced is not None, "LateralJerkTorqueController item missing"
|
||||
torque_enable_keys = {r.get("key") for r in torque.get("enablement", []) if r.get("type") == "param"}
|
||||
assert "NeuralNetworkLateralControl" in torque_enable_keys
|
||||
nnlc_enable_keys = {r.get("key") for r in nnlc.get("enablement", []) if r.get("type") == "param"}
|
||||
assert "EnforceTorqueControl" in nnlc_enable_keys
|
||||
assert "LateralJerkTorqueController" in nnlc_enable_keys
|
||||
enhanced_enable_keys = {r.get("key") for r in enhanced.get("enablement", []) if r.get("type") == "param"}
|
||||
assert "NeuralNetworkLateralControl" in enhanced_enable_keys
|
||||
|
||||
|
||||
class TestKnownVehicleSettings:
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
"""
|
||||
Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||
|
||||
This file is part of sunnypilot and is licensed under the MIT License.
|
||||
See the LICENSE.md file in the root directory for more details.
|
||||
"""
|
||||
|
||||
import os
|
||||
|
||||
SUNNYPILOT_CAR_SEGMENTS_REPO = os.environ.get("SUNNYPILOT_CAR_SEGMENTS_REPO",
|
||||
"https://huggingface.co/datasets/sunnypilot/sunnypilotCarSegments")
|
||||
SUNNYPILOT_CAR_SEGMENTS_BRANCH = os.environ.get("SUNNYPILOT_CAR_SEGMENTS_BRANCH", "main")
|
||||
|
||||
|
||||
def get_url(route, segment, file="rlog.zst"):
|
||||
return f"{SUNNYPILOT_CAR_SEGMENTS_REPO}/resolve/{SUNNYPILOT_CAR_SEGMENTS_BRANCH}/segments/{route.replace('|', '/')}/{segment}/{file}"
|
||||
|
||||
|
||||
def sunnypilot_car_segments_source(sr, seg_idxs, fns, /):
|
||||
from openpilot.tools.lib.file_sources import eval_source
|
||||
return eval_source({seg: [get_url(sr.route_name, seg, fn) for fn in fns] for seg in seg_idxs})
|
||||
+68
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Copyright (c) 2021-, Haibin Wen, sunnypilot, and a number of other contributors.
|
||||
|
||||
This file is part of sunnypilot and is licensed under the MIT License.
|
||||
See the LICENSE.md file in the root directory for more details.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
import requests
|
||||
from huggingface_hub import HfApi
|
||||
from tqdm import tqdm
|
||||
|
||||
from openpilot.tools.lib.route import Route
|
||||
|
||||
REPO_ID = os.environ.get("SUNNYPILOT_CAR_SEGMENTS_REPO_ID", "sunnypilot/sunnypilotCarSegments")
|
||||
|
||||
|
||||
def upload_route(route_name: str, dry_run: bool = False) -> None:
|
||||
route = Route(route_name)
|
||||
log_paths = route.log_paths()
|
||||
valid_segments = [(i, url) for i, url in enumerate(log_paths) if url is not None]
|
||||
|
||||
print(f"Route: {route_name}")
|
||||
print(f"Segments: {len(valid_segments)}/{len(log_paths)}")
|
||||
|
||||
if not valid_segments:
|
||||
print("No segments found.")
|
||||
return
|
||||
|
||||
api = HfApi()
|
||||
|
||||
with tempfile.TemporaryDirectory() as tmpdir:
|
||||
for seg_idx, url in tqdm(valid_segments, desc="Uploading"):
|
||||
filename = url.split("?")[0].rsplit("/", 1)[-1]
|
||||
local_path = os.path.join(tmpdir, f"{seg_idx}_{filename}")
|
||||
resp = requests.get(url, stream=True)
|
||||
resp.raise_for_status()
|
||||
with open(local_path, "wb") as f:
|
||||
for chunk in resp.iter_content(chunk_size=8192):
|
||||
f.write(chunk)
|
||||
|
||||
repo_path = f"segments/{route_name.replace('|', '/')}/{seg_idx}/{filename}"
|
||||
|
||||
if dry_run:
|
||||
size_mb = os.path.getsize(local_path) / 1024 / 1024
|
||||
print(f" [{seg_idx}] {size_mb:.1f} MB -> {repo_path}")
|
||||
else:
|
||||
api.upload_file(
|
||||
path_or_fileobj=local_path,
|
||||
path_in_repo=repo_path,
|
||||
repo_id=REPO_ID,
|
||||
repo_type="dataset",
|
||||
)
|
||||
|
||||
print("Done.")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = argparse.ArgumentParser(description="Upload route rlogs to sunnypilot HuggingFace dataset")
|
||||
parser.add_argument("route", help="Route ID (e.g. 5beb9b58bd12b691/0000010a--a51155e496)")
|
||||
parser.add_argument("--dry-run", action="store_true", help="Download and show sizes without uploading")
|
||||
args = parser.parse_args()
|
||||
|
||||
upload_route(args.route, dry_run=args.dry_run)
|
||||
@@ -22,6 +22,8 @@ from openpilot.tools.lib.file_sources import comma_api_source, internal_source,
|
||||
from openpilot.tools.lib.route import SegmentRange, FileName
|
||||
from openpilot.tools.lib.log_time_series import msgs_to_time_series
|
||||
|
||||
from openpilot.sunnypilot.tools.lib.sunnypilot_car_segments import sunnypilot_car_segments_source
|
||||
|
||||
LogMessage = type[capnp._DynamicStructReader]
|
||||
LogIterable = Iterable[LogMessage]
|
||||
RawLogIterable = Iterable[bytes]
|
||||
@@ -246,7 +248,7 @@ class LogReader:
|
||||
def __init__(self, identifier: str | list[str], default_mode: ReadMode = ReadMode.RLOG,
|
||||
sources: list[Source] | None = None, sort_by_time=False, only_union_types=False):
|
||||
if sources is None:
|
||||
sources = [internal_source, comma_api_source, openpilotci_source, comma_car_segments_source]
|
||||
sources = [internal_source, comma_api_source, openpilotci_source, comma_car_segments_source, sunnypilot_car_segments_source]
|
||||
|
||||
self.default_mode = default_mode
|
||||
self.sources = sources
|
||||
|
||||
@@ -75,6 +75,7 @@ testing = [
|
||||
]
|
||||
|
||||
dev = [
|
||||
"huggingface_hub",
|
||||
"matplotlib",
|
||||
]
|
||||
|
||||
|
||||
@@ -5,6 +5,19 @@ requires-python = ">=3.12.3, <3.13"
|
||||
[manifest]
|
||||
overrides = [{ name = "opendbc", editable = "opendbc_repo" }]
|
||||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.14.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "idna" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/61/cc/a381afa6efea9f496eff839d4a6a1aed3bfafc7b3ab4b0d1b243a12573dd/anyio-4.14.2.tar.gz", hash = "sha256:cfa139f3ed1a23ee8f88a145ddb5ac7605b8bbfd8592baacd7ce3d8bb4313c7f", size = 260176, upload-time = "2026-07-12T20:29:07.082Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/da/35/f2287558c17e29fafc8ef3daf819bb9834061cfa43bff8014f7df7f63bdc/anyio-4.14.2-py3-none-any.whl", hash = "sha256:9f505dda5ac9f0c8309b5e8bd445a8c2bf7246f3ce950121e45ea15bc41d1494", size = 125813, upload-time = "2026-07-12T20:29:05.763Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "attrs"
|
||||
version = "26.1.0"
|
||||
@@ -395,6 +408,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/84/02fc1827e8cdded4aa65baef11296a9bbe595c474f0d6d758af082d849fd/execnet-2.1.2-py3-none-any.whl", hash = "sha256:67fba928dd5a544b783f6056f449e5e3931a5c378b128bc18501f7ea79e296ec", size = 40708, upload-time = "2025-11-12T09:56:36.333Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "filelock"
|
||||
version = "3.32.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f6/57/3ba6e6cb097f85b855b00163d169f35365f44277df044dcf96d55b8f62a3/filelock-3.32.2.tar.gz", hash = "sha256:c33351e1f49cae33414acbc6d56784e6ecee82514ec90795da1161fc4836b5b8", size = 217172, upload-time = "2026-07-29T22:46:04.895Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/e8/72f8cef9fdfeffe06213fe8508039396ee48daa0e3259457ed766173bfd6/filelock-3.32.2-py3-none-any.whl", hash = "sha256:87dd94cf281e586d135fa51132b8e3d9a598b316e90377a288663c9321036c82", size = 98830, upload-time = "2026-07-29T22:46:03.52Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fonttools"
|
||||
version = "4.63.0"
|
||||
@@ -412,6 +434,88 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/47/c99d5268f354002ce80f8d029cd9d7d872969da1de8b93d32de4dc56d6f4/fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d", size = 1164562, upload-time = "2026-05-14T12:04:29.092Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fsspec"
|
||||
version = "2026.7.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/00/78/f34251dadb8f3921264a1d9b8946f5e542014ee2614b285261b4e40e6775/fsspec-2026.7.0.tar.gz", hash = "sha256:c803c40f4cf860b49dea58ee3e1c33cb9c790520e233537e1340049f89b82a88", size = 317040, upload-time = "2026-07-28T16:34:51.052Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/3c/6a2bf344106328fd04963664a60b9bb6496fc25df8e962fcdc1367285fb9/fsspec-2026.7.0-py3-none-any.whl", hash = "sha256:b57ddbafedfaef7018c1ecab32aa200a9d7ca26b77965f64e48b70061249d279", size = 206583, upload-time = "2026-07-28T16:34:49.538Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h11"
|
||||
version = "0.16.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hf-xet"
|
||||
version = "1.6.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1b/ab/522a2ab67f27971a9d48ca666d4fca85ef7d5282d142e31fd087e27b1bbe/hf_xet-1.6.0.tar.gz", hash = "sha256:2e58454a340b3556dfa4972d5451aff4fba8dd42a236600ba1a1d2b1514f0fef", size = 920527, upload-time = "2026-08-03T22:33:13.243Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/50/7afa2c9c787405864fc47a0d1bbc02c62e9101947ed43c1f43899fc7d91d/hf_xet-1.6.0-cp38-abi3-macosx_10_12_x86_64.whl", hash = "sha256:633dc0cd71d32da58ab8c03ad38e2fac452c15c2b0a2866ebf6ededfe0a5061d", size = 4071729, upload-time = "2026-08-03T22:33:00.721Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/69/55b8dcf636142ae660fec1869fcac14c4da2e8412e14d6eee1523be77e9f/hf_xet-1.6.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:f0906082d9932ae0c0057fa194041c22b4e2cdb46b2592ef3b91f020d62a081a", size = 3876287, upload-time = "2026-08-03T22:33:02.251Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/4e/a28359bf1c1ecf11eba22123168c138698f7cb576ac678f5a2e16cd5da08/hf_xet-1.6.0-cp38-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d62671bb130879cef0ee4c9ebe47a14af6c66ec53e6d84dc15936e5ffdfac82f", size = 4464663, upload-time = "2026-08-03T22:33:03.802Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/69/1f0cbc2fb22ae6082d094f743d1b8945a3f36f6089cb95f42b7ee348cda7/hf_xet-1.6.0-cp38-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:0e6e21fa3cdfcdcd76748564bf593870a5e013f47d97cf10aed63aa222cff5b7", size = 4262538, upload-time = "2026-08-03T22:33:05.287Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/3a/4f4f2301ade26e404462d3336fa11f7958d914cabbabdd6e03c3c5d5658c/hf_xet-1.6.0-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:4fc74352a17015bd0ee90038bc9efe38db894cde45f268b6712b04fce8cd0acb", size = 4460520, upload-time = "2026-08-03T22:33:06.81Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/5f/311725e2a905534dfee2dcb5b08414f249147f1f12252bfc2bd24caa075c/hf_xet-1.6.0-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8fb4f71cba6129110c3374a33f919001ff130488fc23553698e34cc1c2a1198c", size = 4675937, upload-time = "2026-08-03T22:33:08.616Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/b7/8c59a66d15205024662f1d66968136f13893f96df1ddc5087e2e281fc95f/hf_xet-1.6.0-cp38-abi3-win_amd64.whl", hash = "sha256:fb4fadde1b2b70bf4c0c14a6dccbe7194b1c28947fefd5bbe3fed9d940676c3b", size = 4033128, upload-time = "2026-08-03T22:33:10.171Z" },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/63/ca511b6f802f28cf3489b280fe77475bcca8de85e81a6299d7916b5b5555/hf_xet-1.6.0-cp38-abi3-win_arm64.whl", hash = "sha256:3dc3e35441ba395006af5aaacc40ef2e603c51ef46c3530b9156185f00935ea3", size = 3859359, upload-time = "2026-08-03T22:33:11.725Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpcore"
|
||||
version = "1.0.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "certifi" },
|
||||
{ name = "h11" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
version = "0.28.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "certifi" },
|
||||
{ name = "httpcore" },
|
||||
{ name = "idna" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "huggingface-hub"
|
||||
version = "1.27.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "click" },
|
||||
{ name = "filelock" },
|
||||
{ name = "fsspec" },
|
||||
{ name = "hf-xet", marker = "platform_machine == 'AMD64' or platform_machine == 'aarch64' or platform_machine == 'amd64' or platform_machine == 'arm64' or platform_machine == 'x86_64'" },
|
||||
{ name = "httpx" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pyyaml" },
|
||||
{ name = "tqdm" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/3e/9b/ddf3d02a8681f1b9ce52fda03d755dad6b74c4f8172304c4c8d2975450f9/huggingface_hub-1.27.0.tar.gz", hash = "sha256:c1fed40ea82a6b41b477f5243546549b792ae0a93abcea608cff66089bf8f8df", size = 942668, upload-time = "2026-08-07T12:48:05.161Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/de/d8/95b735e183957c1f26d94c52977f09d466d55119cbbc1558ea4975e4c216/huggingface_hub-1.27.0-py3-none-any.whl", hash = "sha256:7df6827c2f956c60fbaa64646e979e566db76f619dd0a9729dfb8c5a3eb4f68d", size = 784926, upload-time = "2026-08-07T12:48:02.905Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hypothesis"
|
||||
version = "6.47.5"
|
||||
@@ -730,6 +834,7 @@ dependencies = [
|
||||
|
||||
[package.optional-dependencies]
|
||||
dev = [
|
||||
{ name = "huggingface-hub" },
|
||||
{ name = "matplotlib" },
|
||||
]
|
||||
docs = [
|
||||
@@ -788,6 +893,7 @@ requires-dist = [
|
||||
{ name = "comma-deps-zstd" },
|
||||
{ name = "coverage", marker = "extra == 'testing'" },
|
||||
{ name = "cython" },
|
||||
{ name = "huggingface-hub", marker = "extra == 'dev'" },
|
||||
{ name = "hypothesis", marker = "extra == 'testing'", specifier = "==6.47.*" },
|
||||
{ name = "inputs" },
|
||||
{ name = "jeepney" },
|
||||
@@ -1302,7 +1408,7 @@ provides-extras = ["dev"]
|
||||
|
||||
[[package]]
|
||||
name = "tinygrad"
|
||||
version = "0.12.0"
|
||||
version = "0.13.0"
|
||||
source = { editable = "tinygrad_repo" }
|
||||
|
||||
[package.metadata]
|
||||
@@ -1413,6 +1519,15 @@ wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/fc/6a183e71edde90d0c35c2303f23f7a45b6891d1a2c45daf7b8f869831e19/ty-0.0.56-py3-none-win_arm64.whl", hash = "sha256:57538f273d444a5f1293fa7860e967178afe3917611fc5eff16b64e1204fe0d6", size = 11538780, upload-time = "2026-07-01T16:44:53.8Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.16.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "urllib3"
|
||||
version = "2.7.0"
|
||||
|
||||
Reference in New Issue
Block a user