Merge branch 'master' into mqb-long

# Conflicts:
#	panda
mqb-long
Jason Young 3 years ago
commit 7037350fbc
  1. 16
      .pre-commit-config.yaml
  2. 6
      Pipfile
  3. 1051
      Pipfile.lock
  4. 2
      cereal
  5. 2
      common/realtime.py
  6. 14
      mypy.ini
  7. 7
      selfdrive/car/ecu_addrs.py
  8. 3
      selfdrive/car/fw_versions.py
  9. 6
      selfdrive/car/gm/values.py
  10. 4
      selfdrive/car/honda/values.py
  11. 18
      selfdrive/car/hyundai/values.py
  12. 7
      selfdrive/car/isotp_parallel_query.py
  13. 13
      selfdrive/car/subaru/values.py
  14. 4
      selfdrive/car/toyota/values.py
  15. 17
      selfdrive/car/vin.py
  16. 5
      selfdrive/controls/lib/longitudinal_mpc_lib/long_mpc.py
  17. 4
      selfdrive/controls/lib/longitudinal_planner.py
  18. 3
      selfdrive/controls/lib/radar_helpers.py
  19. 4
      selfdrive/debug/check_freq.py
  20. 4
      selfdrive/debug/check_timings.py
  21. 2
      selfdrive/sensord/tests/test_sensord.py
  22. 5
      selfdrive/test/longitudinal_maneuvers/plant.py
  23. 2
      selfdrive/test/process_replay/ref_commit
  24. 61
      selfdrive/test/process_replay/regen.py
  25. 30
      selfdrive/test/process_replay/test_processes.py
  26. 87
      system/camerad/test/test_camerad.py
  27. 1
      system/hardware/tici/casync.py

@ -24,18 +24,14 @@ repos:
# if you've got a short variable name that's getting flagged, add it here
- -L bu,ro,te,ue,alo,hda,ois,nam,nams,ned,som,parm,setts,inout,warmup
- --builtins clear,rare,informal,usage,code,names,en-GB_to_en-US
- repo: https://github.com/pre-commit/mirrors-mypy
rev: v0.931
- repo: local
hooks:
- id: mypy
exclude: '^(pyextra/)|(cereal/)|(rednose/)|(panda/)|(laika/)|(opendbc/)|(laika_repo/)|(rednose_repo/)/|(tinygrad/)|(tinygrad_repo/)'
additional_dependencies: ['types-PyYAML', 'lxml', 'numpy', 'types-atomicwrites', 'types-pycurl', 'types-requests', 'types-certifi']
args:
- --warn-redundant-casts
- --warn-return-any
- --warn-unreachable
- --warn-unused-ignores
#- --html-report=/home/batman/openpilot
name: mypy
entry: mypy
language: system
types: [python]
exclude: '^(pyextra/)|(cereal/)|(opendbc/)|(panda/)|(laika/)|(laika_repo/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(xx/)'
- repo: https://github.com/PyCQA/flake8
rev: 4.0.1
hooks:

@ -43,6 +43,12 @@ carla = {version = "==0.9.13", markers="platform_system != 'Darwin'"}
ft4222 = "*"
pandas = "*"
tabulate = "*"
types-pyyaml = "*"
lxml = "*"
types-atomicwrites = "*"
types-pycurl = "*"
types-requests = "*"
types-certifi = "*"
[packages]
atomicwrites = "*"

1051
Pipfile.lock generated

File diff suppressed because it is too large Load Diff

@ -1 +1 @@
Subproject commit a0c6f28d6bce2fd7d7ef2fd29e80d2eab118a6c6
Subproject commit e310f4860d349d2e260cfd4bb060b0705b17244c

@ -31,7 +31,7 @@ class Priority:
def set_realtime_priority(level: int) -> None:
if not PC:
os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(level)) # type: ignore[attr-defined] # pylint: disable=no-member
os.sched_setscheduler(0, os.SCHED_FIFO, os.sched_param(level)) # pylint: disable=no-member
def set_core_affinity(cores: List[int]) -> None:

@ -1,4 +1,16 @@
[mypy]
python_version = 3.8
ignore_missing_imports = True
plugins = numpy.typing.mypy_plugin
files = body, common, docs, scripts, selfdrive, site_scons, system, tools
exclude = ^(pyextra/)|(cereal/)|(opendbc/)|(panda/)|(laika/)|(laika_repo/)|(rednose/)|(rednose_repo/)|(tinygrad/)|(tinygrad_repo/)|(xx/)
; third-party packages
ignore_missing_imports = True
; helpful warnings
warn_redundant_casts = True
warn_unreachable = True
warn_unused_ignores = True
; restrict dynamic typing
warn_return_any = True

@ -1,7 +1,6 @@
#!/usr/bin/env python3
import capnp
import time
import traceback
from typing import Optional, Set, Tuple
import cereal.messaging as messaging
@ -62,7 +61,7 @@ def get_ecu_addrs(logcan: messaging.SubSocket, sendcan: messaging.PubSocket, que
print(f"Duplicate ECU address: {hex(msg.address)}")
ecu_responses.add((msg.address, subaddr, msg.src))
except Exception:
cloudlog.warning(f"ECU addr scan exception: {traceback.format_exc()}")
cloudlog.exception("ECU addr scan exception")
return ecu_responses
@ -71,6 +70,8 @@ if __name__ == "__main__":
parser = argparse.ArgumentParser(description='Get addresses of all ECUs')
parser.add_argument('--debug', action='store_true')
parser.add_argument('--bus', type=int, default=1)
parser.add_argument('--timeout', type=float, default=1.0)
args = parser.parse_args()
logcan = messaging.sub_sock('can')
@ -79,7 +80,7 @@ if __name__ == "__main__":
time.sleep(1.0)
print("Getting ECU addresses ...")
ecu_addrs = get_all_ecu_addrs(logcan, sendcan, 1, debug=args.debug)
ecu_addrs = get_all_ecu_addrs(logcan, sendcan, args.bus, args.timeout, debug=args.debug)
print()
print("Found ECUs on addresses:")

@ -1,5 +1,4 @@
#!/usr/bin/env python3
import traceback
from collections import defaultdict
from typing import Any, Optional, Set, Tuple
from tqdm import tqdm
@ -270,7 +269,7 @@ def get_fw_versions(logcan, sendcan, query_brand=None, extra=None, timeout=0.1,
car_fw.append(f)
except Exception:
cloudlog.warning(f"FW query exception: {traceback.format_exc()}")
cloudlog.exception("FW query exception")
return car_fw

@ -86,13 +86,13 @@ CAR_INFO: Dict[str, Union[GMCarInfo, List[GMCarInfo]]] = {
CAR.ACADIA: GMCarInfo("GMC Acadia 2018", video_link="https://www.youtube.com/watch?v=0ZN6DdsBUZo"),
CAR.BUICK_REGAL: GMCarInfo("Buick Regal Essence 2018"),
CAR.ESCALADE_ESV: GMCarInfo("Cadillac Escalade ESV 2016", "Adaptive Cruise Control (ACC) & LKAS"),
CAR.BOLT_EV: GMCarInfo("Chevrolet Bolt EV 2022-23", "Adaptive Cruise Control (ACC)", footnotes=[], harness=Harness.gm),
CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", video_link="https://youtu.be/xvwzGMUA210", footnotes=[], harness=Harness.gm),
CAR.BOLT_EV: GMCarInfo("Chevrolet Bolt EV 2022-23", footnotes=[], harness=Harness.gm),
CAR.BOLT_EUV: GMCarInfo("Chevrolet Bolt EUV 2022-23", "Premier or Premier Redline Trim without Super Cruise Package", "https://youtu.be/xvwzGMUA210", footnotes=[], harness=Harness.gm),
CAR.SILVERADO: [
GMCarInfo("Chevrolet Silverado 1500 2020-21", "Safety Package II", footnotes=[], harness=Harness.gm),
GMCarInfo("GMC Sierra 1500 2020-21", "Driver Alert Package II", footnotes=[], harness=Harness.gm),
],
CAR.EQUINOX: GMCarInfo("Chevrolet Equinox 2019-22", "Adaptive Cruise Control (ACC)", footnotes=[], harness=Harness.gm),
CAR.EQUINOX: GMCarInfo("Chevrolet Equinox 2019-22", footnotes=[], harness=Harness.gm),
}

@ -110,13 +110,13 @@ class HondaCarInfo(CarInfo):
CAR_INFO: Dict[str, Optional[Union[HondaCarInfo, List[HondaCarInfo]]]] = {
CAR.ACCORD: [
HondaCarInfo("Honda Accord 2018-22", "All", video_link="https://www.youtube.com/watch?v=mrUwlj3Mi58", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a),
HondaCarInfo("Honda Accord 2018-22", "All", "https://www.youtube.com/watch?v=mrUwlj3Mi58", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a),
HondaCarInfo("Honda Inspire 2018", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a),
],
CAR.ACCORDH: HondaCarInfo("Honda Accord Hybrid 2018-22", "All", min_steer_speed=3. * CV.MPH_TO_MS, harness=Harness.bosch_a),
CAR.CIVIC: HondaCarInfo("Honda Civic 2016-18", harness=Harness.nidec, video_link="https://youtu.be/-IkImTe1NYE"),
CAR.CIVIC_BOSCH: [
HondaCarInfo("Honda Civic 2019-21", "All", video_link="https://www.youtube.com/watch?v=4Iz1Mz5LGF8", footnotes=[Footnote.CIVIC_DIESEL], min_steer_speed=2. * CV.MPH_TO_MS, harness=Harness.bosch_a),
HondaCarInfo("Honda Civic 2019-21", "All", "https://www.youtube.com/watch?v=4Iz1Mz5LGF8", [Footnote.CIVIC_DIESEL], min_steer_speed=2. * CV.MPH_TO_MS, harness=Harness.bosch_a),
HondaCarInfo("Honda Civic Hatchback 2017-21", harness=Harness.bosch_a),
],
CAR.CIVIC_BOSCH_DIESEL: None, # same platform

@ -113,7 +113,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = {
CAR.ELANTRA_GT_I30: None, # dashcamOnly and same platform as CAR.ELANTRA
CAR.HYUNDAI_GENESIS: HyundaiCarInfo("Hyundai Genesis 2015-16", min_enable_speed=19 * CV.MPH_TO_MS, harness=Harness.hyundai_j), # TODO: check 2015 packages
CAR.IONIQ: HyundaiCarInfo("Hyundai Ioniq Hybrid 2017-19", harness=Harness.hyundai_c),
CAR.IONIQ_HEV_2022: HyundaiCarInfo("Hyundai Ioniq Hybrid 2020-22", "Smart Cruise Control (SCC)", harness=Harness.hyundai_h), # TODO: confirm 2020-21 harness
CAR.IONIQ_HEV_2022: HyundaiCarInfo("Hyundai Ioniq Hybrid 2020-22", harness=Harness.hyundai_h), # TODO: confirm 2020-21 harness
CAR.IONIQ_EV_LTD: HyundaiCarInfo("Hyundai Ioniq Electric 2019", harness=Harness.hyundai_c),
CAR.IONIQ_EV_2020: HyundaiCarInfo("Hyundai Ioniq Electric 2020", "All", harness=Harness.hyundai_h),
CAR.IONIQ_PHEV_2019: HyundaiCarInfo("Hyundai Ioniq Plug-in Hybrid 2019", harness=Harness.hyundai_c),
@ -123,17 +123,17 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = {
CAR.KONA_EV_2022: HyundaiCarInfo("Hyundai Kona Electric 2022", harness=Harness.hyundai_o),
CAR.KONA_HEV: HyundaiCarInfo("Hyundai Kona Hybrid 2020", video_link="https://youtu.be/0dwpAHiZgFo", harness=Harness.hyundai_i), # TODO: check packages
CAR.SANTA_FE: HyundaiCarInfo("Hyundai Santa Fe 2019-20", "All", harness=Harness.hyundai_d),
CAR.SANTA_FE_2022: HyundaiCarInfo("Hyundai Santa Fe 2021-22", "All", video_link="https://youtu.be/VnHzSTygTS4", harness=Harness.hyundai_l),
CAR.SANTA_FE_2022: HyundaiCarInfo("Hyundai Santa Fe 2021-22", "All", "https://youtu.be/VnHzSTygTS4", harness=Harness.hyundai_l),
CAR.SANTA_FE_HEV_2022: HyundaiCarInfo("Hyundai Santa Fe Hybrid 2022", "All", harness=Harness.hyundai_l),
CAR.SANTA_FE_PHEV_2022: HyundaiCarInfo("Hyundai Santa Fe Plug-in Hybrid 2022", "All", harness=Harness.hyundai_l),
CAR.SONATA: HyundaiCarInfo("Hyundai Sonata 2020-22", "All", video_link="https://www.youtube.com/watch?v=ix63r9kE3Fw", harness=Harness.hyundai_a),
CAR.SONATA: HyundaiCarInfo("Hyundai Sonata 2020-22", "All", "https://www.youtube.com/watch?v=ix63r9kE3Fw", harness=Harness.hyundai_a),
CAR.SONATA_LF: HyundaiCarInfo("Hyundai Sonata 2018-19", harness=Harness.hyundai_e),
CAR.TUCSON: [
HyundaiCarInfo("Hyundai Tucson 2021", min_enable_speed=19 * CV.MPH_TO_MS, harness=Harness.hyundai_l),
HyundaiCarInfo("Hyundai Tucson Diesel 2019", harness=Harness.hyundai_l),
],
CAR.PALISADE: [
HyundaiCarInfo("Hyundai Palisade 2020-22", "All", video_link="https://youtu.be/TAnDqjF4fDY?t=456", harness=Harness.hyundai_h),
HyundaiCarInfo("Hyundai Palisade 2020-22", "All", "https://youtu.be/TAnDqjF4fDY?t=456", harness=Harness.hyundai_h),
HyundaiCarInfo("Kia Telluride 2020", "All", harness=Harness.hyundai_h),
],
CAR.VELOSTER: HyundaiCarInfo("Hyundai Veloster 2019-20", min_enable_speed=5. * CV.MPH_TO_MS, harness=Harness.hyundai_e),
@ -145,10 +145,10 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = {
CAR.KIA_FORTE: HyundaiCarInfo("Kia Forte 2019-21", harness=Harness.hyundai_g),
CAR.KIA_K5_2021: HyundaiCarInfo("Kia K5 2021-22", harness=Harness.hyundai_a),
CAR.KIA_NIRO_EV: [
HyundaiCarInfo("Kia Niro EV 2019", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_h),
HyundaiCarInfo("Kia Niro EV 2020", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_f),
HyundaiCarInfo("Kia Niro EV 2021", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_c),
HyundaiCarInfo("Kia Niro EV 2022", "All", video_link="https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_h),
HyundaiCarInfo("Kia Niro EV 2019", "All", "https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_h),
HyundaiCarInfo("Kia Niro EV 2020", "All", "https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_f),
HyundaiCarInfo("Kia Niro EV 2021", "All", "https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_c),
HyundaiCarInfo("Kia Niro EV 2022", "All", "https://www.youtube.com/watch?v=lT7zcG6ZpGo", harness=Harness.hyundai_h),
],
CAR.KIA_NIRO_PHEV: HyundaiCarInfo("Kia Niro Plug-in Hybrid 2018-19", "All", min_enable_speed=10. * CV.MPH_TO_MS, harness=Harness.hyundai_c),
CAR.KIA_NIRO_HEV_2021: [
@ -163,7 +163,7 @@ CAR_INFO: Dict[str, Optional[Union[HyundaiCarInfo, List[HyundaiCarInfo]]]] = {
],
CAR.KIA_SELTOS: HyundaiCarInfo("Kia Seltos 2021", harness=Harness.hyundai_a),
CAR.KIA_SORENTO: [
HyundaiCarInfo("Kia Sorento 2018", "Advanced Smart Cruise Control", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", harness=Harness.hyundai_c),
HyundaiCarInfo("Kia Sorento 2018", "Advanced Smart Cruise Control", "https://www.youtube.com/watch?v=Fkh3s6WHJz8", harness=Harness.hyundai_c),
HyundaiCarInfo("Kia Sorento 2019", video_link="https://www.youtube.com/watch?v=Fkh3s6WHJz8", harness=Harness.hyundai_e),
],
CAR.KIA_STINGER: HyundaiCarInfo("Kia Stinger 2018-20", video_link="https://www.youtube.com/watch?v=MJ94qoofYw0", harness=Harness.hyundai_c),

@ -1,7 +1,6 @@
import time
from collections import defaultdict
from functools import partial
from typing import Optional
import cereal.messaging as messaging
from system.swaglog import cloudlog
@ -107,12 +106,15 @@ class IsoTpParallelQuery:
for tx_addr, msg in msgs.items():
try:
dat: Optional[bytes] = msg.recv()
dat, updated = msg.recv()
except Exception:
cloudlog.exception(f"Error processing UDS response: {tx_addr}")
request_done[tx_addr] = True
continue
if updated:
response_timeouts[tx_addr] = time.monotonic() + timeout
if not dat:
continue
@ -121,7 +123,6 @@ class IsoTpParallelQuery:
response_valid = dat[:len(expected_response)] == expected_response
if response_valid:
response_timeouts[tx_addr] = time.monotonic() + timeout
if counter + 1 < len(self.request):
msg.send(self.request[counter + 1])
request_counter[tx_addr] += 1

@ -124,23 +124,26 @@ FW_VERSIONS = {
CAR.LEGACY: {
(Ecu.abs, 0x7b0, None): [
b'\xa1\\ x04\x01',
b'\xa1 \x03\x03'
b'\xa1 \x03\x03',
b'\xa1 \x02\x01',
],
(Ecu.eps, 0x746, None): [
b'\x9b\xc0\x11\x00',
b'\x9b\xc0\x11\x02'
b'\x9b\xc0\x11\x02',
],
(Ecu.fwdCamera, 0x787, None): [
b'\x00\x00e\x80\x00\x1f@ \x19\x00',
b'\x00\x00e\x9a\x00\x00\x00\x00\x00\x00'
b'\x00\x00e\x9a\x00\x00\x00\x00\x00\x00',
],
(Ecu.engine, 0x7e0, None): [
b'\xde\"a0\x07',
b'\xe2"aq\x07'
b'\xe2"aq\x07',
b'\xde,\xa0@\x07',
],
(Ecu.transmission, 0x7e1, None): [
b'\xa5\xf6\x05@\x00',
b'\xa7\xf6\x04@\x00'
b'\xa7\xf6\x04@\x00',
b'\xa5\xfe\xc7@\x00',
],
},
CAR.IMPREZA: {

@ -136,7 +136,7 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = {
CAR.HIGHLANDERH: ToyotaCarInfo("Toyota Highlander Hybrid 2017-19", footnotes=[Footnote.DSU]),
CAR.HIGHLANDERH_TSS2: ToyotaCarInfo("Toyota Highlander Hybrid 2020-22"),
CAR.PRIUS: [
ToyotaCarInfo("Toyota Prius 2016", "Toyota Safety Sense P", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0", footnotes=[Footnote.DSU]),
ToyotaCarInfo("Toyota Prius 2016", "Toyota Safety Sense P", "https://www.youtube.com/watch?v=8zopPJI8XQ0", [Footnote.DSU]),
ToyotaCarInfo("Toyota Prius 2017-20", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0", footnotes=[Footnote.DSU]),
ToyotaCarInfo("Toyota Prius Prime 2017-20", video_link="https://www.youtube.com/watch?v=8zopPJI8XQ0", footnotes=[Footnote.DSU]),
],
@ -150,7 +150,7 @@ CAR_INFO: Dict[str, Union[ToyotaCarInfo, List[ToyotaCarInfo]]] = {
ToyotaCarInfo("Toyota RAV4 2017-18", footnotes=[Footnote.DSU])
],
CAR.RAV4H: [
ToyotaCarInfo("Toyota RAV4 Hybrid 2016", "Toyota Safety Sense P", video_link="https://youtu.be/LhT5VzJVfNI?t=26", footnotes=[Footnote.DSU]),
ToyotaCarInfo("Toyota RAV4 Hybrid 2016", "Toyota Safety Sense P", "https://youtu.be/LhT5VzJVfNI?t=26", [Footnote.DSU]),
ToyotaCarInfo("Toyota RAV4 Hybrid 2017-18", video_link="https://youtu.be/LhT5VzJVfNI?t=26", footnotes=[Footnote.DSU])
],
CAR.RAV4_TSS2: ToyotaCarInfo("Toyota RAV4 2019-21", video_link="https://www.youtube.com/watch?v=wJxjDd42gGA"),

@ -1,6 +1,5 @@
#!/usr/bin/env python3
import re
import traceback
import cereal.messaging as messaging
from selfdrive.car.isotp_parallel_query import IsoTpParallelQuery
@ -28,17 +27,27 @@ def get_vin(logcan, sendcan, bus, timeout=0.1, retry=5, debug=False):
vin = vin[1:18]
return addr[0], rx_addr, vin.decode()
print(f"vin query retry ({i+1}) ...")
cloudlog.error(f"vin query retry ({i+1}) ...")
except Exception:
cloudlog.warning(f"VIN query exception: {traceback.format_exc()}")
cloudlog.exception("VIN query exception")
return 0, 0, VIN_UNKNOWN
if __name__ == "__main__":
import argparse
import time
parser = argparse.ArgumentParser(description='Get VIN of the car')
parser.add_argument('--debug', action='store_true')
parser.add_argument('--bus', type=int, default=1)
parser.add_argument('--timeout', type=float, default=0.1)
parser.add_argument('--retry', type=int, default=5)
args = parser.parse_args()
sendcan = messaging.pub_sock('sendcan')
logcan = messaging.sub_sock('can')
time.sleep(1)
addr, vin_rx_addr, vin = get_vin(logcan, sendcan, 1, debug=False)
addr, vin_rx_addr, vin = get_vin(logcan, sendcan, args.bus, args.timeout, args.retry, debug=args.debug)
print(f'TX: {hex(addr)}, RX: {hex(vin_rx_addr)}, VIN: {vin}')

@ -320,7 +320,7 @@ class LongitudinalMpc:
# Update in ACC mode or ACC/e2e blend
if self.mode == 'acc':
self.params[:,0] = MIN_ACCEL if self.status else self.cruise_min_a
self.params[:,0] = MIN_ACCEL
self.params[:,1] = self.cruise_max_a
self.params[:,5] = LEAD_DANGER_FACTOR
@ -341,11 +341,12 @@ class LongitudinalMpc:
elif self.mode == 'blended':
self.params[:,0] = MIN_ACCEL
self.params[:,1] = MAX_ACCEL
self.params[:,5] = 1.0
x_obstacles = np.column_stack([lead_0_obstacle,
lead_1_obstacle])
cruise_target = T_IDXS * v_cruise + x[0]
cruise_target = T_IDXS * np.clip(v_cruise, v_ego - 2.0, 1e3) + x[0]
xforward = ((v[1:] + v[:-1]) / 2) * (T_IDXS[1:] - T_IDXS[:-1])
x = np.cumsum(np.insert(xforward, 0, x[0]))

@ -18,8 +18,8 @@ from system.swaglog import cloudlog
LON_MPC_STEP = 0.2 # first step is 0.2s
AWARENESS_DECEL = -0.2 # car smoothly decel at .2m/s^2 when user is distracted
A_CRUISE_MIN = -1.2
A_CRUISE_MAX_VALS = [1.2, 1.2, 0.8, 0.6]
A_CRUISE_MAX_BP = [0., 15., 25., 40.]
A_CRUISE_MAX_VALS = [1.6, 1.2, 0.8, 0.6]
A_CRUISE_MAX_BP = [0., 10.0, 25., 40.]
# Lookup table for turns
_A_TOTAL_MAX_V = [1.7, 3.2]

@ -2,8 +2,7 @@ from common.numpy_fast import mean
from common.kalman.simple_kalman import KF1D
# the longer lead decels, the more likely it will keep decelerating
# TODO is this a good default?
# Default lead acceleration decay set to 50% at 1s
_LEAD_ACCEL_TAU = 1.5
# radar tracks

@ -2,7 +2,7 @@
import argparse
import numpy as np
from collections import defaultdict, deque
from typing import DefaultDict, Deque
from typing import DefaultDict, Deque, MutableSequence
from common.realtime import sec_since_boot
import cereal.messaging as messaging
@ -19,7 +19,7 @@ if __name__ == "__main__":
socket_names = args.socket
sockets = {}
rcv_times: DefaultDict[str, Deque[float]] = defaultdict(lambda: deque(maxlen=100))
rcv_times: DefaultDict[str, MutableSequence[float]] = defaultdict(lambda: deque(maxlen=100))
valids: DefaultDict[str, Deque[bool]] = defaultdict(lambda: deque(maxlen=100))
t = sec_since_boot()

@ -3,13 +3,13 @@
import sys
import time
import numpy as np
from typing import DefaultDict, Deque
from typing import DefaultDict, MutableSequence
from collections import defaultdict, deque
import cereal.messaging as messaging
socks = {s: messaging.sub_sock(s, conflate=False) for s in sys.argv[1:]}
ts: DefaultDict[str, Deque[float]] = defaultdict(lambda: deque(maxlen=100))
ts: DefaultDict[str, MutableSequence[float]] = defaultdict(lambda: deque(maxlen=100))
if __name__ == "__main__":
while True:

@ -51,7 +51,7 @@ Sensor = log.SensorEventData.SensorSource
SensorConfig = namedtuple('SensorConfig', ['type', 'sanity_min', 'sanity_max'])
ALL_SENSORS = {
Sensor.rpr0521: {
SensorConfig("light", 0, 150),
SensorConfig("light", 0, 1023),
},
Sensor.lsm6ds3: {

@ -8,7 +8,7 @@ from common.realtime import Ratekeeper, DT_MDL
from selfdrive.controls.lib.longcontrol import LongCtrlState
from selfdrive.modeld.constants import T_IDXS
from selfdrive.controls.lib.longitudinal_planner import LongitudinalPlanner
from selfdrive.controls.lib.radar_helpers import _LEAD_ACCEL_TAU
class Plant():
messaging_initialized = False
@ -83,7 +83,8 @@ class Plant():
lead.vLead = float(v_lead)
lead.vLeadK = float(v_lead)
lead.aLeadK = float(a_lead)
lead.aLeadTau = float(1.5)
# TODO use real radard logic for this
lead.aLeadTau = float(_LEAD_ACCEL_TAU)
lead.status = status
lead.modelProb = float(prob)
if not self.only_lead2:

@ -1 +1 @@
051fa5bea42027c1a756ae61fd0c752c1e911899
9098c1cf6993598071c3e27448356eef86660d02

@ -106,6 +106,23 @@ def replay_sensor_events(s, msgs):
rk.keep_time()
def replay_sensor_event(s, msgs):
smsgs = [m for m in msgs if m.which() == s]
#if len(smsgs) == 0:
# return
pm = messaging.PubMaster([s, ])
rk = Ratekeeper(service_list[s].frequency, print_delay_threshold=None)
while True:
for m in smsgs:
m = m.as_builder()
m.logMonoTime = int(sec_since_boot() * 1e9)
getattr(m, m.which()).timestamp = m.logMonoTime
pm.send(m.which(), m)
rk.keep_time()
def replay_service(s, msgs):
pm = messaging.PubMaster([s, ])
rk = Ratekeeper(service_list[s].frequency, print_delay_threshold=None)
@ -193,8 +210,49 @@ def migrate_carparams(lr):
return all_msgs
def migrate_sensorEvents(lr):
all_msgs = []
for msg in lr:
if msg.which() != 'sensorEvents':
all_msgs.append(msg)
continue
# migrate to split sensor events
for evt in msg.sensorEvents:
# build new message for each sensor type
sensor_service = ''
if evt.which() == 'acceleration':
sensor_service = 'accelerometer'
elif evt.which() == 'gyro' or evt.which() == 'gyroUncalibrated':
sensor_service = 'gyroscope'
elif evt.which() == 'light' or evt.which() == 'proximity':
sensor_service = 'lightSensor'
elif evt.which() == 'magnetic' or evt.which() == 'magneticUncalibrated':
sensor_service = 'magnetometer'
elif evt.which() == 'temperature':
sensor_service = 'temperatureSensor'
m = messaging.new_message(sensor_service)
m.valid = True
m_dat = getattr(m, sensor_service)
m_dat.version = evt.version
m_dat.sensor = evt.sensor
m_dat.type = evt.type
m_dat.source = evt.source
setattr(m_dat, evt.which(), getattr(evt, evt.which()))
all_msgs.append(m.as_reader())
# append also legacy sensorEvents, to have both (remove later)
all_msgs.append(msg)
return all_msgs
def regen_segment(lr, frs=None, outdir=FAKEDATA, disable_tqdm=False):
lr = migrate_carparams(list(lr))
lr = migrate_sensorEvents(list(lr))
if frs is None:
frs = dict()
@ -213,6 +271,9 @@ def regen_segment(lr, frs=None, outdir=FAKEDATA, disable_tqdm=False):
fake_daemons = {
'sensord': [
multiprocessing.Process(target=replay_sensor_events, args=('sensorEvents', lr)),
multiprocessing.Process(target=replay_sensor_event, args=('accelerometer', lr)),
multiprocessing.Process(target=replay_sensor_event, args=('gyroscope', lr)),
multiprocessing.Process(target=replay_sensor_event, args=('magnetometer', lr)),
],
'pandad': [
multiprocessing.Process(target=replay_service, args=('can', lr)),

@ -38,21 +38,21 @@ source_segments = [
]
segments = [
("BODY", "regen9D38397D30D|2022-09-09--13-12-48--0"),
("HYUNDAI", "regenB3953B393C0|2022-09-09--14-49-37--0"),
("HYUNDAI", "regen8DB830E5376|2022-09-13--17-24-37--0"),
("TOYOTA", "regen8FCBB6F06F1|2022-09-09--13-14-07--0"),
("TOYOTA2", "regen956BFA75300|2022-09-09--14-51-24--0"),
("TOYOTA3", "regenE909BC2F430|2022-09-09--20-44-49--0"),
("HONDA", "regenD1D10209015|2022-09-09--14-53-09--0"),
("HONDA2", "regen3F7C2EFDC08|2022-09-09--19-41-19--0"),
("CHRYSLER", "regen92783EAE66B|2022-09-09--13-15-44--0"),
("RAM", "regenBE5DAAEF30F|2022-09-13--17-06-24--0"),
("SUBARU", "regen8A363AF7E14|2022-09-13--17-20-39--0"),
("GM", "regen31EA3F9A37C|2022-09-09--21-06-36--0"),
("NISSAN", "regenAA21ADE5921|2022-09-09--19-44-37--0"),
("VOLKSWAGEN", "regenA1BF4D17761|2022-09-09--19-46-24--0"),
("MAZDA", "regen1994C97E977|2022-09-13--16-34-44--0"),
("BODY", "regenFA002A80700|2022-09-27--15-37-02--0"),
("HYUNDAI", "regenBE53A59065B|2022-09-27--16-52-03--0"),
("HYUNDAI", "regen11AA43BCA5F|2022-09-27--15-39-54--0"),
("TOYOTA", "regen929C5790007|2022-09-27--16-27-47--0"),
("TOYOTA2", "regenEA3950D7F22|2022-09-27--15-43-24--0"),
("TOYOTA3", "regen89026F6BD8D|2022-09-27--15-45-37--0"),
("HONDA", "regenC7D5645EB17|2022-09-27--15-47-29--0"),
("HONDA2", "regenCC2ECCE5742|2022-09-27--16-18-01--0"),
("CHRYSLER", "regenC253C4DAC90|2022-09-27--15-51-03--0"),
("RAM", "regen20490083AE7|2022-09-27--15-53-15--0"),
("SUBARU", "regen1E72BBDCED5|2022-09-27--15-55-31--0"),
("GM", "regen45B05A80EF6|2022-09-27--15-57-22--0"),
("NISSAN", "regenC19D899B46D|2022-09-27--15-59-13--0"),
("VOLKSWAGEN", "regenD8F7AC4BD0D|2022-09-27--16-41-45--0"),
("MAZDA", "regenFC3F9ECBB64|2022-09-27--16-03-09--0"),
]
# dashcamOnly makes don't need to be tested until a full port is done

@ -1,25 +1,18 @@
#!/usr/bin/env python3
import time
import unittest
from collections import defaultdict
import cereal.messaging as messaging
from cereal.services import service_list
from selfdrive.manager.process_config import managed_processes
from system.hardware import TICI
from selfdrive.test.helpers import with_processes
TEST_TIMESPAN = 30 # random.randint(60, 180) # seconds
SKIP_FRAME_TOLERANCE = 0
LAG_FRAME_TOLERANCE = 2 # ms
TEST_TIMESPAN = 30
LAG_FRAME_TOLERANCE = 0.5 # ms
FPS_BASELINE = 20
CAMERAS = {
"roadCameraState": FPS_BASELINE,
"driverCameraState": FPS_BASELINE // 2,
}
CAMERAS = ('roadCameraState', 'driverCameraState', 'wideRoadCameraState')
if TICI:
CAMERAS["driverCameraState"] = FPS_BASELINE
CAMERAS["wideRoadCameraState"] = FPS_BASELINE
class TestCamerad(unittest.TestCase):
@classmethod
@ -27,37 +20,57 @@ class TestCamerad(unittest.TestCase):
if not TICI:
raise unittest.SkipTest
@with_processes(['camerad'])
def test_frame_packets(self):
print("checking frame pkts continuity")
print(TEST_TIMESPAN)
# run camerad and record logs
managed_processes['camerad'].start()
time.sleep(3)
socks = {c: messaging.sub_sock(c, conflate=False, timeout=100) for c in CAMERAS}
cls.logs = defaultdict(list)
start_time = time.monotonic()
while time.monotonic()- start_time < TEST_TIMESPAN:
for cam, s in socks.items():
cls.logs[cam] += messaging.drain_sock(s)
time.sleep(0.2)
managed_processes['camerad'].stop()
sm = messaging.SubMaster([socket_name for socket_name in CAMERAS])
cls.log_by_frame_id = defaultdict(list)
for cam, msgs in cls.logs.items():
expected_frames = service_list[cam].frequency * TEST_TIMESPAN
assert expected_frames*0.95 < len(msgs) < expected_frames*1.05, f"unexpected frame count {cam}: {expected_frames=}, got {len(msgs)}"
last_frame_id = dict.fromkeys(CAMERAS, None)
last_ts = dict.fromkeys(CAMERAS, None)
start_time_sec = time.time()
while time.time()- start_time_sec < TEST_TIMESPAN:
sm.update()
for m in msgs:
cls.log_by_frame_id[getattr(m, m.which()).frameId].append(m)
for camera in CAMERAS:
if sm.updated[camera]:
ct = (sm[camera].timestampEof if not TICI else sm[camera].timestampSof) / 1e6
if last_frame_id[camera] is None:
last_frame_id[camera] = sm[camera].frameId
last_ts[camera] = ct
continue
# strip beginning and end
for _ in range(3):
mn, mx = min(cls.log_by_frame_id.keys()), max(cls.log_by_frame_id.keys())
del cls.log_by_frame_id[mn]
del cls.log_by_frame_id[mx]
@classmethod
def tearDownClass(cls):
managed_processes['camerad'].stop()
dfid = sm[camera].frameId - last_frame_id[camera]
self.assertTrue(abs(dfid - 1) <= SKIP_FRAME_TOLERANCE, "%s frame id diff is %d" % (camera, dfid))
def test_frame_skips(self):
skips = {}
frame_ids = self.log_by_frame_id.keys()
for frame_id in range(min(frame_ids), max(frame_ids)):
seen_cams = [msg.which() for msg in self.log_by_frame_id[frame_id]]
skip_cams = set(CAMERAS) - set(seen_cams)
if len(skip_cams):
skips[frame_id] = skip_cams
assert len(skips) == 0, f"Found frame skips, missing cameras for the following frames: {skips}"
dts = ct - last_ts[camera]
self.assertTrue(abs(dts - (1000/CAMERAS[camera])) < LAG_FRAME_TOLERANCE, f"{camera} frame t(ms) diff is {dts:f}")
def test_frame_sync(self):
frame_times = {frame_id: [getattr(m, m.which()).timestampSof for m in msgs] for frame_id, msgs in self.log_by_frame_id.items()}
diffs = {frame_id: (max(ts) - min(ts))/1e6 for frame_id, ts in frame_times.items()}
last_frame_id[camera] = sm[camera].frameId
last_ts[camera] = ct
time.sleep(0.01)
def get_desc(fid, diff):
cam_times = [(m.which(), getattr(m, m.which()).timestampSof/1e6) for m in self.log_by_frame_id[fid]]
return f"{diff=} {cam_times=}"
laggy_frames = {k: get_desc(k, v) for k, v in diffs.items() if v > LAG_FRAME_TOLERANCE}
assert len(laggy_frames) == 0, f"Frames not synced properly: {laggy_frames=}"
if __name__ == "__main__":
unittest.main()

@ -86,6 +86,7 @@ class RemoteChunkReader(ChunkReader):
def parse_caibx(caibx_path: str) -> List[Chunk]:
"""Parses the chunks from a caibx file. Can handle both local and remote files.
Returns a list of chunks with hash, offset and length"""
caibx: io.BufferedIOBase
if os.path.isfile(caibx_path):
caibx = open(caibx_path, 'rb')
else:

Loading…
Cancel
Save