Merge remote-tracking branch 'upstream/master' into civic22_long

pull/25364/head
royjr 3 years ago
commit 8f6f3c10df
  1. 18
      poetry.lock
  2. 1
      pyproject.toml
  3. 3
      selfdrive/car/body/values.py
  4. 2
      selfdrive/car/chrysler/carcontroller.py
  5. 1
      selfdrive/car/chrysler/values.py
  6. 2
      selfdrive/car/ford/carcontroller.py
  7. 5
      selfdrive/car/ford/values.py
  8. 2
      selfdrive/car/gm/carcontroller.py
  9. 2
      selfdrive/car/gm/values.py
  10. 3
      selfdrive/car/hyundai/carcontroller.py
  11. 2
      selfdrive/car/hyundai/interface.py
  12. 1
      selfdrive/car/hyundai/values.py
  13. 4
      selfdrive/car/mazda/values.py
  14. 3
      selfdrive/car/nissan/values.py
  15. 3
      selfdrive/car/tesla/values.py
  16. 97
      selfdrive/car/tests/test_lateral_limits.py
  17. 1
      selfdrive/car/toyota/values.py
  18. 6
      selfdrive/car/volkswagen/carcontroller.py
  19. 2
      selfdrive/car/volkswagen/values.py
  20. 17
      selfdrive/navd/map_renderer.py
  21. 2
      selfdrive/test/process_replay/ref_commit
  22. 3
      selfdrive/ui/qt/widgets/input.cc

18
poetry.lock generated

@ -2755,6 +2755,17 @@ python-versions = ">=3.7,<4.0"
poetry = ">=1.2.0,<2.0.0"
poetry-core = ">=1.1.0,<2.0.0"
[[package]]
name = "polyline"
version = "1.4.0"
description = "A Python implementation of Google's Encoded Polyline Algorithm Format."
category = "main"
optional = false
python-versions = "*"
[package.dependencies]
six = ">=1.8.0"
[[package]]
name = "portalocker"
version = "2.6.0"
@ -4414,7 +4425,7 @@ testing = ["coverage (>=5.0.3)", "zope.event", "zope.testing"]
[metadata]
lock-version = "1.1"
python-versions = "~3.8"
content-hash = "82e450801a9a1de9fd98615d7deb3d8f0aa5bd3ccf0cf8b258cd8f6e6e4c5309"
content-hash = "d894380c87f5558e032708cc1230aed172ad3e1db9aa112e2e105bebefff4e20"
[metadata.files]
adal = [
@ -5420,6 +5431,7 @@ gevent = [
{file = "gevent-22.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:d2ea4ce36c09355379bc038be2bd50118f97d2eb6381b7096de4d05aa4c3e241"},
{file = "gevent-22.10.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3e73c9f71aa2a6795ecbec9b57282b002375e863e283558feb87b62840c8c1ac"},
{file = "gevent-22.10.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5bc3758f0dc95007c1780d28a9fd2150416a79c50f308f62a674d78a845ea1b9"},
{file = "gevent-22.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03c10ca0beeab0c6be516030471ea630447ddd1f649d3335e5b162097cd4130a"},
{file = "gevent-22.10.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fe2c0ff095171c49f78f1d4e6dc89fa58253783c7b6dccab9f1d76e2ee391f10"},
{file = "gevent-22.10.1-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d18fcc324f39a3b21795022eb47c7752d6e4f4ed89d8cca41f1cc604553265b3"},
{file = "gevent-22.10.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:06ea39c70ce166c4a1d4386c7fae96cb8d84ad799527b3378406051104d15443"},
@ -6666,6 +6678,10 @@ poetry-plugin-export = [
{file = "poetry-plugin-export-1.1.2.tar.gz", hash = "sha256:5e92525dd63f38ce74a51ed68ea91d753523f21ce5f9ef8d3b793e2a4b2222ef"},
{file = "poetry_plugin_export-1.1.2-py3-none-any.whl", hash = "sha256:946e3313b3d00c18fb9a50522e9d5e6a7e111beaba8d6ae33297662fc2070ac1"},
]
polyline = [
{file = "polyline-1.4.0-py2.py3-none-any.whl", hash = "sha256:6559a0d5d37f4d14255744b3c6a648d5ff480d3d5c5f30186effc72a4142fd6c"},
{file = "polyline-1.4.0.tar.gz", hash = "sha256:7c7f89d09a09c7b6161bdbfb4fd304b186fc7a2060fa4f31cb3f61c646a5c074"},
]
portalocker = [
{file = "portalocker-2.6.0-py2.py3-none-any.whl", hash = "sha256:102ed1f2badd8dec9af3d732ef70e94b215b85ba45a8d7ff3c0003f19b442f4e"},
{file = "portalocker-2.6.0.tar.gz", hash = "sha256:964f6830fb42a74b5d32bce99ed37d8308c1d7d44ddf18f3dd89f4680de97b39"},

@ -57,6 +57,7 @@ tqdm = "^4.64.0"
urllib3 = "^1.26.10"
utm = "^0.7.0"
websocket_client = "^1.3.3"
polyline = "^1.4.0"
[tool.poetry.group.dev.dependencies]

@ -17,6 +17,9 @@ class CarControllerParams:
LKAS_MAX_TORQUE = 1 # A value of 1 is easy to overpower
STEER_THRESHOLD = 1.0
def __init__(self, CP):
pass
class CAR:
BODY = "COMMA BODY"

@ -45,7 +45,7 @@ class CarController:
self.hud_count += 1
# steering
if self.frame % 2 == 0:
if self.frame % self.params.STEER_STEP == 0:
# TODO: can we make this more sane? why is it different for all the cars?
lkas_control_bit = self.lkas_control_bit_prev

@ -35,6 +35,7 @@ class CAR:
class CarControllerParams:
def __init__(self, CP):
self.STEER_STEP = 2 # 50 Hz
self.STEER_ERROR_MAX = 80
if CP.carFingerprint in RAM_HD:
self.STEER_DELTA_UP = 14

@ -66,7 +66,7 @@ class CarController:
apply_angle = 0.
# send steering commands at 20Hz
if (self.frame % CarControllerParams.LKAS_STEER_STEP) == 0:
if (self.frame % CarControllerParams.STEER_STEP) == 0:
# use LatCtlPath_An_Actl to actuate steering
path_angle = math.radians(apply_angle) / CarControllerParams.LKAS_STEER_RATIO

@ -17,7 +17,7 @@ AngleRateLimit = namedtuple('AngleRateLimit', ['speed_points', 'max_angle_diff_p
class CarControllerParams:
# Messages: Lane_Assist_Data1, LateralMotionControl
LKAS_STEER_STEP = 5
STEER_STEP = 5
# Message: IPMA_Data
LKAS_UI_STEP = 100
# Message: ACCDATA_3
@ -32,6 +32,9 @@ class CarControllerParams:
RATE_LIMIT_UP = AngleRateLimit(speed_points=[0., 5., 15.], max_angle_diff_points=[5., .8, .15])
RATE_LIMIT_DOWN = AngleRateLimit(speed_points=[0., 5., 15.], max_angle_diff_points=[5., 3.5, 0.4])
def __init__(self, CP):
pass
class CANBUS:
main = 0

@ -53,7 +53,7 @@ class CarController:
init_lka_counter = not self.sent_lka_steering_cmd and self.CP.networkLocation == NetworkLocation.fwdCamera
steer_step = self.params.INACTIVE_STEER_STEP
if CC.latActive or init_lka_counter:
steer_step = self.params.ACTIVE_STEER_STEP
steer_step = self.params.STEER_STEP
# Avoid GM EPS faults when transmitting messages too close together: skip this transmit if we just received the
# next Panda loopback confirmation in the current CS frame.

@ -11,7 +11,7 @@ Ecu = car.CarParams.Ecu
class CarControllerParams:
STEER_MAX = 300 # GM limit is 3Nm. Used by carcontroller to generate LKA output
ACTIVE_STEER_STEP = 2 # Active control frames per command (50hz)
STEER_STEP = 2 # Active control frames per command (50hz)
INACTIVE_STEER_STEP = 10 # Inactive control frames per command (10hz)
STEER_DELTA_UP = 7 # Delta rates require review due to observed EPS weakness
STEER_DELTA_DOWN = 17

@ -59,8 +59,7 @@ class CarController:
hud_control = CC.hudControl
# steering torque
steer = actuators.steer
new_steer = int(round(steer * self.params.STEER_MAX))
new_steer = int(round(actuators.steer * self.params.STEER_MAX))
apply_steer = apply_std_steer_torque_limits(new_steer, self.apply_steer_last, CS.out.steeringTorque, self.params)
if not CC.latActive:

@ -232,7 +232,7 @@ class CarInterface(CarInterfaceBase):
ret.stoppingControl = True
ret.startingState = True
ret.vEgoStarting = 0.1
ret.startAccel = 2.0
ret.startAccel = 1.0
ret.longitudinalActuatorDelayLowerBound = 0.5
ret.longitudinalActuatorDelayUpperBound = 0.5

@ -23,6 +23,7 @@ class CarControllerParams:
self.STEER_DRIVER_MULTIPLIER = 2
self.STEER_DRIVER_FACTOR = 1
self.STEER_THRESHOLD = 150
self.STEER_STEP = 1 # 100 Hz
if CP.carFingerprint in CANFD_CAR:
self.STEER_MAX = 270

@ -20,6 +20,10 @@ class CarControllerParams:
STEER_DRIVER_MULTIPLIER = 1 # weight driver torque
STEER_DRIVER_FACTOR = 1 # from dbc
STEER_ERROR_MAX = 350 # max delta between torque cmd and torque motor
STEER_STEP = 1 # 100 Hz
def __init__(self, CP):
pass
class CAR:

@ -17,6 +17,9 @@ class CarControllerParams:
LKAS_MAX_TORQUE = 1 # A value of 1 is easy to overpower
STEER_THRESHOLD = 1.0
def __init__(self, CP):
pass
class CAR:
XTRAIL = "NISSAN X-TRAIL 2017"

@ -108,3 +108,6 @@ class CarControllerParams:
JERK_LIMIT_MAX = 8
JERK_LIMIT_MIN = -8
ACCEL_TO_SPEED_MULTIPLIER = 3
def __init__(self, CP):
pass

@ -0,0 +1,97 @@
#!/usr/bin/env python3
from collections import defaultdict
import importlib
from parameterized import parameterized_class
import sys
from typing import DefaultDict, Dict
import unittest
from common.realtime import DT_CTRL
from selfdrive.car.car_helpers import interfaces
from selfdrive.car.fingerprints import all_known_cars
from selfdrive.car.interfaces import get_torque_params
from selfdrive.car.hyundai.values import CAR as HYUNDAI
CAR_MODELS = all_known_cars()
# ISO 11270
MAX_LAT_JERK = 2.5 # m/s^3
MAX_LAT_JERK_TOLERANCE = 0.75 # m/s^3
MAX_LAT_ACCEL = 3.0 # m/s^2
# jerk is measured over half a second
JERK_MEAS_FRAMES = 0.5 / DT_CTRL
# TODO: update the max measured lateral accel for these cars
ABOVE_LIMITS_CARS = [
HYUNDAI.KONA_EV,
HYUNDAI.KONA_HEV,
HYUNDAI.KONA,
HYUNDAI.KONA_EV_2022,
]
car_model_jerks: DefaultDict[str, Dict[str, float]] = defaultdict(dict)
@parameterized_class('car_model', [(c,) for c in CAR_MODELS])
class TestLateralLimits(unittest.TestCase):
car_model: str
@classmethod
def setUpClass(cls):
CarInterface, _, _ = interfaces[cls.car_model]
CP = CarInterface.get_params(cls.car_model)
if CP.dashcamOnly:
raise unittest.SkipTest("Platform is behind dashcamOnly")
# TODO: test all platforms
if CP.lateralTuning.which() != 'torque':
raise unittest.SkipTest
if CP.notCar:
raise unittest.SkipTest
if CP.carFingerprint in ABOVE_LIMITS_CARS:
raise unittest.SkipTest
CarControllerParams = importlib.import_module(f'selfdrive.car.{CP.carName}.values').CarControllerParams
cls.control_params = CarControllerParams(CP)
cls.torque_params = get_torque_params(cls.car_model)
@staticmethod
def calculate_0_5s_jerk(control_params, torque_params):
steer_step = control_params.STEER_STEP
steer_up_per_frame = (control_params.STEER_DELTA_UP / control_params.STEER_MAX) / steer_step
steer_down_per_frame = (control_params.STEER_DELTA_DOWN / control_params.STEER_MAX) / steer_step
steer_up_0_5_sec = min(steer_up_per_frame * JERK_MEAS_FRAMES, 1.0)
steer_down_0_5_sec = min(steer_down_per_frame * JERK_MEAS_FRAMES, 1.0)
max_lat_accel = torque_params['MAX_LAT_ACCEL_MEASURED']
return steer_up_0_5_sec * max_lat_accel, steer_down_0_5_sec * max_lat_accel
def test_jerk_limits(self):
up_jerk, down_jerk = self.calculate_0_5s_jerk(self.control_params, self.torque_params)
car_model_jerks[self.car_model] = {"up_jerk": up_jerk, "down_jerk": down_jerk}
self.assertLessEqual(up_jerk, MAX_LAT_JERK + MAX_LAT_JERK_TOLERANCE)
self.assertLessEqual(down_jerk, MAX_LAT_JERK + MAX_LAT_JERK_TOLERANCE)
def test_max_lateral_accel(self):
self.assertLessEqual(self.torque_params["MAX_LAT_ACCEL_MEASURED"], MAX_LAT_ACCEL)
if __name__ == "__main__":
result = unittest.main(exit=False)
print(f"\n\n---- Lateral limit report ({len(CAR_MODELS)} cars) ----\n")
max_car_model_len = max([len(car_model) for car_model in car_model_jerks])
for car_model, _jerks in sorted(car_model_jerks.items(), key=lambda i: i[1]['up_jerk'], reverse=True):
violation = any([_jerk >= MAX_LAT_JERK + MAX_LAT_JERK_TOLERANCE for _jerk in _jerks.values()])
violation_str = " - VIOLATION" if violation else ""
print(f"{car_model:{max_car_model_len}} - up jerk: {round(_jerks['up_jerk'], 2):5} m/s^3, down jerk: {round(_jerks['down_jerk'], 2):5} m/s^3{violation_str}")
# exit with test result
sys.exit(not result.result.wasSuccessful())

@ -18,6 +18,7 @@ class CarControllerParams:
ACCEL_MAX = 1.5 # m/s2, lower than allowed 2.0 m/s2 for tuning reasons
ACCEL_MIN = -3.5 # m/s2
STEER_STEP = 1
STEER_MAX = 1500
STEER_ERROR_MAX = 350 # max delta between torque cmd and torque motor

@ -31,7 +31,7 @@ class CarController:
# **** Steering Controls ************************************************ #
if self.frame % self.CCP.HCA_STEP == 0:
if self.frame % self.CCP.STEER_STEP == 0:
# Logic to avoid HCA state 4 "refused":
# * Don't steer unless HCA is in state 3 "ready" or 5 "active"
# * Don't steer at standstill
@ -50,14 +50,14 @@ class CarController:
self.hcaEnabledFrameCount = 0
else:
self.hcaEnabledFrameCount += 1
if self.hcaEnabledFrameCount >= 118 * (100 / self.CCP.HCA_STEP): # 118s
if self.hcaEnabledFrameCount >= 118 * (100 / self.CCP.STEER_STEP): # 118s
hcaEnabled = False
self.hcaEnabledFrameCount = 0
else:
hcaEnabled = True
if self.apply_steer_last == apply_steer:
self.hcaSameTorqueCount += 1
if self.hcaSameTorqueCount > 1.9 * (100 / self.CCP.HCA_STEP): # 1.9s
if self.hcaSameTorqueCount > 1.9 * (100 / self.CCP.STEER_STEP): # 1.9s
apply_steer -= (1, -1)[apply_steer < 0]
self.hcaSameTorqueCount = 0
else:

@ -18,7 +18,7 @@ Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values'])
class CarControllerParams:
HCA_STEP = 2 # HCA_01/HCA_1 message frequency 50Hz
STEER_STEP = 2 # HCA_01/HCA_1 message frequency 50Hz
ACC_CONTROL_STEP = 2 # ACC_06/ACC_07/ACC_System frequency 50Hz
ACCEL_MAX = 2.0 # 2.0 m/s max acceleration

@ -4,6 +4,7 @@
import os
import time
import numpy as np
import polyline
from cffi import FFI
from common.ffi_wrapper import suffix
@ -50,6 +51,22 @@ def get_image(lib, renderer):
return r.reshape((WIDTH, HEIGHT))
def navRoute_to_polyline(nr):
coords = [(m.latitude, m.longitude) for m in nr.navRoute.coordinates]
return coords_to_polyline(coords)
def coords_to_polyline(coords):
# TODO: where does this factor of 10 come from?
return polyline.encode([(lat * 10., lon * 10.) for lat, lon in coords])
def polyline_to_coords(p):
coords = polyline.decode(p)
return [(lat / 10., lon / 10.) for lat, lon in coords]
if __name__ == "__main__":
import matplotlib.pyplot as plt

@ -1 +1 @@
358d330ffde4ecd679129b0e0a20806aaf21b786
05ba201bcf97b6c1067dbcde2a60f71f43469c56

@ -296,12 +296,13 @@ MultiOptionDialog::MultiOptionDialog(const QString &prompt_text, const QStringLi
group->addButton(selectionLabel);
listLayout->addWidget(selectionLabel);
}
// add stretch to keep buttons spaced correctly
listLayout->addStretch(1);
ScrollView *scroll_view = new ScrollView(listWidget, this);
scroll_view->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
main_layout->addWidget(scroll_view);
main_layout->addStretch(1);
main_layout->addSpacing(35);
// cancel + confirm buttons

Loading…
Cancel
Save