mirror of
https://github.com/sunnypilot/sunnypilot.git
synced 2026-07-21 14:42:07 +08:00
Merge branch 'lt' into lt
This commit is contained in:
@@ -28,6 +28,9 @@ sunnypilot - 0.9.8.0 (2024-xx-xx)
|
||||
* 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
|
||||
@@ -45,6 +48,10 @@ 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)
|
||||
@@ -82,6 +89,8 @@ 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
|
||||
@@ -89,6 +98,8 @@ 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
|
||||
|
||||
@@ -48,6 +48,7 @@ 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
|
||||
@@ -114,12 +115,40 @@ 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
|
||||
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
|
||||
```
|
||||
|
||||
After running the command to install the desired branch, your comma device should reboot.
|
||||
@@ -194,7 +223,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 sunnypilot completely when `OFF` **(strictly enforced in panda safety code)**
|
||||
* `CRUISE (MAIN)` button disables ACC/SCC 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:
|
||||
@@ -326,7 +355,7 @@ Example:
|
||||
|
||||
---
|
||||
|
||||
How-To instructions can be found in [HOW-TOS.md](HOW-TOS.md).
|
||||
How-To instructions can be found in [HOW-TOS.md](https://github.com/sunnyhaibin/openpilot/blob/(!)README/HOW-TOS.md).
|
||||
|
||||
</details>
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@ enum LongitudinalPersonalitySP {
|
||||
moderate @1;
|
||||
standard @2;
|
||||
relaxed @3;
|
||||
overtake @4;
|
||||
}
|
||||
|
||||
enum AccelerationPersonality {
|
||||
@@ -44,6 +45,7 @@ struct ControlsStateSP @0x81c2f05a394cf4af {
|
||||
personality @8 :LongitudinalPersonalitySP;
|
||||
dynamicPersonality @9 :Bool;
|
||||
accelPersonality @10 :AccelerationPersonality;
|
||||
overtakingAccelerationAssist @11 :Bool;
|
||||
|
||||
lateralControlState :union {
|
||||
indiState @1 :LateralINDIState;
|
||||
|
||||
@@ -232,6 +232,7 @@ 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,6 +264,7 @@ std::unordered_map<std::string, uint32_t> keys = {
|
||||
{"HideVEgoUi", PERSISTENT | BACKUP},
|
||||
{"HkgCustomLongTuning", PERSISTENT | BACKUP},
|
||||
{"HkgSmoothStop", PERSISTENT | BACKUP},
|
||||
{"HyundaiCruiseMainDefault", PERSISTENT | BACKUP},
|
||||
{"HotspotOnBoot", PERSISTENT},
|
||||
{"HotspotOnBootConfirmed", PERSISTENT},
|
||||
{"LastCarModel", PERSISTENT | BACKUP},
|
||||
@@ -281,6 +283,7 @@ 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},
|
||||
@@ -291,8 +294,11 @@ 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},
|
||||
@@ -317,6 +323,7 @@ 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},
|
||||
{"ToyotaAutoHold", PERSISTENT | BACKUP},
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
third_party/libyuv/x86_64/**
|
||||
third_party/snpe/x86_64/**
|
||||
third_party/snpe/x86_64-linux-clang/**
|
||||
third_party/acados/x86_64/**
|
||||
@@ -0,0 +1,15 @@
|
||||
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
|
||||
@@ -218,7 +218,7 @@ def create_gas_interceptor_command(packer, gas_amount, idx):
|
||||
values["GAS_COMMAND"] = gas_amount * 255.
|
||||
values["GAS_COMMAND2"] = gas_amount * 255.
|
||||
|
||||
dat = packer.make_can_msg("GAS_COMMAND", 0, values)[2]
|
||||
dat = packer.make_can_msg("GAS_COMMAND", 0, values)[1]
|
||||
|
||||
checksum = crc8_pedal(dat[:-1])
|
||||
values["CHECKSUM_PEDAL"] = checksum
|
||||
|
||||
@@ -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
|
||||
from openpilot.selfdrive.car.ford.values import CarControllerParams, FordFlags, FordFlagsSP
|
||||
from openpilot.selfdrive.car.interfaces import CarControllerBase
|
||||
|
||||
LongCtrlState = car.CarControl.Actuators.LongControlState
|
||||
@@ -35,6 +35,9 @@ 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 = []
|
||||
@@ -74,7 +77,10 @@ class CarController(CarControllerBase):
|
||||
# TODO: extended mode
|
||||
mode = 1 if CC.latActive else 0
|
||||
counter = (self.frame // CarControllerParams.STEER_STEP) % 0x10
|
||||
can_sends.append(fordcan.create_lat_ctl2_msg(self.packer, self.CAN, mode, 0., 0., -apply_curvature, 0., counter))
|
||||
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))
|
||||
else:
|
||||
can_sends.append(fordcan.create_lat_ctl_msg(self.packer, self.CAN, CC.latActive, 0., 0., -apply_curvature, 0.))
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ 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}
|
||||
|
||||
@@ -72,6 +73,10 @@ 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
|
||||
|
||||
@@ -129,6 +134,16 @@ 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 = [
|
||||
@@ -185,6 +200,11 @@ 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),
|
||||
|
||||
@@ -3,7 +3,8 @@ 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.selfdrive.car.ford.values import Ecu, FordFlags
|
||||
from openpilot.common.params import Params
|
||||
from openpilot.selfdrive.car.ford.values import Ecu, FordFlags, FordFlagsSP
|
||||
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
|
||||
|
||||
ButtonType = car.CarState.ButtonEvent.Type
|
||||
@@ -18,13 +19,15 @@ 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:
|
||||
@@ -51,6 +54,13 @@ 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:
|
||||
|
||||
@@ -11,6 +11,7 @@ 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)
|
||||
@@ -28,6 +29,9 @@ 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):
|
||||
@@ -45,6 +49,10 @@ 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}")
|
||||
|
||||
@@ -68,11 +76,67 @@ 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]
|
||||
|
||||
@@ -48,9 +48,14 @@ 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):
|
||||
@@ -91,7 +96,7 @@ class FordPlatformConfig(PlatformConfig):
|
||||
|
||||
@dataclass
|
||||
class FordCANFDPlatformConfig(FordPlatformConfig):
|
||||
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('ford_lincoln_base_pt', None))
|
||||
dbc_dict: DbcDict = field(default_factory=lambda: dbc_dict('ford_lincoln_base_pt', RADAR.STEER_ASSIST_DATA))
|
||||
|
||||
def init(self):
|
||||
super().init()
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
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
|
||||
@@ -6,6 +8,7 @@ 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
|
||||
@@ -37,6 +40,36 @@ 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
|
||||
@@ -45,9 +78,40 @@ 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
|
||||
|
||||
@@ -148,6 +212,15 @@ 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:
|
||||
@@ -161,3 +234,120 @@ 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
|
||||
|
||||
@@ -119,6 +119,7 @@ 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
|
||||
@@ -240,7 +241,7 @@ class CarInterface(CarInterfaceBase):
|
||||
else:
|
||||
self.CS.madsEnabled = False
|
||||
|
||||
if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0):
|
||||
if not self.CP.pcmCruise or (self.CP.pcmCruise and self.CP.minEnableSpeed > 0) or not self.CP.pcmCruiseSpeed:
|
||||
if any(b.type == ButtonType.cancel for b in self.CS.button_events):
|
||||
self.CS.madsEnabled, self.CS.accEnabled = self.get_sp_cancel_cruise_state(self.CS.madsEnabled)
|
||||
if self.get_sp_pedal_disengage(ret):
|
||||
@@ -281,6 +282,10 @@ class CarInterface(CarInterfaceBase):
|
||||
if ret.vEgo < self.CP.minSteerSpeed and self.CS.madsEnabled:
|
||||
events.add(EventName.belowSteerSpeed)
|
||||
|
||||
ret.customStockLong = self.CS.update_custom_stock_long(self.CC.cruise_button, self.CC.final_speed_kph,
|
||||
self.CC.target_speed, self.CC.v_set_dis,
|
||||
self.CC.speed_diff, self.CC.button_type)
|
||||
|
||||
ret.events = events.to_msg()
|
||||
|
||||
return ret
|
||||
|
||||
@@ -62,7 +62,7 @@ class CarController(CarControllerBase):
|
||||
self.lat_disengage_init = False
|
||||
self.lat_active_last = False
|
||||
|
||||
sub_services = ['longitudinalPlanSP']
|
||||
sub_services = ['longitudinalPlan', 'longitudinalPlanSP']
|
||||
if CP.openpilotLongitudinalControl:
|
||||
sub_services.append('radarState')
|
||||
# TODO: Always true, prep for future conditional refactoring
|
||||
@@ -94,7 +94,10 @@ class CarController(CarControllerBase):
|
||||
self.v_tsc = 0
|
||||
self.m_tsc = 0
|
||||
self.steady_speed = 0
|
||||
self.speeds = 0
|
||||
self.v_target_plan = 0
|
||||
self.hkg_can_smooth_stop = self.param_s.get_bool("HkgSmoothStop")
|
||||
self.custom_stock_planner_speed = self.param_s.get_bool("CustomStockLongPlanner")
|
||||
self.lead_distance = 0
|
||||
|
||||
self.jerk = 0.0
|
||||
@@ -126,6 +129,10 @@ class CarController(CarControllerBase):
|
||||
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
|
||||
@@ -135,14 +142,21 @@ class CarController(CarControllerBase):
|
||||
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,
|
||||
@@ -203,7 +217,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, 0
|
||||
addr, bus = 0x7d0, self.CAN.ECAN if self.CP.carFingerprint in CANFD_CAR else 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))
|
||||
@@ -241,6 +255,8 @@ 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))
|
||||
@@ -463,6 +479,8 @@ class CarController(CarControllerBase):
|
||||
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:
|
||||
|
||||
@@ -1171,6 +1171,17 @@ 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',
|
||||
|
||||
@@ -172,6 +172,20 @@ 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
|
||||
@@ -182,15 +196,7 @@ def create_adrv_messages(packer, CAN, frame):
|
||||
}
|
||||
ret.append(packer.make_can_msg("ADRV_0x51", CAN.ACAN, values))
|
||||
|
||||
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))
|
||||
ret.extend(create_fca_warning_light(packer, CAN, frame))
|
||||
|
||||
if frame % 5 == 0:
|
||||
values = {
|
||||
|
||||
@@ -91,7 +91,7 @@ class CarInterface(CarInterfaceBase):
|
||||
|
||||
# *** longitudinal control ***
|
||||
if candidate in CANFD_CAR:
|
||||
ret.experimentalLongitudinalAvailable = candidate not in (CANFD_UNSUPPORTED_LONGITUDINAL_CAR | CANFD_RADAR_SCC_CAR | NON_SCC_CAR)
|
||||
ret.experimentalLongitudinalAvailable = candidate not in (CANFD_UNSUPPORTED_LONGITUDINAL_CAR | NON_SCC_CAR)
|
||||
if ret.flags & HyundaiFlags.CANFD_CAMERA_SCC and not hda2:
|
||||
ret.spFlags |= HyundaiFlagsSP.SP_CAMERA_SCC_LEAD.value
|
||||
else:
|
||||
@@ -102,12 +102,16 @@ class CarInterface(CarInterfaceBase):
|
||||
ret.pcmCruise = not ret.openpilotLongitudinalControl
|
||||
|
||||
ret.stoppingControl = True
|
||||
ret.startingState = True
|
||||
ret.vEgoStarting = 0.1
|
||||
ret.startAccel = 1.6
|
||||
ret.vEgoStarting = 0.5
|
||||
ret.startAccel = 1.0
|
||||
ret.stopAccel = -1.0
|
||||
ret.longitudinalActuatorDelay = 0.5
|
||||
|
||||
if ret.flags & (HyundaiFlags.HYBRID | HyundaiFlags.EV):
|
||||
ret.startingState = False
|
||||
else:
|
||||
ret.startingState = True
|
||||
|
||||
if DBC[ret.carFingerprint]["radar"] is None:
|
||||
if ret.spFlags & (HyundaiFlagsSP.SP_ENHANCED_SCC | HyundaiFlagsSP.SP_CAMERA_SCC_LEAD):
|
||||
ret.radarUnavailable = False
|
||||
@@ -118,6 +122,8 @@ 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]
|
||||
|
||||
@@ -143,6 +149,8 @@ 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
|
||||
@@ -168,7 +176,8 @@ 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):
|
||||
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):
|
||||
ret.flags |= HyundaiFlags.ALT_LIMITS.value
|
||||
ret.safetyConfigs[-1].safetyParam |= Panda.FLAG_HYUNDAI_ALT_LIMITS
|
||||
|
||||
@@ -187,7 +196,7 @@ class CarInterface(CarInterfaceBase):
|
||||
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, 0
|
||||
addr, bus = 0x7d0, CanBus(CP).ECAN if CP.carFingerprint in CANFD_CAR else 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')
|
||||
@@ -203,6 +212,10 @@ class CarInterface(CarInterfaceBase):
|
||||
enable_radar_tracks(logcan, sendcan, bus=0, addr=0x7d0, config_data_id=b'\x01\x42')
|
||||
|
||||
def _update(self, c):
|
||||
if not self.CS.control_initialized:
|
||||
can_cruise_main_default = self.CP.spFlags & HyundaiFlagsSP.SP_CAN_LFA_BTN and not self.CP.flags & HyundaiFlags.CANFD and self.CS.params_list.hyundai_cruise_main_default
|
||||
self.CS.mainEnabled = True if can_cruise_main_default or self.CP.carFingerprint in CANFD_CAR else False
|
||||
|
||||
ret = self.CS.update(self.cp, self.cp_cam)
|
||||
|
||||
self.CS.button_events = [
|
||||
|
||||
@@ -3,7 +3,7 @@ from dataclasses import dataclass, field
|
||||
from enum import Enum, IntFlag
|
||||
|
||||
from cereal import car
|
||||
from panda.python import uds
|
||||
from panda.python import uds, Panda
|
||||
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):
|
||||
def __init__(self, CP, vEgoRaw=100.):
|
||||
self.STEER_DELTA_UP = 3
|
||||
self.STEER_DELTA_DOWN = 7
|
||||
self.STEER_DRIVER_ALLOWANCE = 50
|
||||
@@ -26,12 +26,13 @@ class CarControllerParams:
|
||||
self.STEER_STEP = 1 # 100 Hz
|
||||
|
||||
if CP.carFingerprint in CANFD_CAR:
|
||||
self.STEER_MAX = 270
|
||||
self.STEER_DRIVER_ALLOWANCE = 250
|
||||
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_DRIVER_MULTIPLIER = 2
|
||||
self.STEER_THRESHOLD = 250
|
||||
self.STEER_DELTA_UP = 2
|
||||
self.STEER_DELTA_DOWN = 3
|
||||
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
|
||||
|
||||
# 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.
|
||||
@@ -108,6 +109,7 @@ 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):
|
||||
@@ -574,6 +576,12 @@ 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),
|
||||
|
||||
@@ -408,7 +408,7 @@ class CarInterfaceBase(ABC):
|
||||
|
||||
@staticmethod
|
||||
def sp_configure_custom_torque_tune(ret, params):
|
||||
ret.lateralTuning.torque.friction = float(params.get("TorqueFriction", encoding="utf8")) * 0.01
|
||||
ret.lateralTuning.torque.friction = float(params.get("TorqueFriction", encoding="utf8")) * 0.001
|
||||
ret.lateralTuning.torque.latAccelFactor = float(params.get("TorqueMaxLatAccel", encoding="utf8")) * 0.01
|
||||
return ret
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ class ParamManager:
|
||||
"experimental_mode": False,
|
||||
"is_metric": False,
|
||||
"last_speed_limit_sign_tap": False,
|
||||
"hyundai_cruise_main_default": False,
|
||||
"mads_main_toggle": False,
|
||||
"pause_lateral_speed": 0,
|
||||
"reverse_acc_change": False,
|
||||
@@ -37,6 +38,7 @@ class ParamManager:
|
||||
"experimental_mode": params.get_bool("ExperimentalMode"),
|
||||
"is_metric": params.get_bool("IsMetric"),
|
||||
"last_speed_limit_sign_tap": params.get_bool("LastSpeedLimitSignTap"),
|
||||
"hyundai_cruise_main_default": params.get_bool("HyundaiCruiseMainDefault"),
|
||||
"mads_main_toggle": params.get_bool("MadsCruiseMain"),
|
||||
"pause_lateral_speed": int(params.get("PauseLateralSpeed", encoding="utf8")),
|
||||
"reverse_acc_change": params.get_bool("ReverseAccChange"),
|
||||
|
||||
@@ -21,7 +21,7 @@ class CarControllerParams:
|
||||
self.STEER_DRIVER_FACTOR = 1 # from dbc
|
||||
|
||||
if CP.flags & SubaruFlags.GLOBAL_GEN2:
|
||||
self.STEER_MAX = 1000
|
||||
self.STEER_MAX = 1600
|
||||
self.STEER_DELTA_UP = 40
|
||||
self.STEER_DELTA_DOWN = 40
|
||||
elif CP.carFingerprint == CAR.SUBARU_IMPREZA_2020:
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
"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",
|
||||
@@ -38,6 +41,8 @@
|
||||
"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",
|
||||
@@ -101,6 +106,7 @@
|
||||
"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",
|
||||
|
||||
@@ -17,7 +17,6 @@ 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,
|
||||
@@ -54,6 +53,7 @@ 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),
|
||||
|
||||
@@ -86,6 +86,7 @@ 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"
|
||||
|
||||
@@ -174,10 +174,13 @@ 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.custom_model_metadata = CustomModelMetadata(params=self.params, init_only=True)
|
||||
@@ -185,6 +188,7 @@ 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.accel_personality = self.read_accel_personality_param()
|
||||
|
||||
@@ -489,7 +493,9 @@ class Controls:
|
||||
def state_transition(self, CS):
|
||||
"""Compute conditional state transitions and execute actions on state transitions"""
|
||||
|
||||
self.v_cruise_helper.update_v_cruise(CS, self.enabled_long, self.is_metric, self.reverse_acc_change, self.sm['longitudinalPlanSP'])
|
||||
# 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'])
|
||||
|
||||
# decrement the soft disable timer at every step, as it's reset on
|
||||
# entrance in SOFT_DISABLING state
|
||||
@@ -638,9 +644,14 @@ class Controls:
|
||||
self.LoC.reset()
|
||||
|
||||
if not self.joystick_mode:
|
||||
speeds = long_plan.speeds
|
||||
resume = False
|
||||
if len(speeds):
|
||||
resume = self.enabled_long and CS.standstill and speeds[-1] > 0.1 and self.CP.carName == "hyundai"
|
||||
|
||||
# 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)
|
||||
actuators.accel = self.LoC.update(CC.longActive, CS, long_plan.aTarget, long_plan.shouldStop, pid_accel_limits, resume)
|
||||
|
||||
# Steering PID loop and lateral MPC
|
||||
if self.model_use_lateral_planner:
|
||||
@@ -806,11 +817,21 @@ class Controls:
|
||||
|
||||
# Curvature & Steering angle
|
||||
lp = self.sm['liveParameters']
|
||||
lp_mono_time_svs = 'lateralPlanDEPRECATED' if self.model_use_lateral_planner else 'modelV2'
|
||||
dh = '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)
|
||||
|
||||
lc_svs = self.sm[dh]
|
||||
long_plan = self.sm['longitudinalPlan'].hasLead
|
||||
dm_state = self.sm['driverMonitoringState']
|
||||
overtaking_accel_allowed = ((lc_svs.laneChangeDirection == LaneChangeDirection.right and dm_state.isRHD) or
|
||||
(lc_svs.laneChangeDirection == LaneChangeDirection.left and not dm_state.isRHD)) and \
|
||||
(lc_svs.laneChangeState in (LaneChangeState.preLaneChange, LaneChangeState.laneChangeStarting))
|
||||
overtaking_accel_engaged = self.overtaking_accel and overtaking_accel_allowed and \
|
||||
CS.vEgo > (60 * CV.KPH_TO_MS) if self.is_metric else (40 * CV.MPH_TO_MS) and long_plan.hasLead and \
|
||||
long_plan.aTarget > -0.2 and not (CS.leftBlinker and CS.rightBlinker)
|
||||
|
||||
# controlsState
|
||||
dat = messaging.new_message('controlsState')
|
||||
dat.valid = CS.canValid
|
||||
@@ -825,7 +846,7 @@ class Controls:
|
||||
controlsState.alertSound = current_alert.audible_alert
|
||||
|
||||
controlsState.longitudinalPlanMonoTime = self.sm.logMonoTime['longitudinalPlan']
|
||||
controlsState.lateralPlanMonoTime = self.sm.logMonoTime[lp_mono_time_svs]
|
||||
controlsState.lateralPlanMonoTime = self.sm.logMonoTime[dh]
|
||||
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
|
||||
@@ -863,6 +884,7 @@ class Controls:
|
||||
controlsStateSP.personality = self.personality
|
||||
controlsStateSP.dynamicPersonality = self.dynamic_personality
|
||||
controlsStateSP.accelPersonality = self.accel_personality
|
||||
controlsStateSP.overtakingAccelerationAssist = overtaking_accel_engaged
|
||||
|
||||
if self.enable_nnff and lat_tuning == 'torque':
|
||||
controlsStateSP.lateralControlState.torqueState = self.LaC.pid_long_sp
|
||||
@@ -920,7 +942,8 @@ 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
|
||||
self.experimental_mode = self.params.get_bool("ExperimentalMode") and (self.CP.openpilotLongitudinalControl or
|
||||
(not self.CP.pcmCruiseSpeed and self.custom_stock_planner_speed))
|
||||
self.personality = self.read_personality_param()
|
||||
self.dynamic_personality = self.params.get_bool("DynamicPersonality")
|
||||
self.accel_personality = self.read_accel_personality_param()
|
||||
@@ -929,9 +952,11 @@ 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):
|
||||
|
||||
@@ -65,6 +65,10 @@ 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
|
||||
|
||||
@@ -84,11 +88,16 @@ 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
|
||||
|
||||
@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, long_plan_sp):
|
||||
def update_v_cruise(self, CS, enabled, is_metric, reverse_acc, sp_override_speed, long_plan_sp):
|
||||
self.v_cruise_kph_last = self.v_cruise_kph
|
||||
self.slc_state = long_plan_sp.speedLimitControlState
|
||||
|
||||
@@ -103,9 +112,28 @@ class VCruiseHelper:
|
||||
self.v_cruise_cluster_kph = self.v_cruise_kph
|
||||
self.update_button_timers(CS, enabled)
|
||||
else:
|
||||
self.v_cruise_kph = CS.cruiseState.speed * CV.MS_TO_KPH
|
||||
self.v_cruise_cluster_kph = CS.cruiseState.speedCluster * CV.MS_TO_KPH
|
||||
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
|
||||
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
|
||||
|
||||
@@ -202,6 +230,8 @@ 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:
|
||||
@@ -234,6 +264,8 @@ 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
|
||||
|
||||
|
||||
|
||||
@@ -83,7 +83,8 @@ class LatControlTorque(LatControl):
|
||||
self.torqued_override = self.param_s.get_bool("TorquedOverride")
|
||||
self._frame = 0
|
||||
|
||||
self.use_lateral_jerk = False # TODO: make this a parameter in the UI
|
||||
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
|
||||
|
||||
# Twilsonco's Lateral Neural Network Feedforward
|
||||
self.use_nn = CI.has_lateral_torque_nn
|
||||
@@ -140,11 +141,13 @@ 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.01
|
||||
self.torque_params.friction = float(self.param_s.get("TorqueFriction", encoding="utf8")) * 0.001
|
||||
|
||||
@property
|
||||
def pid_long_sp(self):
|
||||
@@ -197,7 +200,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.use_steering_angle or lookahead_lateral_jerk == 0.0:
|
||||
if self.nnff_no_lateral_jerk or 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
|
||||
@@ -206,6 +209,7 @@ 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])
|
||||
@@ -231,7 +235,14 @@ 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
|
||||
|
||||
@@ -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):
|
||||
should_stop, brake_pressed, cruise_standstill, resume):
|
||||
# Ignore cruise standstill if car has a gas interceptor
|
||||
cruise_standstill = cruise_standstill and not CP.enableGasInterceptorDEPRECATED
|
||||
stopping_condition = should_stop
|
||||
starting_condition = (not should_stop and
|
||||
stopping_condition = should_stop and not resume
|
||||
starting_condition = ((not should_stop or resume) 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):
|
||||
def update(self, active, CS, a_target, should_stop, accel_limits, resume):
|
||||
"""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)
|
||||
CS.cruiseState.standstill, resume)
|
||||
if self.long_control_state == LongCtrlState.off:
|
||||
self.reset()
|
||||
output_accel = 0.
|
||||
|
||||
@@ -3,8 +3,7 @@ import os
|
||||
import time
|
||||
import numpy as np
|
||||
from cereal import custom
|
||||
from openpilot.common.numpy_fast import clip, interp
|
||||
from openpilot.common.conversions import Conversions as CV
|
||||
from openpilot.common.numpy_fast import clip
|
||||
from openpilot.common.realtime import DT_MDL
|
||||
from openpilot.common.swaglog import cloudlog
|
||||
# WARNING: imports outside of constants will not trigger a rebuild
|
||||
@@ -67,6 +66,8 @@ def get_jerk_factor(personality=custom.LongitudinalPersonalitySP.standard):
|
||||
return 0.8
|
||||
elif personality==custom.LongitudinalPersonalitySP.aggressive:
|
||||
return 0.65
|
||||
elif personality==custom.LongitudinalPersonalitySP.overtake:
|
||||
return 0.1
|
||||
else:
|
||||
raise NotImplementedError("Longitudinal personality not supported")
|
||||
|
||||
@@ -80,6 +81,8 @@ 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.5
|
||||
else:
|
||||
raise NotImplementedError("Longitudinal personality not supported")
|
||||
|
||||
@@ -101,61 +104,6 @@ def get_dynamic_personality(v_ego, personality=custom.LongitudinalPersonalitySP.
|
||||
raise NotImplementedError("Dynamic personality not supported")
|
||||
return np.interp(v_ego, x_vel, y_dist)
|
||||
|
||||
# multiplier for A_CHANGE_COST = 200.
|
||||
def get_a_change_cost_multiplier(v_ego, v_lead0, v_lead1, personality=custom.LongitudinalPersonalitySP.standard):
|
||||
if personality==custom.LongitudinalPersonalitySP.relaxed:
|
||||
a_change_cost_multiplier_follow_distance = 1.0
|
||||
elif personality==custom.LongitudinalPersonalitySP.standard:
|
||||
a_change_cost_multiplier_follow_distance = 0.5
|
||||
elif personality==custom.LongitudinalPersonalitySP.moderate:
|
||||
a_change_cost_multiplier_follow_distance = 0.5
|
||||
elif personality==custom.LongitudinalPersonalitySP.aggressive:
|
||||
a_change_cost_multiplier_follow_distance = 0.1
|
||||
else:
|
||||
raise NotImplementedError("Longitudinal personality not supported")
|
||||
|
||||
# stolen from @KRKeegan
|
||||
# values used for interpolation
|
||||
# start with a small a_change_multiplier_values during interpolation to allow for faster change in accel
|
||||
A_CHANGE_COST_MULTIPLIER_BP = [0., 10.] # vEgo, in m/s
|
||||
A_CHANGE_COST_MULTIPLIER_V = [.05, 1.] # multiplier values
|
||||
|
||||
# when lead is pulling away, and speed is between 0 and 10 m/s, interpolate a_change_cost_multiplier_v_ego
|
||||
a_change_cost_multiplier_v_ego = 1.
|
||||
if (v_lead0 - v_ego > 1e-3) and (v_lead1 - v_ego > 1e-3):
|
||||
a_change_cost_multiplier_v_ego = interp(v_ego, A_CHANGE_COST_MULTIPLIER_BP, A_CHANGE_COST_MULTIPLIER_V)
|
||||
|
||||
# get the minimum between a_change_multiplier based on driving personality, and a_change_multiplier based
|
||||
# on v_ego
|
||||
a_change_multiplier = min(a_change_cost_multiplier_follow_distance, a_change_cost_multiplier_v_ego)
|
||||
|
||||
# and pass it on as the final result
|
||||
return a_change_multiplier
|
||||
|
||||
# multiplier for DANGER_ZONE_COST = 100.
|
||||
def get_danger_zone_cost_multiplier(personality=custom.LongitudinalPersonalitySP.standard):
|
||||
if personality==custom.LongitudinalPersonalitySP.relaxed:
|
||||
return 1.6
|
||||
elif personality==custom.LongitudinalPersonalitySP.standard:
|
||||
return 1.3
|
||||
elif personality==custom.LongitudinalPersonalitySP.moderate:
|
||||
return 1.3
|
||||
elif personality==custom.LongitudinalPersonalitySP.aggressive:
|
||||
return 1.0
|
||||
else:
|
||||
raise NotImplementedError("Longitudinal personality not supported")
|
||||
|
||||
#def get_STOP_DISTANCE(personality=custom.LongitudinalPersonalitySP.standard):
|
||||
# if personality==log.LongitudinalPersonality.relaxed:
|
||||
# return 6.0
|
||||
# elif personality==log.LongitudinalPersonality.standard:
|
||||
# return 5.5
|
||||
# elif personality==log.LongitudinalPersonality.aggressive:
|
||||
# return 4.5
|
||||
# else:
|
||||
# raise NotImplementedError("dynamic stop distance not supported")
|
||||
|
||||
|
||||
|
||||
def get_stopped_equivalence_factor(v_lead):
|
||||
return (v_lead**2) / (2 * COMFORT_BRAKE)
|
||||
@@ -354,16 +302,12 @@ class LongitudinalMpc:
|
||||
for i in range(N):
|
||||
self.solver.cost_set(i, 'Zl', Zl)
|
||||
|
||||
def set_weights(self, prev_accel_constraint=True, v_lead0 = 0., v_lead1 = 0., personality=custom.LongitudinalPersonalitySP.standard):
|
||||
v_ego = self.x0[1]
|
||||
def set_weights(self, prev_accel_constraint=True, personality=custom.LongitudinalPersonalitySP.standard):
|
||||
jerk_factor = get_jerk_factor(personality)
|
||||
a_change_cost_multiplier = get_a_change_cost_multiplier(v_ego, v_lead0, v_lead1, personality)
|
||||
danger_zone_cost_multiplier = get_danger_zone_cost_multiplier(personality)
|
||||
if self.mode == 'acc':
|
||||
a_change_cost = A_CHANGE_COST if prev_accel_constraint else 0
|
||||
cost_weights = [X_EGO_OBSTACLE_COST, X_EGO_COST, V_EGO_COST, A_EGO_COST, jerk_factor * a_change_cost_multiplier \
|
||||
* a_change_cost, jerk_factor * J_EGO_COST]
|
||||
constraint_cost_weights = [LIMIT_COST, LIMIT_COST, LIMIT_COST, DANGER_ZONE_COST * danger_zone_cost_multiplier]
|
||||
cost_weights = [X_EGO_OBSTACLE_COST, X_EGO_COST, V_EGO_COST, A_EGO_COST, jerk_factor * a_change_cost, jerk_factor * J_EGO_COST]
|
||||
constraint_cost_weights = [LIMIT_COST, LIMIT_COST, LIMIT_COST, DANGER_ZONE_COST]
|
||||
elif self.mode == 'blended':
|
||||
a_change_cost = 40.0 if prev_accel_constraint else 0
|
||||
cost_weights = [0., 0.1, 0.2, 5.0, a_change_cost, 1.0]
|
||||
@@ -417,16 +361,16 @@ class LongitudinalMpc:
|
||||
self.cruise_min_a = min_a
|
||||
self.max_a = max_a
|
||||
|
||||
def update(self, radarstate, v_cruise, prev_accel_constraint, x, v, a, j, personality=custom.LongitudinalPersonalitySP.standard, dynamic_personality=False):
|
||||
def update(self, radarstate, v_cruise, x, v, a, j, personality=custom.LongitudinalPersonalitySP.standard,
|
||||
dynamic_personality=False, overtaking_acceleration_assist=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)
|
||||
lead_xv_1 = self.process_lead(radarstate.leadTwo)
|
||||
|
||||
self.set_weights(prev_accel_constraint=prev_accel_constraint, v_lead0=lead_xv_0[0, 1], v_lead1=lead_xv_1[0, 1], personality=personality)
|
||||
|
||||
# To estimate a safe distance from a moving lead, we calculate how much stopping
|
||||
# distance that lead needs as a minimum. We can add that to the current distance
|
||||
# and then treat that as a stopped car/obstacle at this new distance.
|
||||
|
||||
@@ -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, custom
|
||||
from cereal import car, log, custom
|
||||
|
||||
import cereal.messaging as messaging
|
||||
from openpilot.common.conversions import Conversions as CV
|
||||
@@ -83,7 +83,8 @@ class LongitudinalPlanner:
|
||||
self.dt = dt
|
||||
|
||||
self.a_desired = init_a
|
||||
self.v_desired_filter = FirstOrderFilter(init_v, 2.0, self.dt)
|
||||
v_ego_sec = 0.6 if CP.carName == "hyundai" else 2.0
|
||||
self.v_desired_filter = FirstOrderFilter(init_v, v_ego_sec, self.dt)
|
||||
self.v_model_error = 0.0
|
||||
|
||||
self.v_desired_trajectory = np.zeros(CONTROL_N)
|
||||
@@ -157,8 +158,10 @@ 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=sm['controlsStateSP'].accelPersonality):
|
||||
if self.accel_controller.is_enabled(accel_personality=custom.AccelerationPersonality.sport if overtaking_accel_engaged else
|
||||
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':
|
||||
@@ -193,11 +196,12 @@ 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=sm['controlsStateSP'].personality)
|
||||
self.mpc.set_weights(prev_accel_constraint, personality=custom.LongitudinalPersonalitySP.overtake if overtaking_accel_engaged else 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, prev_accel_constraint, x, v, a, j, personality=sm['controlsStateSP'].personality, dynamic_personality=sm['controlsStateSP'].dynamicPersonality)
|
||||
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.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)
|
||||
|
||||
@@ -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'] + lateral_planner_svs,
|
||||
'liveMapDataSP', 'e2eLongStateSP', 'controlsStateSP', 'driverMonitoringState'] + lateral_planner_svs,
|
||||
poll='modelV2', ignore_avg_freq=['radarState'])
|
||||
|
||||
while True:
|
||||
|
||||
@@ -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.01
|
||||
self.offline_friction = float(params.get("TorqueFriction", encoding="utf8")) * 0.001
|
||||
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)
|
||||
|
||||
@@ -145,4 +145,4 @@ void HttpRequest::requestFinished() {
|
||||
QNetworkAccessManager *HttpRequest::nam() {
|
||||
static QNetworkAccessManager *networkAccessManager = new QNetworkAccessManager(qApp);
|
||||
return networkAccessManager;
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
};
|
||||
};
|
||||
@@ -86,7 +86,8 @@ void HomeWindow::mousePressEvent(QMouseEvent* e) {
|
||||
}
|
||||
|
||||
void HomeWindow::mouseDoubleClickEvent(QMouseEvent* e) {
|
||||
HomeWindow::mousePressEvent(e);
|
||||
// By removing the static call to HomeWindow::mousePressEvent, we can now rely on child classes to handle the event
|
||||
mousePressEvent(e);
|
||||
const SubMaster &sm = *(uiState()->sm);
|
||||
if (sm["carParams"].getCarParams().getNotCar()) {
|
||||
if (onroad->isVisible()) {
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
};
|
||||
@@ -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
|
||||
|
||||
@@ -91,6 +91,7 @@ protected:
|
||||
virtual void updateToggles();
|
||||
};
|
||||
|
||||
|
||||
class SoftwarePanel : public ListWidget {
|
||||
Q_OBJECT
|
||||
public:
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
|
||||
void SoftwarePanel::checkForUpdates() {
|
||||
std::system("pkill -SIGUSR1 -f system.updated.updated");
|
||||
std::system("pkill -SIGUSR1 -f 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 system.updated.updated");
|
||||
std::system("pkill -SIGHUP -f updated");
|
||||
}
|
||||
});
|
||||
addItem(downloadBtn);
|
||||
@@ -162,4 +162,4 @@ void SoftwarePanel::updateLabels() {
|
||||
installBtn->setDescription(QString::fromStdString(params.get("UpdaterNewReleaseNotes")));
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <QHBoxLayout>
|
||||
#include <QMouseEvent>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "selfdrive/ui/qt/offroad/experimental_mode.h"
|
||||
#include "selfdrive/ui/qt/util.h"
|
||||
|
||||
@@ -1,12 +1,19 @@
|
||||
#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"
|
||||
|
||||
@@ -385,4 +385,4 @@ void AnnotatedCameraWidget::showEvent(QShowEvent *event) {
|
||||
|
||||
ui_update_params(uiState());
|
||||
prev_draw_t = millis_since_boot();
|
||||
}
|
||||
}
|
||||
@@ -50,4 +50,4 @@ protected:
|
||||
|
||||
double prev_draw_t = 0;
|
||||
FirstOrderFilter fps_filter;
|
||||
};
|
||||
};
|
||||
@@ -26,7 +26,8 @@ ExperimentalButton::ExperimentalButton(QWidget *parent) : experimental_mode(fals
|
||||
|
||||
void ExperimentalButton::changeMode() {
|
||||
const auto cp = (*uiState()->sm)["carParams"].getCarParams();
|
||||
bool can_change = hasLongitudinalControl(cp) && params.getBool("ExperimentalModeConfirmed");
|
||||
bool can_change = (hasLongitudinalControl(cp) || (!cp.getPcmCruiseSpeed() && params.getBool("CustomStockLongPlanner")))
|
||||
&& params.getBool("ExperimentalModeConfirmed");
|
||||
if (can_change) {
|
||||
params.putBool("ExperimentalMode", !experimental_mode);
|
||||
}
|
||||
|
||||
@@ -31,4 +31,4 @@ private:
|
||||
QPixmap experimental_img;
|
||||
};
|
||||
|
||||
void drawIcon(QPainter &p, const QPoint ¢er, const QPixmap &img, const QBrush &bg, float opacity);
|
||||
void drawIcon(QPainter &p, const QPoint ¢er, const QPixmap &img, const QBrush &bg, float opacity);
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -26,4 +26,4 @@ protected:
|
||||
protected slots:
|
||||
virtual void offroadTransition(bool offroad);
|
||||
virtual void updateState(const UIState &s);
|
||||
};
|
||||
};
|
||||
@@ -20,4 +20,4 @@ private:
|
||||
Params params;
|
||||
QTimer *timer;
|
||||
QString prevResp;
|
||||
};
|
||||
};
|
||||
@@ -65,4 +65,4 @@ protected:
|
||||
|
||||
private:
|
||||
std::unique_ptr<PubMaster> pm;
|
||||
};
|
||||
};
|
||||
@@ -61,4 +61,4 @@ int main(int argc, char *argv[]) {
|
||||
)");
|
||||
|
||||
return a.exec();
|
||||
}
|
||||
}
|
||||
@@ -59,4 +59,4 @@ private:
|
||||
QFileSystemWatcher *watcher;
|
||||
QHash<QString, QString> params_hash;
|
||||
Params params;
|
||||
};
|
||||
};
|
||||
@@ -35,4 +35,4 @@ private:
|
||||
|
||||
void refresh();
|
||||
void getUserKeys(const QString &username);
|
||||
};
|
||||
};
|
||||
@@ -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",
|
||||
]
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@ Last updated: July 29, 2024
|
||||
#include <QApplication>
|
||||
#include <QJsonDocument>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <common/swaglog.h>
|
||||
|
||||
|
||||
@@ -26,6 +26,11 @@ 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"
|
||||
|
||||
@@ -28,10 +28,13 @@ 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){
|
||||
|
||||
@@ -27,9 +27,14 @@ 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"
|
||||
@@ -37,6 +42,7 @@ 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"
|
||||
|
||||
@@ -30,6 +30,7 @@ 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"
|
||||
|
||||
|
||||
@@ -28,9 +28,11 @@ 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
|
||||
|
||||
@@ -57,6 +57,12 @@ 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"),
|
||||
@@ -223,6 +229,7 @@ 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>"
|
||||
@@ -261,16 +268,22 @@ 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(false);
|
||||
long_personality_setting->setEnabled(false);
|
||||
accel_personality_setting->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");
|
||||
}
|
||||
params.remove("ExperimentalLongitudinalEnabled");
|
||||
params.remove("ExperimentalMode");
|
||||
} else {
|
||||
// no long for now
|
||||
experimental_mode_toggle->setEnabled(false);
|
||||
@@ -295,6 +308,7 @@ 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");
|
||||
}
|
||||
@@ -302,6 +316,7 @@ 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 {
|
||||
@@ -310,6 +325,7 @@ void TogglesPanelSP::updateToggles() {
|
||||
custom_stock_long_toggle->setVisible(false);
|
||||
dec_toggle->setVisible(false);
|
||||
dynamic_personality_toggle->setVisible(false);
|
||||
custom_stock_long_planner->setVisible(false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -49,6 +49,12 @@ 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 Smart Cruise Control is operating."),
|
||||
"../assets/offroad/icon_blank.png",
|
||||
},
|
||||
{
|
||||
"EnableSlc",
|
||||
tr("Speed Limit Control (SLC)"),
|
||||
@@ -91,12 +97,24 @@ 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"),
|
||||
@@ -298,7 +316,7 @@ SunnypilotPanel::SunnypilotPanel(QWidget *parent) : QFrame(parent) {
|
||||
list->addItem(dlp_settings);
|
||||
}
|
||||
|
||||
if (param == "VisionCurveLaneless") {
|
||||
if (param == "OvertakingAccelerationAssist") {
|
||||
list->addItem(laneChangeSettingsLayout);
|
||||
list->addItem(horizontal_line());
|
||||
|
||||
@@ -345,6 +363,17 @@ 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()) {
|
||||
@@ -366,6 +395,7 @@ 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) {
|
||||
@@ -577,7 +607,7 @@ void SunnypilotPanel::updateToggles() {
|
||||
}
|
||||
|
||||
// toggle names to update when EnforceTorqueLateral is flipped
|
||||
std::vector<std::string> torqueLateralGroup{"CustomTorqueLateral", "LiveTorque", "LiveTorqueRelaxed", "TorquedOverride"};
|
||||
std::vector<std::string> torqueLateralGroup{"CustomTorqueLateral", "TorqueLateralJerk", "LiveTorque", "LiveTorqueRelaxed", "TorquedOverride"};
|
||||
for (const auto& torqueLateralToggle : torqueLateralGroup) {
|
||||
if (toggles.find(torqueLateralToggle) != toggles.end()) {
|
||||
if (nnff_toggle->isToggled()) {
|
||||
@@ -594,6 +624,24 @@ 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());
|
||||
@@ -622,13 +670,14 @@ 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, 50}) {
|
||||
{0, 500},
|
||||
5) {
|
||||
|
||||
refresh();
|
||||
}
|
||||
|
||||
void TorqueFriction::refresh() {
|
||||
float torqueFrictionVal = QString::fromStdString(params.get("TorqueFriction")).toInt() * 0.01;
|
||||
float torqueFrictionVal = QString::fromStdString(params.get("TorqueFriction")).toInt() * 0.001;
|
||||
setTitle("FRICTION - " + (params.getBool("TorquedOverride") ? tr("Real-time and Offline") : tr("Offline Only")));
|
||||
setLabel(QString::number(torqueFrictionVal));
|
||||
}
|
||||
|
||||
@@ -29,6 +29,7 @@ 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"
|
||||
|
||||
@@ -110,6 +110,13 @@ SPVehiclesTogglesPanel::SPVehiclesTogglesPanel(VehiclePanel *parent) : ListWidge
|
||||
hkgCustomLongTuning->setConfirmation(true, false);
|
||||
addItem(hkgCustomLongTuning);
|
||||
|
||||
hyundaiCruiseMainDefault = new ParamControlSP(
|
||||
"HyundaiCruiseMainDefault",
|
||||
tr("HKG CAN: Enable Cruise Main By Default"),
|
||||
tr("Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS"),
|
||||
"../assets/offroad/icon_blank.png");
|
||||
addItem(hyundaiCruiseMainDefault);
|
||||
|
||||
// Subaru
|
||||
addItem(new LabelControlSP(tr("Subaru")));
|
||||
auto subaruManualParkingBrakeSng = new ParamControlSP(
|
||||
@@ -207,6 +214,7 @@ SPVehiclesTogglesPanel::SPVehiclesTogglesPanel(VehiclePanel *parent) : ListWidge
|
||||
connect(uiStateSP(), &UIStateSP::offroadTransition, [=](bool offroad) {
|
||||
is_onroad = !offroad;
|
||||
hkgCustomLongTuning->setEnabled(offroad);
|
||||
hyundaiCruiseMainDefault->setEnabled(offroad);
|
||||
toyotaTss2LongTune->setEnabled(offroad);
|
||||
toyotaAbh->setEnabled(offroad);
|
||||
toyotaEnhancedBsm->setEnabled(offroad);
|
||||
@@ -237,6 +245,17 @@ void SPVehiclesTogglesPanel::updateToggles() {
|
||||
capnp::FlatArrayMessageReader cmsg(aligned_buf.align(cp_bytes.data(), cp_bytes.size()));
|
||||
cereal::CarParams::Reader CP = cmsg.getRoot<cereal::CarParams>();
|
||||
|
||||
// Hyundai/Kia/Genesis
|
||||
{
|
||||
if (CP.getCarName() == "hyundai") {
|
||||
if ((CP.getSpFlags() & 2) and !(CP.getFlags() & 8192)) {
|
||||
hyundaiCruiseMainDefault->setEnabled(true);
|
||||
} else {
|
||||
hyundaiCruiseMainDefault->setEnabled(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Toyota: Enhanced Blind Spot Monitor
|
||||
{
|
||||
if (CP.getCarName() == "toyota") {
|
||||
|
||||
@@ -28,8 +28,10 @@ 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
|
||||
@@ -67,6 +69,7 @@ private:
|
||||
Params params;
|
||||
bool is_onroad = false;
|
||||
|
||||
ParamControlSP *hyundaiCruiseMainDefault;
|
||||
ParamControlSP *stockLongToyota;
|
||||
ParamControlSP *toyotaEnhancedBsm;
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ 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
|
||||
|
||||
@@ -31,6 +31,7 @@ Last updated: July 29, 2024
|
||||
#include "selfdrive/ui/qt/maps/map_settings.h"
|
||||
#endif
|
||||
|
||||
|
||||
class OffroadHomeSP : public OffroadHome {
|
||||
Q_OBJECT
|
||||
|
||||
|
||||
@@ -1290,46 +1290,25 @@ 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;
|
||||
|
||||
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%
|
||||
if (accel > 0) {
|
||||
p.setBrush(QColor(0, 245, 0, 200));
|
||||
}
|
||||
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);
|
||||
scannerRect = QRect(0, widgetHeight / 2 - halfHeightAbs, scannerWidth, halfHeightAbs);
|
||||
} else {
|
||||
QRect ra = QRect(rect_w - wp, rect_h / 2, wp, hha / 2);
|
||||
p.drawRect(ra);
|
||||
p.setBrush(QColor(245, 0, 0, 200));
|
||||
scannerRect = QRect(0, widgetHeight / 2, scannerWidth, halfHeightAbs);
|
||||
}
|
||||
|
||||
p.drawRect(scannerRect);
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
|
||||
@@ -26,6 +26,8 @@ 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"
|
||||
|
||||
@@ -29,6 +29,9 @@ 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
|
||||
@@ -59,6 +62,7 @@ private:
|
||||
void createMapWidget();
|
||||
void createOnroadSettingsWidget();
|
||||
void mousePressEvent(QMouseEvent* e) override;
|
||||
// AnnotatedCameraWidgetSP *nvg;
|
||||
QWidget *map = nullptr;
|
||||
QWidget *onroad_settings = nullptr;
|
||||
|
||||
|
||||
@@ -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);
|
||||
bool can_change = hasLongitudinalControl(cp) || (!cp.getPcmCruiseSpeed() && params.getBool("CustomStockLongPlanner"));
|
||||
if (can_change) {
|
||||
scene.dynamic_experimental_control = !scene.dynamic_experimental_control;
|
||||
params.putBool("DynamicExperimentalControl", scene.dynamic_experimental_control);
|
||||
|
||||
@@ -26,6 +26,7 @@ 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"
|
||||
|
||||
@@ -34,6 +34,7 @@ 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);
|
||||
@@ -122,6 +123,7 @@ void SidebarSP::updateState(const UIStateSP &s) {
|
||||
setProperty("sunnylinkStatus", QVariant::fromValue(sunnylinkStatus));
|
||||
}
|
||||
|
||||
|
||||
void SidebarSP::DrawSidebar(QPainter &p){
|
||||
Sidebar::DrawSidebar(p);
|
||||
// metrics
|
||||
|
||||
@@ -28,6 +28,8 @@ Last updated: July 29, 2024
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QFrame>
|
||||
#include <QMap>
|
||||
#include "selfdrive/ui/qt/sidebar.h"
|
||||
|
||||
#include "selfdrive/ui/sunnypilot/ui.h"
|
||||
|
||||
@@ -25,6 +25,7 @@ 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;
|
||||
|
||||
@@ -31,6 +31,13 @@ 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"
|
||||
|
||||
@@ -36,6 +36,7 @@ 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);
|
||||
|
||||
@@ -34,6 +34,7 @@ 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"
|
||||
|
||||
@@ -33,9 +33,11 @@ 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;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -207,6 +207,14 @@
|
||||
<source>LIMIT</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>blended</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>acc</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>AutoLaneChangeTimer</name>
|
||||
@@ -1445,14 +1453,6 @@ Esto puede tardar un minuto.</translation>
|
||||
<source>Hyundai/Kia/Genesis</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>HKG CAN: Smoother Stopping Performance (Beta)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Smoother stopping behind a stopped car or desired stopping event. This is only applicable to HKG CAN platforms using openpilot longitudinal control.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Subaru</source>
|
||||
<translation type="unfinished"></translation>
|
||||
@@ -1563,6 +1563,34 @@ Reboot Required.</source>
|
||||
<source>Tested on RAV4 TSS1, Lexus LSS1, Toyota TSS1/1.5, and Prius TSS2.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>HKG CAN: Enable Cruise Main By Default</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enabling this toggle sets CRUISE MAIN to ON by default when the car starts, without engaging MADS. The user still needs to manually engage MADS</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>HKG: Custom Tuning for New Longitudinal API</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Enable Automatic Brake Hold (AHB)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>WARNING: Only for Toyota/Lexus vehicles with TSS2/LSS2. USE AT YOUR OWN RISK.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>When you stop the vehicle completely by depressing the brake pedal, sunnypilot will activate Auto Brake Hold.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Changing this setting takes effect when the car is powered off.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>SettingsWindow</name>
|
||||
@@ -2669,6 +2697,22 @@ Reboot Required.</source>
|
||||
<source>Default is Laneless. In Auto mode, sunnnypilot dynamically chooses between Laneline or Laneless model based on lane recognition confidence level on road and certain conditions.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>NNLC: Remove Lateral Jerk Response (Alpha)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>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.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Lateral Jerk with Torque Lateral Control (Alpha)</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>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.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TermsPage</name>
|
||||
@@ -3034,6 +3078,10 @@ This feature must be used along with SLC, and/or V-TSC, and/or M-TSC.</source>
|
||||
<source>Enable the sunnypilot longitudinal control (alpha) toggle to allow Experimental mode.</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
<message>
|
||||
<source>Use Planner Speed</source>
|
||||
<translation type="unfinished"></translation>
|
||||
</message>
|
||||
</context>
|
||||
<context>
|
||||
<name>TorqueFriction</name>
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+3
-1
@@ -59,6 +59,8 @@ typedef enum UIStatus {
|
||||
EXTRA_UI_STATES
|
||||
} UIStatus;
|
||||
|
||||
|
||||
|
||||
enum PrimeType {
|
||||
UNKNOWN = -2,
|
||||
UNPAIRED = -1,
|
||||
@@ -152,7 +154,7 @@ protected:
|
||||
QTimer *timer;
|
||||
PrimeType prime_type = PrimeType::UNKNOWN;
|
||||
|
||||
private:
|
||||
private:
|
||||
bool started_prev = false;
|
||||
};
|
||||
#undef UIScene
|
||||
|
||||
@@ -5,6 +5,7 @@ from __future__ import annotations
|
||||
import base64
|
||||
import gzip
|
||||
import os
|
||||
import ssl
|
||||
import threading
|
||||
import time
|
||||
|
||||
@@ -29,7 +30,8 @@ SUNNYLINK_RECONNECT_TIMEOUT_S = 70 # FYI changing this will also would require
|
||||
DISALLOW_LOG_UPLOAD = threading.Event()
|
||||
|
||||
params = Params()
|
||||
sunnylink_api = SunnylinkApi(params.get("SunnylinkDongleId", encoding='utf-8'))
|
||||
sunnylink_dongle_id = params.get("SunnylinkDongleId", encoding='utf-8')
|
||||
sunnylink_api = SunnylinkApi(sunnylink_dongle_id)
|
||||
def handle_long_poll(ws: WebSocket, exit_event: threading.Event | None) -> None:
|
||||
cloudlog.info("sunnylinkd.handle_long_poll started")
|
||||
sm = messaging.SubMaster(['deviceState'])
|
||||
@@ -204,7 +206,7 @@ def main(exit_event: threading.Event = None):
|
||||
|
||||
UploadQueueCache.initialize(upload_queue)
|
||||
|
||||
ws_uri = SUNNYLINK_ATHENA_HOST
|
||||
ws_uri = f"{SUNNYLINK_ATHENA_HOST}"
|
||||
conn_start = None
|
||||
conn_retries = 0
|
||||
while (exit_event is None or not exit_event.is_set()) and sunnylink_ready(params):
|
||||
@@ -214,8 +216,9 @@ def main(exit_event: threading.Event = None):
|
||||
|
||||
cloudlog.event("sunnylinkd.main.connecting_ws", ws_uri=ws_uri, retries=conn_retries)
|
||||
ws = create_connection(ws_uri,
|
||||
cookie="jwt=" + sunnylink_api.get_token(),
|
||||
header={"Authorization": f"Bearer {sunnylink_api.get_token()}"},
|
||||
enable_multithread=True,
|
||||
sslopt={"cert_reqs": ssl.CERT_NONE if "localhost" in ws_uri else ssl.CERT_REQUIRED},
|
||||
timeout=SUNNYLINK_RECONNECT_TIMEOUT_S)
|
||||
cloudlog.event("sunnylinkd.main.connected_ws", ws_uri=ws_uri, retries=conn_retries,
|
||||
duration=time.monotonic() - conn_start)
|
||||
|
||||
@@ -147,15 +147,19 @@ int main(int argc, char* argv[]) {
|
||||
ret = util::set_core_affinity({3});
|
||||
assert(ret == 0);
|
||||
}
|
||||
|
||||
bool no_dcam = Params().getBool("DriverCameraHardwareMissing");
|
||||
if (argc > 1) {
|
||||
std::string arg1(argv[1]);
|
||||
if (arg1 == "--stream") {
|
||||
encoderd_thread(stream_cameras_logged);
|
||||
encoderd_thread(no_dcam ? stream_cameras_logged_no_dcam :
|
||||
stream_cameras_logged);
|
||||
} else {
|
||||
LOGE("Argument '%s' is not supported", arg1.c_str());
|
||||
}
|
||||
} else {
|
||||
encoderd_thread(cameras_logged);
|
||||
encoderd_thread(no_dcam ? cameras_logged_no_dcam :
|
||||
cameras_logged);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -234,8 +234,9 @@ void loggerd_thread() {
|
||||
logger_rotate(&s);
|
||||
Params().put("CurrentRoute", s.logger.routeName());
|
||||
|
||||
bool no_dcam = Params().getBool("DriverCameraHardwareMissing");
|
||||
std::map<std::string, EncoderInfo> encoder_infos_dict;
|
||||
for (const auto &cam : cameras_logged) {
|
||||
for (const auto &cam : (no_dcam ? cameras_logged_no_dcam : cameras_logged)) {
|
||||
for (const auto &encoder_info : cam.encoder_infos) {
|
||||
encoder_infos_dict[encoder_info.publish_name] = encoder_info;
|
||||
s.max_waiting++;
|
||||
|
||||
@@ -154,3 +154,6 @@ const LogCameraInfo stream_driver_camera_info{
|
||||
|
||||
const LogCameraInfo cameras_logged[] = {road_camera_info, wide_road_camera_info, driver_camera_info};
|
||||
const LogCameraInfo stream_cameras_logged[] = {stream_road_camera_info, stream_wide_road_camera_info, stream_driver_camera_info};
|
||||
|
||||
const LogCameraInfo cameras_logged_no_dcam[] = {road_camera_info, wide_road_camera_info, driver_camera_info};
|
||||
const LogCameraInfo stream_cameras_logged_no_dcam[] = {stream_road_camera_info, stream_wide_road_camera_info, stream_driver_camera_info};
|
||||
|
||||
@@ -71,6 +71,7 @@ def manager_init() -> None:
|
||||
("FeatureStatus", "1"),
|
||||
("HandsOnWheelMonitoring", "0"),
|
||||
("HasAcceptedTermsSP", "0"),
|
||||
("HyundaiCruiseMainDefault", "0"),
|
||||
("HideVEgoUi", "0"),
|
||||
("LastSpeedLimitSignTap", "0"),
|
||||
("LkasToggle", "0"),
|
||||
@@ -84,6 +85,8 @@ def manager_init() -> None:
|
||||
("OnroadSettings", "1"),
|
||||
("PathOffset", "0"),
|
||||
("PauseLateralSpeed", "0"),
|
||||
("PCMVCruiseOverride", "0"),
|
||||
("PCMVCruiseOverrideSpeed", "30"),
|
||||
("ReverseAccChange", "0"),
|
||||
("ScreenRecorder", "1"),
|
||||
("ShowDebugUI", "1"),
|
||||
@@ -97,7 +100,7 @@ def manager_init() -> None:
|
||||
("StandStillTimer", "0"),
|
||||
("StockLongToyota", "0"),
|
||||
("TorqueDeadzoneDeg", "0"),
|
||||
("TorqueFriction", "1"),
|
||||
("TorqueFriction", "10"),
|
||||
("TorqueMaxLatAccel", "250"),
|
||||
("ToyotaAutoHold", "0"),
|
||||
("ToyotaAutoLockBySpeed", "0"),
|
||||
|
||||
@@ -102,7 +102,7 @@ procs = [
|
||||
PythonProcess("radard", "selfdrive.controls.radard", only_onroad),
|
||||
PythonProcess("hardwared", "system.hardware.hardwared", always_run),
|
||||
PythonProcess("tombstoned", "system.tombstoned", always_run, enabled=not PC),
|
||||
PythonProcess("updated", "system.updated.updated", only_offroad, enabled=not PC),
|
||||
NativeProcess("updated", "system/updated", ["./updated.py"], only_offroad, enabled=not PC),
|
||||
PythonProcess("uploader", "system.loggerd.uploader", always_run),
|
||||
PythonProcess("statsd", "system.statsd", always_run),
|
||||
|
||||
|
||||
Reference in New Issue
Block a user