Merge remote-tracking branch 'upstream/master' into no-capnp-cars-simple

pull/33208/head
Shane Smiskol 1 year ago
commit cfb8453acc
  1. 2
      .github/workflows/badges.yaml
  2. 10
      .github/workflows/selfdrive_tests.yaml
  3. 3
      .importlinter
  4. 4
      release/release_files.py
  5. 15
      scripts/git_rewrite/rewrite-git-history.sh
  6. 4
      scripts/lint/check_shebang_format.sh
  7. 2
      selfdrive/car/__init__.py
  8. 2
      selfdrive/car/car_specific.py
  9. 0
      selfdrive/car/common/__init__.py
  10. 0
      selfdrive/car/common/filter_simple.py
  11. 0
      selfdrive/car/common/numpy_fast.py
  12. 54
      selfdrive/car/common/simple_kalman.py
  13. 4
      selfdrive/car/fingerprints.py
  14. 2
      selfdrive/car/ford/carcontroller.py
  15. 2
      selfdrive/car/gm/carcontroller.py
  16. 2
      selfdrive/car/gm/carstate.py
  17. 2
      selfdrive/car/honda/carcontroller.py
  18. 2
      selfdrive/car/honda/carstate.py
  19. 2
      selfdrive/car/honda/interface.py
  20. 2
      selfdrive/car/hyundai/carcontroller.py
  21. 2
      selfdrive/car/hyundai/hyundaicanfd.py
  22. 4
      selfdrive/car/interfaces.py
  23. 2
      selfdrive/car/subaru/carcontroller.py
  24. 67
      selfdrive/car/tesla/carcontroller.py
  25. 140
      selfdrive/car/tesla/carstate.py
  26. 32
      selfdrive/car/tesla/fingerprints.py
  27. 42
      selfdrive/car/tesla/interface.py
  28. 90
      selfdrive/car/tesla/radar_interface.py
  29. 94
      selfdrive/car/tesla/teslacan.py
  30. 98
      selfdrive/car/tesla/values.py
  31. 5
      selfdrive/car/tests/routes.py
  32. 2
      selfdrive/car/tests/test_car_interfaces.py
  33. 4
      selfdrive/car/tests/test_fw_fingerprint.py
  34. 5
      selfdrive/car/torque_data/override.toml
  35. 2
      selfdrive/car/toyota/carcontroller.py
  36. 4
      selfdrive/car/toyota/carstate.py
  37. 3
      selfdrive/car/values.py
  38. 2
      selfdrive/car/volkswagen/carcontroller.py
  39. 1
      selfdrive/controls/controlsd.py
  40. 3
      selfdrive/test/ci_shell.sh
  41. 3
      selfdrive/test/process_replay/test_processes.py
  42. 2
      selfdrive/ui/qt/sidebar.cc
  43. 2
      selfdrive/ui/tests/test_ui/run.py
  44. 8
      selfdrive/ui/translations/main_ar.ts
  45. 8
      selfdrive/ui/translations/main_de.ts
  46. 8
      selfdrive/ui/translations/main_es.ts
  47. 8
      selfdrive/ui/translations/main_fr.ts
  48. 8
      selfdrive/ui/translations/main_ja.ts
  49. 8
      selfdrive/ui/translations/main_ko.ts
  50. 8
      selfdrive/ui/translations/main_pt-BR.ts
  51. 8
      selfdrive/ui/translations/main_th.ts
  52. 8
      selfdrive/ui/translations/main_tr.ts
  53. 8
      selfdrive/ui/translations/main_zh-CHS.ts
  54. 8
      selfdrive/ui/translations/main_zh-CHT.ts
  55. 2
      selfdrive/ui/ui.cc
  56. 2
      tools/cabana/streams/replaystream.cc
  57. 8
      tools/camerastream/README.md
  58. 6
      tools/car_porting/README.md
  59. 3
      tools/install_python_dependencies.sh
  60. 2
      tools/latencylogger/README.md
  61. 13
      tools/op.sh
  62. 4
      tools/replay/README.md
  63. 2
      tools/sim/launch_openpilot.sh

@ -23,7 +23,7 @@ jobs:
- uses: ./.github/workflows/setup-with-retry
- name: Push badges
run: |
${{ env.RUN }} "scons -j$(nproc) && python selfdrive/ui/translations/create_badges.py"
${{ env.RUN }} "scons -j$(nproc) && python3 selfdrive/ui/translations/create_badges.py"
rm .gitattributes

@ -54,7 +54,7 @@ jobs:
timeout-minutes: ${{ ((steps.restore-scons-cache.outputs.cache-hit == 'true') && 10 || 30) }} # allow more time when we missed the scons cache
run: |
cd $STRIPPED_DIR
${{ env.RUN }} "python system/manager/build.py"
${{ env.RUN }} "python3 system/manager/build.py"
- name: Run tests
timeout-minutes: 3
run: |
@ -221,7 +221,7 @@ jobs:
- name: Upload reference logs
if: ${{ failure() && steps.print-diff.outcome == 'success' && github.repository == 'commaai/openpilot' && env.AZURE_TOKEN != '' }}
run: |
${{ env.RUN }} "unset PYTHONWARNINGS && AZURE_TOKEN='$AZURE_TOKEN' python selfdrive/test/process_replay/test_processes.py -j$(nproc) --upload-only"
${{ env.RUN }} "unset PYTHONWARNINGS && AZURE_TOKEN='$AZURE_TOKEN' python3 selfdrive/test/process_replay/test_processes.py -j$(nproc) --upload-only"
# PYTHONWARNINGS triggers a SyntaxError in onnxruntime
- name: Run model replay with ONNX
timeout-minutes: 4
@ -291,7 +291,7 @@ jobs:
- uses: ./.github/workflows/setup-with-retry
- name: Get base car info
run: |
${{ env.RUN }} "scons -j$(nproc) && python selfdrive/debug/dump_car_docs.py --path /tmp/openpilot_cache/base_car_docs"
${{ env.RUN }} "scons -j$(nproc) && python3 selfdrive/debug/dump_car_docs.py --path /tmp/openpilot_cache/base_car_docs"
sudo chown -R $USER:$USER ${{ github.workspace }}
- uses: actions/checkout@v4
with:
@ -303,7 +303,7 @@ jobs:
run: |
cd current
${{ env.RUN }} "scons -j$(nproc)"
output=$(${{ env.RUN }} "python selfdrive/debug/print_docs_diff.py --path /tmp/openpilot_cache/base_car_docs")
output=$(${{ env.RUN }} "python3 selfdrive/debug/print_docs_diff.py --path /tmp/openpilot_cache/base_car_docs")
output="${output//$'\n'/'%0A'}"
echo "::set-output name=diff::$output"
- name: Find comment
@ -348,7 +348,7 @@ jobs:
run: >
${{ env.RUN }} "PYTHONWARNINGS=ignore &&
source selfdrive/test/setup_xvfb.sh &&
python selfdrive/ui/tests/test_ui/run.py"
python3 selfdrive/ui/tests/test_ui/run.py"
- name: Upload Test Report
uses: actions/upload-artifact@v4
with:

@ -33,9 +33,6 @@ ignore_imports =
openpilot.selfdrive.car.tests.test_docs -> openpilot.common.basedir
openpilot.selfdrive.car.docs -> openpilot.common.basedir
# car interface will not filter the speed
openpilot.selfdrive.car.interfaces -> openpilot.common.simple_kalman
openpilot.selfdrive.car.gm.interface -> openpilot.common.basedir
openpilot.selfdrive.car.interfaces -> openpilot.common.basedir

@ -118,10 +118,6 @@ whitelist = [
"opendbc_repo/dbc/toyota_tss2_adas.dbc",
"opendbc_repo/dbc/vw_golf_mk4.dbc",
"opendbc_repo/dbc/vw_mqb_2010.dbc",
"opendbc_repo/dbc/tesla_can.dbc",
"opendbc_repo/dbc/tesla_radar_bosch_generated.dbc",
"opendbc_repo/dbc/tesla_radar_continental_generated.dbc",
"opendbc_repo/dbc/tesla_powertrain.dbc",
]

@ -1,4 +1,5 @@
#!/bin/bash -e
#!/usr/bin/env bash
set -e
SRC=/tmp/openpilot/
SRC_CLONE=/tmp/openpilot-clone/
@ -209,7 +210,7 @@ if [ ! -f "$SRC_CLONE/rewrite-branches-done" ]; then
MERGE_BASE=$(git merge-base master origin/$BRANCH) || true
if [ -n "$MERGE_BASE" ]; then
echo "Rewriting branch: $BRANCH"
# create a new branch based on the new master
NEW_MERGE_BASE=$(grep "^$MERGE_BASE " "commit-map.txt" | awk '{print $2}')
if [ -z "$NEW_MERGE_BASE" ]; then
@ -217,10 +218,10 @@ if [ ! -f "$SRC_CLONE/rewrite-branches-done" ]; then
continue
fi
git checkout -b ${BRANCH}_new $NEW_MERGE_BASE
# get the range of commits unique to this branch
COMMITS=$(git rev-list --reverse $MERGE_BASE..origin/${BRANCH})
HAS_ERROR=0
# simple delimiter
@ -263,7 +264,7 @@ if [ ! -f "$SRC_CLONE/rewrite-branches-done" ]; then
git commit --amend -m "$(git log -1 --pretty=%B)" -m "Former-commit-id: $COMMIT" > /dev/null
fi
done
# force push the new branch
if [ $HAS_ERROR -eq 0 ]; then
# git lfs goes haywire here, so we need to install and uninstall
@ -271,7 +272,7 @@ if [ ! -f "$SRC_CLONE/rewrite-branches-done" ]; then
git lfs uninstall --local > /dev/null
git push -f origin ${BRANCH}_new:${BRANCH}
fi
# clean up local branch
git checkout master > /dev/null
git branch -D ${BRANCH}_new > /dev/null
@ -318,7 +319,7 @@ if [ ! -f "$SRC_CLONE/validation-done" ]; then
# echo -ne "[$CURRENT_COMMIT_NUMBER/$TOTAL_COMMITS] Comparing old commit $OLD_COMMIT_SHORT ($OLD_DATE) with new commit $NEW_COMMIT_SHORT ($NEW_DATE)"\\r
echo "[$CURRENT_COMMIT_NUMBER/$TOTAL_COMMITS] Comparing old commit $OLD_COMMIT_SHORT ($OLD_DATE) with new commit $NEW_COMMIT_SHORT ($NEW_DATE)"
# generate lists of files and their hashes for the old and new commits, excluding ignored files
OLD_FILES=$(git ls-tree -r $OLD_COMMIT | grep -vE "$(IFS='|'; echo "${VALIDATE_IGNORE_FILES[*]}")")
NEW_FILES=$(git ls-tree -r $NEW_COMMIT | grep -vE "$(IFS='|'; echo "${VALIDATE_IGNORE_FILES[*]}")")

@ -2,12 +2,12 @@
FAIL=0
if grep '^#!.*python$' $@ | grep -v '#!/usr/bin/env python3$'; then
if grep '^#!.*python' $@ | grep -v '#!/usr/bin/env python3$'; then
echo -e "Invalid shebang! Must use '#!/usr/bin/env python3'\n"
FAIL=1
fi
if grep '^#!.*bash$' $@ | grep -v '#!/usr/bin/env bash$'; then
if grep '^#!.*bash' $@ | grep -v '#!/usr/bin/env bash$'; then
echo -e "Invalid shebang! Must use '#!/usr/bin/env bash'"
FAIL=1
fi

@ -9,7 +9,7 @@ from panda.python.uds import SERVICE_TYPE
from openpilot.selfdrive.car import structs
from openpilot.selfdrive.car.can_definitions import CanData
from openpilot.selfdrive.car.docs_definitions import CarDocs
from openpilot.selfdrive.car.helpers import clip, interp
from openpilot.selfdrive.car.common.numpy_fast import clip, interp
# set up logging
carlog = logging.getLogger('carlog')

@ -41,7 +41,7 @@ class CarSpecificEvents:
if self.CP.carName in ('body', 'mock'):
events = Events()
elif self.CP.carName in ('tesla', 'subaru'):
elif self.CP.carName == 'subaru':
events = self.create_common_events(CS.out, CS_prev)
elif self.CP.carName == 'ford':

@ -0,0 +1,54 @@
import numpy as np
def get_kalman_gain(dt, A, C, Q, R, iterations=100):
P = np.zeros_like(Q)
for _ in range(iterations):
P = A.dot(P).dot(A.T) + dt * Q
S = C.dot(P).dot(C.T) + R
K = P.dot(C.T).dot(np.linalg.inv(S))
P = (np.eye(len(P)) - K.dot(C)).dot(P)
return K
class KF1D:
# this EKF assumes constant covariance matrix, so calculations are much simpler
# the Kalman gain also needs to be precomputed using the control module
def __init__(self, x0, A, C, K):
self.x0_0 = x0[0][0]
self.x1_0 = x0[1][0]
self.A0_0 = A[0][0]
self.A0_1 = A[0][1]
self.A1_0 = A[1][0]
self.A1_1 = A[1][1]
self.C0_0 = C[0]
self.C0_1 = C[1]
self.K0_0 = K[0][0]
self.K1_0 = K[1][0]
self.A_K_0 = self.A0_0 - self.K0_0 * self.C0_0
self.A_K_1 = self.A0_1 - self.K0_0 * self.C0_1
self.A_K_2 = self.A1_0 - self.K1_0 * self.C0_0
self.A_K_3 = self.A1_1 - self.K1_0 * self.C0_1
# K matrix needs to be pre-computed as follow:
# import control
# (x, l, K) = control.dare(np.transpose(self.A), np.transpose(self.C), Q, R)
# self.K = np.transpose(K)
def update(self, meas):
#self.x = np.dot(self.A_K, self.x) + np.dot(self.K, meas)
x0_0 = self.A_K_0 * self.x0_0 + self.A_K_1 * self.x1_0 + self.K0_0 * meas
x1_0 = self.A_K_2 * self.x0_0 + self.A_K_3 * self.x1_0 + self.K1_0 * meas
self.x0_0 = x0_0
self.x1_0 = x1_0
return [self.x0_0, self.x1_0]
@property
def x(self):
return [[self.x0_0], [self.x1_0]]
def set_x(self, x):
self.x0_0 = x[0][0]
self.x1_0 = x[1][0]

@ -9,7 +9,6 @@ from openpilot.selfdrive.car.mazda.values import CAR as MAZDA
from openpilot.selfdrive.car.mock.values import CAR as MOCK
from openpilot.selfdrive.car.nissan.values import CAR as NISSAN
from openpilot.selfdrive.car.subaru.values import CAR as SUBARU
from openpilot.selfdrive.car.tesla.values import CAR as TESLA
from openpilot.selfdrive.car.toyota.values import CAR as TOYOTA
from openpilot.selfdrive.car.volkswagen.values import CAR as VW
@ -276,9 +275,6 @@ MIGRATION = {
"SUBARU FORESTER 2022": SUBARU.SUBARU_FORESTER_2022,
"SUBARU OUTBACK 7TH GEN": SUBARU.SUBARU_OUTBACK_2023,
"SUBARU ASCENT 2023": SUBARU.SUBARU_ASCENT_2023,
'TESLA AP1 MODEL S': TESLA.TESLA_AP1_MODELS,
'TESLA AP2 MODEL S': TESLA.TESLA_AP2_MODELS,
'TESLA MODEL S RAVEN': TESLA.TESLA_MODELS_RAVEN,
"TOYOTA ALPHARD 2020": TOYOTA.TOYOTA_ALPHARD_TSS2,
"TOYOTA AVALON 2016": TOYOTA.TOYOTA_AVALON,
"TOYOTA AVALON 2019": TOYOTA.TOYOTA_AVALON_2019,

@ -3,7 +3,7 @@ from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import apply_std_steer_angle_limits, structs
from openpilot.selfdrive.car.ford import fordcan
from openpilot.selfdrive.car.ford.values import CarControllerParams, FordFlags
from openpilot.selfdrive.car.helpers import clip
from openpilot.selfdrive.car.common.numpy_fast import clip
from openpilot.selfdrive.car.interfaces import CarControllerBase, V_CRUISE_MAX
LongCtrlState = structs.CarControl.Actuators.LongControlState

@ -4,7 +4,7 @@ from openpilot.selfdrive.car import DT_CTRL, apply_driver_steer_torque_limits, s
from openpilot.selfdrive.car.gm import gmcan
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.gm.values import DBC, CanBus, CarControllerParams, CruiseButtons
from openpilot.selfdrive.car.helpers import interp
from openpilot.selfdrive.car.common.numpy_fast import interp
from openpilot.selfdrive.car.interfaces import CarControllerBase
VisualAlert = structs.CarControl.HUDControl.VisualAlert

@ -3,7 +3,7 @@ from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car import create_button_events, structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.helpers import mean
from openpilot.selfdrive.car.common.numpy_fast import mean
from openpilot.selfdrive.car.interfaces import CarStateBase
from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, CruiseButtons, STEER_THRESHOLD

@ -3,7 +3,7 @@ from collections import namedtuple
from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import DT_CTRL, rate_limit, make_tester_present_msg, structs
from openpilot.selfdrive.car.helpers import clip, interp
from openpilot.selfdrive.car.common.numpy_fast import clip, interp
from openpilot.selfdrive.car.honda import hondacan
from openpilot.selfdrive.car.honda.values import CruiseButtons, VISUAL_HUD, HONDA_BOSCH, HONDA_BOSCH_RADARLESS, HONDA_NIDEC_ALT_PCM_ACCEL, CarControllerParams
from openpilot.selfdrive.car.interfaces import CarControllerBase

@ -5,7 +5,7 @@ from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car import create_button_events, structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.helpers import interp
from openpilot.selfdrive.car.common.numpy_fast import interp
from openpilot.selfdrive.car.honda.hondacan import CanBus, get_cruise_speed_conversion
from openpilot.selfdrive.car.honda.values import CAR, DBC, STEER_THRESHOLD, HONDA_BOSCH, \
HONDA_NIDEC_ALT_SCM_MESSAGES, HONDA_BOSCH_RADARLESS, \

@ -2,7 +2,7 @@
from panda import Panda
from openpilot.selfdrive.car import get_safety_config, structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.helpers import interp
from openpilot.selfdrive.car.common.numpy_fast import interp
from openpilot.selfdrive.car.honda.carstate import CarState
from openpilot.selfdrive.car.honda.hondacan import CanBus
from openpilot.selfdrive.car.honda.values import CarControllerParams, HondaFlags, CAR, HONDA_BOSCH, \

@ -2,7 +2,7 @@ import copy
from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import DT_CTRL, apply_driver_steer_torque_limits, common_fault_avoidance, make_tester_present_msg, structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.helpers import clip
from openpilot.selfdrive.car.common.numpy_fast import clip
from openpilot.selfdrive.car.hyundai import hyundaicanfd, hyundaican
from openpilot.selfdrive.car.hyundai.carstate import CarState
from openpilot.selfdrive.car.hyundai.hyundaicanfd import CanBus

@ -1,5 +1,5 @@
from openpilot.selfdrive.car import CanBusBase
from openpilot.selfdrive.car.helpers import clip
from openpilot.selfdrive.car.common.numpy_fast import clip
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags

@ -10,12 +10,12 @@ from collections.abc import Callable
from functools import cache
from openpilot.common.basedir import BASEDIR
from openpilot.common.simple_kalman import KF1D, get_kalman_gain
from openpilot.selfdrive.car import DT_CTRL, apply_hysteresis, gen_empty_fingerprint, scale_rot_inertia, scale_tire_stiffness, get_friction, STD_CARGO_KG
from openpilot.selfdrive.car import structs
from openpilot.selfdrive.car.can_definitions import CanData, CanRecvCallable, CanSendCallable
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.helpers import clip
from openpilot.selfdrive.car.common.simple_kalman import KF1D, get_kalman_gain
from openpilot.selfdrive.car.common.numpy_fast import clip
from openpilot.selfdrive.car.values import PLATFORMS
GearShifter = structs.CarState.GearShifter

@ -1,7 +1,7 @@
import copy
from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import apply_driver_steer_torque_limits, common_fault_avoidance, make_tester_present_msg
from openpilot.selfdrive.car.helpers import clip, interp
from openpilot.selfdrive.car.common.numpy_fast import clip, interp
from openpilot.selfdrive.car.interfaces import CarControllerBase
from openpilot.selfdrive.car.subaru import subarucan
from openpilot.selfdrive.car.subaru.values import DBC, GLOBAL_ES_ADDR, CanBus, CarControllerParams, SubaruFlags

@ -1,67 +0,0 @@
import copy
from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import apply_std_steer_angle_limits
from openpilot.selfdrive.car.helpers import clip
from openpilot.selfdrive.car.interfaces import CarControllerBase
from openpilot.selfdrive.car.tesla.teslacan import TeslaCAN
from openpilot.selfdrive.car.tesla.values import DBC, CANBUS, CarControllerParams
class CarController(CarControllerBase):
def __init__(self, dbc_name, CP):
super().__init__(dbc_name, CP)
self.apply_angle_last = 0
self.packer = CANPacker(dbc_name)
self.pt_packer = CANPacker(DBC[CP.carFingerprint]['pt'])
self.tesla_can = TeslaCAN(self.packer, self.pt_packer)
def update(self, CC, CS, now_nanos):
actuators = CC.actuators
pcm_cancel_cmd = CC.cruiseControl.cancel
can_sends = []
# Temp disable steering on a hands_on_fault, and allow for user override
hands_on_fault = CS.steer_warning == "EAC_ERROR_HANDS_ON" and CS.hands_on_level >= 3
lkas_enabled = CC.latActive and not hands_on_fault
if self.frame % 2 == 0:
if lkas_enabled:
# Angular rate limit based on speed
apply_angle = apply_std_steer_angle_limits(actuators.steeringAngleDeg, self.apply_angle_last, CS.out.vEgo, CarControllerParams)
# To not fault the EPS
apply_angle = clip(apply_angle, CS.out.steeringAngleDeg - 20, CS.out.steeringAngleDeg + 20)
else:
apply_angle = CS.out.steeringAngleDeg
self.apply_angle_last = apply_angle
can_sends.append(self.tesla_can.create_steering_control(apply_angle, lkas_enabled, (self.frame // 2) % 16))
# Longitudinal control (in sync with stock message, about 40Hz)
if self.CP.openpilotLongitudinalControl:
target_accel = actuators.accel
target_speed = max(CS.out.vEgo + (target_accel * CarControllerParams.ACCEL_TO_SPEED_MULTIPLIER), 0)
max_accel = 0 if target_accel < 0 else target_accel
min_accel = 0 if target_accel > 0 else target_accel
while len(CS.das_control_counters) > 0:
can_sends.extend(self.tesla_can.create_longitudinal_commands(CS.acc_state, target_speed, min_accel, max_accel, CS.das_control_counters.popleft()))
# Cancel on user steering override, since there is no steering torque blending
if hands_on_fault:
pcm_cancel_cmd = True
if self.frame % 10 == 0 and pcm_cancel_cmd:
# Spam every possible counter value, otherwise it might not be accepted
for counter in range(16):
can_sends.append(self.tesla_can.create_action_request(CS.msg_stw_actn_req, pcm_cancel_cmd, CANBUS.chassis, counter))
can_sends.append(self.tesla_can.create_action_request(CS.msg_stw_actn_req, pcm_cancel_cmd, CANBUS.autopilot_chassis, counter))
# TODO: HUD control
new_actuators = copy.deepcopy(actuators)
new_actuators.steeringAngleDeg = self.apply_angle_last
self.frame += 1
return new_actuators, can_sends

@ -1,140 +0,0 @@
import copy
from collections import deque
from opendbc.can.parser import CANParser
from opendbc.can.can_define import CANDefine
from openpilot.selfdrive.car import structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.tesla.values import CAR, DBC, CANBUS, GEAR_MAP, DOORS, BUTTONS
from openpilot.selfdrive.car.interfaces import CarStateBase
class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
self.button_states = {button.event_type: False for button in BUTTONS}
self.can_define = CANDefine(DBC[CP.carFingerprint]['chassis'])
# Needed by carcontroller
self.msg_stw_actn_req = None
self.hands_on_level = 0
self.steer_warning = None
self.acc_state = 0
self.das_control_counters = deque(maxlen=32)
def update(self, cp, cp_cam, *_) -> structs.CarState:
ret = structs.CarState()
# Vehicle speed
ret.vEgoRaw = cp.vl["ESP_B"]["ESP_vehicleSpeed"] * CV.KPH_TO_MS
ret.vEgo, ret.aEgo = self.update_speed_kf(ret.vEgoRaw)
ret.standstill = (ret.vEgo < 0.1)
# Gas pedal
ret.gas = cp.vl["DI_torque1"]["DI_pedalPos"] / 100.0
ret.gasPressed = (ret.gas > 0)
# Brake pedal
ret.brake = 0
ret.brakePressed = bool(cp.vl["BrakeMessage"]["driverBrakeStatus"] != 1)
# Steering wheel
epas_status = cp_cam.vl["EPAS3P_sysStatus"] if self.CP.carFingerprint == CAR.TESLA_MODELS_RAVEN else cp.vl["EPAS_sysStatus"]
self.hands_on_level = epas_status["EPAS_handsOnLevel"]
self.steer_warning = self.can_define.dv["EPAS_sysStatus"]["EPAS_eacErrorCode"].get(int(epas_status["EPAS_eacErrorCode"]), None)
steer_status = self.can_define.dv["EPAS_sysStatus"]["EPAS_eacStatus"].get(int(epas_status["EPAS_eacStatus"]), None)
ret.steeringAngleDeg = -epas_status["EPAS_internalSAS"]
ret.steeringRateDeg = -cp.vl["STW_ANGLHP_STAT"]["StW_AnglHP_Spd"] # This is from a different angle sensor, and at different rate
ret.steeringTorque = -epas_status["EPAS_torsionBarTorque"]
ret.steeringPressed = (self.hands_on_level > 0)
ret.steerFaultPermanent = steer_status == "EAC_FAULT"
ret.steerFaultTemporary = (self.steer_warning not in ("EAC_ERROR_IDLE", "EAC_ERROR_HANDS_ON"))
# Cruise state
cruise_state = self.can_define.dv["DI_state"]["DI_cruiseState"].get(int(cp.vl["DI_state"]["DI_cruiseState"]), None)
speed_units = self.can_define.dv["DI_state"]["DI_speedUnits"].get(int(cp.vl["DI_state"]["DI_speedUnits"]), None)
acc_enabled = (cruise_state in ("ENABLED", "STANDSTILL", "OVERRIDE", "PRE_FAULT", "PRE_CANCEL"))
ret.cruiseState.enabled = acc_enabled
if speed_units == "KPH":
ret.cruiseState.speed = cp.vl["DI_state"]["DI_digitalSpeed"] * CV.KPH_TO_MS
elif speed_units == "MPH":
ret.cruiseState.speed = cp.vl["DI_state"]["DI_digitalSpeed"] * CV.MPH_TO_MS
ret.cruiseState.available = ((cruise_state == "STANDBY") or ret.cruiseState.enabled)
ret.cruiseState.standstill = False # This needs to be false, since we can resume from stop without sending anything special
# Gear
ret.gearShifter = GEAR_MAP[self.can_define.dv["DI_torque2"]["DI_gear"].get(int(cp.vl["DI_torque2"]["DI_gear"]), "DI_GEAR_INVALID")]
# Buttons
buttonEvents = []
for button in BUTTONS:
state = (cp.vl[button.can_addr][button.can_msg] in button.values)
if self.button_states[button.event_type] != state:
event = structs.CarState.ButtonEvent()
event.type = button.event_type
event.pressed = state
buttonEvents.append(event)
self.button_states[button.event_type] = state
ret.buttonEvents = buttonEvents
# Doors
ret.doorOpen = any((self.can_define.dv["GTW_carState"][door].get(int(cp.vl["GTW_carState"][door]), "OPEN") == "OPEN") for door in DOORS)
# Blinkers
ret.leftBlinker = (cp.vl["GTW_carState"]["BC_indicatorLStatus"] == 1)
ret.rightBlinker = (cp.vl["GTW_carState"]["BC_indicatorRStatus"] == 1)
# Seatbelt
if self.CP.carFingerprint == CAR.TESLA_MODELS_RAVEN:
ret.seatbeltUnlatched = (cp.vl["DriverSeat"]["buckleStatus"] != 1)
else:
ret.seatbeltUnlatched = (cp.vl["SDM1"]["SDM_bcklDrivStatus"] != 1)
# TODO: blindspot
# AEB
ret.stockAeb = (cp_cam.vl["DAS_control"]["DAS_aebEvent"] == 1)
# Messages needed by carcontroller
self.msg_stw_actn_req = copy.copy(cp.vl["STW_ACTN_RQ"])
self.acc_state = cp_cam.vl["DAS_control"]["DAS_accState"]
self.das_control_counters.extend(cp_cam.vl_all["DAS_control"]["DAS_controlCounter"])
return ret
@staticmethod
def get_can_parser(CP):
messages = [
# sig_address, frequency
("ESP_B", 50),
("DI_torque1", 100),
("DI_torque2", 100),
("STW_ANGLHP_STAT", 100),
("EPAS_sysStatus", 25),
("DI_state", 10),
("STW_ACTN_RQ", 10),
("GTW_carState", 10),
("BrakeMessage", 50),
]
if CP.carFingerprint == CAR.TESLA_MODELS_RAVEN:
messages.append(("DriverSeat", 20))
else:
messages.append(("SDM1", 10))
return CANParser(DBC[CP.carFingerprint]['chassis'], messages, CANBUS.chassis)
@staticmethod
def get_cam_can_parser(CP):
messages = [
# sig_address, frequency
("DAS_control", 40),
]
if CP.carFingerprint == CAR.TESLA_MODELS_RAVEN:
messages.append(("EPAS3P_sysStatus", 100))
return CANParser(DBC[CP.carFingerprint]['chassis'], messages, CANBUS.autopilot_chassis)

@ -1,32 +0,0 @@
from openpilot.selfdrive.car.structs import CarParams
from openpilot.selfdrive.car.tesla.values import CAR
Ecu = CarParams.Ecu
FW_VERSIONS = {
CAR.TESLA_AP2_MODELS: {
(Ecu.adas, 0x649, None): [
b'\x01\x00\x8b\x07\x01\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11',
],
(Ecu.electricBrakeBooster, 0x64d, None): [
b'1037123-00-A',
],
(Ecu.fwdRadar, 0x671, None): [
b'\x01\x00W\x00\x00\x00\x07\x00\x00\x00\x00\x08\x01\x00\x00\x00\x07\xff\xfe',
],
(Ecu.eps, 0x730, None): [
b'\x10#\x01',
],
},
CAR.TESLA_MODELS_RAVEN: {
(Ecu.electricBrakeBooster, 0x64d, None): [
b'1037123-00-A',
],
(Ecu.fwdRadar, 0x671, None): [
b'\x01\x00\x99\x02\x01\x00\x10\x00\x00AP8.3.03\x00\x10',
],
(Ecu.eps, 0x730, None): [
b'SX_0.0.0 (99),SR013.7',
],
},
}

@ -1,42 +0,0 @@
#!/usr/bin/env python3
from panda import Panda
from openpilot.selfdrive.car import get_safety_config, structs
from openpilot.selfdrive.car.tesla.carstate import CarState
from openpilot.selfdrive.car.tesla.values import CANBUS, CAR
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
class CarInterface(CarInterfaceBase):
CS: CarState
@staticmethod
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experimental_long, docs):
ret.carName = "tesla"
# There is no safe way to do steer blending with user torque,
# so the steering behaves like autopilot. This is not
# how openpilot should be, hence dashcamOnly
ret.dashcamOnly = True
ret.steerControlType = structs.CarParams.SteerControlType.angle
ret.longitudinalActuatorDelay = 0.5 # s
ret.radarTimeStep = (1.0 / 8) # 8Hz
# Check if we have messages on an auxiliary panda, and that 0x2bf (DAS_control) is present on the AP powertrain bus
# If so, we assume that it is connected to the longitudinal harness.
flags = (Panda.FLAG_TESLA_RAVEN if candidate == CAR.TESLA_MODELS_RAVEN else 0)
if (CANBUS.autopilot_powertrain in fingerprint.keys()) and (0x2bf in fingerprint[CANBUS.autopilot_powertrain].keys()):
ret.openpilotLongitudinalControl = True
flags |= Panda.FLAG_TESLA_LONG_CONTROL
ret.safetyConfigs = [
get_safety_config(structs.CarParams.SafetyModel.tesla, flags),
get_safety_config(structs.CarParams.SafetyModel.tesla, flags | Panda.FLAG_TESLA_POWERTRAIN),
]
else:
ret.openpilotLongitudinalControl = False
ret.safetyConfigs = [get_safety_config(structs.CarParams.SafetyModel.tesla, flags)]
ret.steerLimitTimer = 1.0
ret.steerActuatorDelay = 0.25
return ret

@ -1,90 +0,0 @@
#!/usr/bin/env python3
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car import structs
from openpilot.selfdrive.car.tesla.values import CAR, DBC, CANBUS
from openpilot.selfdrive.car.interfaces import RadarInterfaceBase
class RadarInterface(RadarInterfaceBase):
def __init__(self, CP):
super().__init__(CP)
if CP.carFingerprint == CAR.TESLA_MODELS_RAVEN:
messages = [('RadarStatus', 16)]
self.num_points = 40
self.trigger_msg = 1119
else:
messages = [('TeslaRadarSguInfo', 10)]
self.num_points = 32
self.trigger_msg = 878
for i in range(self.num_points):
messages.extend([
(f'RadarPoint{i}_A', 16),
(f'RadarPoint{i}_B', 16),
])
self.rcp = CANParser(DBC[CP.carFingerprint]['radar'], messages, CANBUS.radar)
self.updated_messages = set()
self.track_id = 0
def update(self, can_strings):
if self.rcp is None:
return super().update(None)
values = self.rcp.update_strings(can_strings)
self.updated_messages.update(values)
if self.trigger_msg not in self.updated_messages:
return None
ret = structs.RadarData()
# Errors
errors = []
if not self.rcp.can_valid:
errors.append('canError')
if self.CP.carFingerprint == CAR.TESLA_MODELS_RAVEN:
radar_status = self.rcp.vl['RadarStatus']
if radar_status['sensorBlocked'] or radar_status['shortTermUnavailable'] or radar_status['vehDynamicsError']:
errors.append('fault')
else:
radar_status = self.rcp.vl['TeslaRadarSguInfo']
if radar_status['RADC_HWFail'] or radar_status['RADC_SGUFail'] or radar_status['RADC_SensorDirty']:
errors.append('fault')
ret.errors = errors
# Radar tracks
for i in range(self.num_points):
msg_a = self.rcp.vl[f'RadarPoint{i}_A']
msg_b = self.rcp.vl[f'RadarPoint{i}_B']
# Make sure msg A and B are together
if msg_a['Index'] != msg_b['Index2']:
continue
# Check if it's a valid track
if not msg_a['Tracked']:
if i in self.pts:
del self.pts[i]
continue
# New track!
if i not in self.pts:
self.pts[i] = structs.RadarData.RadarPoint()
self.pts[i].trackId = self.track_id
self.track_id += 1
# Parse track data
self.pts[i].dRel = msg_a['LongDist']
self.pts[i].yRel = msg_a['LatDist']
self.pts[i].vRel = msg_a['LongSpeed']
self.pts[i].aRel = msg_a['LongAccel']
self.pts[i].yvRel = msg_b['LatSpeed']
self.pts[i].measured = bool(msg_a['Meas'])
ret.points = list(self.pts.values())
self.updated_messages.clear()
return ret

@ -1,94 +0,0 @@
import crcmod
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.tesla.values import CANBUS, CarControllerParams
class TeslaCAN:
def __init__(self, packer, pt_packer):
self.packer = packer
self.pt_packer = pt_packer
self.crc = crcmod.mkCrcFun(0x11d, initCrc=0x00, rev=False, xorOut=0xff)
@staticmethod
def checksum(msg_id, dat):
# TODO: get message ID from name instead
ret = (msg_id & 0xFF) + ((msg_id >> 8) & 0xFF)
ret += sum(dat)
return ret & 0xFF
def create_steering_control(self, angle, enabled, counter):
values = {
"DAS_steeringAngleRequest": -angle,
"DAS_steeringHapticRequest": 0,
"DAS_steeringControlType": 1 if enabled else 0,
"DAS_steeringControlCounter": counter,
}
data = self.packer.make_can_msg("DAS_steeringControl", CANBUS.chassis, values)[1]
values["DAS_steeringControlChecksum"] = self.checksum(0x488, data[:3])
return self.packer.make_can_msg("DAS_steeringControl", CANBUS.chassis, values)
def create_action_request(self, msg_stw_actn_req, cancel, bus, counter):
# We copy this whole message when spamming cancel
values = {s: msg_stw_actn_req[s] for s in [
"SpdCtrlLvr_Stat",
"VSL_Enbl_Rq",
"SpdCtrlLvrStat_Inv",
"DTR_Dist_Rq",
"TurnIndLvr_Stat",
"HiBmLvr_Stat",
"WprWashSw_Psd",
"WprWash_R_Sw_Posn_V2",
"StW_Lvr_Stat",
"StW_Cond_Flt",
"StW_Cond_Psd",
"HrnSw_Psd",
"StW_Sw00_Psd",
"StW_Sw01_Psd",
"StW_Sw02_Psd",
"StW_Sw03_Psd",
"StW_Sw04_Psd",
"StW_Sw05_Psd",
"StW_Sw06_Psd",
"StW_Sw07_Psd",
"StW_Sw08_Psd",
"StW_Sw09_Psd",
"StW_Sw10_Psd",
"StW_Sw11_Psd",
"StW_Sw12_Psd",
"StW_Sw13_Psd",
"StW_Sw14_Psd",
"StW_Sw15_Psd",
"WprSw6Posn",
"MC_STW_ACTN_RQ",
"CRC_STW_ACTN_RQ",
]}
if cancel:
values["SpdCtrlLvr_Stat"] = 1
values["MC_STW_ACTN_RQ"] = counter
data = self.packer.make_can_msg("STW_ACTN_RQ", bus, values)[1]
values["CRC_STW_ACTN_RQ"] = self.crc(data[:7])
return self.packer.make_can_msg("STW_ACTN_RQ", bus, values)
def create_longitudinal_commands(self, acc_state, speed, min_accel, max_accel, cnt):
messages = []
values = {
"DAS_setSpeed": speed * CV.MS_TO_KPH,
"DAS_accState": acc_state,
"DAS_aebEvent": 0,
"DAS_jerkMin": CarControllerParams.JERK_LIMIT_MIN,
"DAS_jerkMax": CarControllerParams.JERK_LIMIT_MAX,
"DAS_accelMin": min_accel,
"DAS_accelMax": max_accel,
"DAS_controlCounter": cnt,
"DAS_controlChecksum": 0,
}
for packer, bus in [(self.packer, CANBUS.chassis), (self.pt_packer, CANBUS.powertrain)]:
data = packer.make_can_msg("DAS_control", bus, values)[1]
values["DAS_controlChecksum"] = self.checksum(0x2b9, data[:7])
messages.append(packer.make_can_msg("DAS_control", bus, values))
return messages

@ -1,98 +0,0 @@
from collections import namedtuple
from openpilot.selfdrive.car import AngleRateLimit, CarSpecs, PlatformConfig, Platforms, dbc_dict
from openpilot.selfdrive.car import structs
from openpilot.selfdrive.car.docs_definitions import CarDocs
from openpilot.selfdrive.car.fw_query_definitions import FwQueryConfig, Request, StdQueries
Ecu = structs.CarParams.Ecu
Button = namedtuple('Button', ['event_type', 'can_addr', 'can_msg', 'values'])
class CAR(Platforms):
TESLA_AP1_MODELS = PlatformConfig(
[CarDocs("Tesla AP1 Model S", "All")],
CarSpecs(mass=2100., wheelbase=2.959, steerRatio=15.0),
dbc_dict('tesla_powertrain', 'tesla_radar_bosch_generated', chassis_dbc='tesla_can')
)
TESLA_AP2_MODELS = PlatformConfig(
[CarDocs("Tesla AP2 Model S", "All")],
TESLA_AP1_MODELS.specs,
TESLA_AP1_MODELS.dbc_dict
)
TESLA_MODELS_RAVEN = PlatformConfig(
[CarDocs("Tesla Model S Raven", "All")],
TESLA_AP1_MODELS.specs,
dbc_dict('tesla_powertrain', 'tesla_radar_continental_generated', chassis_dbc='tesla_can')
)
FW_QUERY_CONFIG = FwQueryConfig(
requests=[
Request(
[StdQueries.TESTER_PRESENT_REQUEST, StdQueries.UDS_VERSION_REQUEST],
[StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.UDS_VERSION_RESPONSE],
whitelist_ecus=[Ecu.eps],
rx_offset=0x08,
bus=0,
),
Request(
[StdQueries.TESTER_PRESENT_REQUEST, StdQueries.SUPPLIER_SOFTWARE_VERSION_REQUEST],
[StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.SUPPLIER_SOFTWARE_VERSION_RESPONSE],
whitelist_ecus=[Ecu.eps],
rx_offset=0x08,
bus=0,
),
Request(
[StdQueries.TESTER_PRESENT_REQUEST, StdQueries.UDS_VERSION_REQUEST],
[StdQueries.TESTER_PRESENT_RESPONSE, StdQueries.UDS_VERSION_RESPONSE],
whitelist_ecus=[Ecu.adas, Ecu.electricBrakeBooster, Ecu.fwdRadar],
rx_offset=0x10,
bus=0,
),
]
)
class CANBUS:
# Lateral harness
chassis = 0
radar = 1
autopilot_chassis = 2
# Longitudinal harness
powertrain = 4
private = 5
autopilot_powertrain = 6
GEAR_MAP = {
"DI_GEAR_INVALID": structs.CarState.GearShifter.unknown,
"DI_GEAR_P": structs.CarState.GearShifter.park,
"DI_GEAR_R": structs.CarState.GearShifter.reverse,
"DI_GEAR_N": structs.CarState.GearShifter.neutral,
"DI_GEAR_D": structs.CarState.GearShifter.drive,
"DI_GEAR_SNA": structs.CarState.GearShifter.unknown,
}
DOORS = ["DOOR_STATE_FL", "DOOR_STATE_FR", "DOOR_STATE_RL", "DOOR_STATE_RR", "DOOR_STATE_FrontTrunk", "BOOT_STATE"]
# Make sure the message and addr is also in the CAN parser!
BUTTONS = [
Button(structs.CarState.ButtonEvent.Type.leftBlinker, "STW_ACTN_RQ", "TurnIndLvr_Stat", [1]),
Button(structs.CarState.ButtonEvent.Type.rightBlinker, "STW_ACTN_RQ", "TurnIndLvr_Stat", [2]),
Button(structs.CarState.ButtonEvent.Type.accelCruise, "STW_ACTN_RQ", "SpdCtrlLvr_Stat", [4, 16]),
Button(structs.CarState.ButtonEvent.Type.decelCruise, "STW_ACTN_RQ", "SpdCtrlLvr_Stat", [8, 32]),
Button(structs.CarState.ButtonEvent.Type.cancel, "STW_ACTN_RQ", "SpdCtrlLvr_Stat", [1]),
Button(structs.CarState.ButtonEvent.Type.resumeCruise, "STW_ACTN_RQ", "SpdCtrlLvr_Stat", [2]),
]
class CarControllerParams:
ANGLE_RATE_LIMIT_UP = AngleRateLimit(speed_bp=[0., 5., 15.], angle_v=[10., 1.6, .3])
ANGLE_RATE_LIMIT_DOWN = AngleRateLimit(speed_bp=[0., 5., 15.], angle_v=[10., 7.0, 0.8])
JERK_LIMIT_MAX = 8
JERK_LIMIT_MIN = -8
ACCEL_TO_SPEED_MULTIPLIER = 3
def __init__(self, CP):
pass
DBC = CAR.create_dbc_map()

@ -12,7 +12,6 @@ from openpilot.selfdrive.car.subaru.values import CAR as SUBARU
from openpilot.selfdrive.car.toyota.values import CAR as TOYOTA
from openpilot.selfdrive.car.values import Platform
from openpilot.selfdrive.car.volkswagen.values import CAR as VOLKSWAGEN
from openpilot.selfdrive.car.tesla.values import CAR as TESLA
from openpilot.selfdrive.car.body.values import CAR as COMMA
# TODO: add routes for these cars
@ -289,10 +288,6 @@ routes = [
CarTestRoute("f6d5b1a9d7a1c92e|2021-07-08--06-56-59", MAZDA.MAZDA_CX9_2021),
CarTestRoute("a4af1602d8e668ac|2022-02-03--12-17-07", MAZDA.MAZDA_CX5_2022),
CarTestRoute("6c14ee12b74823ce|2021-06-30--11-49-02", TESLA.TESLA_AP1_MODELS),
CarTestRoute("bb50caf5f0945ab1|2021-06-19--17-20-18", TESLA.TESLA_AP2_MODELS),
CarTestRoute("66c1699b7697267d/2024-03-03--13-09-53", TESLA.TESLA_MODELS_RAVEN),
# Segments that test specific issues
# Controls mismatch due to standstill threshold
CarTestRoute("bec2dcfde6a64235|2022-04-08--14-21-32", HONDA.HONDA_CRV_HYBRID, segment=22),

@ -142,7 +142,7 @@ class TestCarInterfaces:
def test_interface_attrs(self):
"""Asserts basic behavior of interface attribute getter"""
num_brands = len(get_interface_attr('CAR'))
assert num_brands >= 13
assert num_brands >= 12
# Should return value for all brands when not combining, even if attribute doesn't exist
ret = get_interface_attr('FAKE_ATTR')

@ -265,7 +265,7 @@ class TestFwFingerprintTiming:
print(f'get_vin {name} case, query time={self.total_time / self.N} seconds')
def test_fw_query_timing(self, subtests, mocker):
total_ref_time = {1: 7.2, 2: 7.8}
total_ref_time = {1: 6.9, 2: 7.5}
brand_ref_times = {
1: {
'gm': 1.0,
@ -277,14 +277,12 @@ class TestFwFingerprintTiming:
'mazda': 0.1,
'nissan': 0.8,
'subaru': 0.65,
'tesla': 0.3,
'toyota': 0.7,
'volkswagen': 0.65,
},
2: {
'ford': 1.6,
'hyundai': 1.15,
'tesla': 0.3,
}
}

@ -15,11 +15,6 @@ legend = ["LAT_ACCEL_FACTOR", "MAX_LAT_ACCEL_MEASURED", "FRICTION"]
# Toyota LTA also has torque
"TOYOTA_RAV4_TSS2_2023" = [nan, 3.0, nan]
# Tesla has high torque
"TESLA_AP1_MODELS" = [nan, 2.5, nan]
"TESLA_AP2_MODELS" = [nan, 2.5, nan]
"TESLA_MODELS_RAVEN" = [nan, 2.5, nan]
# Guess
"FORD_BRONCO_SPORT_MK1" = [nan, 1.5, nan]
"FORD_ESCAPE_MK4" = [nan, 1.5, nan]

@ -1,7 +1,7 @@
import copy
from openpilot.selfdrive.car import apply_meas_steer_torque_limits, apply_std_steer_angle_limits, common_fault_avoidance, make_tester_present_msg, structs
from openpilot.selfdrive.car.can_definitions import CanData
from openpilot.selfdrive.car.helpers import clip
from openpilot.selfdrive.car.common.numpy_fast import clip
from openpilot.selfdrive.car.interfaces import CarControllerBase
from openpilot.selfdrive.car.toyota import toyotacan
from openpilot.selfdrive.car.toyota.values import CAR, STATIC_DSU_MSGS, NO_STOP_TIMER_CAR, TSS2_CAR, \

@ -4,8 +4,8 @@ from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car import DT_CTRL, create_button_events, structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.filter_simple import FirstOrderFilter
from openpilot.selfdrive.car.helpers import mean
from openpilot.selfdrive.car.common.filter_simple import FirstOrderFilter
from openpilot.selfdrive.car.common.numpy_fast import mean
from openpilot.selfdrive.car.interfaces import CarStateBase
from openpilot.selfdrive.car.toyota.values import ToyotaFlags, CAR, DBC, STEER_THRESHOLD, NO_STOP_TIMER_CAR, \
TSS2_CAR, RADAR_ACC_CAR, EPS_SCALE, UNSUPPORTED_DSU_CAR

@ -9,11 +9,10 @@ from openpilot.selfdrive.car.mazda.values import CAR as MAZDA
from openpilot.selfdrive.car.mock.values import CAR as MOCK
from openpilot.selfdrive.car.nissan.values import CAR as NISSAN
from openpilot.selfdrive.car.subaru.values import CAR as SUBARU
from openpilot.selfdrive.car.tesla.values import CAR as TESLA
from openpilot.selfdrive.car.toyota.values import CAR as TOYOTA
from openpilot.selfdrive.car.volkswagen.values import CAR as VOLKSWAGEN
Platform = BODY | CHRYSLER | FORD | GM | HONDA | HYUNDAI | MAZDA | MOCK | NISSAN | SUBARU | TESLA | TOYOTA | VOLKSWAGEN
Platform = BODY | CHRYSLER | FORD | GM | HONDA | HYUNDAI | MAZDA | MOCK | NISSAN | SUBARU | TOYOTA | VOLKSWAGEN
BRANDS = get_args(Platform)
PLATFORMS: dict[str, Platform] = {str(platform): platform for brand in BRANDS for platform in brand}

@ -2,7 +2,7 @@ import copy
from opendbc.can.packer import CANPacker
from openpilot.selfdrive.car import DT_CTRL, apply_driver_steer_torque_limits, structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.helpers import clip
from openpilot.selfdrive.car.common.numpy_fast import clip
from openpilot.selfdrive.car.interfaces import CarControllerBase
from openpilot.selfdrive.car.volkswagen import mqbcan, pqcan
from openpilot.selfdrive.car.volkswagen.values import CANBUS, CarControllerParams, VolkswagenFlags

@ -382,6 +382,7 @@ class Controls:
# TODO: fix simulator
if not SIMULATION or REPLAY:
# Not show in first 1.5 km to allow for driving out of garage. This event shows after 5 minutes
gps_ok = self.sm.recv_frame[self.gps_location_service] > 0 and (self.sm.frame - self.sm.recv_frame[self.gps_location_service]) * DT_CTRL < 2.0
if not gps_ok and self.sm['livePose'].inputsOK and (self.distance_traveled > 1500):
self.events.add(EventName.noGps)

@ -1,4 +1,5 @@
#!/bin/bash -e
#!/usr/bin/env bash
set -e
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
OP_ROOT="$DIR/../../"

@ -36,7 +36,6 @@ source_segments = [
("FORD", "54827bf84c38b14f|2023-01-26--21-59-07--4"), # FORD.FORD_BRONCO_SPORT_MK1
# Enable when port is tested and dashcamOnly is no longer set
#("TESLA", "bb50caf5f0945ab1|2021-06-19--17-20-18--3"), # TESLA.TESLA_AP2_MODELS
#("VOLKSWAGEN2", "3cfdec54aa035f3f|2022-07-19--23-45-10--2"), # VOLKSWAGEN.VOLKSWAGEN_PASSAT_NMS
]
@ -61,7 +60,7 @@ segments = [
]
# dashcamOnly makes don't need to be tested until a full port is done
excluded_interfaces = ["mock", "tesla"]
excluded_interfaces = ["mock"]
BASE_URL = "https://commadataci.blob.core.windows.net/openpilotci/"
REF_COMMIT_FN = os.path.join(PROC_REPLAY_DIR, "ref_commit")

@ -102,8 +102,6 @@ void Sidebar::updateState(const UIState &s) {
ItemStatus pandaStatus = {{tr("VEHICLE"), tr("ONLINE")}, good_color};
if (s.scene.pandaType == cereal::PandaState::PandaType::UNKNOWN) {
pandaStatus = {{tr("NO"), tr("PANDA")}, danger_color};
} else if (s.scene.started && !sm["liveLocationKalman"].getLiveLocationKalman().getGpsOK()) {
pandaStatus = {{tr("GPS"), tr("SEARCH")}, warning_color};
}
setProperty("pandaStatus", QVariant::fromValue(pandaStatus));
}

@ -116,7 +116,7 @@ class TestUI:
def setup(self):
self.sm = SubMaster(["uiDebug"])
self.pm = PubMaster(["deviceState", "pandaStates", "controlsState", 'roadCameraState', 'wideRoadCameraState', 'liveLocationKalman'])
self.pm = PubMaster(["deviceState", "pandaStates", "controlsState", 'roadCameraState', 'wideRoadCameraState'])
while not self.sm.valid["uiDebug"]:
self.sm.update(1)
time.sleep(UI_DELAY) # wait a bit more for the UI to start rendering

@ -779,14 +779,6 @@ This may take up to a minute.</source>
<source>PANDA</source>
<translation>PANDA</translation>
</message>
<message>
<source>GPS</source>
<translation>GPS</translation>
</message>
<message>
<source>SEARCH</source>
<translation>بحث</translation>
</message>
<message>
<source>--</source>
<translation>--</translation>

@ -762,14 +762,6 @@ This may take up to a minute.</source>
<source>PANDA</source>
<translation>PANDA</translation>
</message>
<message>
<source>GPS</source>
<translation>GPS</translation>
</message>
<message>
<source>SEARCH</source>
<translation>SUCHEN</translation>
</message>
<message>
<source>--</source>
<translation>--</translation>

@ -763,14 +763,6 @@ Esto puede tardar un minuto.</translation>
<source>PANDA</source>
<translation>PANDA</translation>
</message>
<message>
<source>GPS</source>
<translation>GPS</translation>
</message>
<message>
<source>SEARCH</source>
<translation>BÚSQUEDA</translation>
</message>
<message>
<source>--</source>
<translation>--</translation>

@ -763,14 +763,6 @@ Cela peut prendre jusqu&apos;à une minute.</translation>
<source>PANDA</source>
<translation>PANDA</translation>
</message>
<message>
<source>GPS</source>
<translation>GPS</translation>
</message>
<message>
<source>SEARCH</source>
<translation>RECHERCHE</translation>
</message>
<message>
<source>--</source>
<translation>--</translation>

@ -757,14 +757,6 @@ This may take up to a minute.</source>
<source>PANDA</source>
<translation>PANDA</translation>
</message>
<message>
<source>GPS</source>
<translation>GPS</translation>
</message>
<message>
<source>SEARCH</source>
<translation></translation>
</message>
<message>
<source>--</source>
<translation>--</translation>

@ -759,14 +759,6 @@ This may take up to a minute.</source>
<source>PANDA</source>
<translation>PANDA</translation>
</message>
<message>
<source>GPS</source>
<translation>GPS</translation>
</message>
<message>
<source>SEARCH</source>
<translation></translation>
</message>
<message>
<source>--</source>
<translation>--</translation>

@ -763,14 +763,6 @@ Isso pode levar até um minuto.</translation>
<source>PANDA</source>
<translation>PANDA</translation>
</message>
<message>
<source>GPS</source>
<translation>GPS</translation>
</message>
<message>
<source>SEARCH</source>
<translation>PROCURA</translation>
</message>
<message>
<source>--</source>
<translation>--</translation>

@ -759,14 +759,6 @@ This may take up to a minute.</source>
<source>PANDA</source>
<translation>PANDA</translation>
</message>
<message>
<source>GPS</source>
<translation></translation>
</message>
<message>
<source>SEARCH</source>
<translation></translation>
</message>
<message>
<source>--</source>
<translation>--</translation>

@ -757,14 +757,6 @@ This may take up to a minute.</source>
<source>PANDA</source>
<translation>PANDA</translation>
</message>
<message>
<source>GPS</source>
<translation>GPS</translation>
</message>
<message>
<source>SEARCH</source>
<translation>ARA</translation>
</message>
<message>
<source>--</source>
<translation>--</translation>

@ -759,14 +759,6 @@ This may take up to a minute.</source>
<source>PANDA</source>
<translation>PANDA</translation>
</message>
<message>
<source>GPS</source>
<translation>GPS</translation>
</message>
<message>
<source>SEARCH</source>
<translation></translation>
</message>
<message>
<source>--</source>
<translation>--</translation>

@ -759,14 +759,6 @@ This may take up to a minute.</source>
<source>PANDA</source>
<translation></translation>
</message>
<message>
<source>GPS</source>
<translation>GPS</translation>
</message>
<message>
<source>SEARCH</source>
<translation></translation>
</message>
<message>
<source>--</source>
<translation>--</translation>

@ -242,7 +242,7 @@ void UIState::updateStatus() {
UIState::UIState(QObject *parent) : QObject(parent) {
sm = std::make_unique<SubMaster, const std::initializer_list<const char *>>({
"modelV2", "controlsState", "liveCalibration", "radarState", "deviceState",
"pandaStates", "carParams", "driverMonitoringState", "carState", "liveLocationKalman", "driverStateV2",
"pandaStates", "carParams", "driverMonitoringState", "carState", "driverStateV2",
"wideRoadCameraState", "managerState", "clocks",
});

@ -63,7 +63,7 @@ bool ReplayStream::loadRoute(const QString &route, const QString &data_dir, uint
QString message;
if (auth_content.empty()) {
message = "Authentication Required. Please run the following command to authenticate:\n\n"
"python tools/lib/auth.py\n\n"
"python3 tools/lib/auth.py\n\n"
"This will grant access to routes from your comma account.";
} else {
message = tr("Access Denied. You do not have permission to access route:\n\n%1\n\n"

@ -1,10 +1,10 @@
# Camera stream
`compressed_vipc.py` connects to a remote device running openpilot, decodes the video streams, and republishes them over VisionIPC.
`compressed_vipc.py` connects to a remote device running openpilot, decodes the video streams, and republishes them over VisionIPC.
## Usage
### On the device
### On the device
SSH into the device and run following in separate terminals:
`cd /data/openpilot/cereal/messaging && ./bridge`
@ -30,7 +30,7 @@ Alternatively paste this as a single command:
wait
) ; trap 'kill $(jobs -p)' SIGINT
```
Ctrl+C will stop all three processes.
Ctrl+C will stop all three processes.
### On the PC
Decode the stream with `compressed_vipc.py`:
@ -43,7 +43,7 @@ To actually display the stream, run `watch3` in separate terminal:
## compressed_vipc.py usage
```
$ python compressed_vipc.py -h
$ python3 compressed_vipc.py -h
usage: compressed_vipc.py [-h] [--nvidia] [--cams CAMS] [--silent] addr
Decode video streams and broadcast on VisionIPC

@ -21,7 +21,7 @@ Given a route and platform, automatically inserts FW fingerprints from the platf
Example:
```bash
> python tools/car_porting/auto_fingerprint.py '1bbe6bf2d62f58a8|2022-07-14--17-11-43' 'OUTBACK'
> python3 tools/car_porting/auto_fingerprint.py '1bbe6bf2d62f58a8|2022-07-14--17-11-43' 'OUTBACK'
Attempting to add fw version for: OUTBACK
```
@ -45,7 +45,7 @@ Given a route, runs most of the car interface to check for common errors like mi
#### Example: panda safety mismatch for gasPressed
```bash
> python tools/car_porting/test_car_model.py '4822a427b188122a|2023-08-14--16-22-21'
> python3 tools/car_porting/test_car_model.py '4822a427b188122a|2023-08-14--16-22-21'
=====================================================================
FAIL: test_panda_safety_carstate (__main__.CarModelTestCase.test_panda_safety_carstate)
@ -93,4 +93,4 @@ vin: 1FM5K8GC7NGXXXXXX real platform: FORD EXPLORER 6TH GEN determi
vin: 5LM5J7XC8MGXXXXXX real platform: FORD EXPLORER 6TH GEN determined platform: mock correct: False
vin: 3FTTW8E31PRXXXXXX real platform: FORD MAVERICK 1ST GEN determined platform: mock correct: False
vin: 3FTTW8E99NRXXXXXX real platform: FORD MAVERICK 1ST GEN determined platform: mock correct: False
```
```

@ -32,9 +32,8 @@ fi
echo "updating uv..."
update_uv
# TODO: remove --no-cache once this is fixed: https://github.com/astral-sh/uv/issues/4378
echo "installing python packages..."
uv --no-cache sync --frozen --all-extras
uv sync --frozen --all-extras
source .venv/bin/activate
# TODO: remove this. Workaround till get a new release. PEP508 doesn't seem to have find-links option

@ -5,7 +5,7 @@ LatencyLogger is a tool to track the time from first pixel to actuation. Timesta
## Usage
```
$ python latency_logger.py -h
$ python3 latency_logger.py -h
usage: latency_logger.py [-h] [--relative] [--demo] [--plot] [route_or_segment_name]
A tool for analyzing openpilot's end-to-end latency

@ -312,19 +312,22 @@ function op_default() {
echo ""
echo -e "${BOLD}${UNDERLINE}Usage:${NC} op [OPTIONS] <COMMAND>"
echo ""
echo -e "${BOLD}${UNDERLINE}Commands:${NC}"
echo -e " ${BOLD}venv${NC} Activate the python virtual environment"
echo -e "${BOLD}${UNDERLINE}Commands [System]:${NC}"
echo -e " ${BOLD}check${NC} Check the development environment (git, os, python) to start using openpilot"
echo -e " ${BOLD}venv${NC} Activate the python virtual environment"
echo -e " ${BOLD}setup${NC} Install openpilot dependencies"
echo -e " ${BOLD}build${NC} Run the openpilot build system in the current working directory"
echo -e " ${BOLD}sim${NC} Run openpilot in a simulator"
echo -e " ${BOLD}install${NC} Install the 'op' tool system wide"
echo ""
echo -e "${BOLD}${UNDERLINE}Commands [Tooling]:${NC}"
echo -e " ${BOLD}juggle${NC} Run PlotJuggler"
echo -e " ${BOLD}replay${NC} Run Replay"
echo -e " ${BOLD}cabana${NC} Run Cabana"
echo ""
echo -e "${BOLD}${UNDERLINE}Commands [Testing]:${NC}"
echo -e " ${BOLD}sim${NC} Run openpilot in a simulator"
echo -e " ${BOLD}lint${NC} Run the linter"
echo -e " ${BOLD}test${NC} Run all unit tests from pytest"
echo -e " ${BOLD}help${NC} Show this message"
echo -e " ${BOLD}install${NC} Install the 'op' tool system wide"
echo ""
echo -e "${BOLD}${UNDERLINE}Options:${NC}"
echo -e " ${BOLD}-d, --dir${NC}"

@ -6,7 +6,7 @@
```bash
# Log in via browser to have access to routes from your comma account
python tools/lib/auth.py
python3 tools/lib/auth.py
# Start a replay
tools/replay/replay <route-name>
@ -20,7 +20,7 @@ tools/replay/replay --demo
cd selfdrive/ui && ./ui
# or try out radar point visualization in Rerun:
python replay/rp_visualization.py
python3 replay/rp_visualization.py
# NOTE: To visualize radar points, make sure tools/replay/replay is running.
```

@ -12,7 +12,7 @@ if [[ "$CI" ]]; then
export BLOCK="${BLOCK},ui"
fi
python -c "from openpilot.selfdrive.test.helpers import set_params_enabled; set_params_enabled()"
python3 -c "from openpilot.selfdrive.test.helpers import set_params_enabled; set_params_enabled()"
SCRIPT_DIR=$(dirname "$0")
OPENPILOT_DIR=$SCRIPT_DIR/../../

Loading…
Cancel
Save