Compare commits

..

102 Commits

Author SHA1 Message Date
Jason Wen
f24986ee7a fix hkg canfd 2024-09-19 18:07:24 -04:00
Jason Wen
45739d199c fixes 2024-09-16 10:19:54 -04:00
Jason Wen
29c143e6ee unused 2024-09-16 00:16:38 -04:00
Jason Wen
6d51225a9a move to method 2024-09-16 00:12:51 -04:00
Jason Wen
2d130b41c3 decouple and implement for volkswagen (mqb & pq) 2024-09-16 00:04:44 -04:00
Jason Wen
cacdb08b05 updated 2024-09-15 23:09:53 -04:00
Jason Wen
ed5dbc4dd2 missed 2024-09-15 22:07:34 -04:00
Jason Wen
028a468290 init package 2024-09-15 22:03:11 -04:00
Jason Wen
5b3acfbaf6 Update helpers.py 2024-09-15 18:02:25 -04:00
Jason Wen
d54bc4d0b4 Fix 2024-09-15 17:57:22 -04:00
Jason Wen
bb1ed2489c no longer needed 2024-09-15 13:47:15 -04:00
Jason Wen
aee0a96e02 hkg rename 2024-09-15 10:58:17 -04:00
Jason Wen
cc5a6b7fa4 fixup! decouple and implement for honda 2024-09-15 03:54:50 -04:00
Jason Wen
4cb50eeb96 decouple and implement for mazda 2024-09-15 03:47:32 -04:00
Jason Wen
3014e01865 decouple and implement for honda 2024-09-15 03:41:31 -04:00
Jason Wen
fbde6d8d07 decouple and implement for fca 2024-09-15 03:30:43 -04:00
Jason Wen
457c82a3b1 todo for future investigation, default for now 2024-09-15 03:06:14 -04:00
Jason Wen
e73c5dfc1d fix min set speed 2024-09-15 03:00:58 -04:00
Jason Wen
31accc75f9 more consistent button sends thanks to multikyd! 2024-09-15 02:56:53 -04:00
Jason Wen
f34d61b9bd todo for future investigation, default for now 2024-09-15 02:47:05 -04:00
Jason Wen
b4b494e6e9 only update hold time when ready 2024-09-15 02:16:07 -04:00
Jason Wen
deafc23ea3 must check manual presses this way 2024-09-15 02:10:56 -04:00
Jason Wen
f113940993 fix hysteresis 2024-09-15 01:54:03 -04:00
Jason Wen
ddcabf9dea introduce random hold time (thanks to multikyd!) 2024-09-15 00:24:46 -04:00
Jason Wen
16354d4f63 initialize car state 2024-09-15 00:13:18 -04:00
Jason Wen
73e620245a add super 2024-09-15 00:11:24 -04:00
Jason Wen
2a62ca2600 set controller in constructor 2024-09-14 23:50:54 -04:00
Jason Wen
2d55dd0d12 flip them 2024-09-14 23:29:25 -04:00
Jason Wen
61b9db6666 explicit return type hint 2024-09-14 22:45:25 -04:00
Jason Wen
5135802760 newer platforms has pause/resume 2024-09-14 22:44:13 -04:00
Jason Wen
be46484b6e missing symlink 2024-09-14 22:33:13 -04:00
Jason Wen
12f6278f96 redundant 2024-09-14 22:32:24 -04:00
Jason Wen
53bed607bb check not is ready once 2024-09-14 22:31:41 -04:00
Jason Wen
6aaba7bda4 make sure to immediately apply state change 2024-09-14 21:18:54 -04:00
Jason Wen
8879d158f8 reset count in holding 2024-09-14 21:11:08 -04:00
Jason Wen
3889accb5d move timer to state base 2024-09-14 20:44:30 -04:00
Jason Wen
c8bef28d26 less is more 2024-09-14 20:39:07 -04:00
Jason Wen
3798118a76 always reset if not ready 2024-09-14 20:34:55 -04:00
Jason Wen
6e9a2eefeb more explicit inactive and loading 2024-09-14 20:24:45 -04:00
Jason Wen
6efef44bbe keep inactive simple 2024-09-14 20:21:14 -04:00
Jason Wen
4488ad70dd move to openpilot package 2024-09-14 20:00:29 -04:00
Jason Wen
9e3f15245e only 1 instance, so no need for list 2024-09-14 18:37:00 -04:00
Jason Wen
99b61454bd simplify 2024-09-14 18:27:23 -04:00
Jason Wen
cc720d2800 move subs to method 2024-09-14 18:21:12 -04:00
Jason Wen
69b43269c1 move speed hysteresis to helpers 2024-09-14 18:18:46 -04:00
Jason Wen
e2872e6f32 init list 2024-09-14 17:59:53 -04:00
Jason Wen
a3a202fa87 ready state refactor 2024-09-14 17:58:28 -04:00
Jason Wen
a5d6fe83ae diff 2024-09-14 17:50:38 -04:00
Jason Wen
a70f9a642d callable state classes 2024-09-14 17:42:24 -04:00
Jason Wen
c63c7d8bfd fixes 2024-09-14 17:30:29 -04:00
Jason Wen
931e79e801 fix publishing 2024-09-14 17:15:42 -04:00
Jason Wen
bc3f0fa6a4 fix typo 2024-09-14 00:24:07 -04:00
Jason Wen
121a863cbf refactor logging 2024-09-14 00:22:13 -04:00
Jason Wen
7f146c5cce less 2024-09-13 23:30:43 -04:00
Jason Wen
3b30419dee add loading state 2024-09-13 23:26:19 -04:00
Jason Wen
ddad143b7f decouple even more 2024-09-13 23:01:45 -04:00
Jason Wen
efa292ca3f it's ok in init only 2024-09-13 22:31:59 -04:00
Jason Wen
28c85087dc unused 2024-09-13 22:27:47 -04:00
Jason Wen
ca0a00b546 updated name 2024-09-13 22:27:29 -04:00
Jason Wen
6da758f53e set directly 2024-09-13 22:26:06 -04:00
Jason Wen
cb4ba22ac7 Assign to class var 2024-09-13 11:19:44 -04:00
Jason Wen
78d35cb24e rename base class 2024-09-13 09:25:48 -04:00
Jason Wen
3cc0656961 move to helpers 2024-09-13 09:24:25 -04:00
Jason Wen
675e9957f9 no longer used 2024-09-13 09:21:26 -04:00
Jason Wen
f2526cf0d1 entire obj 2024-09-13 09:19:49 -04:00
Jason Wen
cc4ebe717b refactor speed checks 2024-09-13 09:13:19 -04:00
Jason Wen
b54d7d486e typo 2024-09-13 08:57:45 -04:00
Jason Wen
814b623bfe simplify slc checks 2024-09-13 08:48:42 -04:00
Jason Wen
72b36d5482 use cereal 2024-09-13 08:48:03 -04:00
Jason Wen
cc59dabc09 type hint 2024-09-13 08:18:45 -04:00
Jason Wen
e5f9885288 typo 2024-09-13 08:18:31 -04:00
Jason Wen
4e81036d6c no longer used 2024-09-13 08:00:34 -04:00
Jason Wen
a0b09e7154 hyundai: decouple completely 2024-09-13 07:40:33 -04:00
Jason Wen
3097d451fe implement in card 2024-09-13 00:58:50 -04:00
Jason Wen
f90cfc2d0a unused 2024-09-13 00:39:44 -04:00
Jason Wen
cfc8878392 not needed 2024-09-13 00:37:34 -04:00
Jason Wen
da5a198bd0 new state machine 2024-09-13 00:33:10 -04:00
Jason Wen
cecf82e951 set point in base class only 2024-09-13 00:32:30 -04:00
Jason Wen
43b87b53f5 new set speed buttons 2024-09-13 00:30:03 -04:00
Jason Wen
9d84814aba new button mapping 2024-09-13 00:25:15 -04:00
Jason Wen
30718cba8b move to card 2024-09-13 00:11:28 -04:00
Jason Wen
48b7567e38 no need 2024-09-12 23:49:42 -04:00
Jason Wen
ddb1c92b2e new cereal name 2024-09-12 23:29:13 -04:00
Jason Wen
af5ea57188 pass car instead 2024-09-12 23:12:19 -04:00
Jason Wen
4be8029ead infra for carControlSP 2024-09-12 23:03:01 -04:00
Jason Wen
480da5f8b8 remove from car interface 2024-09-12 22:42:19 -04:00
Jason Wen
8d39d5045d cut it 2024-09-09 19:59:27 -04:00
Jason Wen
455aa3d140 more fix 2024-09-09 19:49:56 -04:00
Jason Wen
47bd75a1b1 fix 2024-09-09 19:48:41 -04:00
Jason Wen
c1d08539e7 services 2024-09-09 19:46:55 -04:00
Jason Wen
e8b4d7c5a8 cleaner 2024-09-09 19:24:56 -04:00
Jason Wen
659c2ab446 more 2024-09-09 19:20:50 -04:00
Jason Wen
8dff996b8b more simplify 2024-09-09 18:54:36 -04:00
Jason Wen
08ec79db30 simplify 2024-09-09 18:52:14 -04:00
Jason Wen
a88412f25a type hints 2024-09-06 03:31:54 -04:00
Jason Wen
73075c8b5a unused 2024-09-06 03:23:03 -04:00
Jason Wen
859b2fb29e implement for hyundai 2024-09-06 02:48:45 -04:00
Jason Wen
59a1122851 type hint 2024-09-06 02:43:00 -04:00
Jason Wen
4a9894d843 logging 2024-09-06 02:33:02 -04:00
Jason Wen
385d8c20d2 add hyundai 2024-09-06 02:26:18 -04:00
Jason Wen
43791061bb abstract out buttons 2024-09-06 02:26:13 -04:00
Jason Wen
8eff79892c init 2024-09-05 02:00:06 -04:00
149 changed files with 948 additions and 2193 deletions

View File

@@ -5,16 +5,9 @@ sunnypilot - 0.9.8.0 (2024-xx-xx)
* UPDATED: Synced with commaai's openpilot
* master commit 4ef757c (July 06, 2024)
* NEW❗: Default Driving Model: Notre Dame (July 01, 2024)
* NEW❗: Longitudinal: Acceleration Personality thanks to kegman, rav4kumar, and arne1282! (CTV 2.0: GlideTech)
* NEW❗: Longitudinal: Acceleration Personality thanks to kegman, rav4kumar, and arne1282!
* Select from three distinct acceleration personalities: Eco, Normal, and Sport
* Acceleration personalities are integrated directly into the model's acceleration matrix and can be activated in real-time!
* NEW❗: Toyota - Drive Mode Selector
* When enabled you can control acceleration personality just with press of button!
* UPDATED: Dynamic Experimental Control
* Switched to weighted moving averages to enhance responsiveness to recent data.
* Goal is to improve real-time detection accuracy in dynamic conditions.
* Capable of handling the increased complexity that comes with this approach.
* Particularly beneficial in environments where recent changes are critical to performance.
* NEW❗: Longitudinal: Dynamic Personality thanks to rav4kumar!
* Dynamically adjusts following distance and reaction based on your "Driving Personality" setting
* Personalities adapt in real-time to your speed and the distance to the lead car
@@ -33,14 +26,11 @@ sunnypilot - 0.9.8.0 (2024-xx-xx)
* Toyota TSS1/1.5, equipped with factory Blind Spot Monitoring (BSM)
* Prius TSS2, equipped with factory Blind Spot Monitoring (BSM)
* NOTE: Only enable this feature if your Toyota/Lexus vehicle has factory Blind Spot Monitor equipped, and mentioned in the supported platforms list
* UPDATED: Toyota: TSS2 longitudinal: Custom Tuning (CTV 2.0: GlideTech)
* Re-tuned and tested by the community (September 29, 2024)
* UPDATED: Toyota: TSS2 longitudinal: Custom Tuning
* Re-tuned and tested by the community (July 1, 2024)
* UPDATED: Driving Model Selector v5
* NEW❗: Driving Model additions
* Notre Dame (July 01, 2024) - NDv3
* UPDATED: Neural Network Lateral Control (NNLC)
* NEW❗: Remove Lateral Jerk Response (Alpha)
* FIXED: Hotfix for "lazy" steering performance in tighter curves thanks to twilsonco!
* UPDATED: Toyota: Continued support for Smart DSU (SDSU) and Radar CAN Filter
* In response to the official deprecation of support for Smart DSU (SDSU) and Radar CAN Filter in the upstream ([commaai/openpilot#32777](https://github.com/commaai/openpilot/pull/32777)), sunnypilot will continue maintaining software support for Smart DSU (SDSU) and Radar CAN Filter
* UPDATED: Continued support for Mapbox navigation
@@ -58,10 +48,6 @@ sunnypilot - 0.9.8.0 (2024-xx-xx)
* NEW❗: Time to Lead Car
* Displays the time to reach the position previously occupied by the lead car
* NEW❗: Display Distance, Speed, and Time to Lead Car simultaneously
* Ford F-150 2022-23 support
* Ford F-150 Lightning 2021-23 support
* Ford Mustang Mach-E 2021-23 support
* Hyundai Kona Electric Non-SCC 2019 support thanks to NikitaNekrasov!
* Kia Ceed Plug-in Hybrid Non-SCC 2022 support thanks to TerminatorNL!
sunnypilot - 0.9.7.1 (2024-06-13)
@@ -99,8 +85,6 @@ sunnypilot - 0.9.7.1 (2024-06-13)
* Force sunnypilot in the offroad state even when the car is on
* When Forced Offroad mode is on, allows changing offroad-only settings even when the car is turned on
* To engage/disengage Force Offroad, go to Settings -> Device panel
* NEW❗: Ford CAN-FD longitudinal
* NEW❗: Parse speed limit sign recognition from camera for certain supported platforms
* UPDATED: Auto Lane Change Timer -> Auto Lane Change by Blinker
* NEW❗: New "Off" option to disable lane change by blinker
* UPDATED: Pause Lateral Below Speed with Blinker
@@ -108,8 +92,6 @@ sunnypilot - 0.9.7.1 (2024-06-13)
* Pause lateral actuation with blinker when traveling below the desired speed selected. Default is 20 MPH or 32 km/h.
* UPDATED: Hyundai CAN Longitudinal
* Auto-enable radar tracks on platforms with applicable Mando radar
* UPDATED: Hyundai CAN-FD Radar-based SCC
* Longitudinal support for CAN-FD Radar-based SCC cars
* UPDATED: Hyundai CAN-FD Camera-based SCC
* NEW❗: Parse lead info for camera-based SCC platforms with longitudinal support
* Improve lead tracking when using openpilot longitudinal

View File

@@ -48,7 +48,6 @@ Join the official sunnypilot Discord server to stay up to date with all the late
To use sunnypilot in a car, you need the following:
* A supported device to run this software
* a [comma three](https://comma.ai/shop/products/three), or
* a comma two (only with older versions below 0.8.13)
* This software
* One of [the 250+ supported cars](https://github.com/commaai/openpilot/blob/master/docs/CARS.md). We support Honda, Toyota, Hyundai, Nissan, Kia, Chrysler, Lexus, Acura, Audi, VW, Ford and more. If your car is not supported but has adaptive cruise control and lane-keeping assist, it's likely able to run sunnypilot.
* A [car harness](https://comma.ai/shop/products/car-harness) to connect to your car
@@ -115,40 +114,12 @@ Please refer to [Recommended Branches](#-recommended-branches) to find your pref
Requires further assistance with software installation? Join the [sunnypilot Discord server](https://discord.sunnypilot.com) and message us in the `#installation-help` channel.
comma two
------
1. [Factory reset/uninstall](https://github.com/commaai/openpilot/wiki/FAQ#how-can-i-reset-the-device) the previous software if you have another software/fork installed.
2. After factory reset/uninstall and upon reboot, select `Custom Software` when given the option.
3. Input the installation URL per [Recommended Branches](#-recommended-branches). Example: ```https://smiskol.com/fork/sunnyhaibin/0.8.12-4-prod```
4. Complete the rest of the installation following the onscreen instructions.
Requires further assistance with software installation? Join the [sunnypilot Discord server](https://discord.sunnypilot.com) and message us in the `#installation-help` channel.
</details>
<details>
<summary>SSH (More Versatile)</summary>
<br>
Prerequisites: [How to SSH](https://github.com/commaai/openpilot/wiki/SSH)
If you are looking to install sunnypilot via SSH, run the following command in an SSH terminal after connecting to your device:
comma three:
------
* [`release-c3`](https://github.com/sunnyhaibin/openpilot/tree/release-c3):
```
cd /data; rm -rf ./openpilot; git clone -b release-c3 --recurse-submodules https://github.com/sunnyhaibin/sunnypilot.git openpilot; cd openpilot; sudo reboot
```
comma two:
------
* [`0.8.12-prod-personal-hkg`](https://github.com/sunnyhaibin/openpilot/tree/0.8.12-prod-personal-hkg):
```
cd /data; rm -rf ./openpilot; git clone -b 0.8.12-prod-personal-hkg --recurse-submodules https://github.com/sunnyhaibin/sunnypilot.git openpilot; cd openpilot; sudo reboot
cd /data && rm -rf ./openpilot && git clone -b release-c3 --recurse-submodules https://github.com/sunnyhaibin/sunnypilot.git openpilot && cd openpilot && sudo reboot
```
After running the command to install the desired branch, your comma device should reboot.
@@ -223,7 +194,7 @@ The goal of Modified Assistive Driving Safety (MADS) is to enhance the user driv
* `SET-` button enables ACC/SCC
* `CANCEL` button only disables ACC/SCC
* `CRUISE (MAIN)` must be `ON` to use ACC/SCC
* `CRUISE (MAIN)` button disables ACC/SCC completely when `OFF` **(strictly enforced in panda safety code)**
* `CRUISE (MAIN)` button disables sunnypilot completely when `OFF` **(strictly enforced in panda safety code)**
### Disengage Lateral ALC on Brake Press Mode toggle
Dedicated toggle to handle Lateral state on brake pedal press and release:
@@ -355,7 +326,7 @@ Example:
---
How-To instructions can be found in [HOW-TOS.md](https://github.com/sunnyhaibin/openpilot/blob/(!)README/HOW-TOS.md).
How-To instructions can be found in [HOW-TOS.md](HOW-TOS.md).
</details>

View File

@@ -16,7 +16,6 @@ enum LongitudinalPersonalitySP {
moderate @1;
standard @2;
relaxed @3;
overtake @4;
}
enum AccelerationPersonality {
@@ -35,17 +34,11 @@ enum ModelGeneration {
five @5;
}
enum MpcSource {
acc @0;
blended @1;
}
struct ControlsStateSP @0x81c2f05a394cf4af {
lateralState @0 :Text;
personality @8 :LongitudinalPersonalitySP;
dynamicPersonality @9 :Bool;
accelPersonality @10 :AccelerationPersonality;
overtakingAccelerationAssist @11 :Bool;
lateralControlState :union {
indiState @1 :LateralINDIState;
@@ -97,10 +90,8 @@ struct LongitudinalPlanSP @0xaedffd8f31e7b55d {
desiredTF @13 :Float32;
notSpeedLimit @14 :Int16;
e2eX @15 :List(Float32);
e2eBlendedDEPRECATED @18 :Text;
e2eBlended @18 :Text;
e2eStatus @22 :Bool;
mpcSource @23 :MpcSource;
dynamicExperimentalControl @24 :Bool;
distToTurn @7 :Float32;
turnSpeed @8 :Float32;
@@ -212,7 +203,24 @@ struct ModelDataV2SP @0xf98d843bfd7004a3 {
modelCapabilities @4 :UInt32;
}
struct CustomReserved7 @0xb86e6369214c01c8 {
struct CarControlSP @0xb86e6369214c01c8 {
customStockLongitudinalControl @0 :CustomStockLongitudinalControl;
struct CustomStockLongitudinalControl {
state @0 :ButtonControlState;
cruiseButton @1 :Int16;
finalSpeedKphDEPRECATED @2 :Float32;
vTarget @3 :Float32;
vCruiseCluster @4 :Float32;
enum ButtonControlState {
inactive @0; # No button press or default state
loading @1; # Loading state before transitioning to accelerating or decelerating
accelerating @2; # Increasing speed
decelerating @3; # Decreasing speed
holding @4; # Holding steady speed
}
}
}
struct CustomReserved8 @0xf416ec09499d9d19 {

View File

@@ -2388,7 +2388,7 @@ struct Event {
liveMapDataSP @111 :Custom.LiveMapDataSP;
e2eLongStateSP @112 :Custom.E2eLongStateSP;
modelV2SP @113 :Custom.ModelDataV2SP;
customReserved7 @114 :Custom.CustomReserved7;
carControlSP @114 :Custom.CarControlSP;
customReserved8 @115 :Custom.CustomReserved8;
customReserved9 @116 :Custom.CustomReserved9;

View File

@@ -83,6 +83,7 @@ _services: dict[str, tuple] = {
"liveMapDataSP": (True, 0.),
"e2eLongStateSP": (True, 0.),
"modelV2SP": (True, 20., 40),
"carControlSP": (True, 100., 10),
# debug
"uiDebug": (True, 0., 1),

View File

@@ -232,7 +232,6 @@ std::unordered_map<std::string, uint32_t> keys = {
{"CustomMapboxTokenSk", PERSISTENT | BACKUP},
{"CustomOffsets", PERSISTENT | BACKUP},
{"CustomStockLong", PERSISTENT | BACKUP},
{"CustomStockLongPlanner", PERSISTENT | BACKUP},
{"CustomTorqueLateral", PERSISTENT | BACKUP},
{"DevUIInfo", PERSISTENT | BACKUP},
{"DisableOnroadUploads", PERSISTENT | BACKUP},
@@ -263,9 +262,7 @@ std::unordered_map<std::string, uint32_t> keys = {
{"HasAcceptedTermsSP", PERSISTENT},
{"HideVEgoUi", PERSISTENT | BACKUP},
{"HyundaiCruiseMainDefault", PERSISTENT | BACKUP},
{"HkgCustomLongTuning", PERSISTENT | BACKUP},
{"HkgSmoothStop", PERSISTENT | BACKUP},
{"HyundaiCruiseMainDefault", PERSISTENT | BACKUP},
{"HotspotOnBoot", PERSISTENT},
{"HotspotOnBootConfirmed", PERSISTENT},
{"HyundaiRadarTracksAvailable", PERSISTENT},
@@ -287,7 +284,6 @@ std::unordered_map<std::string, uint32_t> keys = {
{"NavModelUrl", PERSISTENT | BACKUP},
{"NNFF", PERSISTENT | BACKUP},
{"NNFFCarModel", PERSISTENT | BACKUP},
{"NNFFNoLateralJerk", PERSISTENT | BACKUP},
{"OnroadScreenOff", PERSISTENT | BACKUP},
{"OnroadScreenOffBrightness", PERSISTENT | BACKUP},
{"OnroadScreenOffEvent", PERSISTENT | BACKUP},
@@ -298,11 +294,8 @@ std::unordered_map<std::string, uint32_t> keys = {
{"OsmLocationUrl", PERSISTENT},
{"OsmWayTest", PERSISTENT},
{"OsmDownloadedDate", PERSISTENT},
{"OvertakingAccelerationAssist", PERSISTENT},
{"PathOffset", PERSISTENT | BACKUP},
{"PauseLateralSpeed", PERSISTENT | BACKUP},
{"PCMVCruiseOverride", PERSISTENT | BACKUP},
{"PCMVCruiseOverrideSpeed", PERSISTENT | BACKUP},
{"QuietDrive", PERSISTENT | BACKUP},
{"RoadEdge", PERSISTENT | BACKUP},
{"ReverseAccChange", PERSISTENT | BACKUP},
@@ -327,12 +320,10 @@ std::unordered_map<std::string, uint32_t> keys = {
{"TermsVersionSunnypilot", PERSISTENT},
{"TorqueDeadzoneDeg", PERSISTENT | BACKUP},
{"TorqueFriction", PERSISTENT | BACKUP},
{"TorqueLateralJerk", PERSISTENT | BACKUP},
{"TorqueMaxLatAccel", PERSISTENT | BACKUP},
{"TorquedOverride", PERSISTENT | BACKUP},
{"ToyotaAutoLockBySpeed", PERSISTENT | BACKUP},
{"ToyotaAutoUnlockByShifter", PERSISTENT | BACKUP},
{"ToyotaDriveMode", PERSISTENT | BACKUP},
{"ToyotaEnhancedBsm", PERSISTENT | BACKUP},
{"ToyotaSnG", PERSISTENT | BACKUP},
{"ToyotaTSS2Long", PERSISTENT | BACKUP},

1
openpilot/sunnypilot Symbolic link
View File

@@ -0,0 +1 @@
../sunnypilot/

2
panda

Submodule panda updated: 55018eafc2...6a6cd44519

View File

@@ -1,4 +0,0 @@
third_party/libyuv/x86_64/**
third_party/snpe/x86_64/**
third_party/snpe/x86_64-linux-clang/**
third_party/acados/x86_64/**

View File

@@ -1,15 +0,0 @@
third_party/libyuv/larch64/**
third_party/snpe/larch64**
third_party/snpe/aarch64-ubuntu-gcc7.5/*
third_party/acados/larch64/**
system/camerad/cameras/camera_qcom2.cc
system/camerad/cameras/camera_qcom2.h
system/camerad/cameras/camera_util.cc
system/camerad/cameras/camera_util.h
system/camerad/cameras/process_raw.cl
system/qcomgpsd/*
selfdrive/ui/qt/spinner_larch64
selfdrive/ui/qt/text_larch64

View File

@@ -31,7 +31,7 @@ class Car:
def __init__(self, CI=None):
self.can_sock = messaging.sub_sock('can', timeout=20)
self.sm = messaging.SubMaster(['pandaStates', 'carControl', 'onroadEvents'])
self.pm = messaging.PubMaster(['sendcan', 'carState', 'carParams', 'carOutput'])
self.pm = messaging.PubMaster(['sendcan', 'carState', 'carParams', 'carOutput', 'carControlSP'])
self.can_rcv_cum_timeout_counter = 0
@@ -70,6 +70,12 @@ class Car:
if self.CP.customStockLongAvailable and self.CP.pcmCruise and self.params.get_bool("CustomStockLong"):
self.CP.pcmCruiseSpeed = False
services = self.sm.data.keys() | {'longitudinalPlanSP'}
self.sm = messaging.SubMaster(list(services))
cslc_path = f'openpilot.sunnypilot.selfdrive.car.{self.CP.carName}.custom_stock_longitudinal_controller'
CustomStockLongitudinalController = __import__(cslc_path + '.controller', fromlist=['CustomStockLongitudinalController']).CustomStockLongitudinalController
self.custom_stock_longitudinal_controller = CustomStockLongitudinalController(self, self.CI.CC, self.CI.CS, self.CP)
openpilot_enabled_toggle = self.params.get_bool("OpenpilotEnabledToggle")
@@ -175,8 +181,16 @@ class Car:
# send car controls over can
now_nanos = self.can_log_mono_time if REPLAY else int(time.monotonic() * 1e9)
self.last_actuators_output, can_sends = self.CI.apply(CC, now_nanos)
if not self.CP.pcmCruiseSpeed:
can_sends.extend(self.custom_stock_longitudinal_controller.update(CS, CC))
self.pm.send('sendcan', can_list_to_can_capnp(can_sends, msgtype='sendcan', valid=CS.canValid))
cc_send_sp = messaging.new_message('carControlSP')
cc_send_sp.valid = self.sm.all_checks(['carControl'])
if not self.CP.pcmCruiseSpeed:
cc_send_sp.carControlSP.customStockLongitudinalControl = self.custom_stock_longitudinal_controller.state_publish()
self.pm.send('carControlSP', cc_send_sp)
self.CC_prev = CC
def step(self):

View File

@@ -1,14 +1,10 @@
from cereal import car
import cereal.messaging as messaging
from common.conversions import Conversions as CV
from opendbc.can.packer import CANPacker
from openpilot.common.params import Params
from openpilot.selfdrive.car import DT_CTRL, apply_meas_steer_torque_limits
from openpilot.selfdrive.car import apply_meas_steer_torque_limits
from openpilot.selfdrive.car.chrysler import chryslercan
from openpilot.selfdrive.car.chrysler.values import RAM_CARS, RAM_DT, CarControllerParams, ChryslerFlags, ChryslerFlagsSP
from openpilot.selfdrive.car.interfaces import CarControllerBase, FORWARD_GEARS
from openpilot.selfdrive.controls.lib.drive_helpers import FCA_V_CRUISE_MIN
ButtonType = car.CarState.ButtonEvent.Type
@@ -26,64 +22,9 @@ class CarController(CarControllerBase):
self.packer = CANPacker(dbc_name)
self.params = CarControllerParams(CP)
self.sm = messaging.SubMaster(['longitudinalPlanSP'])
self.param_s = Params()
self.last_speed_limit_sign_tap_prev = False
self.speed_limit = 0.
self.speed_limit_offset = 0
self.timer = 0
self.final_speed_kph = 0
self.init_speed = 0
self.current_speed = 0
self.v_set_dis = 0
self.v_cruise_min = 0
self.button_type = 0
self.button_select = 0
self.button_count = 0
self.target_speed = 0
self.t_interval = 7
self.slc_active_stock = False
self.sl_force_active_timer = 0
self.v_tsc_state = 0
self.slc_state = 0
self.m_tsc_state = 0
self.cruise_button = None
self.speed_diff = 0
self.v_tsc = 0
self.m_tsc = 0
self.steady_speed = 0
self.button_frame = 0
def update(self, CC, CS, now_nanos):
if not self.CP.pcmCruiseSpeed:
self.sm.update(0)
if self.sm.updated['longitudinalPlanSP']:
self.v_tsc_state = self.sm['longitudinalPlanSP'].visionTurnControllerState
self.slc_state = self.sm['longitudinalPlanSP'].speedLimitControlState
self.m_tsc_state = self.sm['longitudinalPlanSP'].turnSpeedControlState
self.speed_limit = self.sm['longitudinalPlanSP'].speedLimit
self.speed_limit_offset = self.sm['longitudinalPlanSP'].speedLimitOffset
self.v_tsc = self.sm['longitudinalPlanSP'].visionTurnSpeed
self.m_tsc = self.sm['longitudinalPlanSP'].turnSpeed
self.v_cruise_min = FCA_V_CRUISE_MIN[CS.params_list.is_metric] * (CV.KPH_TO_MPH if not CS.params_list.is_metric else 1)
can_sends = []
if not self.CP.pcmCruiseSpeed:
if not self.last_speed_limit_sign_tap_prev and CS.params_list.last_speed_limit_sign_tap:
self.sl_force_active_timer = self.frame
self.param_s.put_bool_nonblocking("LastSpeedLimitSignTap", False)
self.last_speed_limit_sign_tap_prev = CS.params_list.last_speed_limit_sign_tap
sl_force_active = CS.params_list.speed_limit_control_enabled and (self.frame < (self.sl_force_active_timer * DT_CTRL + 2.0))
sl_inactive = not sl_force_active and (not CS.params_list.speed_limit_control_enabled or (True if self.slc_state == 0 else False))
sl_temp_inactive = not sl_force_active and (CS.params_list.speed_limit_control_enabled and (True if self.slc_state == 1 else False))
slc_active = not sl_inactive and not sl_temp_inactive
self.slc_active_stock = slc_active
lkas_active = CC.latActive and CS.madsEnabled
if self.frame % 10 == 0 and self.CP.carFingerprint not in RAM_CARS:
@@ -114,20 +55,6 @@ class CarController(CarControllerBase):
self.last_button_frame = self.frame
can_sends.append(chryslercan.create_cruise_buttons(self.packer, CS.button_counter + 1, das_bus, self.CP, resume=True))
if not (CC.cruiseControl.cancel or CC.cruiseControl.resume) and not self.CP.pcmCruiseSpeed and CS.out.cruiseState.enabled:
self.button_frame += 1
button_counter_offset = [1, 1, 0, None][self.button_frame % 4]
if ram_cars:
self.cruise_button = self.get_cruise_buttons(CS, CC.vCruise)
elif button_counter_offset is not None:
self.cruise_button = self.get_cruise_buttons(CS, CC.vCruise)
if self.cruise_button is not None:
if ram_cars:
can_sends.append(chryslercan.create_cruise_buttons(self.packer, CS.button_counter, das_bus, self.CP, buttons=self.cruise_button))
elif button_counter_offset is not None:
can_sends.append(chryslercan.create_cruise_buttons(self.packer, CS.button_counter + button_counter_offset, das_bus, self.CP, buttons=self.cruise_button))
# HUD alerts
if self.frame % 25 == 0:
if CS.lkas_car_model != -1:
@@ -179,122 +106,3 @@ class CarController(CarControllerBase):
new_actuators.steerOutputCan = self.apply_steer_last
return new_actuators, can_sends
# multikyd methods, sunnyhaibin logic
def get_cruise_buttons_status(self, CS):
if not CS.out.cruiseState.enabled:
for be in CS.out.buttonEvents:
if be.type in (ButtonType.accelCruise, ButtonType.decelCruise, ButtonType.resumeCruise) and be.pressed:
self.timer = 40
elif self.timer:
self.timer -= 1
else:
return 1
return 0
def get_target_speed(self, v_cruise_kph_prev):
v_cruise_kph = v_cruise_kph_prev
if self.slc_state > 1:
v_cruise_kph = (self.speed_limit + self.speed_limit_offset) * CV.MS_TO_KPH
if not self.slc_active_stock:
v_cruise_kph = v_cruise_kph_prev
return v_cruise_kph
def get_button_type(self, button_type):
self.type_status = "type_" + str(button_type)
self.button_picker = getattr(self, self.type_status, lambda: "default")
return self.button_picker()
def reset_button(self):
if self.button_type != 3:
self.button_type = 0
def type_default(self):
self.button_type = 0
return None
def type_0(self):
self.button_count = 0
self.target_speed = self.init_speed
self.speed_diff = self.target_speed - self.v_set_dis
if self.target_speed > self.v_set_dis:
self.button_type = 1
elif self.target_speed < self.v_set_dis and self.v_set_dis > self.v_cruise_min:
self.button_type = 2
return None
def type_1(self):
cruise_button = 1
self.button_count += 1
if self.target_speed <= self.v_set_dis:
self.button_count = 0
self.button_type = 3
elif self.button_count > 5:
self.button_count = 0
self.button_type = 3
return cruise_button
def type_2(self):
cruise_button = 2
self.button_count += 1
if self.target_speed >= self.v_set_dis or self.v_set_dis <= self.v_cruise_min:
self.button_count = 0
self.button_type = 3
elif self.button_count > 5:
self.button_count = 0
self.button_type = 3
return cruise_button
def type_3(self):
cruise_button = None
self.button_count += 1
if self.button_count > self.t_interval:
self.button_type = 0
return cruise_button
def get_curve_speed(self, target_speed_kph, v_cruise_kph_prev):
if self.v_tsc_state != 0:
vision_v_cruise_kph = self.v_tsc * CV.MS_TO_KPH
if int(vision_v_cruise_kph) == int(v_cruise_kph_prev):
vision_v_cruise_kph = 255
else:
vision_v_cruise_kph = 255
if self.m_tsc_state > 1:
map_v_cruise_kph = self.m_tsc * CV.MS_TO_KPH
if int(map_v_cruise_kph) == 0.0:
map_v_cruise_kph = 255
else:
map_v_cruise_kph = 255
curve_speed = self.curve_speed_hysteresis(min(vision_v_cruise_kph, map_v_cruise_kph) + 2 * CV.MPH_TO_KPH)
return min(target_speed_kph, curve_speed)
def get_button_control(self, CS, final_speed, v_cruise_kph_prev):
self.init_speed = round(min(final_speed, v_cruise_kph_prev) * (CV.KPH_TO_MPH if not CS.params_list.is_metric else 1))
self.v_set_dis = round(CS.out.cruiseState.speed * (CV.MS_TO_MPH if not CS.params_list.is_metric else CV.MS_TO_KPH))
cruise_button = self.get_button_type(self.button_type)
return cruise_button
def curve_speed_hysteresis(self, cur_speed: float, hyst=(0.75 * CV.MPH_TO_KPH)):
if cur_speed > self.steady_speed:
self.steady_speed = cur_speed
elif cur_speed < self.steady_speed - hyst:
self.steady_speed = cur_speed
return self.steady_speed
def get_cruise_buttons(self, CS, v_cruise_kph_prev):
cruise_button = None
if not self.get_cruise_buttons_status(CS):
pass
elif CS.out.cruiseState.enabled:
set_speed_kph = self.get_target_speed(v_cruise_kph_prev)
if self.slc_state > 1:
target_speed_kph = set_speed_kph
else:
target_speed_kph = min(v_cruise_kph_prev, set_speed_kph)
if self.v_tsc_state != 0 or self.m_tsc_state > 1:
self.final_speed_kph = self.get_curve_speed(target_speed_kph, v_cruise_kph_prev)
else:
self.final_speed_kph = target_speed_kph
cruise_button = self.get_button_control(CS, self.final_speed_kph, v_cruise_kph_prev) # MPH/KPH based button presses
return cruise_button

View File

@@ -65,14 +65,9 @@ def create_lkas_command(packer, CP, apply_steer, lkas_control_bit):
def create_cruise_buttons(packer, frame, bus, CP, cruise_buttons_msg=None, buttons=0, cancel=False, resume=False):
acc_accel = 1 if buttons == 1 else 0
acc_decel = 1 if buttons == 2 else 0
values = {
"ACC_Cancel": cancel,
"ACC_Resume": resume,
"ACC_Accel": acc_accel,
"ACC_Decel": acc_decel,
"COUNTER": frame % 0x10,
}

View File

@@ -161,8 +161,6 @@ class CarInterface(CarInterfaceBase):
if self.low_speed_alert:
events.add(car.CarEvent.EventName.belowSteerSpeed)
ret.customStockLong = self.update_custom_stock_long()
ret.events = events.to_msg()
return ret

View File

@@ -3,7 +3,7 @@ from opendbc.can.packer import CANPacker
from openpilot.common.numpy_fast import clip
from openpilot.selfdrive.car import apply_std_steer_angle_limits
from openpilot.selfdrive.car.ford import fordcan
from openpilot.selfdrive.car.ford.values import CarControllerParams, FordFlags, FordFlagsSP
from openpilot.selfdrive.car.ford.values import CarControllerParams, FordFlags
from openpilot.selfdrive.car.interfaces import CarControllerBase
LongCtrlState = car.CarControl.Actuators.LongControlState
@@ -35,9 +35,6 @@ class CarController(CarControllerBase):
self.lkas_enabled_last = False
self.steer_alert_last = False
self.lead_distance_bars_last = None
self.path_angle = 0.
self.path_offset = 0.
self.curvature_rate = 0.
def update(self, CC, CS, now_nanos):
can_sends = []
@@ -77,10 +74,7 @@ class CarController(CarControllerBase):
# TODO: extended mode
mode = 1 if CC.latActive else 0
counter = (self.frame // CarControllerParams.STEER_STEP) % 0x10
if self.CP.spFlags & FordFlagsSP.SP_ENHANCED_LAT_CONTROL.value:
can_sends.append(fordcan.create_lat_ctl2_msg(self.packer, self.CAN, mode, self.path_offset, self.path_angle, -apply_curvature, self.curvature_rate, counter))
else:
can_sends.append(fordcan.create_lat_ctl2_msg(self.packer, self.CAN, mode, 0., 0., -apply_curvature, 0., counter))
can_sends.append(fordcan.create_lat_ctl2_msg(self.packer, self.CAN, mode, 0., 0., -apply_curvature, 0., counter))
else:
can_sends.append(fordcan.create_lat_ctl_msg(self.packer, self.CAN, CC.latActive, 0., 0., -apply_curvature, 0.))

View File

@@ -24,7 +24,6 @@ class CarState(CarStateBase):
self.lkas_enabled = None
self.prev_lkas_enabled = None
self.v_limit = 0
self.button_states = {button.event_type: False for button in BUTTONS}
@@ -73,10 +72,6 @@ class CarState(CarStateBase):
ret.cruiseState.nonAdaptive = cp.vl["Cluster_Info1_FD1"]["AccEnbl_B_RqDrv"] == 0
ret.cruiseState.standstill = cp.vl["EngBrakeData"]["AccStopMde_D_Rq"] == 3
ret.accFaulted = cp.vl["EngBrakeData"]["CcStat_D_Actl"] in (1, 2)
if self.CP.flags & FordFlags.CANFD:
ret.cruiseState.speedLimit = self.update_traffic_signals(cp_cam)
if not self.CP.openpilotLongitudinalControl:
ret.accFaulted = ret.accFaulted or cp_cam.vl["ACCDATA"]["CmbbDeny_B_Actl"] == 1
@@ -134,16 +129,6 @@ class CarState(CarStateBase):
return ret
def update_traffic_signals(self, cp_cam):
# TODO: Check if CAN platforms have the same signals
if self.CP.flags & FordFlags.CANFD:
self.v_limit = cp_cam.vl["Traffic_RecognitnData"]["TsrVLim1MsgTxt_D_Rq"]
v_limit_unit = cp_cam.vl["Traffic_RecognitnData"]["TsrVlUnitMsgTxt_D_Rq"]
speed_factor = CV.MPH_TO_MS if v_limit_unit == 2 else CV.KPH_TO_MS if v_limit_unit == 1 else 0
return self.v_limit * speed_factor if self.v_limit not in (0, 255) else 0
@staticmethod
def get_can_parser(CP):
messages = [
@@ -200,11 +185,6 @@ class CarState(CarStateBase):
("IPMA_Data", 1),
]
if CP.flags & FordFlags.CANFD:
messages += [
("Traffic_RecognitnData", 1),
]
if CP.enableBsm and CP.flags & FordFlags.CANFD:
messages += [
("Side_Detect_L_Stat", 5),

View File

@@ -3,8 +3,7 @@ from panda import Panda
from openpilot.common.conversions import Conversions as CV
from openpilot.selfdrive.car import create_button_events, get_safety_config
from openpilot.selfdrive.car.ford.fordcan import CanBus
from openpilot.common.params import Params
from openpilot.selfdrive.car.ford.values import Ecu, FordFlags, FordFlagsSP
from openpilot.selfdrive.car.ford.values import Ecu, FordFlags
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
ButtonType = car.CarState.ButtonEvent.Type
@@ -19,15 +18,13 @@ class CarInterface(CarInterfaceBase):
@staticmethod
def _get_params(ret, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "ford"
ret.dashcamOnly = bool(ret.flags & FordFlags.CANFD)
ret.radarUnavailable = True
ret.steerControlType = car.CarParams.SteerControlType.angle
ret.steerActuatorDelay = 0.2
ret.steerLimitTimer = 1.0
if Params().get("DongleId", encoding='utf8') in ("4fde83db16dc0802", "112e4d6e0cad05e1", "e36b272d5679115f", "24574459dd7fb3e0", "83a4e056c7072678"):
ret.spFlags |= FordFlagsSP.SP_ENHANCED_LAT_CONTROL.value
CAN = CanBus(fingerprint=fingerprint)
cfgs = [get_safety_config(car.CarParams.SafetyModel.ford)]
if CAN.main >= 4:
@@ -54,13 +51,6 @@ class CarInterface(CarInterfaceBase):
if config_tja != 0xFF or config_lca != 0xFF:
ret.dashcamOnly = True
if ret.spFlags & FordFlagsSP.SP_ENHANCED_LAT_CONTROL:
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_FORD_ENHANCED_LAT_CONTROL
ret.longitudinalTuning.kpBP = [0.]
ret.longitudinalTuning.kpV = [0.5]
ret.longitudinalTuning.kiV = [0.]
# Auto Transmission: 0x732 ECU or Gear_Shift_by_Wire_FD1
found_ecus = [fw.ecu for fw in car_fw]
if Ecu.shiftByWire in found_ecus or 0x5A in fingerprint[CAN.main] or docs:

View File

@@ -11,7 +11,6 @@ DELPHI_ESR_RADAR_MSGS = list(range(0x500, 0x540))
DELPHI_MRR_RADAR_START_ADDR = 0x120
DELPHI_MRR_RADAR_MSG_COUNT = 64
STEER_ASSIST_DATA_MSGS = 0x3d7
def _create_delphi_esr_radar_can_parser(CP) -> CANParser:
msg_n = len(DELPHI_ESR_RADAR_MSGS)
@@ -29,9 +28,6 @@ def _create_delphi_mrr_radar_can_parser(CP) -> CANParser:
return CANParser(RADAR.DELPHI_MRR, messages, CanBus(CP).radar)
def _create_steer_assist_data(CP) -> CANParser:
messages = [("Steer_Assist_Data", 20)]
return CANParser(RADAR.STEER_ASSIST_DATA, messages, CanBus(CP).camera)
class RadarInterface(RadarInterfaceBase):
def __init__(self, CP):
@@ -49,10 +45,6 @@ class RadarInterface(RadarInterfaceBase):
elif self.radar == RADAR.DELPHI_MRR:
self.rcp = _create_delphi_mrr_radar_can_parser(CP)
self.trigger_msg = DELPHI_MRR_RADAR_START_ADDR + DELPHI_MRR_RADAR_MSG_COUNT - 1
elif self.radar == RADAR.STEER_ASSIST_DATA:
self.rcp = _create_steer_assist_data(CP)
self.trigger_msg = STEER_ASSIST_DATA_MSGS
else:
raise ValueError(f"Unsupported radar: {self.radar}")
@@ -76,67 +68,11 @@ class RadarInterface(RadarInterfaceBase):
self._update_delphi_esr()
elif self.radar == RADAR.DELPHI_MRR:
self._update_delphi_mrr()
elif self.radar == RADAR.STEER_ASSIST_DATA:
self._update_steer_assist_data()
ret.points = list(self.pts.values())
self.updated_messages.clear()
return ret
def _update_steer_assist_data(self):
msg = self.rcp.vl["Steer_Assist_Data"]
updated_msg = self.updated_messages
dRel = msg['CmbbObjDistLong_L_Actl']
confidence = msg['CmbbObjConfdnc_D_Stat']
new_track = False
# if dRel < 1022:
if confidence > 0:
if 0 not in self.pts:
self.pts[0] = car.RadarData.RadarPoint.new_message()
self.pts[0].trackId = self.track_id
self.vRelCol[0] = collections.deque(maxlen=20)
self.track_id += 1
new_track = True
yRel = msg['CmbbObjDistLat_L_Actl']
vRel = msg['CmbbObjRelLong_V_Actl']
yvRel = msg['CmbbObjRelLat_V_Actl']
calc = 0
if not new_track:
# if this is a newly created track - we don't have historical data so skip it
# if we are on the same track
# Let's see if we are moving:
# positive gap - lead is moving faster than us
# negative gap - lead is moving slower than us
dDiff = dRel - self.pts[0].dRel
if (abs(vRel) < 1.0e-2):
self.vRelCol[0].append(dDiff)
vRel = sum(self.vRelCol[0])
calc = 1
else:
if len(self.vRelCol[0]) > 0:
self.vRelCol[0].clear()
if abs(self.pts[0].vRel - vRel) > 2 or abs(self.pts[0].dRel - dRel) > 5:
self.pts[0].trackId = self.track_id
if len(self.vRelCol[0]) > 0:
self.vRelCol[0].clear()
self.track_id += 1
self.pts[0].dRel = dRel # from front of car
self.pts[0].yRel = yRel # in car frame's y axis, left is positive
self.pts[0].vRel = vRel
self.pts[0].aRel = float('nan')
self.pts[0].yvRel = yvRel
self.pts[0].measured = True
else:
if 0 in self.pts:
del self.pts[0]
del self.vRelCol[0]
def _update_delphi_esr(self):
for ii in sorted(self.updated_messages):
cpt = self.rcp.vl[ii]

View File

@@ -48,14 +48,9 @@ class FordFlags(IntFlag):
CANFD = 1
class FordFlagsSP(IntFlag):
SP_ENHANCED_LAT_CONTROL = 1
class RADAR:
DELPHI_ESR = 'ford_fusion_2018_adas'
DELPHI_MRR = 'FORD_CADS'
STEER_ASSIST_DATA = 'ford_lincoln_base_pt'
class Footnote(Enum):
@@ -96,7 +91,7 @@ class FordPlatformConfig(PlatformConfig):
@dataclass
class FordCANFDPlatformConfig(FordPlatformConfig):
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('ford_lincoln_base_pt', RADAR.STEER_ASSIST_DATA))
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('ford_lincoln_base_pt', None))
def init(self):
super().init()

View File

@@ -1,6 +1,4 @@
from cereal import car
import cereal.messaging as messaging
from openpilot.common.params import Params
from openpilot.common.conversions import Conversions as CV
from openpilot.common.numpy_fast import interp
from opendbc.can.packer import CANPacker
@@ -8,7 +6,6 @@ from openpilot.selfdrive.car import DT_CTRL, apply_driver_steer_torque_limits
from openpilot.selfdrive.car.gm import gmcan
from openpilot.selfdrive.car.gm.values import DBC, CanBus, CarControllerParams, CruiseButtons
from openpilot.selfdrive.car.interfaces import CarControllerBase
from selfdrive.controls.lib.drive_helpers import GM_V_CRUISE_MIN
VisualAlert = car.CarControl.HUDControl.VisualAlert
NetworkLocation = car.CarParams.NetworkLocation
@@ -40,36 +37,6 @@ class CarController(CarControllerBase):
self.packer_obj = CANPacker(DBC[self.CP.carFingerprint]['radar'])
self.packer_ch = CANPacker(DBC[self.CP.carFingerprint]['chassis'])
self.sm = messaging.SubMaster(['longitudinalPlanSP'])
self.param_s = Params()
self.is_metric = self.param_s.get_bool("IsMetric")
self.speed_limit_control_enabled = False
self.last_speed_limit_sign_tap = False
self.last_speed_limit_sign_tap_prev = False
self.speed_limit = 0.
self.speed_limit_offset = 0
self.timer = 0
self.final_speed_kph = 0
self.init_speed = 0
self.current_speed = 0
self.v_set_dis = 0
self.v_cruise_min = 0
self.button_type = 0
self.button_select = 0
self.button_count = 0
self.target_speed = 0
self.t_interval = 7
self.slc_active_stock = False
self.sl_force_active_timer = 0
self.v_tsc_state = 0
self.slc_state = 0
self.m_tsc_state = 0
self.cruise_button = None
self.speed_diff = 0
self.v_tsc = 0
self.m_tsc = 0
self.steady_speed = 0
def update(self, CC, CS, now_nanos):
actuators = CC.actuators
hud_control = CC.hudControl
@@ -78,40 +45,9 @@ class CarController(CarControllerBase):
if hud_v_cruise > 70:
hud_v_cruise = 0
if not self.CP.pcmCruiseSpeed:
self.sm.update(0)
if self.sm.updated['longitudinalPlanSP']:
self.v_tsc_state = self.sm['longitudinalPlanSP'].visionTurnControllerState
self.slc_state = self.sm['longitudinalPlanSP'].speedLimitControlState
self.m_tsc_state = self.sm['longitudinalPlanSP'].turnSpeedControlState
self.speed_limit = self.sm['longitudinalPlanSP'].speedLimit
self.speed_limit_offset = self.sm['longitudinalPlanSP'].speedLimitOffset
self.v_tsc = self.sm['longitudinalPlanSP'].visionTurnSpeed
self.m_tsc = self.sm['longitudinalPlanSP'].turnSpeed
if self.frame % 200 == 0:
self.speed_limit_control_enabled = self.param_s.get_bool("EnableSlc")
self.is_metric = self.param_s.get_bool("IsMetric")
self.last_speed_limit_sign_tap = self.param_s.get_bool("LastSpeedLimitSignTap")
self.v_cruise_min = GM_V_CRUISE_MIN[self.is_metric] * (CV.KPH_TO_MPH if not self.is_metric else 1)
# Send CAN commands.
can_sends = []
if not self.CP.pcmCruiseSpeed:
if not self.last_speed_limit_sign_tap_prev and self.last_speed_limit_sign_tap:
self.sl_force_active_timer = self.frame
self.param_s.put_bool_nonblocking("LastSpeedLimitSignTap", False)
self.last_speed_limit_sign_tap_prev = self.last_speed_limit_sign_tap
sl_force_active = self.speed_limit_control_enabled and (self.frame < (self.sl_force_active_timer * DT_CTRL + 2.0))
sl_inactive = not sl_force_active and (not self.speed_limit_control_enabled or (True if self.slc_state == 0 else False))
sl_temp_inactive = not sl_force_active and (self.speed_limit_control_enabled and (True if self.slc_state == 1 else False))
slc_active = not sl_inactive and not sl_temp_inactive
self.slc_active_stock = slc_active
# Steering (Active: 50Hz, inactive: 10Hz)
steer_step = self.params.STEER_STEP if CC.latActive else self.params.INACTIVE_STEER_STEP
@@ -212,15 +148,6 @@ class CarController(CarControllerBase):
self.last_button_frame = self.frame
can_sends.append(gmcan.create_buttons(self.packer_pt, CanBus.CAMERA, CS.buttons_counter, CruiseButtons.CANCEL))
if not (CC.cruiseControl.cancel or CC.cruiseControl.resume) and not self.CP.pcmCruiseSpeed and CS.out.cruiseState.enabled:
self.cruise_button = self.get_cruise_buttons(CS, CC.vCruise)
if self.cruise_button is not None:
send_freq = 1
if not (self.v_tsc_state != 0 or self.m_tsc_state > 1) and abs(self.target_speed - self.v_set_dis) <= 2:
send_freq = 3
if self.frame % 12 < 6: # thanks to mochi86420 for the magic numbers
can_sends.extend([gmcan.create_buttons(self.packer_pt, CanBus.CAMERA, (CS.buttons_counter + 2) % 4, self.cruise_button)] * 3)
if self.CP.networkLocation == NetworkLocation.fwdCamera:
# Silence "Take Steering" alert sent by camera, forward PSCMStatus with HandsOffSWlDetectionStatus=1
if self.frame % 10 == 0:
@@ -234,120 +161,3 @@ class CarController(CarControllerBase):
self.frame += 1
return new_actuators, can_sends
# multikyd methods, sunnyhaibin logic
def get_cruise_buttons_status(self, CS):
if not CS.out.cruiseState.enabled or CS.cruise_buttons != CruiseButtons.UNPRESS:
self.timer = 40
elif self.timer:
self.timer -= 1
else:
return 1
return 0
def get_target_speed(self, v_cruise_kph_prev):
v_cruise_kph = v_cruise_kph_prev
if self.slc_state > 1:
v_cruise_kph = (self.speed_limit + self.speed_limit_offset) * CV.MS_TO_KPH
if not self.slc_active_stock:
v_cruise_kph = v_cruise_kph_prev
return v_cruise_kph
def get_button_type(self, button_type):
self.type_status = "type_" + str(button_type)
self.button_picker = getattr(self, self.type_status, lambda: "default")
return self.button_picker()
def reset_button(self):
if self.button_type != 3:
self.button_type = 0
def type_default(self):
self.button_type = 0
return None
def type_0(self):
self.button_count = 0
self.target_speed = self.init_speed
self.speed_diff = self.target_speed - self.v_set_dis
if self.target_speed > self.v_set_dis:
self.button_type = 1
elif self.target_speed < self.v_set_dis and self.v_set_dis > self.v_cruise_min:
self.button_type = 2
return None
def type_1(self):
cruise_button = CruiseButtons.RES_ACCEL
self.button_count += 1
if self.target_speed <= self.v_set_dis:
self.button_count = 0
self.button_type = 3
elif self.button_count > 5:
self.button_count = 0
self.button_type = 3
return cruise_button
def type_2(self):
cruise_button = CruiseButtons.DECEL_SET
self.button_count += 1
if self.target_speed >= self.v_set_dis or self.v_set_dis <= self.v_cruise_min:
self.button_count = 0
self.button_type = 3
elif self.button_count > 5:
self.button_count = 0
self.button_type = 3
return cruise_button
def type_3(self):
cruise_button = CruiseButtons.UNPRESS
self.button_count += 1
if self.button_count > self.t_interval:
self.button_type = 0
return cruise_button
def get_curve_speed(self, target_speed_kph, v_cruise_kph_prev):
if self.v_tsc_state != 0:
vision_v_cruise_kph = self.v_tsc * CV.MS_TO_KPH
if int(vision_v_cruise_kph) == int(v_cruise_kph_prev):
vision_v_cruise_kph = 255
else:
vision_v_cruise_kph = 255
if self.m_tsc_state > 1:
map_v_cruise_kph = self.m_tsc * CV.MS_TO_KPH
if int(map_v_cruise_kph) == 0.0:
map_v_cruise_kph = 255
else:
map_v_cruise_kph = 255
curve_speed = self.curve_speed_hysteresis(min(vision_v_cruise_kph, map_v_cruise_kph) + 2 * CV.MPH_TO_KPH)
return min(target_speed_kph, curve_speed)
def get_button_control(self, CS, final_speed, v_cruise_kph_prev):
self.init_speed = round(min(final_speed, v_cruise_kph_prev) * (CV.KPH_TO_MPH if not self.is_metric else 1))
self.v_set_dis = round(CS.out.cruiseState.speed * (CV.MS_TO_MPH if not self.is_metric else CV.MS_TO_KPH))
cruise_button = self.get_button_type(self.button_type)
return cruise_button
def curve_speed_hysteresis(self, cur_speed: float, hyst=(0.75 * CV.MPH_TO_KPH)):
if cur_speed > self.steady_speed:
self.steady_speed = cur_speed
elif cur_speed < self.steady_speed - hyst:
self.steady_speed = cur_speed
return self.steady_speed
def get_cruise_buttons(self, CS, v_cruise_kph_prev):
cruise_button = None
if not self.get_cruise_buttons_status(CS):
pass
elif CS.out.cruiseState.enabled:
set_speed_kph = self.get_target_speed(v_cruise_kph_prev)
if self.slc_state > 1:
target_speed_kph = set_speed_kph
else:
target_speed_kph = min(v_cruise_kph_prev, set_speed_kph)
if self.v_tsc_state != 0 or self.m_tsc_state > 1:
self.final_speed_kph = self.get_curve_speed(target_speed_kph, v_cruise_kph_prev)
else:
self.final_speed_kph = target_speed_kph
cruise_button = self.get_button_control(CS, self.final_speed_kph, v_cruise_kph_prev) # MPH/KPH based button presses
return cruise_button

View File

@@ -119,7 +119,6 @@ class CarInterface(CarInterfaceBase):
ret.pcmCruise = False
ret.openpilotLongitudinalControl = True
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_GM_HW_CAM_LONG
ret.customStockLongAvailable = True
else: # ASCM, OBD-II harness
ret.openpilotLongitudinalControl = True
@@ -237,7 +236,7 @@ class CarInterface(CarInterfaceBase):
else:
self.CS.madsEnabled = False
if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0) or not self.CP.pcmCruiseSpeed:
if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0):
if any(b.type == ButtonType.cancel for b in self.CS.button_events):
self.get_sp_cancel_cruise_state()
if self.get_sp_pedal_disengage(ret):
@@ -278,8 +277,6 @@ class CarInterface(CarInterfaceBase):
if ret.vEgo < self.CP.minSteerSpeed and self.CS.madsEnabled:
events.add(EventName.belowSteerSpeed)
ret.customStockLong = self.update_custom_stock_long()
ret.events = events.to_msg()
return ret

View File

@@ -1,16 +1,12 @@
from collections import namedtuple
from cereal import car
import cereal.messaging as messaging
from openpilot.common.conversions import Conversions as CV
from openpilot.common.numpy_fast import clip, interp
from openpilot.common.params import Params
from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import DT_CTRL, rate_limit, make_tester_present_msg, create_gas_interceptor_command
from openpilot.selfdrive.car.honda import hondacan
from openpilot.selfdrive.car.honda.values import CruiseButtons, VISUAL_HUD, HONDA_BOSCH, HONDA_BOSCH_RADARLESS, HONDA_NIDEC_ALT_PCM_ACCEL, CarControllerParams
from openpilot.selfdrive.car.interfaces import CarControllerBase
from openpilot.selfdrive.controls.lib.drive_helpers import HONDA_V_CRUISE_MIN
VisualAlert = car.CarControl.HUDControl.VisualAlert
LongCtrlState = car.CarControl.Actuators.LongControlState
@@ -128,48 +124,7 @@ class CarController(CarControllerBase):
self.last_steer = 0.0
self.last_button_frame = 0
self.sm = messaging.SubMaster(['longitudinalPlanSP'])
self.param_s = Params()
self.last_speed_limit_sign_tap_prev = False
self.speed_limit = 0.
self.speed_limit_offset = 0
self.timer = 0
self.final_speed_kph = 0
self.init_speed = 0
self.current_speed = 0
self.v_set_dis = 0
self.v_cruise_min = 0
self.button_type = 0
self.button_select = 0
self.button_count = 0
self.target_speed = 0
self.t_interval = 7
self.slc_active_stock = False
self.sl_force_active_timer = 0
self.v_tsc_state = 0
self.slc_state = 0
self.m_tsc_state = 0
self.cruise_button = None
self.speed_diff = 0
self.v_tsc = 0
self.m_tsc = 0
self.steady_speed = 0
def update(self, CC, CS, now_nanos):
if not self.CP.pcmCruiseSpeed:
self.sm.update(0)
if self.sm.updated['longitudinalPlanSP']:
self.v_tsc_state = self.sm['longitudinalPlanSP'].visionTurnControllerState
self.slc_state = self.sm['longitudinalPlanSP'].speedLimitControlState
self.m_tsc_state = self.sm['longitudinalPlanSP'].turnSpeedControlState
self.speed_limit = self.sm['longitudinalPlanSP'].speedLimit
self.speed_limit_offset = self.sm['longitudinalPlanSP'].speedLimitOffset
self.v_tsc = self.sm['longitudinalPlanSP'].visionTurnSpeed
self.m_tsc = self.sm['longitudinalPlanSP'].turnSpeed
self.v_cruise_min = HONDA_V_CRUISE_MIN[CS.params_list.is_metric] * (CV.KPH_TO_MPH if not CS.params_list.is_metric else 1)
actuators = CC.actuators
hud_control = CC.hudControl
conversion = hondacan.get_cruise_speed_conversion(self.CP.carFingerprint, CS.is_metric)
@@ -203,19 +158,6 @@ class CarController(CarControllerBase):
apply_steer = int(interp(-limited_steer * self.params.STEER_MAX,
self.params.STEER_LOOKUP_BP, self.params.STEER_LOOKUP_V))
if not self.CP.pcmCruiseSpeed:
if not self.last_speed_limit_sign_tap_prev and CS.params_list.last_speed_limit_sign_tap:
self.sl_force_active_timer = self.frame
self.param_s.put_bool_nonblocking("LastSpeedLimitSignTap", False)
self.last_speed_limit_sign_tap_prev = CS.params_list.last_speed_limit_sign_tap
sl_force_active = CS.params_list.speed_limit_control_enabled and (self.frame < (self.sl_force_active_timer * DT_CTRL + 2.0))
sl_inactive = not sl_force_active and (not CS.params_list.speed_limit_control_enabled or (True if self.slc_state == 0 else False))
sl_temp_inactive = not sl_force_active and (CS.params_list.speed_limit_control_enabled and (True if self.slc_state == 1 else False))
slc_active = not sl_inactive and not sl_temp_inactive
self.slc_active_stock = slc_active
# Send CAN commands
can_sends = []
@@ -265,15 +207,6 @@ class CarController(CarControllerBase):
can_sends.append(hondacan.spam_buttons_command(self.packer, self.CAN, CruiseButtons.CANCEL, self.CP.carFingerprint))
elif CC.cruiseControl.resume:
can_sends.append(hondacan.spam_buttons_command(self.packer, self.CAN, CruiseButtons.RES_ACCEL, self.CP.carFingerprint))
elif CS.out.cruiseState.enabled and not self.CP.pcmCruiseSpeed:
self.cruise_button = self.get_cruise_buttons(CS, CC.vCruise)
if self.cruise_button is not None:
send_freq = 1
if not (self.v_tsc_state != 0 or self.m_tsc_state > 1) and abs(self.target_speed - self.v_set_dis) <= 2:
send_freq = 3
if (self.frame - self.last_button_frame) * DT_CTRL > 0.01 * send_freq:
can_sends.append(hondacan.spam_buttons_command(self.packer, self.CAN, self.cruise_button, self.CP.carFingerprint))
self.last_button_frame = self.frame
else:
# Send gas and brake commands.
@@ -335,120 +268,3 @@ class CarController(CarControllerBase):
self.frame += 1
return new_actuators, can_sends
# multikyd methods, sunnyhaibin logic
def get_cruise_buttons_status(self, CS):
if not CS.out.cruiseState.enabled or CS.cruise_buttons != 0:
self.timer = 40
elif self.timer:
self.timer -= 1
else:
return 1
return 0
def get_target_speed(self, v_cruise_kph_prev):
v_cruise_kph = v_cruise_kph_prev
if self.slc_state > 1:
v_cruise_kph = (self.speed_limit + self.speed_limit_offset) * CV.MS_TO_KPH
if not self.slc_active_stock:
v_cruise_kph = v_cruise_kph_prev
return v_cruise_kph
def get_button_type(self, button_type):
self.type_status = "type_" + str(button_type)
self.button_picker = getattr(self, self.type_status, lambda: "default")
return self.button_picker()
def reset_button(self):
if self.button_type != 3:
self.button_type = 0
def type_default(self):
self.button_type = 0
return None
def type_0(self):
self.button_count = 0
self.target_speed = self.init_speed
self.speed_diff = self.target_speed - self.v_set_dis
if self.target_speed > self.v_set_dis:
self.button_type = 1
elif self.target_speed < self.v_set_dis and self.v_set_dis > self.v_cruise_min:
self.button_type = 2
return None
def type_1(self):
cruise_button = CruiseButtons.RES_ACCEL
self.button_count += 1
if self.target_speed <= self.v_set_dis:
self.button_count = 0
self.button_type = 3
elif self.button_count > 5:
self.button_count = 0
self.button_type = 3
return cruise_button
def type_2(self):
cruise_button = CruiseButtons.DECEL_SET
self.button_count += 1
if self.target_speed >= self.v_set_dis or self.v_set_dis <= self.v_cruise_min:
self.button_count = 0
self.button_type = 3
elif self.button_count > 5:
self.button_count = 0
self.button_type = 3
return cruise_button
def type_3(self):
cruise_button = None
self.button_count += 1
if self.button_count > self.t_interval:
self.button_type = 0
return cruise_button
def get_curve_speed(self, target_speed_kph, v_cruise_kph_prev):
if self.v_tsc_state != 0:
vision_v_cruise_kph = self.v_tsc * CV.MS_TO_KPH
if int(vision_v_cruise_kph) == int(v_cruise_kph_prev):
vision_v_cruise_kph = 255
else:
vision_v_cruise_kph = 255
if self.m_tsc_state > 1:
map_v_cruise_kph = self.m_tsc * CV.MS_TO_KPH
if int(map_v_cruise_kph) == 0.0:
map_v_cruise_kph = 255
else:
map_v_cruise_kph = 255
curve_speed = self.curve_speed_hysteresis(min(vision_v_cruise_kph, map_v_cruise_kph) + 2 * CV.MPH_TO_KPH)
return min(target_speed_kph, curve_speed)
def get_button_control(self, CS, final_speed, v_cruise_kph_prev):
self.init_speed = round(min(final_speed, v_cruise_kph_prev) * (CV.KPH_TO_MPH if not CS.params_list.is_metric else 1))
self.v_set_dis = round(CS.out.cruiseState.speed * (CV.MS_TO_MPH if not CS.params_list.is_metric else CV.MS_TO_KPH))
cruise_button = self.get_button_type(self.button_type)
return cruise_button
def curve_speed_hysteresis(self, cur_speed: float, hyst=(0.75 * CV.MPH_TO_KPH)):
if cur_speed > self.steady_speed:
self.steady_speed = cur_speed
elif cur_speed < self.steady_speed - hyst:
self.steady_speed = cur_speed
return self.steady_speed
def get_cruise_buttons(self, CS, v_cruise_kph_prev):
cruise_button = None
if not self.get_cruise_buttons_status(CS):
pass
elif CS.out.cruiseState.enabled:
set_speed_kph = self.get_target_speed(v_cruise_kph_prev)
if self.slc_state > 1:
target_speed_kph = set_speed_kph
else:
target_speed_kph = min(v_cruise_kph_prev, set_speed_kph)
if self.v_tsc_state != 0 or self.m_tsc_state > 1:
self.final_speed_kph = self.get_curve_speed(target_speed_kph, v_cruise_kph_prev)
else:
self.final_speed_kph = target_speed_kph
cruise_button = self.get_button_control(CS, self.final_speed_kph, v_cruise_kph_prev) # MPH/KPH based button presses
return cruise_button

View File

@@ -329,8 +329,6 @@ class CarInterface(CarInterfaceBase):
if self.CS.CP.minEnableSpeed > 0 and ret.vEgo < 0.001:
events.add(EventName.manualRestart)
ret.customStockLong = self.update_custom_stock_long()
ret.events = events.to_msg()
return ret

View File

@@ -1,15 +1,14 @@
from cereal import car
import cereal.messaging as messaging
from openpilot.common.conversions import Conversions as CV
from openpilot.common.numpy_fast import clip, interp
from openpilot.common.numpy_fast import clip
from openpilot.common.params import Params
from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import DT_CTRL, apply_driver_steer_torque_limits, common_fault_avoidance, make_tester_present_msg
from openpilot.selfdrive.car.hyundai import hyundaicanfd, hyundaican
from openpilot.selfdrive.car.hyundai.hyundaicanfd import CanBus
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, HyundaiFlagsSP, Buttons, CarControllerParams, CANFD_CAR, CAR, CAMERA_SCC_CAR, LEGACY_SAFETY_MODE_CAR
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, HyundaiFlagsSP, Buttons, CarControllerParams, CANFD_CAR, CAR, CAMERA_SCC_CAR
from openpilot.selfdrive.car.interfaces import CarControllerBase
from openpilot.selfdrive.controls.lib.drive_helpers import HYUNDAI_V_CRUISE_MIN
VisualAlert = car.CarControl.HUDControl.VisualAlert
LongCtrlState = car.CarControl.Actuators.LongControlState
@@ -62,56 +61,13 @@ class CarController(CarControllerBase):
self.lat_disengage_init = False
self.lat_active_last = False
sub_services = ['longitudinalPlan', 'longitudinalPlanSP']
if CP.openpilotLongitudinalControl:
sub_services.append('radarState')
# TODO: Always true, prep for future conditional refactoring
if sub_services:
self.sm = messaging.SubMaster(sub_services)
self.sm = messaging.SubMaster(['radarState'])
self.param_s = Params()
self.last_speed_limit_sign_tap_prev = False
self.speed_limit = 0.
self.speed_limit_offset = 0
self.timer = 0
self.final_speed_kph = 0
self.init_speed = 0
self.current_speed = 0
self.v_set_dis = 0
self.v_cruise_min = 0
self.button_type = 0
self.button_select = 0
self.button_count = 0
self.target_speed = 0
self.t_interval = 7
self.slc_active_stock = False
self.sl_force_active_timer = 0
self.v_tsc_state = 0
self.slc_state = 0
self.m_tsc_state = 0
self.cruise_button = None
self.speed_diff = 0
self.v_tsc = 0
self.m_tsc = 0
self.steady_speed = 0
self.speeds = 0
self.v_target_plan = 0
self.custom_stock_planner_speed = self.param_s.get_bool("CustomStockLongPlanner")
self.hkg_can_smooth_stop = self.param_s.get_bool("HkgSmoothStop")
self.lead_distance = 0
self.jerk = 0.0
self.jerk_l = 0.0
self.jerk_u = 0.0
self.jerkStartLimit = 2.0
self.cb_upper = 0.0
self.cb_lower = 0.0
self.jerk_count = 0.0
self.accel_raw = 0
self.accel_val = 0
self.accel_last_jerk = 0
self.hkg_custom_long_tuning = self.param_s.get_bool("HkgCustomLongTuning")
def calculate_lead_distance(self, hud_control: car.CarControl.HUDControl) -> float:
lead_one = self.sm["radarState"].leadOne
lead_two = self.sm["radarState"].leadTwo
@@ -124,38 +80,15 @@ class CarController(CarControllerBase):
return 19 if hud_control.leadVisible else 0
def update(self, CC, CS, now_nanos):
if not self.CP.pcmCruiseSpeed or (self.CP.openpilotLongitudinalControl and self.frame % 5 == 0):
if self.CP.openpilotLongitudinalControl and self.frame % 5 == 0:
self.sm.update(0)
if not self.CP.pcmCruiseSpeed:
if self.sm.updated['longitudinalPlan']:
_speeds = self.sm['longitudinalPlan'].speeds
self.speeds = _speeds[-1] if len(_speeds) else 0
if self.sm.updated['longitudinalPlanSP']:
self.v_tsc_state = self.sm['longitudinalPlanSP'].visionTurnControllerState
self.slc_state = self.sm['longitudinalPlanSP'].speedLimitControlState
self.m_tsc_state = self.sm['longitudinalPlanSP'].turnSpeedControlState
self.speed_limit = self.sm['longitudinalPlanSP'].speedLimit
self.speed_limit_offset = self.sm['longitudinalPlanSP'].speedLimitOffset
self.v_tsc = self.sm['longitudinalPlanSP'].visionTurnSpeed
self.m_tsc = self.sm['longitudinalPlanSP'].turnSpeed
if self.frame % 200 == 0:
self.custom_stock_planner_speed = self.param_s.get_bool("CustomStockLongPlanner")
self.v_cruise_min = HYUNDAI_V_CRUISE_MIN[CS.params_list.is_metric] * (CV.KPH_TO_MPH if not CS.params_list.is_metric else 1)
self.v_target_plan = min(CC.vCruise * CV.KPH_TO_MS, self.speeds)
actuators = CC.actuators
hud_control = CC.hudControl
# steering torque
if self.CP.spFlags & HyundaiFlagsSP.SP_UPSTREAM_TACO.value:
self.params = CarControllerParams(self.CP, CS.out.vEgoRaw)
new_steer = int(round(actuators.steer * self.params.STEER_MAX))
apply_steer = apply_driver_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params)
if self.CP.spFlags & HyundaiFlagsSP.SP_UPSTREAM_TACO.value:
apply_steer = clip(apply_steer, -self.params.STEER_MAX, self.params.STEER_MAX)
# >90 degree steering fault prevention
self.angle_limit_counter, apply_steer_req = common_fault_avoidance(abs(CS.out.steeringAngleDeg) >= MAX_ANGLE, CC.latActive,
@@ -191,19 +124,6 @@ class CarController(CarControllerBase):
blinking_icon = (self.frame - self.disengage_blink) * DT_CTRL < 1.0 if self.lat_disengage_init else False
if not self.CP.pcmCruiseSpeed:
if not self.last_speed_limit_sign_tap_prev and CS.params_list.last_speed_limit_sign_tap:
self.sl_force_active_timer = self.frame
self.param_s.put_bool_nonblocking("LastSpeedLimitSignTap", False)
self.last_speed_limit_sign_tap_prev = CS.params_list.last_speed_limit_sign_tap
sl_force_active = CS.params_list.speed_limit_control_enabled and (self.frame < (self.sl_force_active_timer * DT_CTRL + 2.0))
sl_inactive = not sl_force_active and (not CS.params_list.speed_limit_control_enabled or (True if self.slc_state == 0 else False))
sl_temp_inactive = not sl_force_active and (CS.params_list.speed_limit_control_enabled and (True if self.slc_state == 1 else False))
slc_active = not sl_inactive and not sl_temp_inactive
self.slc_active_stock = slc_active
self.lat_active_last = CC.latActive
escc = self.CP.spFlags & HyundaiFlagsSP.SP_ENHANCED_SCC.value
@@ -216,7 +136,7 @@ class CarController(CarControllerBase):
if self.frame % 100 == 0 and not ((self.CP.flags & HyundaiFlags.CANFD_CAMERA_SCC.value) or escc) and \
self.CP.carFingerprint not in CAMERA_SCC_CAR and self.CP.openpilotLongitudinalControl:
# for longitudinal control, either radar or ADAS driving ECU
addr, bus = 0x7d0, self.CAN.ECAN if self.CP.carFingerprint in CANFD_CAR else 0
addr, bus = 0x7d0, 0
if self.CP.flags & HyundaiFlags.CANFD_HDA2.value:
addr, bus = 0x730, self.CAN.ECAN
can_sends.append(make_tester_present_msg(addr, bus, suppress_response=True))
@@ -225,9 +145,6 @@ class CarController(CarControllerBase):
if self.CP.flags & HyundaiFlags.ENABLE_BLINKERS:
can_sends.append(make_tester_present_msg(0x7b1, self.CAN.ECAN, suppress_response=True))
if self.CP.openpilotLongitudinalControl:
self.make_jerk(CS, accel, actuators)
# CAN-FD platforms
if self.CP.carFingerprint in CANFD_CAR:
hda2 = self.CP.flags & HyundaiFlags.CANFD_HDA2
@@ -254,24 +171,13 @@ class CarController(CarControllerBase):
if self.CP.openpilotLongitudinalControl:
if hda2:
can_sends.extend(hyundaicanfd.create_adrv_messages(self.packer, self.CAN, self.frame))
else:
can_sends.extend(hyundaicanfd.create_fca_warning_light(self.packer, self.CAN, self.frame))
if self.frame % 2 == 0:
can_sends.append(hyundaicanfd.create_acc_control(self.packer, self.CAN, CS, CC.enabled and CS.out.cruiseState.enabled, self.accel_last, accel, stopping, CC.cruiseControl.override,
set_speed_in_units, hud_control, self.jerk_u, self.jerk_l))
set_speed_in_units, hud_control))
self.accel_last = accel
else:
# button presses
can_sends.extend(self.create_button_messages(CC, CS, use_clu11=False))
if not (CC.cruiseControl.cancel or CC.cruiseControl.resume) and CS.out.cruiseState.enabled and not self.CP.pcmCruiseSpeed:
if self.CP.flags & HyundaiFlags.CANFD_ALT_BUTTONS:
# TODO: resume for alt button cars
pass
else:
self.cruise_button = self.get_cruise_buttons(CS, CC.vCruise)
if self.cruise_button is not None:
if self.frame % 2 == 0:
can_sends.append(hyundaicanfd.create_buttons(self.packer, self.CP, self.CAN, ((self.frame // 2) + 1) % 0x10, self.cruise_button))
else:
can_sends.append(hyundaican.create_lkas11(self.packer, self.frame, self.CP, apply_steer, apply_steer_req,
torque_fault, CS.lkas11, sys_warning, sys_state, CC.enabled,
@@ -281,34 +187,21 @@ class CarController(CarControllerBase):
if not self.CP.openpilotLongitudinalControl:
can_sends.extend(self.create_button_messages(CC, CS, use_clu11=True))
if not (CC.cruiseControl.cancel or CC.cruiseControl.resume) and CS.out.cruiseState.enabled and not self.CP.pcmCruiseSpeed:
self.cruise_button = self.get_cruise_buttons(CS, CC.vCruise)
if self.cruise_button is not None:
if self.CP.carFingerprint in LEGACY_SAFETY_MODE_CAR:
send_freq = 1
if not (self.v_tsc_state != 0 or self.m_tsc_state > 1) and abs(self.target_speed - self.v_set_dis) <= 2:
send_freq = 5
# send resume at a max freq of 10Hz
if (self.frame - self.last_button_frame) * DT_CTRL > 0.1 * send_freq:
# send 25 messages at a time to increases the likelihood of cruise buttons being accepted
can_sends.extend([hyundaican.create_clu11(self.packer, self.frame, CS.clu11, self.cruise_button, self.CP)] * 25)
if (self.frame - self.last_button_frame) * DT_CTRL >= 0.15 * send_freq:
self.last_button_frame = self.frame
elif self.frame % 2 == 0:
can_sends.extend([hyundaican.create_clu11(self.packer, (self.frame // 2) + 1, CS.clu11, self.cruise_button, self.CP)] * 25)
# Parse lead distance from radarState and display the corresponding distance in the car's cluster
if self.CP.openpilotLongitudinalControl and self.sm.updated['radarState'] and self.frame % 5 == 0:
self.lead_distance = self.calculate_lead_distance(hud_control)
if self.frame % 2 == 0 and self.CP.openpilotLongitudinalControl:
if self.hkg_can_smooth_stop:
stopping = stopping and CS.out.vEgoRaw < 0.05
# TODO: unclear if this is needed
jerk = 3.0 if actuators.longControlState == LongCtrlState.pid else 1.0
use_fca = self.CP.flags & HyundaiFlags.USE_FCA.value
self.make_accel(CS, actuators)
can_sends.extend(hyundaican.create_acc_commands(self.packer, CC.enabled and CS.out.cruiseState.enabled, self.accel_raw, self.accel_val, self.jerk_l, self.jerk_u, int(self.frame / 2),
can_sends.extend(hyundaican.create_acc_commands(self.packer, CC.enabled and CS.out.cruiseState.enabled, accel, jerk, int(self.frame / 2),
hud_control, set_speed_in_units, stopping,
CC.cruiseControl.override, use_fca, CS, escc, self.CP, self.lead_distance, self.cb_lower, self.cb_upper))
CC.cruiseControl.override, use_fca, CS, escc, self.CP, self.lead_distance))
# 20 Hz LFA MFA message
if self.frame % 5 == 0 and self.CP.flags & HyundaiFlags.SEND_LFA.value:
@@ -365,185 +258,3 @@ class CarController(CarControllerBase):
self.last_button_frame = self.frame
return can_sends
# multikyd methods, sunnyhaibin logic
def get_cruise_buttons_status(self, CS):
if not CS.out.cruiseState.enabled or CS.cruise_buttons[-1] != Buttons.NONE:
self.timer = 40
elif self.timer:
self.timer -= 1
else:
return 1
return 0
def get_target_speed(self, v_cruise_kph_prev):
v_cruise_kph = v_cruise_kph_prev
if self.slc_state > 1:
v_cruise_kph = (self.speed_limit + self.speed_limit_offset) * CV.MS_TO_KPH
if not self.slc_active_stock:
v_cruise_kph = v_cruise_kph_prev
return v_cruise_kph
def get_button_type(self, button_type):
self.type_status = "type_" + str(button_type)
self.button_picker = getattr(self, self.type_status, lambda: "default")
return self.button_picker()
def reset_button(self):
if self.button_type != 3:
self.button_type = 0
def type_default(self):
self.button_type = 0
return None
def type_0(self):
self.button_count = 0
self.target_speed = self.init_speed
self.speed_diff = self.target_speed - self.v_set_dis
if self.target_speed > self.v_set_dis:
self.button_type = 1
elif self.target_speed < self.v_set_dis and self.v_set_dis > self.v_cruise_min:
self.button_type = 2
return None
def type_1(self):
cruise_button = Buttons.RES_ACCEL
self.button_count += 1
if self.target_speed <= self.v_set_dis:
self.button_count = 0
self.button_type = 3
elif self.button_count > 5:
self.button_count = 0
self.button_type = 3
return cruise_button
def type_2(self):
cruise_button = Buttons.SET_DECEL
self.button_count += 1
if self.target_speed >= self.v_set_dis or self.v_set_dis <= self.v_cruise_min:
self.button_count = 0
self.button_type = 3
elif self.button_count > 5:
self.button_count = 0
self.button_type = 3
return cruise_button
def type_3(self):
cruise_button = None
self.button_count += 1
if self.button_count > self.t_interval:
self.button_type = 0
return cruise_button
def get_curve_speed(self, target_speed_kph, v_cruise_kph_prev):
if self.v_tsc_state != 0:
vision_v_cruise_kph = self.v_tsc * CV.MS_TO_KPH
if int(vision_v_cruise_kph) == int(v_cruise_kph_prev):
vision_v_cruise_kph = 255
else:
vision_v_cruise_kph = 255
if self.m_tsc_state > 1:
map_v_cruise_kph = self.m_tsc * CV.MS_TO_KPH
if int(map_v_cruise_kph) == 0.0:
map_v_cruise_kph = 255
else:
map_v_cruise_kph = 255
curve_speed = self.curve_speed_hysteresis(min(vision_v_cruise_kph, map_v_cruise_kph) + 2 * CV.MPH_TO_KPH)
return min(target_speed_kph, curve_speed)
def get_button_control(self, CS, final_speed, v_cruise_kph_prev):
self.init_speed = round(min(final_speed, v_cruise_kph_prev) * (CV.KPH_TO_MPH if not CS.params_list.is_metric else 1))
self.v_set_dis = round(CS.out.cruiseState.speed * (CV.MS_TO_MPH if not CS.params_list.is_metric else CV.MS_TO_KPH))
cruise_button = self.get_button_type(self.button_type)
return cruise_button
def curve_speed_hysteresis(self, cur_speed: float, hyst=(0.75 * CV.MPH_TO_KPH)):
if cur_speed > self.steady_speed:
self.steady_speed = cur_speed
elif cur_speed < self.steady_speed - hyst:
self.steady_speed = cur_speed
return self.steady_speed
def get_cruise_buttons(self, CS, v_cruise_kph_prev):
cruise_button = None
if not self.get_cruise_buttons_status(CS):
pass
elif CS.out.cruiseState.enabled:
set_speed_kph = self.get_target_speed(v_cruise_kph_prev)
if self.slc_state > 1:
target_speed_kph = set_speed_kph
else:
target_speed_kph = min(v_cruise_kph_prev, set_speed_kph)
if self.custom_stock_planner_speed:
target_speed_kph = self.curve_speed_hysteresis(self.v_target_plan * CV.MS_TO_KPH)
if self.v_tsc_state != 0 or self.m_tsc_state > 1:
self.final_speed_kph = self.get_curve_speed(target_speed_kph, v_cruise_kph_prev)
else:
self.final_speed_kph = target_speed_kph
cruise_button = self.get_button_control(CS, self.final_speed_kph, v_cruise_kph_prev) # MPH/KPH based button presses
return cruise_button
# jerk calculations thanks to apilot!
def cal_jerk(self, accel, actuators):
self.accel_raw = accel
if actuators.longControlState == LongCtrlState.off:
accel_diff = 0.0
elif actuators.longControlState == LongCtrlState.stopping:# or hud_control.softHold > 0:
accel_diff = 0.0
else:
accel_diff = self.accel_raw - self.accel_last_jerk
accel_diff /= DT_CTRL
self.jerk = self.jerk * 0.9 + accel_diff * 0.1
return self.jerk
def make_jerk(self, CS, accel, actuators):
jerk = self.cal_jerk(accel, actuators)
a_error = accel - CS.out.aEgo
jerk = jerk + (a_error * 2.0)
if not self.hkg_custom_long_tuning:
self.jerk_u = 3.0 if actuators.longControlState == LongCtrlState.pid else 1.0
self.jerk_l = 5.0
elif True: #self.CP.carFingerprint in CANFD_CAR or self.CP.carFingerprint == CAR.HYUNDAI_KONA_EV_2022:
startingJerk = 0.5
jerkLimit = 5.0
self.jerk_count += DT_CTRL
jerk_max = interp(self.jerk_count, [0, 1.5, 2.5], [startingJerk, startingJerk, jerkLimit])
if actuators.longControlState == LongCtrlState.off:
self.jerk_u = jerkLimit
self.jerk_l = jerkLimit
self.jerk_count = 0
else:
self.jerk_u = min(max(0.5, jerk * 2.0), jerk_max)
self.jerk_l = min(max(1.0, -jerk * 3.0), jerkLimit)
else:
startingJerk = self.jerkStartLimit
jerkLimit = 5.0
self.jerk_count += DT_CTRL
jerk_max = interp(self.jerk_count, [0, 1.5, 2.5], [startingJerk, startingJerk, jerkLimit])
self.cb_upper = self.cb_lower = 0
if actuators.longControlState == LongCtrlState.off:
self.jerk_u = jerkLimit
self.jerk_l = jerkLimit
self.jerk_count = 0
else:
self.jerk_u = min(max(0.5, jerk * 2.0), jerk_max)
self.jerk_l = min(max(0.5, -jerk * 2.0), jerkLimit)
self.cb_upper = clip(0.9 + accel * 0.2, 0, 1.2)
self.cb_lower = clip(0.8 + accel * 0.2, 0, 1.2)
def make_accel(self, CS, actuators):
long_control = actuators.longControlState
is_ice = not self.CP.flags & (HyundaiFlags.HYBRID | HyundaiFlags.EV)
rate_up = 0.1
rate_down = 0.1
if long_control == LongCtrlState.off or (long_control == LongCtrlState.stopping and CS.out.standstill):
self.accel_raw, self.accel_val = 0, 0
else:
#self.accel_val = clip(self.accel_raw, self.accel_last - rate_down, self.accel_last + rate_up)
self.accel_val = self.accel_raw
self.accel_last = self.accel_val
self.accel_last_jerk = self.accel_val

View File

@@ -1171,17 +1171,6 @@ FW_VERSIONS = {
b'\xf1\x006T6J0_C2\x00\x006T6K1051\x00\x00TOS4N20NS2\x00\x00\x00\x00',
],
},
CAR.HYUNDAI_KONA_EV_NON_SCC: {
(Ecu.abs, 0x7d1, None): [
b'\xf1\x00OS IEB \x02 212 \x11\x13 58520-K4000',
],
(Ecu.eps, 0x7d4, None): [
b'\xf1\x00OS MDPS C 1.00 1.04 56310K4000\x00 4OEDC104',
],
(Ecu.fwdCamera, 0x7c4, None): [
b'\xf1\x00OSE LKAS AT USA LHD 1.00 1.00 95740-K4100 W40',
],
},
CAR.KIA_CEED_PHEV_2022_NON_SCC: {
(Ecu.eps, 0x7D4, None): [
b'\xf1\x00CD MDPS C 1.00 1.01 56310-XX000 4CPHC101',

View File

@@ -130,8 +130,8 @@ def create_lfahda_mfc(packer, enabled, lat_active, lateral_paused, blinking_icon
}
return packer.make_can_msg("LFAHDA_MFC", 0, values)
def create_acc_commands(packer, enabled, accel_raw, accel_val, lower_jerk, upper_jerk, idx, hud_control, set_speed, stopping, long_override, use_fca,
CS, escc, CP, lead_distance, cb_lower, cb_upper):
def create_acc_commands(packer, enabled, accel, upper_jerk, idx, hud_control, set_speed, stopping, long_override, use_fca,
CS, escc, CP, lead_distance):
commands = []
scc11_values = {
@@ -150,8 +150,8 @@ def create_acc_commands(packer, enabled, accel_raw, accel_val, lower_jerk, upper
scc12_values = {
"ACCMode": 2 if enabled and long_override else 1 if enabled else 0,
"StopReq": 1 if stopping else 0,
"aReqRaw": accel_raw,
"aReqValue": accel_val, # stock ramps up and down respecting jerk limit until it reaches aReqRaw
"aReqRaw": accel,
"aReqValue": accel, # stock ramps up and down respecting jerk limit until it reaches aReqRaw
"CR_VSM_Alive": idx % 0xF,
}
@@ -172,10 +172,10 @@ def create_acc_commands(packer, enabled, accel_raw, accel_val, lower_jerk, upper
commands.append(packer.make_can_msg("SCC12", 0, scc12_values))
scc14_values = {
"ComfortBandUpper": cb_upper, # stock usually is 0 but sometimes uses higher values
"ComfortBandLower": cb_lower, # stock usually is 0 but sometimes uses higher values
"ComfortBandUpper": 0.0, # stock usually is 0 but sometimes uses higher values
"ComfortBandLower": 0.0, # stock usually is 0 but sometimes uses higher values
"JerkUpperLimit": upper_jerk, # stock usually is 1.0 but sometimes uses higher values
"JerkLowerLimit": lower_jerk, # stock usually is 0.5 but sometimes uses higher values
"JerkLowerLimit": 5.0, # stock usually is 0.5 but sometimes uses higher values
"ACCMode": 2 if enabled and long_override else 1 if enabled else 4, # stock will always be 4 instead of 0 after first disengage
"ObjGap": get_object_gap(lead_distance), # 5: >30, m, 4: 25-30 m, 3: 20-25 m, 2: < 20 m, 0: no lead
}
@@ -207,7 +207,7 @@ def create_acc_opt(packer, escc, CS, CP):
commands = []
scc13_values = {
"SCCDrvModeRValue": 3,
"SCCDrvModeRValue": 2,
"SCC_Equip": 1,
"Lead_Veh_Dep_Alert_USM": 2,
}

View File

@@ -121,7 +121,7 @@ def create_lfahda_cluster(packer, CAN, enabled, lat_active, lateral_paused, blin
return packer.make_can_msg("LFAHDA_CLUSTER", CAN.ECAN, values)
def create_acc_control(packer, CAN, CS, enabled, accel_last, accel, stopping, gas_override, set_speed, hud_control, upper_jerk, lower_jerk):
def create_acc_control(packer, CAN, CS, enabled, accel_last, accel, stopping, gas_override, set_speed, hud_control):
jerk = 5
jn = jerk / 50
if not enabled or gas_override:
@@ -137,8 +137,8 @@ def create_acc_control(packer, CAN, CS, enabled, accel_last, accel, stopping, ga
"aReqValue": a_val,
"aReqRaw": a_raw,
"VSetDis": set_speed,
"JerkLowerLimit": lower_jerk,
"JerkUpperLimit": upper_jerk,
"JerkLowerLimit": jerk if enabled else 1,
"JerkUpperLimit": 3.0,
"ACC_ObjDist": 1,
"ObjValid": 0,
@@ -172,20 +172,6 @@ def create_spas_messages(packer, CAN, frame, left_blink, right_blink):
return ret
def create_fca_warning_light(packer, CAN, frame):
ret = []
if frame % 2 == 0:
values = {
'AEB_SETTING': 0x1, # show AEB disabled icon
'SET_ME_2': 0x2,
'SET_ME_FF': 0xff,
'SET_ME_FC': 0xfc,
'SET_ME_9': 0x9,
}
ret.append(packer.make_can_msg("ADRV_0x160", CAN.ECAN, values))
return ret
def create_adrv_messages(packer, CAN, frame):
# messages needed to car happy after disabling
# the ADAS Driving ECU to do longitudinal control
@@ -196,7 +182,15 @@ def create_adrv_messages(packer, CAN, frame):
}
ret.append(packer.make_can_msg("ADRV_0x51", CAN.ACAN, values))
ret.extend(create_fca_warning_light(packer, CAN, frame))
if frame % 2 == 0:
values = {
'AEB_SETTING': 0x1, # show AEB disabled icon
'SET_ME_2': 0x2,
'SET_ME_FF': 0xff,
'SET_ME_FC': 0xfc,
'SET_ME_9': 0x9,
}
ret.append(packer.make_can_msg("ADRV_0x160", CAN.ECAN, values))
if frame % 5 == 0:
values = {

View File

@@ -93,7 +93,7 @@ class CarInterface(CarInterfaceBase):
# *** longitudinal control ***
if candidate in CANFD_CAR:
ret.experimentalLongitudinalAvailable = candidate not in (CANFD_UNSUPPORTED_LONGITUDINAL_CAR | NON_SCC_CAR)
ret.experimentalLongitudinalAvailable = candidate not in (CANFD_UNSUPPORTED_LONGITUDINAL_CAR | CANFD_RADAR_SCC_CAR | NON_SCC_CAR)
if ret.flags & HyundaiFlags.CANFD_CAMERA_SCC and not hda2:
ret.spFlags |= HyundaiFlagsSP.SP_CAMERA_SCC_LEAD.value
else:
@@ -104,17 +104,11 @@ class CarInterface(CarInterfaceBase):
ret.pcmCruise = not ret.openpilotLongitudinalControl
ret.stoppingControl = True
ret.startingState = True
ret.vEgoStarting = 0.1
ret.startAccel = 1.6
ret.startAccel = 1.0
ret.longitudinalActuatorDelay = 0.5
if ret.flags & (HyundaiFlags.HYBRID | HyundaiFlags.EV):
ret.startingState = False
ret.stopAccel = -2.0
else:
ret.startingState = True
ret.stopAccel = -1.0
if DBC[ret.carFingerprint]["radar"] is None:
if ret.spFlags & (HyundaiFlagsSP.SP_ENHANCED_SCC | HyundaiFlagsSP.SP_CAMERA_SCC_LEAD):
ret.radarTimeStep = 0.02
@@ -126,8 +120,6 @@ class CarInterface(CarInterfaceBase):
if 0x1fa in fingerprint[CAN.ECAN]:
ret.spFlags |= HyundaiFlagsSP.SP_NAV_MSG.value
if Params().get("DongleId", encoding='utf8') in ("012c95f06918eca4", "68d6a96e703c00c9", "11c1f1909ca37bca"):
ret.spFlags |= HyundaiFlagsSP.SP_UPSTREAM_TACO.value
else:
ret.enableBsm = 0x58b in fingerprint[0]
@@ -154,8 +146,6 @@ class CarInterface(CarInterfaceBase):
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_CANFD_ALT_BUTTONS
if ret.flags & HyundaiFlags.CANFD_CAMERA_SCC:
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_CAMERA_SCC
if ret.spFlags & HyundaiFlagsSP.SP_UPSTREAM_TACO:
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_UPSTREAM_TACO
else:
if candidate in LEGACY_SAFETY_MODE_CAR:
# these cars require a special panda safety mode due to missing counters and checksums in the messages
@@ -181,8 +171,7 @@ class CarInterface(CarInterfaceBase):
elif ret.flags & HyundaiFlags.EV:
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_EV_GAS
if candidate in (CAR.HYUNDAI_KONA, CAR.HYUNDAI_KONA_EV, CAR.HYUNDAI_KONA_HEV, CAR.HYUNDAI_KONA_EV_2022,
CAR.HYUNDAI_KONA_NON_SCC, CAR.HYUNDAI_KONA_EV_NON_SCC):
if candidate in (CAR.HYUNDAI_KONA, CAR.HYUNDAI_KONA_EV, CAR.HYUNDAI_KONA_HEV, CAR.HYUNDAI_KONA_EV_2022, CAR.HYUNDAI_KONA_NON_SCC):
ret.flags |= HyundaiFlags.ALT_LIMITS.value
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_ALT_LIMITS
@@ -192,13 +181,16 @@ class CarInterface(CarInterfaceBase):
if 0x2AA in fingerprint[0]:
ret.minSteerSpeed = 0.
if Params().get_bool("HkgSmoothStop"):
ret.vEgoStopping = 0.1
return ret
@staticmethod
def init(CP, logcan, sendcan):
if CP.openpilotLongitudinalControl and not ((CP.flags & HyundaiFlags.CANFD_CAMERA_SCC.value) or (CP.spFlags & HyundaiFlagsSP.SP_ENHANCED_SCC)) and \
CP.carFingerprint not in CAMERA_SCC_CAR:
addr, bus = 0x7d0, CanBus(CP).ECAN if CP.carFingerprint in CANFD_CAR else 0
addr, bus = 0x7d0, 0
if CP.flags & HyundaiFlags.CANFD_HDA2.value:
addr, bus = 0x730, CanBus(CP).ECAN
disable_ecu(logcan, sendcan, bus=bus, addr=addr, com_cont_req=b'\x28\x83\x01')
@@ -296,8 +288,6 @@ class CarInterface(CarInterfaceBase):
if self.CS.params_list.hyundai_radar_tracks_available and not self.CS.params_list.hyundai_radar_tracks_available_cache:
events.add(car.CarEvent.EventName.hyundaiRadarTracksAvailable)
ret.customStockLong = self.update_custom_stock_long()
ret.events = events.to_msg()
return ret

View File

@@ -3,7 +3,7 @@ from dataclasses import dataclass, field
from enum import Enum, IntFlag
from cereal import car
from panda.python import uds, Panda
from panda.python import uds
from openpilot.common.conversions import Conversions as CV
from openpilot.selfdrive.car import CarSpecs, DbcDict, PlatformConfig, Platforms, dbc_dict
from openpilot.selfdrive.car.docs_definitions import CarFootnote, CarHarness, CarDocs, CarParts, Column
@@ -16,7 +16,7 @@ class CarControllerParams:
ACCEL_MIN = -3.5 # m/s
ACCEL_MAX = 2.0 # m/s
def __init__(self, CP, vEgoRaw=100.):
def __init__(self, CP):
self.STEER_DELTA_UP = 3
self.STEER_DELTA_DOWN = 7
self.STEER_DRIVER_ALLOWANCE = 50
@@ -26,13 +26,12 @@ class CarControllerParams:
self.STEER_STEP = 1 # 100 Hz
if CP.carFingerprint in CANFD_CAR:
upstream_taco = CP.safetyConfigs[-1].safetyParam & Panda.FLAG_HYUNDAI_UPSTREAM_TACO
self.STEER_MAX = 270 if not upstream_taco else 384 if vEgoRaw < 11. else 330
self.STEER_DRIVER_ALLOWANCE = 250 if not upstream_taco else 350
self.STEER_MAX = 270
self.STEER_DRIVER_ALLOWANCE = 250
self.STEER_DRIVER_MULTIPLIER = 2
self.STEER_THRESHOLD = 250 if not upstream_taco else 350
self.STEER_DELTA_UP = 2 if not upstream_taco else 10 if vEgoRaw < 11. else 2
self.STEER_DELTA_DOWN = 3 if not upstream_taco else 10 if vEgoRaw < 11. else 3
self.STEER_THRESHOLD = 250
self.STEER_DELTA_UP = 2
self.STEER_DELTA_DOWN = 3
# To determine the limit for your car, find the maximum value that the stock LKAS will request.
# If the max stock LKAS request is <384, add your car to this list.
@@ -109,7 +108,6 @@ class HyundaiFlagsSP(IntFlag):
SP_CAMERA_SCC_LEAD = 2 ** 6
SP_LKAS12 = 2 ** 7
SP_RADAR_TRACKS = 2 ** 8
SP_UPSTREAM_TACO = 2 ** 9
class Footnote(Enum):
@@ -576,12 +574,6 @@ class CAR(Platforms):
HYUNDAI_KONA.specs,
spFlags=HyundaiFlagsSP.SP_NON_SCC | HyundaiFlagsSP.SP_NON_SCC_FCA,
)
HYUNDAI_KONA_EV_NON_SCC = HyundaiPlatformConfig(
[HyundaiCarDocs("Hyundai Kona Electric Non-SCC 2019", "No Smart Cruise Control (SCC)", car_parts=CarParts.common([CarHarness.hyundai_g]))],
HYUNDAI_KONA.specs,
flags=HyundaiFlags.EV,
spFlags=HyundaiFlagsSP.SP_NON_SCC | HyundaiFlagsSP.SP_NON_SCC_FCA,
)
KIA_CEED_PHEV_2022_NON_SCC = HyundaiPlatformConfig(
[HyundaiCarDocs("Kia Ceed PHEV Non-SCC 2022", "No Smart Cruise Control (SCC)", car_parts=CarParts.common([CarHarness.hyundai_i]))],
CarSpecs(mass=1650, wheelbase=2.65, steerRatio=13.75, tireStiffnessFactor=0.5),

View File

@@ -406,7 +406,7 @@ class CarInterfaceBase(ABC):
@staticmethod
def sp_configure_custom_torque_tune(ret, params):
ret.lateralTuning.torque.friction = float(params.get("TorqueFriction", encoding="utf8")) * 0.001
ret.lateralTuning.torque.friction = float(params.get("TorqueFriction", encoding="utf8")) * 0.01
ret.lateralTuning.torque.latAccelFactor = float(params.get("TorqueMaxLatAccel", encoding="utf8")) * 0.01
return ret

View File

@@ -1,14 +1,9 @@
from cereal import car
import cereal.messaging as messaging
from openpilot.common.conversions import Conversions as CV
from openpilot.common.params import Params
from openpilot.common.realtime import DT_CTRL
from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import apply_driver_steer_torque_limits
from openpilot.selfdrive.car.interfaces import CarControllerBase
from openpilot.selfdrive.car.mazda import mazdacan
from openpilot.selfdrive.car.mazda.values import CarControllerParams, Buttons
from openpilot.selfdrive.controls.lib.drive_helpers import MAZDA_V_CRUISE_MIN
VisualAlert = car.CarControl.HUDControl.VisualAlert
ButtonType = car.CarState.ButtonEvent.Type
@@ -21,63 +16,9 @@ class CarController(CarControllerBase):
self.packer = CANPacker(dbc_name)
self.brake_counter = 0
self.sm = messaging.SubMaster(['longitudinalPlanSP'])
self.param_s = Params()
self.last_speed_limit_sign_tap_prev = False
self.speed_limit = 0.
self.speed_limit_offset = 0
self.timer = 0
self.final_speed_kph = 0
self.init_speed = 0
self.current_speed = 0
self.v_set_dis = 0
self.v_cruise_min = 0
self.button_type = 0
self.button_select = 0
self.button_count = 0
self.target_speed = 0
self.t_interval = 7
self.slc_active_stock = False
self.sl_force_active_timer = 0
self.v_tsc_state = 0
self.slc_state = 0
self.m_tsc_state = 0
self.cruise_button = None
self.speed_diff = 0
self.v_tsc = 0
self.m_tsc = 0
self.steady_speed = 0
def update(self, CC, CS, now_nanos):
if not self.CP.pcmCruiseSpeed:
self.sm.update(0)
if self.sm.updated['longitudinalPlanSP']:
self.v_tsc_state = self.sm['longitudinalPlanSP'].visionTurnControllerState
self.slc_state = self.sm['longitudinalPlanSP'].speedLimitControlState
self.m_tsc_state = self.sm['longitudinalPlanSP'].turnSpeedControlState
self.speed_limit = self.sm['longitudinalPlanSP'].speedLimit
self.speed_limit_offset = self.sm['longitudinalPlanSP'].speedLimitOffset
self.v_tsc = self.sm['longitudinalPlanSP'].visionTurnSpeed
self.m_tsc = self.sm['longitudinalPlanSP'].turnSpeed
self.v_cruise_min = MAZDA_V_CRUISE_MIN[CS.params_list.is_metric] * (CV.KPH_TO_MPH if not CS.params_list.is_metric else 1)
can_sends = []
if not self.CP.pcmCruiseSpeed:
if not self.last_speed_limit_sign_tap_prev and CS.params_list.last_speed_limit_sign_tap:
self.sl_force_active_timer = self.frame
self.param_s.put_bool_nonblocking("LastSpeedLimitSignTap", False)
self.last_speed_limit_sign_tap_prev = CS.params_list.last_speed_limit_sign_tap
sl_force_active = CS.params_list.speed_limit_control_enabled and (self.frame < (self.sl_force_active_timer * DT_CTRL + 2.0))
sl_inactive = not sl_force_active and (not CS.params_list.speed_limit_control_enabled or (True if self.slc_state == 0 else False))
sl_temp_inactive = not sl_force_active and (CS.params_list.speed_limit_control_enabled and (True if self.slc_state == 1 else False))
slc_active = not sl_inactive and not sl_temp_inactive
self.slc_active_stock = slc_active
apply_steer = 0
if CC.latActive:
@@ -102,11 +43,6 @@ class CarController(CarControllerBase):
# Mazda Stop and Go requires a RES button (or gas) press if the car stops more than 3 seconds
# Send Resume button when planner wants car to move
can_sends.append(mazdacan.create_button_cmd(self.packer, self.CP, CS.crz_btns_counter, Buttons.RESUME))
elif CS.out.cruiseState.enabled and not self.CP.pcmCruiseSpeed:
self.cruise_button = self.get_cruise_buttons(CS, CC.vCruise)
if self.cruise_button is not None:
if self.frame % 10 == 0:
can_sends.append(mazdacan.create_button_cmd(self.packer, self.CP, self.frame // 10, self.cruise_button))
self.apply_steer_last = apply_steer
@@ -128,125 +64,3 @@ class CarController(CarControllerBase):
self.frame += 1
return new_actuators, can_sends
# multikyd methods, sunnyhaibin logic
def get_cruise_buttons_status(self, CS):
if not CS.out.cruiseState.enabled:
for be in CS.out.buttonEvents:
if be.type in (ButtonType.accelCruise, ButtonType.resumeCruise,
ButtonType.decelCruise, ButtonType.setCruise) and be.pressed:
self.timer = 40
elif self.timer:
self.timer -= 1
else:
return 1
return 0
def get_target_speed(self, v_cruise_kph_prev):
v_cruise_kph = v_cruise_kph_prev
if self.slc_state > 1:
v_cruise_kph = (self.speed_limit + self.speed_limit_offset) * CV.MS_TO_KPH
if not self.slc_active_stock:
v_cruise_kph = v_cruise_kph_prev
return v_cruise_kph
def get_button_type(self, button_type):
self.type_status = "type_" + str(button_type)
self.button_picker = getattr(self, self.type_status, lambda: "default")
return self.button_picker()
def reset_button(self):
if self.button_type != 3:
self.button_type = 0
def type_default(self):
self.button_type = 0
return None
def type_0(self):
self.button_count = 0
self.target_speed = self.init_speed
self.speed_diff = self.target_speed - self.v_set_dis
if self.target_speed > self.v_set_dis:
return Buttons.SET_PLUS
self.button_type = 1
elif self.target_speed < self.v_set_dis and self.v_set_dis > self.v_cruise_min:
return Buttons.SET_MINUS
self.button_type = 2
return None
def type_1(self):
cruise_button = Buttons.SET_PLUS
self.button_count += 1
if self.target_speed <= self.v_set_dis:
self.button_count = 0
self.button_type = 3
elif self.button_count > 5:
self.button_count = 0
self.button_type = 3
return cruise_button
def type_2(self):
cruise_button = Buttons.SET_MINUS
self.button_count += 1
if self.target_speed >= self.v_set_dis or self.v_set_dis <= self.v_cruise_min:
self.button_count = 0
self.button_type = 3
elif self.button_count > 5:
self.button_count = 0
self.button_type = 3
return cruise_button
def type_3(self):
cruise_button = None
self.button_count += 1
if self.button_count > self.t_interval:
self.button_type = 0
return cruise_button
def get_curve_speed(self, target_speed_kph, v_cruise_kph_prev):
if self.v_tsc_state != 0:
vision_v_cruise_kph = self.v_tsc * CV.MS_TO_KPH
if int(vision_v_cruise_kph) == int(v_cruise_kph_prev):
vision_v_cruise_kph = 255
else:
vision_v_cruise_kph = 255
if self.m_tsc_state > 1:
map_v_cruise_kph = self.m_tsc * CV.MS_TO_KPH
if int(map_v_cruise_kph) == 0.0:
map_v_cruise_kph = 255
else:
map_v_cruise_kph = 255
curve_speed = self.curve_speed_hysteresis(min(vision_v_cruise_kph, map_v_cruise_kph) + 2 * CV.MPH_TO_KPH)
return min(target_speed_kph, curve_speed)
def get_button_control(self, CS, final_speed, v_cruise_kph_prev):
self.init_speed = round(min(final_speed, v_cruise_kph_prev) * (CV.KPH_TO_MPH if not CS.params_list.is_metric else 1))
self.v_set_dis = round(CS.out.cruiseState.speed * (CV.MS_TO_MPH if not CS.params_list.is_metric else CV.MS_TO_KPH))
cruise_button = self.get_button_type(self.button_type)
return cruise_button
def curve_speed_hysteresis(self, cur_speed: float, hyst=(0.75 * CV.MPH_TO_KPH)):
if cur_speed > self.steady_speed:
self.steady_speed = cur_speed
elif cur_speed < self.steady_speed - hyst:
self.steady_speed = cur_speed
return self.steady_speed
def get_cruise_buttons(self, CS, v_cruise_kph_prev):
cruise_button = None
if not self.get_cruise_buttons_status(CS):
pass
elif CS.out.cruiseState.enabled:
set_speed_kph = self.get_target_speed(v_cruise_kph_prev)
if self.slc_state > 1:
target_speed_kph = set_speed_kph
else:
target_speed_kph = min(v_cruise_kph_prev, set_speed_kph)
if self.v_tsc_state != 0 or self.m_tsc_state > 1:
self.final_speed_kph = self.get_curve_speed(target_speed_kph, v_cruise_kph_prev)
else:
self.final_speed_kph = target_speed_kph
cruise_button = self.get_button_control(CS, self.final_speed_kph, v_cruise_kph_prev) # MPH/KPH based button presses
return cruise_button

View File

@@ -89,8 +89,6 @@ class CarInterface(CarInterfaceBase):
if self.CS.low_speed_alert:
events.add(EventName.belowSteerSpeed)
ret.customStockLong = self.update_custom_stock_long()
ret.events = events.to_msg()
return ret

View File

@@ -92,22 +92,20 @@ def create_button_cmd(packer, CP, counter, button):
can = int(button == Buttons.CANCEL)
res = int(button == Buttons.RESUME)
inc = int(button == Buttons.SET_PLUS)
dec = int(button == Buttons.SET_MINUS)
if CP.flags & MazdaFlags.GEN1:
values = {
"CAN_OFF": can,
"CAN_OFF_INV": (can + 1) % 2,
"SET_P": inc,
"SET_P_INV": (inc + 1) % 2,
"SET_P": 0,
"SET_P_INV": 1,
"RES": res,
"RES_INV": (res + 1) % 2,
"SET_M": dec,
"SET_M_INV": (dec + 1) % 2,
"SET_M": 0,
"SET_M_INV": 1,
"DISTANCE_LESS": 0,
"DISTANCE_LESS_INV": 1,

View File

@@ -21,7 +21,7 @@ class CarControllerParams:
self.STEER_DRIVER_FACTOR = 1 # from dbc
if CP.flags & SubaruFlags.GLOBAL_GEN2:
self.STEER_MAX = 1600
self.STEER_MAX = 1000
self.STEER_DELTA_UP = 40
self.STEER_DELTA_DOWN = 40
elif CP.carFingerprint == CAR.SUBARU_IMPREZA_2020:

View File

@@ -29,9 +29,6 @@
"Ford Escape Plug-in Hybrid 2020-22": "FORD_ESCAPE_MK4",
"Ford Explorer 2020-23": "FORD_EXPLORER_MK6",
"Ford Explorer Hybrid 2020-23": "FORD_EXPLORER_MK6",
"Ford F-150 2022-23": "FORD_F_150_MK14",
"Ford F-150 Hybrid 2022-23": "FORD_F_150_MK14",
"Ford F-150 Lightning 2021-23": "FORD_F_150_LIGHTNING_MK1",
"Ford Focus 2018": "FORD_FOCUS_MK4",
"Ford Focus Hybrid 2018": "FORD_FOCUS_MK4",
"Ford Kuga 2020-22": "FORD_ESCAPE_MK4",
@@ -41,8 +38,6 @@
"Ford Maverick 2023-24": "FORD_MAVERICK_MK1",
"Ford Maverick Hybrid 2022": "FORD_MAVERICK_MK1",
"Ford Maverick Hybrid 2023-24": "FORD_MAVERICK_MK1",
"Ford Mustang Mach-E 2021-23": "FORD_MUSTANG_MACH_E_MK1",
"Ford Ranger 2024": "FORD_RANGER_MK2",
"Genesis G70 2018": "GENESIS_G70",
"Genesis G70 2019-21": "GENESIS_G70_2020",
"Genesis G70 2022-23": "GENESIS_G70_2020",
@@ -106,7 +101,6 @@
"Hyundai Kona Electric 2018-21": "HYUNDAI_KONA_EV",
"Hyundai Kona Electric 2022-23": "HYUNDAI_KONA_EV_2022",
"Hyundai Kona Electric (with HDA II, Korea only) 2023": "HYUNDAI_KONA_EV_2ND_GEN",
"Hyundai Kona Electric Non-SCC 2019": "HYUNDAI_KONA_EV_NON_SCC",
"Hyundai Kona Hybrid 2020": "HYUNDAI_KONA_HEV",
"Hyundai Kona Non-SCC 2019": "HYUNDAI_KONA_NON_SCC",
"Hyundai Palisade 2020-22": "HYUNDAI_PALISADE",

View File

@@ -17,6 +17,7 @@ from openpilot.selfdrive.car.body.values import CAR as COMMA
# TODO: add routes for these cars
non_tested_cars = [
FORD.FORD_F_150_MK14,
GM.CADILLAC_ATS,
GM.HOLDEN_ASTRA,
GM.CHEVROLET_MALIBU,
@@ -53,7 +54,6 @@ routes = [
CarTestRoute("e886087f430e7fe7|2023-06-16--23-06-36", FORD.FORD_FOCUS_MK4),
CarTestRoute("bd37e43731e5964b|2023-04-30--10-42-26", FORD.FORD_MAVERICK_MK1),
CarTestRoute("112e4d6e0cad05e1|2023-11-14--08-21-43", FORD.FORD_F_150_LIGHTNING_MK1),
CarTestRoute("24574459dd7fb3e0|2023-11-06--06-23-44", FORD.FORD_F_150_MK14),
CarTestRoute("83a4e056c7072678|2023-11-13--16-51-33", FORD.FORD_MUSTANG_MACH_E_MK1),
CarTestRoute("37998aa0fade36ab/00000000--48f927c4f5", FORD.FORD_RANGER_MK2),
#TestRoute("f1b4c567731f4a1b|2018-04-30--10-15-35", FORD.FUSION),

View File

@@ -86,7 +86,6 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
"KIA_FORTE_2021_NON_SCC" = "HYUNDAI_SONATA"
"KIA_SELTOS_2023_NON_SCC" = "HYUNDAI_SONATA"
"HYUNDAI_KONA_NON_SCC" = "HYUNDAI_KONA_EV"
"HYUNDAI_KONA_EV_NON_SCC" = "HYUNDAI_KONA_EV"
"HYUNDAI_ELANTRA_2022_NON_SCC" = "HYUNDAI_ELANTRA_2021"
"GENESIS_G70_2021_NON_SCC" = "HYUNDAI_SONATA"
"KIA_CEED_PHEV_2022_NON_SCC" = "HYUNDAI_SONATA"

View File

@@ -1,19 +1,18 @@
import copy
from cereal import car, custom
from cereal import car
from openpilot.common.conversions import Conversions as CV
from openpilot.common.numpy_fast import mean
from openpilot.common.filter_simple import FirstOrderFilter
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car import DT_CTRL
from openpilot.common.params import Params
from openpilot.selfdrive.car.interfaces import CarStateBase
from openpilot.selfdrive.car.toyota.values import ToyotaFlags, ToyotaFlagsSP, CAR, DBC, STEER_THRESHOLD, NO_STOP_TIMER_CAR, \
TSS2_CAR, RADAR_ACC_CAR, EPS_SCALE, UNSUPPORTED_DSU_CAR
SteerControlType = car.CarParams.SteerControlType
AccelPersonality = custom.AccelerationPersonality
# These steering fault definitions seem to be common across LKA (torque) and LTA (angle):
# - high steer rate fault: goes to 21 or 25 for 1 frame, then 9 for 2 seconds
# - lka/lta msg drop out: goes to 9 then 11 for a combined total of 2 seconds, then 3.
@@ -80,13 +79,6 @@ class CarState(CarStateBase):
self._right_blindspot_d2 = 0
self._right_blindspot_counter = 0
self.signals_checked = False
self.sport_signal_seen = False
self.eco_signal_seen = False
self.accel_profile = None
self.prev_accel_profile = None
self.accel_profile_init = False
self.toyota_drive_mode = Params().get_bool('ToyotaDriveMode')
self.frame = 0
def update(self, cp, cp_cam):
@@ -184,51 +176,6 @@ class CarState(CarStateBase):
ret.leftBlinker = ret.leftBlinkerOn = cp.vl["BLINKERS_STATE"]["TURN_SIGNALS"] == 1
ret.rightBlinker = ret.rightBlinkerOn = cp.vl["BLINKERS_STATE"]["TURN_SIGNALS"] == 2
if self.toyota_drive_mode:
# Determine sport signal based on car model
sport_signal = 'SPORT_ON_2' if self.CP.carFingerprint in (CAR.TOYOTA_RAV4_TSS2, CAR.LEXUS_ES_TSS2, CAR.TOYOTA_HIGHLANDER_TSS2) else 'SPORT_ON'
# Check signals once
if not self.signals_checked:
self.signals_checked = True
# Try to detect sport mode signal, handle missing signal with a fallback
try:
sport_mode = cp.vl["GEAR_PACKET"][sport_signal]
self.sport_signal_seen = True
except KeyError:
sport_mode = 0
self.sport_signal_seen = False
# Try to detect eco mode signal, handle missing signal with a fallback
try:
eco_mode = cp.vl["GEAR_PACKET"]['ECON_ON']
self.eco_signal_seen = True
except KeyError:
eco_mode = 0
self.eco_signal_seen = False
else:
# Always re-check the signals to account for mode changes
sport_mode = cp.vl["GEAR_PACKET"][sport_signal] if self.sport_signal_seen else 0
eco_mode = cp.vl["GEAR_PACKET"]['ECON_ON'] if self.eco_signal_seen else 0
# Set acceleration profile based on detected modes, with sport mode having higher priority
if sport_mode == 1:
self.accel_profile = AccelPersonality.sport
elif eco_mode == 1:
self.accel_profile = AccelPersonality.eco
else:
self.accel_profile = AccelPersonality.normal
print(f"Accel profile set to: {self.accel_profile}")
# If not initialized, sync profile with the current mode on the car
if not self.accel_profile_init or self.accel_profile != self.prev_accel_profile:
Params().put_nonblocking('AccelPersonality', str(self.accel_profile))
self.accel_profile_init = True
# Update the previous profile to prevent unnecessary re-syncing
self.prev_accel_profile = self.accel_profile
if self.CP.carFingerprint != CAR.TOYOTA_MIRAI:
ret.engineRpm = cp.vl["ENGINE_RPM"]["RPM"]

View File

@@ -160,26 +160,26 @@ class CarInterface(CarInterfaceBase):
sp_tss2_long_tune = Params().get_bool("ToyotaTSS2Long")
# Last updated: September 29, 2024
def custom_tss2_longitudinal_tuning(): # hand tuned
ret.vEgoStopping = 0.25
# hand tuned (July 1, 2024)
def custom_tss2_longitudinal_tuning():
ret.vEgoStopping = 0.01
ret.vEgoStarting = 0.01
ret.stoppingDecelRate = 0.006
ret.stoppingDecelRate = 0.35
def default_tss2_longitudinal_tuning(): # stock comma
def default_tss2_longitudinal_tuning():
ret.vEgoStopping = 0.25
ret.vEgoStarting = 0.10
ret.stoppingDecelRate = 0.007 # reach stopping target smoothly
ret.vEgoStarting = 0.25
ret.stoppingDecelRate = 0.3 # reach stopping target smoothly
def default_longitudinal_tuning(): # stock comma
def default_longitudinal_tuning():
tune.kiBP = [0., 5., 35.]
tune.kiV = [3.6, 2.4, 1.5]
tune = ret.longitudinalTuning
if candidate in TSS2_CAR or ret.enableGasInterceptorDEPRECATED:
if sp_tss2_long_tune:
tune.kiBP = [0., 5., 12., 20., 27., 36., 40.]
tune.kiV = [0.34, 0.234, 0.20, 0.17, 0.105, 0.09, 0.08]
tune.kiBP = [0., 5., 12., 20., 27., 36., 50]
tune.kiV = [0.35, 0.23, 0.20, 0.17, 0.10, 0.07, 0.01]
custom_tss2_longitudinal_tuning()
else:
tune.kpV = [0.0]

View File

@@ -1,14 +1,11 @@
from cereal import car
import cereal.messaging as messaging
from opendbc.can.packer import CANPacker
from openpilot.common.numpy_fast import clip
from openpilot.common.conversions import Conversions as CV
from openpilot.common.params import Params
from openpilot.selfdrive.car import DT_CTRL, apply_driver_steer_torque_limits
from openpilot.selfdrive.car.interfaces import CarControllerBase
from openpilot.selfdrive.car.volkswagen import mqbcan, pqcan
from openpilot.selfdrive.car.volkswagen.values import CANBUS, CarControllerParams, VolkswagenFlags
from openpilot.selfdrive.controls.lib.drive_helpers import VOLKSWAGEN_V_CRUISE_MIN
VisualAlert = car.CarControl.HUDControl.VisualAlert
LongCtrlState = car.CarControl.Actuators.LongControlState
@@ -28,70 +25,12 @@ class CarController(CarControllerBase):
self.eps_timer_soft_disable_alert = False
self.hca_frame_timer_running = 0
self.hca_frame_same_torque = 0
self.last_button_frame = 0
self.sm = messaging.SubMaster(['longitudinalPlanSP'])
self.param_s = Params()
self.last_speed_limit_sign_tap_prev = False
self.speed_limit = 0.
self.speed_limit_offset = 0
self.timer = 0
self.final_speed_kph = 0
self.init_speed = 0
self.current_speed = 0
self.v_set_dis = 0
self.v_set_dis_prev = 0
self.v_cruise_min = 0
self.button_type = 0
self.button_select = 0
self.button_count = 0
self.target_speed = 0
self.t_interval = 7
self.slc_active_stock = False
self.sl_force_active_timer = 0
self.v_tsc_state = 0
self.slc_state = 0
self.m_tsc_state = 0
self.cruise_button = None
self.last_cruise_button = None
self.speed_diff = 0
self.v_tsc = 0
self.m_tsc = 0
self.steady_speed = 0
self.acc_type = -1
self.send_count = 0
def update(self, CC, CS, now_nanos):
if not self.CP.pcmCruiseSpeed:
self.sm.update(0)
if self.sm.updated['longitudinalPlanSP']:
self.v_tsc_state = self.sm['longitudinalPlanSP'].visionTurnControllerState
self.slc_state = self.sm['longitudinalPlanSP'].speedLimitControlState
self.m_tsc_state = self.sm['longitudinalPlanSP'].turnSpeedControlState
self.speed_limit = self.sm['longitudinalPlanSP'].speedLimit
self.speed_limit_offset = self.sm['longitudinalPlanSP'].speedLimitOffset
self.v_tsc = self.sm['longitudinalPlanSP'].visionTurnSpeed
self.m_tsc = self.sm['longitudinalPlanSP'].turnSpeed
self.v_cruise_min = VOLKSWAGEN_V_CRUISE_MIN[CS.params_list.is_metric] * (CV.KPH_TO_MPH if not CS.params_list.is_metric else 1)
actuators = CC.actuators
hud_control = CC.hudControl
can_sends = []
if not self.CP.pcmCruiseSpeed:
if not self.last_speed_limit_sign_tap_prev and CS.params_list.last_speed_limit_sign_tap:
self.sl_force_active_timer = self.frame
self.param_s.put_bool_nonblocking("LastSpeedLimitSignTap", False)
self.last_speed_limit_sign_tap_prev = CS.params_list.last_speed_limit_sign_tap
sl_force_active = CS.params_list.speed_limit_control_enabled and (self.frame < (self.sl_force_active_timer * DT_CTRL + 2.0))
sl_inactive = not sl_force_active and (not CS.params_list.speed_limit_control_enabled or (True if self.slc_state == 0 else False))
sl_temp_inactive = not sl_force_active and (CS.params_list.speed_limit_control_enabled and (True if self.slc_state == 1 else False))
slc_active = not sl_inactive and not sl_temp_inactive
self.slc_active_stock = slc_active
# **** Steering Controls ************************************************ #
if self.frame % self.CCP.STEER_STEP == 0:
@@ -171,155 +110,11 @@ class CarController(CarControllerBase):
if gra_send_ready and (CC.cruiseControl.cancel or CC.cruiseControl.resume):
can_sends.append(self.CCS.create_acc_buttons_control(self.packer_pt, self.ext_bus, CS.gra_stock_values,
cancel=CC.cruiseControl.cancel, resume=CC.cruiseControl.resume))
if not (CC.cruiseControl.cancel or CC.cruiseControl.resume) and CS.out.cruiseState.enabled:
if not self.CP.pcmCruiseSpeed:
self.cruise_button = self.get_cruise_buttons(CS, CC.vCruise)
if self.cruise_button is not None:
if self.acc_type == -1:
if self.button_count >= 2 and self.v_set_dis_prev != self.v_set_dis:
self.acc_type = 1 if abs(self.v_set_dis - self.v_set_dis_prev) >= 10 and self.last_cruise_button in (1, 2) else \
0 if abs(self.v_set_dis - self.v_set_dis_prev) < 10 and self.last_cruise_button not in (1, 2) else 1
if self.send_count >= 10 and self.v_set_dis_prev == self.v_set_dis:
self.cruise_button = 3 if self.cruise_button == 1 else 4
if self.acc_type == 0:
self.cruise_button = 1 if self.cruise_button == 1 else 2 # accel, decel
elif self.acc_type == 1:
self.cruise_button = 3 if self.cruise_button == 1 else 4 # resume, set
if self.frame % self.CCP.BTN_STEP == 0:
can_sends.append(self.CCS.create_acc_buttons_control(self.packer_pt, CS.gra_stock_values, frame=(self.frame // self.CCP.BTN_STEP),
buttons=self.cruise_button, custom_stock_long=True))
self.send_count += 1
else:
self.send_count = 0
self.last_cruise_button = self.cruise_button
new_actuators = actuators.as_builder()
new_actuators.steer = self.apply_steer_last / self.CCP.STEER_MAX
new_actuators.steerOutputCan = self.apply_steer_last
self.gra_acc_counter_last = CS.gra_stock_values["COUNTER"]
self.v_set_dis_prev = self.v_set_dis
self.frame += 1
return new_actuators, can_sends
# multikyd methods, sunnyhaibin logic
def get_cruise_buttons_status(self, CS):
if not CS.out.cruiseState.enabled:
for be in CS.out.buttonEvents:
if be.type in (ButtonType.accelCruise, ButtonType.resumeCruise,
ButtonType.decelCruise, ButtonType.setCruise) and be.pressed:
self.timer = 40
elif be.type == ButtonType.gapAdjustCruise and be.pressed:
self.timer = 300
elif self.timer:
self.timer -= 1
else:
return 1
return 0
def get_target_speed(self, v_cruise_kph_prev):
v_cruise_kph = v_cruise_kph_prev
if self.slc_state > 1:
v_cruise_kph = (self.speed_limit + self.speed_limit_offset) * CV.MS_TO_KPH
if not self.slc_active_stock:
v_cruise_kph = v_cruise_kph_prev
return v_cruise_kph
def get_button_type(self, button_type):
self.type_status = "type_" + str(button_type)
self.button_picker = getattr(self, self.type_status, lambda: "default")
return self.button_picker()
def reset_button(self):
if self.button_type != 3:
self.button_type = 0
def type_default(self):
self.button_type = 0
return None
def type_0(self):
self.button_count = 0
self.target_speed = self.init_speed
self.speed_diff = self.target_speed - self.v_set_dis
if self.target_speed > self.v_set_dis:
self.button_type = 1
elif self.target_speed < self.v_set_dis and self.v_set_dis > self.v_cruise_min:
self.button_type = 2
return None
def type_1(self):
cruise_button = 1
self.button_count += 1
if self.target_speed <= self.v_set_dis:
self.button_count = 0
self.button_type = 3
elif self.button_count > 5:
self.button_count = 0
self.button_type = 3
return cruise_button
def type_2(self):
cruise_button = 2
self.button_count += 1
if self.target_speed >= self.v_set_dis or self.v_set_dis <= self.v_cruise_min:
self.button_count = 0
self.button_type = 3
elif self.button_count > 5:
self.button_count = 0
self.button_type = 3
return cruise_button
def type_3(self):
cruise_button = None
self.button_count += 1
if self.button_count > self.t_interval:
self.button_type = 0
return cruise_button
def get_curve_speed(self, target_speed_kph, v_cruise_kph_prev):
if self.v_tsc_state != 0:
vision_v_cruise_kph = self.v_tsc * CV.MS_TO_KPH
if int(vision_v_cruise_kph) == int(v_cruise_kph_prev):
vision_v_cruise_kph = 255
else:
vision_v_cruise_kph = 255
if self.m_tsc_state > 1:
map_v_cruise_kph = self.m_tsc * CV.MS_TO_KPH
if int(map_v_cruise_kph) == 0.0:
map_v_cruise_kph = 255
else:
map_v_cruise_kph = 255
curve_speed = self.curve_speed_hysteresis(min(vision_v_cruise_kph, map_v_cruise_kph) + 2 * CV.MPH_TO_KPH)
return min(target_speed_kph, curve_speed)
def get_button_control(self, CS, final_speed, v_cruise_kph_prev):
self.init_speed = round(min(final_speed, v_cruise_kph_prev) * (CV.KPH_TO_MPH if not CS.params_list.is_metric else 1))
self.v_set_dis = round(CS.out.cruiseState.speed * (CV.MS_TO_MPH if not CS.params_list.is_metric else CV.MS_TO_KPH))
cruise_button = self.get_button_type(self.button_type)
return cruise_button
def curve_speed_hysteresis(self, cur_speed: float, hyst=(0.75 * CV.MPH_TO_KPH)):
if cur_speed > self.steady_speed:
self.steady_speed = cur_speed
elif cur_speed < self.steady_speed - hyst:
self.steady_speed = cur_speed
return self.steady_speed
def get_cruise_buttons(self, CS, v_cruise_kph_prev):
cruise_button = None
if not self.get_cruise_buttons_status(CS):
pass
elif CS.out.cruiseState.enabled:
set_speed_kph = self.get_target_speed(v_cruise_kph_prev)
if self.slc_state > 1:
target_speed_kph = set_speed_kph
else:
target_speed_kph = min(v_cruise_kph_prev, set_speed_kph)
if self.v_tsc_state != 0 or self.m_tsc_state > 1:
self.final_speed_kph = self.get_curve_speed(target_speed_kph, v_cruise_kph_prev)
else:
self.final_speed_kph = target_speed_kph
cruise_button = self.get_button_control(CS, self.final_speed_kph, v_cruise_kph_prev) # MPH/KPH based button presses
return cruise_button

View File

@@ -171,8 +171,6 @@ class CarInterface(CarInterfaceBase):
if self.CC.eps_timer_soft_disable_alert:
events.add(EventName.steerTimeLimit)
ret.customStockLong = self.update_custom_stock_long()
ret.events = events.to_msg()
return ret

View File

@@ -49,7 +49,7 @@ def create_lka_hud_control(packer, bus, ldw_stock_values, lat_active, steering_p
return packer.make_can_msg("LDW_02", bus, values)
def create_acc_buttons_control(packer, bus, gra_stock_values, frame=0, buttons=0, cancel=False, resume=False, custom_stock_long=False):
def create_acc_buttons_control(packer, bus, gra_stock_values, cancel=False, resume=False):
values = {s: gra_stock_values[s] for s in [
"GRA_Hauptschalter", # ACC button, on/off
"GRA_Typ_Hauptschalter", # ACC main button type
@@ -58,18 +58,10 @@ def create_acc_buttons_control(packer, bus, gra_stock_values, frame=0, buttons=0
"GRA_ButtonTypeInfo", # unknown related to stalk type
]}
accel_cruise = 1 if buttons == 1 else 0
decel_cruise = 1 if buttons == 2 else 0
resume_cruise = 1 if buttons == 3 else 0
set_cruise = 1 if buttons == 4 else 0
values.update({
"COUNTER": (frame + 1) % 0x10 if custom_stock_long else (gra_stock_values["COUNTER"] + 1) % 16,
"COUNTER": (gra_stock_values["COUNTER"] + 1) % 16,
"GRA_Abbrechen": cancel,
"GRA_Tip_Wiederaufnahme": resume or resume_cruise,
"GRA_Tip_Setzen": set_cruise,
"GRA_Tip_Runter": decel_cruise,
"GRA_Tip_Hoch": accel_cruise,
"GRA_Tip_Wiederaufnahme": resume,
})
return packer.make_can_msg("GRA_ACC_01", bus, values)

View File

@@ -31,7 +31,7 @@ def create_lka_hud_control(packer, bus, ldw_stock_values, lat_active, steering_p
return packer.make_can_msg("LDW_Status", bus, values)
def create_acc_buttons_control(packer, bus, gra_stock_values, frame=0, buttons=0, cancel=False, resume=False, custom_stock_long=False):
def create_acc_buttons_control(packer, bus, gra_stock_values, cancel=False, resume=False):
values = {s: gra_stock_values[s] for s in [
"GRA_Hauptschalt", # ACC button, on/off
"GRA_Typ_Hauptschalt", # ACC button, momentary vs latching
@@ -39,18 +39,10 @@ def create_acc_buttons_control(packer, bus, gra_stock_values, frame=0, buttons=0
"GRA_Sender", # ACC button, CAN message originator
]}
accel_cruise = 1 if buttons == 1 else 0
decel_cruise = 1 if buttons == 2 else 0
resume_cruise = 1 if buttons == 3 else 0
set_cruise = 1 if buttons == 4 else 0
values.update({
"COUNTER": (frame + 1) % 0x10 if custom_stock_long else (gra_stock_values["COUNTER"] + 1) % 16,
"COUNTER": (gra_stock_values["COUNTER"] + 1) % 16,
"GRA_Abbrechen": cancel,
"GRA_Recall": resume or resume_cruise,
"GRA_Neu_Setzen": set_cruise,
"GRA_Down_kurz": decel_cruise,
"GRA_Up_kurz": accel_cruise,
"GRA_Recall": resume,
})
return packer.make_can_msg("GRA_Neu", bus, values)

View File

@@ -174,13 +174,10 @@ class Controls:
self.live_torque = self.params.get_bool("LiveTorque")
self.torqued_override = self.params.get_bool("TorquedOverride")
self.custom_stock_planner_speed = self.params.get_bool("CustomStockLongPlanner")
self.enable_mads = self.params.get_bool("EnableMads")
self.mads_disengage_lateral_on_brake = self.params.get_bool("DisengageLateralOnBrake")
self.mads_ndlob = self.enable_mads and not self.mads_disengage_lateral_on_brake
self.pcm_v_cruise_override = self.params.get_bool("PCMVCruiseOverride")
self.pcm_v_cruise_override_speed = int(self.params.get("PCMVCruiseOverrideSpeed", encoding="utf-8"))
self.process_not_running = False
self.experimental_mode_update = False
@@ -189,12 +186,6 @@ class Controls:
self.custom_model_metadata.capabilities & ModelCapabilities.LateralPlannerSolution
self.dynamic_personality = self.params.get_bool("DynamicPersonality")
self.overtaking_accel = self.params.get_bool("OvertakingAccelerationAssist")
self.overtaking_accel_engaged = False
self.prev_overtaking_accel_engaged = False
self.overtaking_accel_allowed = False
self.prev_overtaking_accel_allowed = False
self.overtaking_accel_blocked = False
self.accel_personality = self.read_accel_personality_param()
@@ -499,9 +490,7 @@ class Controls:
def state_transition(self, CS):
"""Compute conditional state transitions and execute actions on state transitions"""
# sp - PCM speed override
sp_override_speed = self.pcm_v_cruise_override_speed if self.pcm_v_cruise_override else False
self.v_cruise_helper.update_v_cruise(CS, self.enabled_long, self.is_metric, self.reverse_acc_change, sp_override_speed, self.sm['longitudinalPlanSP'])
self.v_cruise_helper.update_v_cruise(CS, self.enabled_long, self.is_metric, self.reverse_acc_change, self.sm['longitudinalPlanSP'])
# decrement the soft disable timer at every step, as it's reset on
# entrance in SOFT_DISABLING state
@@ -650,15 +639,9 @@ class Controls:
self.LoC.reset()
if not self.joystick_mode:
speeds = long_plan.speeds
a_lead = self.sm['radarState'].leadOne.aLeadK
resume = False
if len(speeds):
resume = self.enabled_long and CS.standstill and self.CP.carName == "hyundai" and speeds[-1] > 0.1 and a_lead > 0.1
# accel PID loop
pid_accel_limits = self.CI.get_pid_accel_limits(self.CP, CS.vEgo, self.v_cruise_helper.v_cruise_kph * CV.KPH_TO_MS)
actuators.accel = self.LoC.update(CC.longActive, CS, long_plan.aTarget, long_plan.shouldStop, pid_accel_limits, resume)
actuators.accel = self.LoC.update(CC.longActive, CS, long_plan.aTarget, long_plan.shouldStop, pid_accel_limits)
# Steering PID loop and lateral MPC
if self.model_use_lateral_planner:
@@ -834,36 +817,11 @@ class Controls:
# Curvature & Steering angle
lp = self.sm['liveParameters']
dh = 'lateralPlanDEPRECATED' if self.model_use_lateral_planner else 'modelV2'
lp_mono_time_svs = 'lateralPlanDEPRECATED' if self.model_use_lateral_planner else 'modelV2'
steer_angle_without_offset = math.radians(CS.steeringAngleDeg - lp.angleOffsetDeg)
curvature = -self.VM.calc_curvature(steer_angle_without_offset, CS.vEgo, lp.roll)
lat_plan = self.sm['lateralPlanDEPRECATED']
long_plan = self.sm['longitudinalPlan']
dm_state = self.sm['driverMonitoringState']
blinker_svs = lat_plan if self.model_use_lateral_planner else model_v2.meta
self.prev_overtaking_accel_allowed = self.overtaking_accel_allowed
if not self.overtaking_accel_allowed and not self.prev_overtaking_accel_allowed:
self.overtaking_accel_blocked = False
self.overtaking_accel_allowed = ((blinker_svs.laneChangeDirection == LaneChangeDirection.right and dm_state.isRHD) or
(blinker_svs.laneChangeDirection == LaneChangeDirection.left and not dm_state.isRHD)) and \
(blinker_svs.laneChangeState in (LaneChangeState.preLaneChange, LaneChangeState.laneChangeStarting)) and \
not self.overtaking_accel_blocked
self.prev_overtaking_accel_engaged = self.overtaking_accel_engaged
ttc = self.sm['radarState'].leadOne.dRel / CS.vEgo if CS.vEgo > 0 else 255
overtaking_accel_engaged = self.overtaking_accel and self.overtaking_accel_allowed and \
(CS.vEgo > ((60 * CV.KPH_TO_MS) if self.is_metric else (40 * CV.MPH_TO_MS))) and \
not (CS.leftBlinker and CS.rightBlinker)
if ttc < 0.75 and self.prev_overtaking_accel_engaged and overtaking_accel_engaged:
overtaking_accel_engaged = False
self.overtaking_accel_blocked = True
if overtaking_accel_engaged and not self.prev_overtaking_accel_engaged and \
long_plan.hasLead and long_plan.aTarget > -0.1 and (0.75 < ttc < 3.0):
self.overtaking_accel_engaged = True
elif not overtaking_accel_engaged:
self.overtaking_accel_engaged = False
# controlsState
dat = messaging.new_message('controlsState')
dat.valid = CS.canValid
@@ -878,7 +836,7 @@ class Controls:
controlsState.alertSound = current_alert.audible_alert
controlsState.longitudinalPlanMonoTime = self.sm.logMonoTime['longitudinalPlan']
controlsState.lateralPlanMonoTime = self.sm.logMonoTime[dh]
controlsState.lateralPlanMonoTime = self.sm.logMonoTime[lp_mono_time_svs]
controlsState.enabled = not (CS.brakePressed and (not self.CS_prev.brakePressed or not CS.standstill)) and (self.enabled or CS.cruiseState.enabled) and CS.gearShifter not in [GearShifter.park, GearShifter.reverse]
controlsState.active = not (CS.brakePressed and (not self.CS_prev.brakePressed or not CS.standstill)) and (self.active or CS.cruiseState.enabled)
controlsState.curvature = curvature
@@ -916,7 +874,6 @@ class Controls:
controlsStateSP.personality = self.personality
controlsStateSP.dynamicPersonality = self.dynamic_personality
controlsStateSP.accelPersonality = self.accel_personality
controlsStateSP.overtakingAccelerationAssist = self.overtaking_accel_engaged
if self.enable_nnff and lat_tuning == 'torque':
controlsStateSP.lateralControlState.torqueState = self.LaC.pid_long_sp
@@ -974,8 +931,7 @@ class Controls:
def params_thread(self, evt):
while not evt.is_set():
self.is_metric = self.params.get_bool("IsMetric")
self.experimental_mode = self.params.get_bool("ExperimentalMode") and (self.CP.openpilotLongitudinalControl or
(not self.CP.pcmCruiseSpeed and self.custom_stock_planner_speed))
self.experimental_mode = self.params.get_bool("ExperimentalMode") and self.CP.openpilotLongitudinalControl
self.personality = self.read_personality_param()
self.dynamic_personality = self.params.get_bool("DynamicPersonality")
self.accel_personality = self.read_accel_personality_param()
@@ -984,11 +940,9 @@ class Controls:
self.reverse_acc_change = self.params.get_bool("ReverseAccChange")
self.dynamic_experimental_control = self.params.get_bool("DynamicExperimentalControl")
self.overtaking_accel = self.params.get_bool("OvertakingAccelerationAssist")
if self.sm.frame % int(2.5 / DT_CTRL) == 0:
self.live_torque = self.params.get_bool("LiveTorque")
self.custom_stock_planner_speed = self.params.get_bool("CustomStockLongPlanner")
time.sleep(0.1)
def controlsd_thread(self):

View File

@@ -65,10 +65,6 @@ VOLKSWAGEN_V_CRUISE_MIN = {
True: 30,
False: int(20 * CV.MPH_TO_KPH),
}
GM_V_CRUISE_MIN = {
True: 30,
False: int(20 * CV.MPH_TO_KPH),
}
SpeedLimitControlState = custom.LongitudinalPlanSP.SpeedLimitControlState
@@ -88,20 +84,12 @@ class VCruiseHelper:
self.slc_state_prev = SpeedLimitControlState.inactive
self.slc_speed_limit_offsetted = 0
# sp: PCM speed override
self.sp_override_v_cruise_kph = V_CRUISE_UNSET
self.sp_override_cruise_speed_last = V_CRUISE_UNSET
self.sp_override_enabled_last = False
self.experimental_mode_update = False
@property
def v_cruise_initialized(self):
return self.v_cruise_kph != V_CRUISE_UNSET
def update_v_cruise(self, CS, enabled, is_metric, reverse_acc, sp_override_speed, long_plan_sp):
def update_v_cruise(self, CS, enabled, is_metric, reverse_acc, long_plan_sp):
self.v_cruise_kph_last = self.v_cruise_kph
self.slc_state_prev = self.slc_state
self.slc_state = long_plan_sp.speedLimitControlState
if not self.CP.pcmCruiseSpeed:
@@ -114,32 +102,12 @@ class VCruiseHelper:
self._update_v_cruise_slc(long_plan_sp)
self.v_cruise_cluster_kph = self.v_cruise_kph
else:
if enabled and sp_override_speed and CS.cruiseState.speed * CV.MS_TO_KPH < sp_override_speed:
if self.sp_override_v_cruise_kph == V_CRUISE_UNSET:
self.sp_override_v_cruise_kph = max(CS.vEgo * CV.MS_TO_KPH, V_CRUISE_MIN)
else:
self.sp_override_v_cruise_kph = V_CRUISE_UNSET
# when we have an override_speed, use it
if self.sp_override_v_cruise_kph != V_CRUISE_UNSET:
self.v_cruise_kph = self.sp_override_v_cruise_kph
self.v_cruise_cluster_kph = self.sp_override_v_cruise_kph
else:
self.v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH
self.v_cruise_cluster_kph = CS.cruiseState.speedCluster * CV.MS_TO_KPH
#print("sp_override_v_cruise_kph:", self.sp_override_v_cruise_kph)
#print("v_cruise_kph:", self.v_cruise_kph)
#print("v_cruise_cluster_kph:", self.v_cruise_cluster_kph)
self.sp_override_cruise_speed_last = CS.cruiseState.speed
self.sp_override_enabled_last = enabled
self.v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH
self.v_cruise_cluster_kph = CS.cruiseState.speedCluster * CV.MS_TO_KPH
self.update_button_timers(CS, enabled)
else:
self.sp_override_v_cruise_kph = V_CRUISE_UNSET
self.v_cruise_kph = V_CRUISE_UNSET
self.v_cruise_cluster_kph = V_CRUISE_UNSET
self.experimental_mode_update = False
def _update_v_cruise_non_pcm(self, CS, enabled, is_metric, reverse_acc):
# handle button presses. TODO: this should be in state_control, but a decelCruise press
@@ -234,8 +202,6 @@ class VCruiseHelper:
initial = MAZDA_V_CRUISE_MIN[is_metric]
elif self.CP.carName == "volkswagen":
initial = VOLKSWAGEN_V_CRUISE_MIN[is_metric]
elif self.CP.carName == "gm":
initial = GM_V_CRUISE_MIN[is_metric]
# 250kph or above probably means we never had a set speed
if any(b.type in resume_buttons for b in CS.buttonEvents) and self.v_cruise_kph_last < 250:
@@ -254,6 +220,8 @@ class VCruiseHelper:
if self.slc_state == SpeedLimitControlState.active and self.slc_state_prev == SpeedLimitControlState.preActive:
self.v_cruise_kph = clip(round(self.slc_speed_limit_offsetted, 1), self.v_cruise_min, V_CRUISE_MAX)
self.slc_state_prev = self.slc_state
def _update_v_cruise_min(self, is_metric):
if is_metric != self.is_metric_prev:
if self.CP.carName == "honda":
@@ -266,8 +234,6 @@ class VCruiseHelper:
self.v_cruise_min = MAZDA_V_CRUISE_MIN[is_metric]
elif self.CP.carName == "volkswagen":
self.v_cruise_min = VOLKSWAGEN_V_CRUISE_MIN[is_metric]
elif self.CP.carName == "gm":
self.v_cruise_min = GM_V_CRUISE_MIN[is_metric]
self.is_metric_prev = is_metric

View File

@@ -83,8 +83,7 @@ class LatControlTorque(LatControl):
self.torqued_override = self.param_s.get_bool("TorquedOverride")
self._frame = 0
self.use_lateral_jerk = self.param_s.get_bool("TorqueLateralJerk") # TODO: make this a parameter in the UI
self.nnff_no_lateral_jerk = self.param_s.get_bool("NNFFNoLateralJerk") # TODO: make this a parameter in the UI
self.use_lateral_jerk = False # TODO: make this a parameter in the UI
# Twilsonco's Lateral Neural Network Feedforward
self.use_nn = CI.has_lateral_torque_nn
@@ -141,13 +140,11 @@ class LatControlTorque(LatControl):
if self._frame % 250 == 0:
self._frame = 0
self.torqued_override = self.param_s.get_bool("TorquedOverride")
self.use_lateral_jerk = self.param_s.get_bool("TorqueLateralJerk")
self.nnff_no_lateral_jerk = self.param_s.get_bool("NNFFNoLateralJerk")
if not self.torqued_override:
return
self.torque_params.latAccelFactor = float(self.param_s.get("TorqueMaxLatAccel", encoding="utf8")) * 0.01
self.torque_params.friction = float(self.param_s.get("TorqueFriction", encoding="utf8")) * 0.001
self.torque_params.friction = float(self.param_s.get("TorqueFriction", encoding="utf8")) * 0.01
@property
def pid_long_sp(self):
@@ -200,7 +197,7 @@ class LatControlTorque(LatControl):
predicted_lateral_jerk = get_predicted_lateral_jerk(model_data.acceleration.y, self.t_diffs)
desired_lateral_jerk = (interp(self.desired_lat_jerk_time, ModelConstants.T_IDXS, model_data.acceleration.y) - desired_lateral_accel) / self.desired_lat_jerk_time
lookahead_lateral_jerk = get_lookahead_value(predicted_lateral_jerk[LAT_PLAN_MIN_IDX:friction_upper_idx], desired_lateral_jerk)
if self.nnff_no_lateral_jerk or self.use_steering_angle or lookahead_lateral_jerk == 0.0:
if self.use_steering_angle or lookahead_lateral_jerk == 0.0:
lookahead_lateral_jerk = 0.0
actual_lateral_jerk = 0.0
self.lat_accel_friction_factor = 1.0
@@ -209,7 +206,6 @@ class LatControlTorque(LatControl):
if self.use_nn and model_good:
# update past data
pitch = 0
roll = params.roll
if len(llk.calibratedOrientationNED.value) > 1:
pitch = self.pitch.update(llk.calibratedOrientationNED.value[1])
@@ -235,14 +231,7 @@ class LatControlTorque(LatControl):
+ past_rolls + future_rolls
torque_from_setpoint = self.torque_from_nn(nnff_setpoint_input)
torque_from_measurement = self.torque_from_nn(nnff_measurement_input)
pid_log.error = torque_from_setpoint - torque_from_measurement
error_blend_factor = interp(abs(desired_lateral_accel), [1.0, 2.0], [0.0, 1.0])
if error_blend_factor > 0.0: # blend in stronger error response when in high lat accel
nnff_error_input = [CS.vEgo, setpoint - measurement, lateral_jerk_setpoint - lateral_jerk_measurement, 0.0]
torque_from_error = self.torque_from_nn(nnff_error_input)
if sign(pid_log.error) == sign(torque_from_error) and abs(pid_log.error) < abs(torque_from_error):
pid_log.error = pid_log.error * (1.0 - error_blend_factor) + torque_from_error * error_blend_factor
# compute feedforward (same as nn setpoint output)
error = setpoint - measurement

View File

@@ -11,11 +11,11 @@ LongCtrlState = car.CarControl.Actuators.LongControlState
def long_control_state_trans(CP, active, long_control_state, v_ego,
should_stop, brake_pressed, cruise_standstill, resume):
should_stop, brake_pressed, cruise_standstill):
# Ignore cruise standstill if car has a gas interceptor
cruise_standstill = cruise_standstill and not CP.enableGasInterceptorDEPRECATED
stopping_condition = should_stop and not resume
starting_condition = ((not should_stop or resume) and
stopping_condition = should_stop
starting_condition = (not should_stop and
not cruise_standstill and
not brake_pressed)
started_condition = v_ego > CP.vEgoStarting
@@ -58,14 +58,14 @@ class LongControl:
def reset(self):
self.pid.reset()
def update(self, active, CS, a_target, should_stop, accel_limits, resume):
def update(self, active, CS, a_target, should_stop, accel_limits):
"""Update longitudinal control. This updates the state machine and runs a PID loop"""
self.pid.neg_limit = accel_limits[0]
self.pid.pos_limit = accel_limits[1]
self.long_control_state = long_control_state_trans(self.CP, active, self.long_control_state, CS.vEgo,
should_stop, CS.brakePressed,
CS.cruiseState.standstill, resume)
CS.cruiseState.standstill)
if self.long_control_state == LongCtrlState.off:
self.reset()
output_accel = 0.

View File

@@ -63,11 +63,9 @@ def get_jerk_factor(personality=custom.LongitudinalPersonalitySP.standard):
elif personality==custom.LongitudinalPersonalitySP.standard:
return 1.0
elif personality==custom.LongitudinalPersonalitySP.moderate:
return 0.9
elif personality==custom.LongitudinalPersonalitySP.aggressive:
return 0.8
elif personality==custom.LongitudinalPersonalitySP.overtake:
return 0.1
elif personality==custom.LongitudinalPersonalitySP.aggressive:
return 0.6
else:
raise NotImplementedError("Longitudinal personality not supported")
@@ -81,27 +79,26 @@ def get_T_FOLLOW(personality=custom.LongitudinalPersonalitySP.standard):
return 1.25
elif personality==custom.LongitudinalPersonalitySP.aggressive:
return 1.0
elif personality==custom.LongitudinalPersonalitySP.overtake:
return 0.25
else:
raise NotImplementedError("Longitudinal personality not supported")
# Last updated: September 29, 2024
def get_dynamic_personality(v_ego, personality=custom.LongitudinalPersonalitySP.standard):
if personality==custom.LongitudinalPersonalitySP.relaxed:
x_vel = [0, 14., 27.7]
y_dist = [1.75, 1.75, 2.00]
x_vel = [0, 11, 14.5, 15, 20, 20.01, 25, 25.01, 36, 36.01]
y_dist = [1.5, 1.5, 1.5, 1.6, 1.76, 1.76, 1.78, 1.78, 1.8, 1.8]
elif personality==custom.LongitudinalPersonalitySP.standard:
x_vel = [0, 14., 27.7]
y_dist = [1.75, 1.75, 1.70]
x_vel = [0, 11, 14.5, 15, 20, 20.01, 25, 25.01, 36, 36.01]
y_dist = [1.40, 1.40, 1.40, 1.50, 1.60, 1.76, 1.76, 1.78, 1.8, 1.8]
elif personality==custom.LongitudinalPersonalitySP.moderate:
x_vel = [0, 14., 27.7]
y_dist = [1.45, 1.45, 1.48]
x_vel = [0, 11, 14.5, 15, 20, 20.01, 25, 25.01, 36, 36.01]
y_dist = [1.3, 1.3, 1.3, 1.35, 1.35, 1.385, 1.385, 1.4, 1.4, 1.45]
elif personality==custom.LongitudinalPersonalitySP.aggressive:
x_vel = [0, 14., 27.7]
y_dist = [1.25, 1.25, 1.28]
x_vel = [0, 5, 5.01, 11, 14.5, 15, 20, 20.01, 25, 25.01, 36, 36.01]
y_dist = [1.12, 1.12, 1.12, 1.12, 1.12, 1.105, 1.105, 1.15, 1.15, 1.18, 1.20, 1.23]
else:
raise NotImplementedError("Dynamic personality not supported")
return np.interp(v_ego, x_vel, y_dist)
@@ -361,11 +358,9 @@ class LongitudinalMpc:
self.cruise_min_a = min_a
self.max_a = max_a
def update(self, radarstate, v_cruise, x, v, a, j, personality=custom.LongitudinalPersonalitySP.standard,
dynamic_personality=False, overtaking_acceleration_assist=False):
def update(self, radarstate, v_cruise, x, v, a, j, personality=custom.LongitudinalPersonalitySP.standard, dynamic_personality=False):
v_ego = self.x0[1]
t_follow = get_dynamic_personality(v_ego, personality) if dynamic_personality else get_T_FOLLOW(personality)
t_follow = get_T_FOLLOW(custom.LongitudinalPersonalitySP.overtake) if overtaking_acceleration_assist else t_follow
self.status = radarstate.leadOne.status or radarstate.leadTwo.status
lead_xv_0 = self.process_lead(radarstate.leadOne)

View File

@@ -3,7 +3,7 @@ import math
import numpy as np
from openpilot.common.numpy_fast import clip, interp
from openpilot.common.params import Params
from cereal import car, log, custom
from cereal import car
import cereal.messaging as messaging
from openpilot.common.conversions import Conversions as CV
@@ -12,7 +12,6 @@ from openpilot.common.realtime import DT_MDL
from openpilot.selfdrive.modeld.constants import ModelConstants
from openpilot.selfdrive.controls.lib.sunnypilot.common import Source
from openpilot.selfdrive.controls.lib.sunnypilot.speed_limit_controller import SpeedLimitController
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags
from openpilot.selfdrive.car.interfaces import ACCEL_MIN, ACCEL_MAX
from openpilot.selfdrive.controls.lib.longcontrol import LongCtrlState
from openpilot.selfdrive.controls.lib.longitudinal_mpc_lib.long_mpc import LongitudinalMpc
@@ -36,7 +35,6 @@ _A_TOTAL_MAX_V = [1.7, 3.2]
_A_TOTAL_MAX_BP = [20., 40.]
MpcSource = custom.MpcSource
EventName = car.CarEvent.EventName
@@ -84,8 +82,7 @@ class LongitudinalPlanner:
self.dt = dt
self.a_desired = init_a
v_ego_sec = 0.6 if CP.carName == "hyundai" and not CP.flags & (HyundaiFlags.HYBRID | HyundaiFlags.EV) else 2.0
self.v_desired_filter = FirstOrderFilter(init_v, v_ego_sec, self.dt)
self.v_desired_filter = FirstOrderFilter(init_v, 2.0, self.dt)
self.v_model_error = 0.0
self.v_desired_trajectory = np.zeros(CONTROL_N)
@@ -132,13 +129,10 @@ class LongitudinalPlanner:
self.read_param()
self.param_read_counter += 1
if self.dynamic_experimental_controller.is_enabled() and sm['controlsState'].experimentalMode:
self.dynamic_experimental_controller.set_mpc_fcw_crash_cnt(self.mpc.crash_cnt)
self.dynamic_experimental_controller.update(self.CP.radarUnavailable, sm['carState'], sm['radarState'].leadOne, sm['modelV2'], sm['controlsState'], sm['navInstruction'].maneuverDistance)
self.mpc.mode = self.dynamic_experimental_controller.get_mpc_mode()
self.mpc.mode = self.dynamic_experimental_controller.get_mpc_mode(self.CP.radarUnavailable, sm['carState'], sm['radarState'].leadOne, sm['modelV2'], sm['controlsState'], sm['navInstruction'].maneuverDistance)
else:
self.mpc.mode = 'blended' if sm['controlsState'].experimentalMode else 'acc'
v_ego = sm['carState'].vEgo
v_cruise_kph = min(sm['controlsState'].vCruise, V_CRUISE_MAX)
v_cruise = v_cruise_kph * CV.KPH_TO_MS
@@ -159,10 +153,8 @@ class LongitudinalPlanner:
accel_limits = [ACCEL_MIN, ACCEL_MAX]
accel_limits_turns = [ACCEL_MIN, ACCEL_MAX]
overtaking_accel_engaged = sm['controlsStateSP'].overtakingAccelerationAssist
# override accel using Accel Controller
if self.accel_controller.is_enabled(accel_personality=custom.AccelerationPersonality.sport if overtaking_accel_engaged else
sm['controlsStateSP'].accelPersonality):
if self.accel_controller.is_enabled(accel_personality=sm['controlsStateSP'].accelPersonality):
# get min, max from accel controller
min_limit, max_limit = self.accel_controller.get_accel_limits(v_ego, accel_limits)
if self.mpc.mode == 'acc':
@@ -197,12 +189,11 @@ class LongitudinalPlanner:
accel_limits_turns[0] = min(accel_limits_turns[0], self.a_desired + 0.05)
accel_limits_turns[1] = max(accel_limits_turns[1], self.a_desired - 0.05)
self.mpc.set_weights(prev_accel_constraint, personality=custom.LongitudinalPersonalitySP.overtake if overtaking_accel_engaged else sm['controlsStateSP'].personality)
self.mpc.set_weights(prev_accel_constraint, personality=sm['controlsStateSP'].personality)
self.mpc.set_accel_limits(accel_limits_turns[0], accel_limits_turns[1])
self.mpc.set_cur_state(self.v_desired_filter.x, self.a_desired)
x, v, a, j = self.parse_model(sm['modelV2'], self.v_model_error)
self.mpc.update(sm['radarState'], v_cruise, x, v, a, j, personality=sm['controlsStateSP'].personality,
dynamic_personality=sm['controlsStateSP'].dynamicPersonality, overtaking_acceleration_assist=overtaking_accel_engaged)
self.mpc.update(sm['radarState'], v_cruise, x, v, a, j, personality=sm['controlsStateSP'].personality, dynamic_personality=sm['controlsStateSP'].dynamicPersonality)
self.v_desired_trajectory = np.interp(CONTROL_N_T_IDX, T_IDXS_MPC, self.mpc.v_solution)
self.a_desired_trajectory = np.interp(CONTROL_N_T_IDX, T_IDXS_MPC, self.mpc.a_solution)
@@ -271,8 +262,7 @@ class LongitudinalPlanner:
longitudinalPlanSP.turnSpeedControlState = self.turn_speed_controller.state
longitudinalPlanSP.turnSpeed = float(self.turn_speed_controller.v_target)
longitudinalPlanSP.mpcSource = MpcSource.blended if self.mpc.mode == 'blended' else MpcSource.acc
longitudinalPlanSP.dynamicExperimentalControl = self.dynamic_experimental_controller.is_enabled()
longitudinalPlanSP.e2eBlended = self.mpc.mode
pm.send('longitudinalPlanSP', plan_sp_send)

View File

@@ -21,23 +21,23 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
# Last updated: September 29, 2024
# Last updated: July 1, 2024
from cereal import custom
from openpilot.common.numpy_fast import interp
AccelPersonality = custom.AccelerationPersonality
# accel personality by @arne182 modified by cgw and kumar
_DP_CRUISE_MIN_V = [-1.0, -1.0, -0.88]
_DP_CRUISE_MIN_V_ECO = [-1.0, -1.0, -0.76]
_DP_CRUISE_MIN_V_SPORT = [-1.0, -1.0, -1.0]
_DP_CRUISE_MIN_BP = [0., 11.1, 20.]
# accel personality by @arne182 modified by cgw
_DP_CRUISE_MIN_V = [-1.03, -0.79, -0.77, -0.77, -0.75, -0.75, -0.88, -0.82]
_DP_CRUISE_MIN_V_ECO = [-1.02, -0.78, -0.75, -0.75, -0.73, -0.73, -0.80, -0.80]
_DP_CRUISE_MIN_V_SPORT = [-1.04, -0.81, -0.79, -0.79, -0.77, -0.77, -0.90, -0.84]
_DP_CRUISE_MIN_BP = [0., 0.05, 0.1, 0.5, 8.33, 16., 30., 40.]
_DP_CRUISE_MAX_V = [2.0, 2.0, 2.0, 1.75, 1.03, .72, .53, .42, .13]
_DP_CRUISE_MAX_V_ECO = [2.0, 2.0, 2.0, 1.50, 0.92, .54, .43, .32, .088]
_DP_CRUISE_MAX_V_SPORT = [2.0, 2.0, 2.0, 2.00, 1.25, .96, .78, .60, .4]
_DP_CRUISE_MAX_BP = [0., 1., 6., 8., 11., 20., 25., 30., 55.]
_DP_CRUISE_MAX_V = [2.5, 2.5, 2.5, 1.70, 1.05, .81, .625, .42, .348, .12]
_DP_CRUISE_MAX_V_ECO = [2.0, 2.0, 2.0, 1.4, .80, .68, .53, .32, .20, .085]
_DP_CRUISE_MAX_V_SPORT = [3.5, 3.5, 2.8, 2.4, 1.4, 1.0, .89, .75, .50, .2]
_DP_CRUISE_MAX_BP = [0., 1., 6., 8., 11., 15., 20., 25., 30., 55.]
class AccelController:

View File

@@ -21,39 +21,33 @@
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# Version = 2024-9-28
# Version = 2024-1-29
from common.numpy_fast import interp
import numpy as np
from openpilot.selfdrive.controls.lib.lateral_planner import TRAJECTORY_SIZE
# d-e2e, from modeldata.h
TRAJECTORY_SIZE = 33
LEAD_WINDOW_SIZE = 4
LEAD_WINDOW_SIZE = 5
LEAD_PROB = 0.6
SLOW_DOWN_WINDOW_SIZE = 4
SLOW_DOWN_WINDOW_SIZE = 5
SLOW_DOWN_PROB = 0.6
SLOW_DOWN_BP = [0., 10., 20., 30., 40., 50., 55., 60.]
SLOW_DOWN_DIST = [25., 38., 55., 75., 95., 115., 130., 150.]
SLOW_DOWN_DIST = [20, 30., 50., 70., 80., 90., 105., 120.]
SLOWNESS_WINDOW_SIZE = 12
SLOWNESS_PROB = 0.5
SLOWNESS_WINDOW_SIZE = 20
SLOWNESS_PROB = 0.6
SLOWNESS_CRUISE_OFFSET = 1.05
DANGEROUS_TTC_WINDOW_SIZE = 3
DANGEROUS_TTC = 2.3
DANGEROUS_TTC_WINDOW_SIZE = 5
DANGEROUS_TTC = 2.0
HIGHWAY_CRUISE_KPH = 70
HIGHWAY_CRUISE_KPH = 75
STOP_AND_GO_FRAME = 60
SET_MODE_TIMEOUT = 10
MPC_FCW_WINDOW_SIZE = 10
MPC_FCW_PROB = 0.5
V_ACC_MIN = 9.72
MPC_FCW_WINDOW_SIZE = 5
MPC_FCW_PROB = 0.6
class SNG_State:
@@ -83,51 +77,29 @@ class GenericMovingAverageCalculator:
self.data = []
self.total = 0
class WeightedMovingAverageCalculator:
def __init__(self, window_size):
self.window_size = window_size
self.data = []
self.weights = np.linspace(1, 3, window_size) # Linear weights, adjust as needed
def add_data(self, value):
if len(self.data) == self.window_size:
self.data.pop(0)
self.data.append(value)
def get_weighted_average(self):
if len(self.data) == 0:
return None
weighted_sum = np.dot(self.data, self.weights[-len(self.data):])
weight_total = np.sum(self.weights[-len(self.data):])
return weighted_sum / weight_total
def reset_data(self):
self.data = []
class DynamicExperimentalController:
def __init__(self):
self._is_enabled = False
self._mode = 'acc'
self._mode_prev = 'acc'
self._mode_changed = False
self._frame = 0
# Use weighted moving average for filtering leads
self._lead_gmac = WeightedMovingAverageCalculator(window_size=LEAD_WINDOW_SIZE)
self._lead_gmac = GenericMovingAverageCalculator(window_size=LEAD_WINDOW_SIZE)
self._has_lead_filtered = False
self._has_lead_filtered_prev = False
self._slow_down_gmac = WeightedMovingAverageCalculator(window_size=SLOW_DOWN_WINDOW_SIZE)
self._slow_down_gmac = GenericMovingAverageCalculator(window_size=SLOW_DOWN_WINDOW_SIZE)
self._has_slow_down = False
self._has_blinkers = False
self._slowness_gmac = WeightedMovingAverageCalculator(window_size=SLOWNESS_WINDOW_SIZE)
self._slowness_gmac = GenericMovingAverageCalculator(window_size=SLOWNESS_WINDOW_SIZE)
self._has_slowness = False
self._has_nav_instruction = False
self._dangerous_ttc_gmac = WeightedMovingAverageCalculator(window_size=DANGEROUS_TTC_WINDOW_SIZE)
self._dangerous_ttc_gmac = GenericMovingAverageCalculator(window_size=DANGEROUS_TTC_WINDOW_SIZE)
self._has_dangerous_ttc = False
self._v_ego_kph = 0.
@@ -141,50 +113,13 @@ class DynamicExperimentalController:
self._sng_transit_frame = 0
self._sng_state = SNG_State.off
self._mpc_fcw_gmac = WeightedMovingAverageCalculator(window_size=MPC_FCW_WINDOW_SIZE)
self._mpc_fcw_gmac = GenericMovingAverageCalculator(window_size=MPC_FCW_WINDOW_SIZE)
self._has_mpc_fcw = False
self._mpc_fcw_crash_cnt = 0
self._set_mode_timeout = 0
pass
def _adaptive_slowdown_threshold(self):
"""
Adapts the slow down threshold based on vehicle speed and recent behavior.
"""
return interp(self._v_ego_kph, SLOW_DOWN_BP, SLOW_DOWN_DIST) * (1.0 + 0.03 * np.log(1 + len(self._slow_down_gmac.data)))
def _anomaly_detection(self, recent_data, threshold=2.0, context_check=True):
"""
Basic anomaly detection using standard deviation.
"""
if len(recent_data) < 5:
return False
mean = np.mean(recent_data)
std_dev = np.std(recent_data)
anomaly = recent_data[-1] > mean + threshold * std_dev
# Context check to ensure repeated anomaly
if context_check:
return np.count_nonzero(np.array(recent_data) > mean + threshold * std_dev) > 1
return anomaly
def _smoothed_lead_detection(self, lead_prob, smoothing_factor=0.2):
"""
Smoothing the lead detection to avoid erratic behavior.
"""
self._has_lead_filtered = (1 - smoothing_factor) * self._has_lead_filtered + smoothing_factor * lead_prob
return self._has_lead_filtered > LEAD_PROB
def _adaptive_lead_prob_threshold(self):
"""
Adapts lead probability threshold based on driving conditions.
"""
if self._v_ego_kph > HIGHWAY_CRUISE_KPH:
return LEAD_PROB + 0.1 # Increase the threshold on highways
return LEAD_PROB
def _update(self, car_state, lead_one, md, controls_state, maneuver_distance):
self._v_ego_kph = car_state.vEgo * 3.6
self._v_cruise_kph = controls_state.vCruise
@@ -193,27 +128,18 @@ class DynamicExperimentalController:
# fcw detection
self._mpc_fcw_gmac.add_data(self._mpc_fcw_crash_cnt > 0)
self._has_mpc_fcw = self._mpc_fcw_gmac.get_weighted_average() > MPC_FCW_PROB
self._has_mpc_fcw = self._mpc_fcw_gmac.get_moving_average() >= MPC_FCW_PROB
# nav enable detection
self._has_nav_instruction = md.navEnabledDEPRECATED and maneuver_distance / max(car_state.vEgo, 1) < 13
# lead detection with smoothing
# lead detection
self._lead_gmac.add_data(lead_one.status)
self._has_lead_filtered = self._lead_gmac.get_weighted_average() > LEAD_PROB
#lead_prob = self._lead_gmac.get_weighted_average() or 0
#self._has_lead_filtered = self._smoothed_lead_detection(lead_prob)
self._has_lead_filtered = self._lead_gmac.get_moving_average() >= LEAD_PROB
# adaptive slow down detection
adaptive_threshold = self._adaptive_slowdown_threshold()
slow_down_trigger = len(md.orientation.x) == len(md.position.x) == TRAJECTORY_SIZE and md.position.x[TRAJECTORY_SIZE - 1] < adaptive_threshold
self._slow_down_gmac.add_data(slow_down_trigger)
self._has_slow_down = self._slow_down_gmac.get_weighted_average() > SLOW_DOWN_PROB
# anomaly detection for slow down events
if self._anomaly_detection(self._slow_down_gmac.data):
# Handle anomaly: potentially log it, adjust behavior, or issue a warning
self._has_slow_down = False # Reset slow down if anomaly detected
# slow down detection
self._slow_down_gmac.add_data(len(md.orientation.x) == len(md.position.x) == TRAJECTORY_SIZE and md.position.x[TRAJECTORY_SIZE - 1] < interp(self._v_ego_kph, SLOW_DOWN_BP, SLOW_DOWN_DIST))
self._has_slow_down = self._slow_down_gmac.get_moving_average() >= SLOW_DOWN_PROB
# blinker detection
self._has_blinkers = car_state.leftBlinker or car_state.rightBlinker
@@ -235,7 +161,7 @@ class DynamicExperimentalController:
# slowness detection
if not self._has_standstill:
self._slowness_gmac.add_data(self._v_ego_kph <= (self._v_cruise_kph*SLOWNESS_CRUISE_OFFSET))
self._has_slowness = self._slowness_gmac.get_weighted_average() > SLOWNESS_PROB
self._has_slowness = self._slowness_gmac.get_moving_average() >= SLOWNESS_PROB
# dangerous TTC detection
if not self._has_lead_filtered and self._has_lead_filtered_prev:
@@ -245,14 +171,14 @@ class DynamicExperimentalController:
if self._has_lead and car_state.vEgo >= 0.01:
self._dangerous_ttc_gmac.add_data(lead_one.dRel/car_state.vEgo)
self._has_dangerous_ttc = self._dangerous_ttc_gmac.get_weighted_average() is not None and self._dangerous_ttc_gmac.get_weighted_average() <= DANGEROUS_TTC
self._has_dangerous_ttc = self._dangerous_ttc_gmac.get_moving_average() is not None and self._dangerous_ttc_gmac.get_moving_average() <= DANGEROUS_TTC
# keep prev values
self._has_standstill_prev = self._has_standstill
self._has_lead_filtered_prev = self._has_lead_filtered
self._frame += 1
def _radarless_mode(self):
def _blended_priority_mode(self):
# when mpc fcw crash prob is high
# use blended to slow down quickly
if self._has_mpc_fcw:
@@ -264,21 +190,21 @@ class DynamicExperimentalController:
self._set_mode('blended')
return
# when blinker is on and speed is driving below V_ACC_MIN: blended
# when blinker is on and speed is driving below highway cruise speed: blended
# we dont want it to switch mode at higher speed, blended may trigger hard brake
#if self._has_blinkers and self._v_ego_kph < V_ACC_MIN:
# self._set_mode('blended')
# return
if self._has_blinkers and self._v_ego_kph < HIGHWAY_CRUISE_KPH:
self._set_mode('blended')
return
# when at highway cruise and SNG: blended
# ensuring blended mode is used because acc is bad at catching SNG lead car
# especially those who accel very fast and then brake very hard.
#if self._sng_state == SNG_State.going and self._v_cruise_kph >= V_ACC_MIN:
# self._set_mode('blended')
# return
if self._sng_state == SNG_State.going and self._v_cruise_kph >= HIGHWAY_CRUISE_KPH:
self._set_mode('blended')
return
# when standstill: blended
# in case of lead car suddenly move away under traffic light, acc mode won't brake at traffic light.
# in case of lead car suddenly move away under traffic light, acc mode wont brake at traffic light.
if self._has_standstill:
self._set_mode('blended')
return
@@ -300,9 +226,9 @@ class DynamicExperimentalController:
self._set_mode('acc')
return
self._set_mode('acc')
self._set_mode('blended')
def _radar_mode(self):
def _acc_priority_mode(self):
# when mpc fcw crash prob is high
# use blended to slow down quickly
if self._has_mpc_fcw:
@@ -310,18 +236,18 @@ class DynamicExperimentalController:
return
# If there is a filtered lead, the vehicle is not in standstill, and the lead vehicle's yRel meets the condition,
if self._has_lead_filtered and not self._has_standstill:
self._set_mode('acc')
return
# when blinker is on and speed is driving below V_ACC_MIN: blended
# we dont want it to switch mode at higher speed, blended may trigger hard brake
#if self._has_blinkers and self._v_ego_kph < V_ACC_MIN:
# self._set_mode('blended')
#if self._has_lead_filtered and not self._has_standstill:
# self._set_mode('acc')
# return
# when blinker is on and speed is driving below highway cruise speed: blended
# we dont want it to switch mode at higher speed, blended may trigger hard brake
if self._has_blinkers and self._v_ego_kph < HIGHWAY_CRUISE_KPH:
self._set_mode('blended')
return
# when standstill: blended
# in case of lead car suddenly move away under traffic light, acc mode won't brake at traffic light.
# in case of lead car suddenly move away under traffic light, acc mode wont brake at traffic light.
if self._has_standstill:
self._set_mode('blended')
return
@@ -344,22 +270,17 @@ class DynamicExperimentalController:
self._set_mode('acc')
def update(self, radar_unavailable, car_state, lead_one, md, controls_state, maneuver_distance):
def get_mpc_mode(self, radar_unavailable, car_state, lead_one, md, controls_state, maneuver_distance):
if self._is_enabled:
self._update(car_state, lead_one, md, controls_state, maneuver_distance)
if radar_unavailable:
self._radarless_mode()
self._blended_priority_mode()
else:
self._radar_mode()
self._mode_changed = self._mode != self._mode_prev
self._acc_priority_mode()
self._mode_prev = self._mode
def get_mpc_mode(self):
return self._mode
def has_changed(self):
return self._mode_changed
def set_enabled(self, enabled):
self._is_enabled = enabled
@@ -376,4 +297,4 @@ class DynamicExperimentalController:
self._set_mode_timeout = SET_MODE_TIMEOUT
if self._set_mode_timeout > 0:
self._set_mode_timeout -= 1
self._set_mode_timeout -= 1

View File

@@ -32,7 +32,7 @@ def plannerd_thread():
pm = messaging.PubMaster(['longitudinalPlan', 'longitudinalPlanSP'] + lateral_planner_svs)
sm = messaging.SubMaster(['carControl', 'carState', 'controlsState', 'radarState', 'modelV2',
'longitudinalPlan', 'navInstruction', 'longitudinalPlanSP',
'liveMapDataSP', 'e2eLongStateSP', 'controlsStateSP', 'driverMonitoringState'] + lateral_planner_svs,
'liveMapDataSP', 'e2eLongStateSP', 'controlsStateSP'] + lateral_planner_svs,
poll='modelV2', ignore_avg_freq=['radarState'])
while True:

View File

@@ -83,7 +83,7 @@ class TorqueEstimator(ParameterEstimator):
params = Params()
if params.get_bool("EnforceTorqueLateral"):
if params.get_bool("CustomTorqueLateral"):
self.offline_friction = float(params.get("TorqueFriction", encoding="utf8")) * 0.001
self.offline_friction = float(params.get("TorqueFriction", encoding="utf8")) * 0.01
self.offline_latAccelFactor = float(params.get("TorqueMaxLatAccel", encoding="utf8")) * 0.01
if params.get_bool("LiveTorqueRelaxed"):
self.min_bucket_points = np.array([0, 200, 300, 500, 500, 300, 200, 0]) / (10 if decimated else 1)

View File

@@ -145,4 +145,4 @@ void HttpRequest::requestFinished() {
QNetworkAccessManager *HttpRequest::nam() {
static QNetworkAccessManager *networkAccessManager = new QNetworkAccessManager(qApp);
return networkAccessManager;
}
}

View File

@@ -24,7 +24,7 @@ class HttpRequest : public QObject {
Q_OBJECT
public:
enum class Method { GET, DELETE, POST, PUT };
enum class Method {GET, DELETE, POST, PUT};
explicit HttpRequest(QObject* parent, bool create_jwt = true, int timeout = 20000);
virtual void sendRequest(const QString &requestURL, Method method);
@@ -47,4 +47,4 @@ protected:
protected slots:
void requestTimeout();
void requestFinished();
};
};

View File

@@ -86,8 +86,7 @@ void HomeWindow::mousePressEvent(QMouseEvent* e) {
}
void HomeWindow::mouseDoubleClickEvent(QMouseEvent* e) {
// By removing the static call to HomeWindow::mousePressEvent, we can now rely on child classes to handle the event
mousePressEvent(e);
HomeWindow::mousePressEvent(e);
const SubMaster &sm = *(uiState()->sm);
if (sm["carParams"].getCarParams().getNotCar()) {
if (onroad->isVisible()) {

View File

@@ -47,7 +47,7 @@ protected:
void mouseDoubleClickEvent(QMouseEvent* e) override;
Sidebar *sidebar;
OffroadHome* home;
OffroadHome *home;
OnroadWindow *onroad;
BodyWindow *body;
DriverViewWindow *driver_view;
@@ -55,4 +55,4 @@ protected:
protected slots:
virtual void updateState(const UIState &s);
};
};

View File

@@ -16,7 +16,7 @@
#include "selfdrive/ui/qt/widgets/ssh_keys.h"
#ifdef SUNNYPILOT
#include "selfdrive/ui/sunnypilot/sunnypilot_main.h"
#endif
#endif
TogglesPanel::TogglesPanel(SettingsWindow *parent) : ListWidget(parent) {
RETURN_IF_SUNNYPILOT

View File

@@ -91,7 +91,6 @@ protected:
virtual void updateToggles();
};
class SoftwarePanel : public ListWidget {
Q_OBJECT
public:

View File

@@ -26,7 +26,7 @@
void SoftwarePanel::checkForUpdates() {
std::system("pkill -SIGUSR1 -f updated");
std::system("pkill -SIGUSR1 -f system.updated.updated");
}
SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) {
@@ -45,7 +45,7 @@ SoftwarePanel::SoftwarePanel(QWidget* parent) : ListWidget(parent) {
if (downloadBtn->text() == tr("CHECK")) {
checkForUpdates();
} else {
std::system("pkill -SIGHUP -f updated");
std::system("pkill -SIGHUP -f system.updated.updated");
}
});
addItem(downloadBtn);
@@ -162,4 +162,4 @@ void SoftwarePanel::updateLabels() {
installBtn->setDescription(QString::fromStdString(params.get("UpdaterNewReleaseNotes")));
update();
}
}

View File

@@ -2,7 +2,6 @@
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QVBoxLayout>
#include "selfdrive/ui/qt/offroad/experimental_mode.h"
#include "selfdrive/ui/qt/util.h"

View File

@@ -1,19 +1,12 @@
#pragma once
#include <QFrame>
#include <QLabel>
#include <QPushButton>
#include <QStackedLayout>
#include <QStackedWidget>
#include <QTimer>
#include <QWidget>
#include "common/params.h"
#include "selfdrive/ui/qt/offroad/driverview.h"
#include "selfdrive/ui/qt/body.h"
#include "selfdrive/ui/qt/onroad/onroad_home.h"
#include "selfdrive/ui/qt/widgets/offroad_alerts.h"
#include "selfdrive/ui/ui.h"
#ifdef SUNNYPILOT
#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h"

View File

@@ -385,4 +385,4 @@ void AnnotatedCameraWidget::showEvent(QShowEvent *event) {
ui_update_params(uiState());
prev_draw_t = millis_since_boot();
}
}

View File

@@ -50,4 +50,4 @@ protected:
double prev_draw_t = 0;
FirstOrderFilter fps_filter;
};
};

View File

@@ -26,8 +26,7 @@ ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(fals
void ExperimentalButton::changeMode() {
const auto cp = (*uiState()->sm)["carParams"].getCarParams();
bool can_change = (hasLongitudinalControl(cp) || (!cp.getPcmCruiseSpeed() && params.getBool("CustomStockLongPlanner")))
&& params.getBool("ExperimentalModeConfirmed");
bool can_change = hasLongitudinalControl(cp) && params.getBool("ExperimentalModeConfirmed");
if (can_change) {
params.putBool("ExperimentalMode", !experimental_mode);
}

View File

@@ -31,4 +31,4 @@ private:
QPixmap experimental_img;
};
void drawIcon(QPainter &p, const QPoint &center, const QPixmap &img, const QBrush &bg, float opacity);
void drawIcon(QPainter &p, const QPoint &center, const QPixmap &img, const QBrush &bg, float opacity);

View File

@@ -66,4 +66,4 @@ void OnroadWindow::offroadTransition(bool offroad) {
void OnroadWindow::paintEvent(QPaintEvent *event) {
QPainter p(this);
p.fillRect(rect(), QColor(bg.red(), bg.green(), bg.blue(), 255));
}
}

View File

@@ -26,4 +26,4 @@ protected:
protected slots:
virtual void offroadTransition(bool offroad);
virtual void updateState(const UIState &s);
};
};

View File

@@ -20,4 +20,4 @@ private:
Params params;
QTimer *timer;
QString prevResp;
};
};

View File

@@ -65,4 +65,4 @@ protected:
private:
std::unique_ptr<PubMaster> pm;
};
};

View File

@@ -61,4 +61,4 @@ int main(int argc, char *argv[]) {
)");
return a.exec();
}
}

View File

@@ -59,4 +59,4 @@ private:
QFileSystemWatcher *watcher;
QHash<QString, QString> params_hash;
Params params;
};
};

View File

@@ -35,4 +35,4 @@ private:
void refresh();
void getUserKeys(const QString &username);
};
};

View File

@@ -30,7 +30,7 @@ sp_maps_widgets_src = [
]
sp_qt_util = [
# "#selfdrive/ui/sunnypilot/qt/api.cc",
# "#selfdrive/ui/sunnypilot/qt/api.cc",
"#selfdrive/ui/sunnypilot/qt/util.cc",
]

View File

@@ -33,7 +33,6 @@ Last updated: July 29, 2024
#include <QApplication>
#include <QJsonDocument>
#include <memory>
#include <string>
#include <common/swaglog.h>

View File

@@ -26,11 +26,6 @@ Last updated: July 29, 2024
#pragma once
#include <QJsonObject>
#include <QNetworkReply>
#include <QString>
#include <QTimer>
#include "selfdrive/ui/qt/api.h"
#include "selfdrive/ui/sunnypilot/qt/util.h"
#include "common/util.h"

View File

@@ -28,13 +28,10 @@ Last updated: July 29, 2024
#include <QHBoxLayout>
#include <QMouseEvent>
#include <QStackedWidget>
#include <QVBoxLayout>
#include <common/swaglog.h>
#include "selfdrive/ui/qt/offroad/experimental_mode.h"
#include "selfdrive/ui/qt/util.h"
#include "selfdrive/ui/qt/widgets/prime.h"
// HomeWindowSP: the container for the offroad and onroad UIs
HomeWindowSP::HomeWindowSP(QWidget* parent) : HomeWindow(parent){

View File

@@ -27,14 +27,9 @@ Last updated: July 29, 2024
#pragma once
#include <QFrame>
#include <QLabel>
#include <QPushButton>
#include <QStackedLayout>
#include <QTimer>
#include <QWidget>
#include "common/params.h"
#include "selfdrive/ui/qt/offroad/driverview.h"
#include "selfdrive/ui/qt/body.h"
#include "selfdrive/ui/qt/widgets/offroad_alerts.h"
#include "selfdrive/ui/sunnypilot/ui.h"
@@ -42,7 +37,6 @@ Last updated: July 29, 2024
#ifdef SUNNYPILOT
#include "selfdrive/ui/sunnypilot/qt/sidebar.h"
#include "selfdrive/ui/sunnypilot/qt/onroad/onroad_home.h"
#define OnroadWindow OnroadWindowSP
#else
#include "selfdrive/ui/qt/sidebar.h"

View File

@@ -30,7 +30,6 @@ Last updated: July 29, 2024
#include <vector>
#include <QFileInfo>
#include "common/watchdog.h"
#include "selfdrive/ui/qt/qt_window.h"
#include "selfdrive/ui/qt/widgets/prime.h"

View File

@@ -28,11 +28,9 @@ Last updated: July 29, 2024
#include <map>
#include <string>
#include <tuple>
#include <vector>
#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h"
#include "selfdrive/ui/sunnypilot/qt/widgets/scrollview.h"
class MonitoringPanel : public QFrame {
Q_OBJECT

View File

@@ -57,12 +57,6 @@ TogglesPanelSP::TogglesPanelSP(SettingsWindow *parent) : TogglesPanel(parent) {
tr("When enabled, sunnypilot will attempt to control stock longitudinal control with ACC button presses.\nThis feature must be used along with SLC, and/or V-TSC, and/or M-TSC."),
"../assets/offroad/icon_blank.png",
},
{
"CustomStockLongPlanner",
tr("Use Planner Speed"),
"",
"../assets/offroad/icon_blank.png",
},
{
"ExperimentalMode",
tr("Experimental Mode"),
@@ -229,7 +223,6 @@ void TogglesPanelSP::updateToggles() {
auto custom_stock_long_toggle = toggles["CustomStockLong"];
auto dec_toggle = toggles["DynamicExperimentalControl"];
auto dynamic_personality_toggle = toggles["DynamicPersonality"];
auto custom_stock_long_planner = toggles["CustomStockLongPlanner"];
const QString e2e_description = QString("%1<br>"
"<h4>%2</h4><br>"
"%3<br>"
@@ -268,22 +261,16 @@ void TogglesPanelSP::updateToggles() {
accel_personality_setting->setEnabled(true);
op_long_toggle->setEnabled(true);
custom_stock_long_toggle->setEnabled(false);
custom_stock_long_planner->setEnabled(false);
params.remove("CustomStockLong");
dec_toggle->setEnabled(true);
dynamic_personality_toggle->setEnabled(true);
} else if (custom_stock_long_toggle->isToggled()) {
op_long_toggle->setEnabled(false);
experimental_mode_toggle->setEnabled(custom_stock_long_planner->isToggled());
experimental_mode_toggle->setDescription(e2e_description);
custom_stock_long_planner->setEnabled(true);
long_personality_setting->setEnabled(custom_stock_long_planner->isToggled());
accel_personality_setting->setEnabled(custom_stock_long_planner->isToggled());
dec_toggle->setEnabled(experimental_mode_toggle->isToggled());
if (!custom_stock_long_planner->isToggled()) {
params.remove("ExperimentalMode");
}
experimental_mode_toggle->setEnabled(false);
long_personality_setting->setEnabled(false);
accel_personality_setting->setEnabled(false);
params.remove("ExperimentalLongitudinalEnabled");
params.remove("ExperimentalMode");
} else {
// no long for now
experimental_mode_toggle->setEnabled(false);
@@ -308,7 +295,6 @@ void TogglesPanelSP::updateToggles() {
custom_stock_long_toggle->setEnabled(CP.getCustomStockLongAvailable());
dec_toggle->setEnabled(false);
dynamic_personality_toggle->setEnabled(false);
custom_stock_long_planner->setEnabled(false);
params.remove("DynamicExperimentalControl");
params.remove("DynamicPersonality");
}
@@ -316,7 +302,6 @@ void TogglesPanelSP::updateToggles() {
experimental_mode_toggle->refresh();
op_long_toggle->refresh();
custom_stock_long_toggle->refresh();
custom_stock_long_planner->refresh();
dec_toggle->refresh();
dynamic_personality_toggle->refresh();
} else {
@@ -325,7 +310,6 @@ void TogglesPanelSP::updateToggles() {
custom_stock_long_toggle->setVisible(false);
dec_toggle->setVisible(false);
dynamic_personality_toggle->setVisible(false);
custom_stock_long_planner->setVisible(false);
}
}

View File

@@ -49,12 +49,6 @@ SunnypilotPanel::SunnypilotPanel(QWidget *parent) : QFrame(parent) {
tr("While in Auto Lane, switch to Laneless for current/future curves."),
"../assets/offroad/icon_blank.png",
},
{
"OvertakingAccelerationAssist",
tr("Overtaking Acceleration Assist"),
tr("Overtaking Acceleration Assist will operate when the turn signal indicator is turned on to the left (left-hand drive) or turned on to the right (right-hand drive) while openpilot Longitudinal Control is operating."),
"../assets/offroad/icon_blank.png",
},
{
"EnableSlc",
tr("Speed Limit Control (SLC)"),
@@ -97,24 +91,12 @@ SunnypilotPanel::SunnypilotPanel(QWidget *parent) : QFrame(parent) {
"",
"../assets/offroad/icon_blank.png",
},
{
"NNFFNoLateralJerk",
tr("NNLC: Remove Lateral Jerk Response (Alpha)"),
tr("When NNLC is active, enable this to disables the use of lateral jerk in steering torque calculations, focusing solely on lateral acceleration for a simplified control response."),
"../assets/offroad/icon_blank.png",
},
{
"EnforceTorqueLateral",
tr("Enforce Torque Lateral Control"),
tr("Enable this to enforce sunnypilot to steer with Torque lateral control."),
"../assets/offroad/icon_blank.png",
},
{
"TorqueLateralJerk",
tr("Lateral Jerk with Torque Lateral Control (Alpha)"),
tr("Utilizes limited lateral jerk control for improved steering response, leveraging stock torque lateral controller capabilities. Designed to mimic NNLC behavior without training models or data collection."),
"../assets/offroad/icon_blank.png",
},
{
"LiveTorque",
tr("Enable Self-Tune"),
@@ -316,7 +298,7 @@ SunnypilotPanel::SunnypilotPanel(QWidget *parent) : QFrame(parent) {
list->addItem(dlp_settings);
}
if (param == "OvertakingAccelerationAssist") {
if (param == "VisionCurveLaneless") {
list->addItem(laneChangeSettingsLayout);
list->addItem(horizontal_line());
@@ -363,17 +345,6 @@ SunnypilotPanel::SunnypilotPanel(QWidget *parent) : QFrame(parent) {
}
});
connect(toggles["EnforceTorqueLateral"], &ToggleControlSP::toggleFlipped, [=](bool state) {
if (state) {
toggles["NNFF"]->setEnabled(false);
params.putBool("NNFF", false);
toggles["NNFF"]->refresh();
} else {
toggles["NNFF"]->setEnabled(true);
toggles["NNFF"]->refresh();
}
});
// trigger updateToggles() when toggleFlipped
for (const auto& updateToggleName : updateTogglesNames) {
if (toggles.find(updateToggleName) != toggles.end()) {
@@ -395,7 +366,6 @@ SunnypilotPanel::SunnypilotPanel(QWidget *parent) : QFrame(parent) {
toggles["EnableMads"]->setConfirmation(true, false);
toggles["EndToEndLongAlertLight"]->setConfirmation(true, false);
toggles["CustomOffsets"]->showDescription();
toggles["OvertakingAccelerationAssist"]->setConfirmation(true, false);
connect(toggles["EnableMads"], &ToggleControlSP::toggleFlipped, mads_settings, &MadsSettings::updateToggles);
connect(toggles["EnableMads"], &ToggleControlSP::toggleFlipped, [=](bool state) {
@@ -500,8 +470,6 @@ void SunnypilotPanel::updateToggles() {
toggles["VisionCurveLaneless"]->setEnabled(dynamic_lane_profile_param == "2");
toggles["VisionCurveLaneless"]->refresh();
auto overtaking_acceleration_assist = toggles["OvertakingAccelerationAssist"];
bool custom_driving_model_valid = params.getBool("CustomDrivingModel");
auto driving_model_generation = QString::fromStdString(params.get("DrivingModelGeneration"));
bool model_use_lateral_planner = custom_driving_model_valid && driving_model_generation == "1";
@@ -581,7 +549,6 @@ void SunnypilotPanel::updateToggles() {
if (!slcSettings->isVisible() && enable_slc_param) {
slcSettings->setVisible(true);
}
overtaking_acceleration_assist->setEnabled(hasLongitudinalControl(CP));
} else {
v_tsc->setEnabled(false);
m_tsc->setEnabled(false);
@@ -589,21 +556,18 @@ void SunnypilotPanel::updateToggles() {
slc_toggle->setEnabled(false);
params.remove("EnableSlc");
slcSettings->setEnabled(false);
overtaking_acceleration_assist->setEnabled(false);
}
enforce_torque_lateral->refresh();
slc_toggle->refresh();
nnff_toggle->refresh();
m_tsc->refresh();
overtaking_acceleration_assist->refresh();
} else {
v_tsc->setEnabled(false);
m_tsc->setEnabled(false);
reverse_acc->setEnabled(false);
slc_toggle->setEnabled(false);
slcSettings->setEnabled(false);
overtaking_acceleration_assist->setEnabled(false);
nnff_toggle->setDescription(nnff_toggle->isToggled() ? nnffDescriptionBuilder(nnff_status_init) : nnff_description);
}
@@ -613,7 +577,7 @@ void SunnypilotPanel::updateToggles() {
}
// toggle names to update when EnforceTorqueLateral is flipped
std::vector<std::string> torqueLateralGroup{"CustomTorqueLateral", "TorqueLateralJerk", "LiveTorque", "LiveTorqueRelaxed", "TorquedOverride"};
std::vector<std::string> torqueLateralGroup{"CustomTorqueLateral", "LiveTorque", "LiveTorqueRelaxed", "TorquedOverride"};
for (const auto& torqueLateralToggle : torqueLateralGroup) {
if (toggles.find(torqueLateralToggle) != toggles.end()) {
if (nnff_toggle->isToggled()) {
@@ -630,24 +594,6 @@ void SunnypilotPanel::updateToggles() {
}
}
// toggle names to update when EnforceTorqueLateral is flipped
std::vector<std::string> nnffGroup{"NNFFNoLateralJerk"};
for (const auto& nnffToggle : nnffGroup) {
if (toggles.find(nnffToggle) != toggles.end()) {
if (enforce_torque_lateral->isToggled()) {
toggles[nnffToggle]->setVisible(false);
toggles[nnffToggle]->setEnabled(false);
}
}
}
for (const auto& nnffToggle : nnffGroup) {
if (toggles.find(nnffToggle) != toggles.end()) {
toggles[nnffToggle]->setVisible(nnff_toggle->isToggled());
toggles[nnffToggle]->setEnabled(nnff_toggle->isToggled());
}
}
if (enforce_torque_lateral->isToggled()) {
live_torque_relaxed->setVisible(live_torque->isToggled());
torqued_override->setVisible(custom_torque_lateral->isToggled());
@@ -676,14 +622,13 @@ TorqueFriction::TorqueFriction() : OptionControlSP(
tr("FRICTION"),
tr("Adjust Friction for the Torque Lateral Controller. <b>Live</b>: Override self-tune values; <b>Offline</b>: Override self-tune offline values at car restart."),
"../assets/offroad/icon_blank.png",
{0, 500},
5) {
{0, 50}) {
refresh();
}
void TorqueFriction::refresh() {
float torqueFrictionVal = QString::fromStdString(params.get("TorqueFriction")).toInt() * 0.001;
float torqueFrictionVal = QString::fromStdString(params.get("TorqueFriction")).toInt() * 0.01;
setTitle("FRICTION - " + (params.getBool("TorquedOverride") ? tr("Real-time and Offline") : tr("Offline Only")));
setLabel(QString::number(torqueFrictionVal));
}

View File

@@ -29,7 +29,6 @@ Last updated: July 29, 2024
#include <map>
#include <string>
#include "common/model.h"
#include "selfdrive/ui/sunnypilot/ui.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot/custom_offsets_settings.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnypilot/lane_change_settings.h"

View File

@@ -101,14 +101,13 @@ SPVehiclesTogglesPanel::SPVehiclesTogglesPanel(VehiclePanel *parent) : ListWidge
// Hyundai/Kia/Genesis
addItem(new LabelControlSP(tr("Hyundai/Kia/Genesis")));
auto hkgCustomLongTuning = new ParamControlSP(
"HkgCustomLongTuning",
tr("HKG: Custom Tuning for New Longitudinal API"),
tr(""),
"../assets/offroad/icon_blank.png"
);
hkgCustomLongTuning->setConfirmation(true, false);
addItem(hkgCustomLongTuning);
auto hkgSmoothStop = new ParamControlSP(
"HkgSmoothStop",
tr("HKG CAN: Smoother Stopping Performance (Beta)"),
tr("Smoother stopping behind a stopped car or desired stopping event. This is only applicable to HKG CAN platforms using openpilot longitudinal control."),
"../assets/offroad/icon_blank.png");
hkgSmoothStop->setConfirmation(true, false);
addItem(hkgSmoothStop);
hyundaiCruiseMainDefault = new ParamControlSP(
"HyundaiCruiseMainDefault",
@@ -191,14 +190,6 @@ SPVehiclesTogglesPanel::SPVehiclesTogglesPanel(VehiclePanel *parent) : ListWidge
toyotaAutoUnlock->setConfirmation(true, false);
addItem(toyotaAutoUnlock);
auto toyotaDriveMode = new ParamControlSP(
"ToyotaDriveMode",
tr("Enable Toyota Drive Mode Button"),
tr("Sunnypilot will link the Acceleration Personality to the car's physical drive mode selector.\nReboot Required."),
"../assets/offroad/icon_blank.png");
toyotaDriveMode->setConfirmation(true, false);
addItem(toyotaDriveMode);
// Volkswagen
addItem(new LabelControlSP(tr("Volkswagen")));
auto volkswagenCCOnly = new ParamControlSP(
@@ -212,7 +203,7 @@ SPVehiclesTogglesPanel::SPVehiclesTogglesPanel(VehiclePanel *parent) : ListWidge
// trigger offroadTransition when going onroad/offroad
connect(uiStateSP(), &UIStateSP::offroadTransition, [=](bool offroad) {
is_onroad = !offroad;
hkgCustomLongTuning->setEnabled(offroad);
hkgSmoothStop->setEnabled(offroad);
hyundaiCruiseMainDefault->setEnabled(offroad);
toyotaTss2LongTune->setEnabled(offroad);
toyotaEnhancedBsm->setEnabled(offroad);

View File

@@ -28,10 +28,8 @@ Last updated: July 29, 2024
#include <QApplication>
#include "common/watchdog.h"
#include "selfdrive/ui/sunnypilot/ui.h"
#include "selfdrive/ui/sunnypilot/qt/widgets/controls.h"
#include "selfdrive/ui/sunnypilot/qt/widgets/scrollview.h"
class VehiclePanel : public QWidget {
Q_OBJECT

View File

@@ -30,7 +30,6 @@ Last updated: July 29, 2024
#include "selfdrive/ui/qt/offroad/experimental_mode.h"
#include "selfdrive/ui/qt/widgets/prime.h"
#include <QStackedWidget>
#include "selfdrive/ui/sunnypilot/sunnypilot_main.h"
#ifdef ENABLE_MAPS

View File

@@ -31,7 +31,6 @@ Last updated: July 29, 2024
#include "selfdrive/ui/qt/maps/map_settings.h"
#endif
class OffroadHomeSP : public OffroadHome {
Q_OBJECT

View File

@@ -320,8 +320,8 @@ void AnnotatedCameraWidgetSP::updateState(const UIStateSP &s) {
// TODO: Add toggle variables to cereal, and parse from cereal
longitudinalPersonality = s.scene.longitudinal_personality;
dynamicLaneProfile = s.scene.dynamic_lane_profile;
const auto mpc_source = lp_sp.getMpcSource();
mpcSource = mpc_source == cereal::MpcSource::BLENDED ? QString(tr("blended")) : QString(tr("acc"));
mpcMode = QString::fromStdString(lp_sp.getE2eBlended());
mpcMode = (mpcMode == "blended") ? mpcMode.replace(0, 1, mpcMode[0].toUpper()) : mpcMode.toUpper();
static int reverse_delay = 0;
bool reverse_allowed = false;
@@ -1061,7 +1061,7 @@ void AnnotatedCameraWidgetSP::drawFeatureStatusText(QPainter &p, int x, int y) {
p.setBrush(dec_color);
p.drawEllipse(dec_btn);
QString dec_status_text;
dec_status_text.sprintf("DEC: %s\n", dynamicExperimentalControlToggle ? (experimentalMode ? QString(mpcSource).toStdString().c_str() : QString("Inactive").toStdString().c_str()) : "OFF");
dec_status_text.sprintf("DEC: %s\n", dynamicExperimentalControlToggle ? (experimentalMode ? QString(mpcMode).toStdString().c_str() : QString("Inactive").toStdString().c_str()) : "OFF");
p.setPen(QPen(shadow_color, 2));
p.drawText(x + drop_shadow_size, y + drop_shadow_size, dec_status_text);
p.setPen(QPen(text_color, 2));
@@ -1177,10 +1177,6 @@ void AnnotatedCameraWidgetSP::drawLaneLines(QPainter &painter, const UIStateSP *
// paint path
QLinearGradient bg(0, height(), 0, 0);
const auto long_plan_sp = sm["longitudinalPlanSP"].getLongitudinalPlanSP();
bool exp_mode_path = (long_plan_sp.getDynamicExperimentalControl() && long_plan_sp.getMpcSource() == cereal::MpcSource::BLENDED) ||
(!long_plan_sp.getDynamicExperimentalControl() && sm["controlsState"].getControlsState().getExperimentalMode());
if (madsEnabled || car_state.getCruiseState().getEnabled()) {
if (steerOverride && latActive) {
bg.setColorAt(0.0, QColor::fromHslF(20 / 360., 0.94, 0.51, 0.17));
@@ -1189,7 +1185,7 @@ void AnnotatedCameraWidgetSP::drawLaneLines(QPainter &painter, const UIStateSP *
} else if (!(latActive || car_state.getCruiseState().getEnabled())) {
bg.setColorAt(0, whiteColor());
bg.setColorAt(1, whiteColor(0));
} else if (exp_mode_path) {
} else if (sm["controlsState"].getControlsState().getExperimentalMode()) {
// The first half of track_vertices are the points for the right side of the path
const auto &acceleration = sm["modelV2"].getModelV2().getAcceleration().getX();
const int max_len = std::min<int>(scene.track_vertices.length() / 2, acceleration.size());
@@ -1290,25 +1286,46 @@ void AnnotatedCameraWidgetSP::drawDriverState(QPainter &painter, const UIStateSP
}
void AnnotatedCameraWidgetSP::rocketFuel(QPainter &p) {
UIState *s = uiState();
float accel = (*s->sm)["carControl"].getCarControl().getActuators().getAccel();
int widgetHeight = rect().height();
float halfHeightAbs = std::abs(accel) * widgetHeight / 2.0f;
const float scannerWidth = 15;
QRect scannerRect;
if (accel > 0) {
static const int ct_n = 1;
static float ct;
int rect_w = rect().width();
int rect_h = rect().height();
const int n = 15 + 1; //Add one off screen due to timing issues
static float t[n];
int dim_n = (sin(ct / 5) + 1) * (n - 0.01);
t[dim_n] = 1.0;
t[(int)(ct/ct_n)] = 1.0;
UIStateSP *s = uiStateSP();
float vc_accel0 = (*s->sm)["carState"].getCarState().getAEgo();
static float vc_accel;
vc_accel = vc_accel + (vc_accel0 - vc_accel) / 5;
float hha = 0;
if (vc_accel > 0) {
hha = 0.85 - 0.1 / vc_accel; // only extend up to 85%
p.setBrush(QColor(0, 245, 0, 200));
scannerRect = QRect(0, widgetHeight / 2 - halfHeightAbs, scannerWidth, halfHeightAbs);
} else {
p.setBrush(QColor(245, 0, 0, 200));
scannerRect = QRect(0, widgetHeight / 2, scannerWidth, halfHeightAbs);
}
p.drawRect(scannerRect);
if (vc_accel < 0) {
hha = 0.85 + 0.1 / vc_accel; // only extend up to 85%
p.setBrush(QColor(245, 0, 0, 200));
}
if (hha < 0) {
hha = 0;
}
hha = hha * rect_h;
float wp = 28;
if (vc_accel > 0) {
QRect ra = QRect(rect_w - wp, rect_h / 2 - hha / 2, wp, hha / 2);
p.drawRect(ra);
} else {
QRect ra = QRect(rect_w - wp, rect_h / 2, wp, hha / 2);
p.drawRect(ra);
}
}
void AnnotatedCameraWidgetSP::drawLead(QPainter &painter, const cereal::RadarState::LeadData::Reader &lead_data, const QPointF &vd,
int num, const cereal::CarState::Reader &car_data, int chevron_data) {
painter.save();

View File

@@ -192,7 +192,7 @@ private:
cereal::LongitudinalPlanSP::SpeedLimitControlState slcState;
int longitudinalPersonality;
int dynamicLaneProfile;
QString mpcSource;
QString mpcMode;
int speed_limit_frame;
bool slcShowSign = true;

View File

@@ -26,8 +26,6 @@ Last updated: July 29, 2024
#include "selfdrive/ui/sunnypilot/qt/onroad/onroad_home.h"
#include <QPainter>
#include <QStackedLayout>
#ifdef ENABLE_MAPS
#include "selfdrive/ui/sunnypilot/qt/maps/map_helpers.h"

View File

@@ -29,9 +29,6 @@ Last updated: July 29, 2024
#include "selfdrive/ui/qt/onroad/onroad_home.h"
#include "common/params.h"
#include "selfdrive/ui/qt/onroad/alerts.h"
// #include "selfdrive/ui/sunnypilot/qt/onroad/annotated_camera.h"
class OnroadWindowSP : public OnroadWindow {
Q_OBJECT
@@ -62,7 +59,6 @@ private:
void createMapWidget();
void createOnroadSettingsWidget();
void mousePressEvent(QMouseEvent* e) override;
// AnnotatedCameraWidgetSP *nvg;
QWidget *map = nullptr;
QWidget *onroad_settings = nullptr;

View File

@@ -193,7 +193,7 @@ void OnroadSettings::changeDynamicPersonality() {
void OnroadSettings::changeDynamicExperimentalControl() {
UISceneSP &scene = uiStateSP()->scene;
const auto cp = (*uiStateSP()->sm)["carParams"].getCarParams();
bool can_change = hasLongitudinalControl(cp) || (!cp.getPcmCruiseSpeed() && params.getBool("CustomStockLongPlanner"));
bool can_change = hasLongitudinalControl(cp);
if (can_change) {
scene.dynamic_experimental_control = !scene.dynamic_experimental_control;
params.putBool("DynamicExperimentalControl", scene.dynamic_experimental_control);

View File

@@ -26,7 +26,6 @@ Last updated: July 29, 2024
#include "selfdrive/ui/sunnypilot/qt/onroad/onroad_settings_panel.h"
#include <QHBoxLayout>
#include <QWidget>
#include "selfdrive/ui/sunnypilot/qt/onroad/onroad_settings.h"

View File

@@ -34,7 +34,6 @@ Last updated: July 29, 2024
#include "selfdrive/ui/sunnypilot/qt/util.h"
#include "common/params.h"
SidebarSP::SidebarSP(QWidget *parent) : Sidebar(parent) {
// Because I know that stock sidebar makes this connection, I will disconnect it and connect it to the new updateState function
QObject::disconnect(uiState(), &UIState::uiUpdate, this, &Sidebar::updateState);
@@ -123,7 +122,6 @@ void SidebarSP::updateState(const UIStateSP &s) {
setProperty("sunnylinkStatus", QVariant::fromValue(sunnylinkStatus));
}
void SidebarSP::DrawSidebar(QPainter &p){
Sidebar::DrawSidebar(p);
// metrics

View File

@@ -28,8 +28,6 @@ Last updated: July 29, 2024
#include <memory>
#include <QFrame>
#include <QMap>
#include "selfdrive/ui/qt/sidebar.h"
#include "selfdrive/ui/sunnypilot/ui.h"

View File

@@ -25,7 +25,6 @@ Last updated: July 29, 2024
***/
#pragma once
#include "selfdrive/ui/ui.h"
const float DRIVING_PATH_WIDE = 0.9;
const float DRIVING_PATH_NARROW = 0.25;

View File

@@ -31,13 +31,6 @@ Last updated: July 29, 2024
#include <string>
#include <vector>
#include <QButtonGroup>
#include <QFrame>
#include <QHBoxLayout>
#include <QLabel>
#include <QPainter>
#include <QPushButton>
#include "common/params.h"
#include "selfdrive/ui/qt/widgets/controls.h"
#include "selfdrive/ui/qt/widgets/input.h"

View File

@@ -36,7 +36,6 @@ Last updated: July 29, 2024
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/software_settings.h"
#include "selfdrive/ui/sunnypilot/qt/offroad/settings/sunnylink_settings.h"
inline void ReplaceWidget(QWidget* old_widget, QWidget* new_widget) {
if (old_widget && old_widget->parentWidget() && old_widget->parentWidget()->layout()) {
old_widget->parentWidget()->layout()->replaceWidget(old_widget, new_widget);

View File

@@ -34,7 +34,6 @@ Last updated: July 29, 2024
#include "common/transformations/orientation.hpp"
#include "common/params.h"
#include "common/swaglog.h"
#include "common/util.h"
#include "common/watchdog.h"
#include "selfdrive/ui/sunnypilot/qt/network/sunnylink/models/role_model.h"

View File

@@ -33,11 +33,9 @@ Last updated: July 29, 2024
#include "selfdrive/ui/ui.h"
#include "cereal/messaging/messaging.h"
#include "common/timing.h"
#include "qt/network/sunnylink/models/role_model.h"
#include "qt/network/sunnylink/models/sponsor_role_model.h"
#include "qt/network/sunnylink/models/user_model.h"
#include "selfdrive/ui/sunnypilot/qt/ui_scene.h"
#include "system/hardware/hw.h"
const int UI_ROAD_NAME_MARGIN_X = 14;

Some files were not shown because too many files have changed in this diff Show More