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

pull/33208/head
Shane Smiskol 1 year ago
commit e0b9e45027
  1. 34
      .github/workflows/repo-maintenance.yaml
  2. 2
      .github/workflows/selfdrive_tests.yaml
  3. 2
      .importlinter
  4. 4
      common/mock/__init__.py
  5. 26
      common/mock/generators.py
  6. 2
      launch_chffrplus.sh
  7. 2
      launch_env.sh
  8. 2
      launch_openpilot.sh
  9. 2
      panda
  10. 2
      pyproject.toml
  11. 2
      release/build_devel.sh
  12. 2
      release/build_release.sh
  13. 2
      release/check-dirty.sh
  14. 2
      release/check-submodules.sh
  15. 2
      scripts/apply-pr.sh
  16. 2
      scripts/build_small.sh
  17. 2
      scripts/cell.sh
  18. 2
      scripts/checkout-pr.sh
  19. 2
      scripts/launch_corolla.sh
  20. 15
      scripts/lint/check_shebang_format.sh
  21. 5
      scripts/lint/lint.sh
  22. 2
      scripts/retry.sh
  23. 2
      selfdrive/assets/compress-images.sh
  24. 2
      selfdrive/assets/strip-svg-metadata.sh
  25. 1
      selfdrive/car/__init__.py
  26. 3
      selfdrive/car/body/carstate.py
  27. 6
      selfdrive/car/body/interface.py
  28. 254
      selfdrive/car/car_specific.py
  29. 13
      selfdrive/car/card.py
  30. 11
      selfdrive/car/chrysler/carstate.py
  31. 24
      selfdrive/car/chrysler/interface.py
  32. 4
      selfdrive/car/disable_ecu.py
  33. 5
      selfdrive/car/ecu_addrs.py
  34. 10
      selfdrive/car/ford/carstate.py
  35. 16
      selfdrive/car/ford/interface.py
  36. 7
      selfdrive/car/fw_versions.py
  37. 25
      selfdrive/car/gm/carstate.py
  38. 47
      selfdrive/car/gm/interface.py
  39. 22
      selfdrive/car/honda/carstate.py
  40. 44
      selfdrive/car/honda/interface.py
  41. 19
      selfdrive/car/hyundai/carstate.py
  42. 1
      selfdrive/car/hyundai/fingerprints.py
  43. 37
      selfdrive/car/hyundai/interface.py
  44. 113
      selfdrive/car/interfaces.py
  45. 13
      selfdrive/car/mazda/carstate.py
  46. 25
      selfdrive/car/mazda/interface.py
  47. 4
      selfdrive/car/mock/carstate.py
  48. 17
      selfdrive/car/mock/interface.py
  49. 12
      selfdrive/car/nissan/carstate.py
  50. 20
      selfdrive/car/nissan/interface.py
  51. 5
      selfdrive/car/subaru/carstate.py
  52. 9
      selfdrive/car/subaru/interface.py
  53. 3
      selfdrive/car/tesla/carstate.py
  54. 7
      selfdrive/car/tesla/interface.py
  55. 4
      selfdrive/car/tests/big_cars_test.sh
  56. 15
      selfdrive/car/tests/test_car_interfaces.py
  57. 14
      selfdrive/car/tests/test_models.py
  58. 13
      selfdrive/car/toyota/carstate.py
  59. 34
      selfdrive/car/toyota/interface.py
  60. 4
      selfdrive/car/vin.py
  61. 22
      selfdrive/car/volkswagen/carstate.py
  62. 1
      selfdrive/car/volkswagen/fingerprints.py
  63. 46
      selfdrive/car/volkswagen/interface.py
  64. 45
      selfdrive/controls/controlsd.py
  65. 2
      selfdrive/controls/lib/latcontrol.py
  66. 2
      selfdrive/controls/lib/latcontrol_angle.py
  67. 2
      selfdrive/controls/lib/latcontrol_pid.py
  68. 7
      selfdrive/controls/lib/latcontrol_torque.py
  69. 9
      selfdrive/controls/lib/tests/test_latcontrol.py
  70. 2
      selfdrive/debug/adb.sh
  71. 2
      selfdrive/debug/cycle_alerts.py
  72. 67
      selfdrive/locationd/helpers.py
  73. 25
      selfdrive/locationd/paramsd.py
  74. 17
      selfdrive/locationd/torqued.py
  75. 2
      selfdrive/modeld/tests/tf_test/build.sh
  76. 10
      selfdrive/test/process_replay/process_replay.py
  77. 2
      selfdrive/test/process_replay/ref_commit
  78. 6
      selfdrive/test/scons_build_test.sh
  79. 4
      selfdrive/test/setup_device_ci.sh
  80. 2
      selfdrive/test/setup_vsound.sh
  81. 2
      selfdrive/ui/installer/continue_openpilot.sh
  82. 2
      selfdrive/ui/tests/create_test_translations.sh
  83. 2
      system/hardware/tici/restart_modem.sh
  84. 2
      system/hardware/tici/tests/test_power_draw.py
  85. 2
      tools/joystick/joystickd.py
  86. 2
      tools/lib/kbhit.py
  87. 34
      tools/op.sh
  88. 2
      tools/profiling/clpeak/build.sh
  89. 2
      tools/profiling/ftrace.sh
  90. 2
      tools/profiling/palanteer/setup.sh
  91. 2
      tools/profiling/perfetto/build.sh
  92. 2
      tools/profiling/perfetto/copy.sh
  93. 2
      tools/profiling/perfetto/record.sh
  94. 2
      tools/profiling/perfetto/server.sh
  95. 2
      tools/profiling/perfetto/traces.sh
  96. 2
      tools/profiling/snapdragon/setup-agnos.sh
  97. 4
      tools/profiling/snapdragon/setup-profiler.sh
  98. 2
      tools/profiling/watch-irqs.sh
  99. 2
      tools/rerun/run.sh
  100. 2
      tools/scripts/save_ubloxraw_stream.py
  101. Some files were not shown because too many files have changed in this diff Show More

@ -6,33 +6,6 @@ on:
workflow_dispatch:
jobs:
bump_submodules:
name: bump_submodules
runs-on: ubuntu-latest
container:
image: ghcr.io/commaai/openpilot-base:latest
if: github.repository == 'commaai/openpilot'
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: bump submodules
run: |
git config --global --add safe.directory '*'
git -c submodule."tinygrad".update=none submodule update --remote
git add .
- name: Create Pull Request
uses: peter-evans/create-pull-request@9153d834b60caba6d51c9b9510b087acf9f33f83
with:
author: Vehicle Researcher <user@comma.ai>
token: ${{ secrets.ACTIONS_CREATE_PR_PAT }}
commit-message: bump submodules
title: '[bot] Bump submodules'
branch: auto-bump-submodules
base: master
delete-branch: true
body: 'Automatic PR from repo-maintenance -> bump_submodules'
labels: bot
package_updates:
name: package_updates
runs-on: ubuntu-latest
@ -41,11 +14,18 @@ jobs:
if: github.repository == 'commaai/openpilot'
steps:
- uses: actions/checkout@v4
with:
submodules: true
- name: uv lock
run: |
python3 -m ensurepip --upgrade
pip3 install uv
uv lock --upgrade
- name: bump submodules
run: |
git config --global --add safe.directory '*'
git -c submodule."tinygrad".update=none submodule update --remote
git add .
- name: Create Pull Request
uses: peter-evans/create-pull-request@9153d834b60caba6d51c9b9510b087acf9f33f83
with:

@ -67,7 +67,7 @@ jobs:
cd $GITHUB_WORKSPACE
cp pyproject.toml $STRIPPED_DIR
cd $STRIPPED_DIR
${{ env.RUN }} "scripts/lint.sh --skip check_added_large_files"
${{ env.RUN }} "scripts/lint/lint.sh --skip check_added_large_files"
build:
strategy:

@ -29,7 +29,6 @@ forbidden_modules =
openpilot.tinygrad
ignore_imports =
# remove these
openpilot.selfdrive.car.interfaces -> openpilot.selfdrive.controls.lib.events
openpilot.selfdrive.car.body.carcontroller -> openpilot.selfdrive.controls.lib.pid
openpilot.selfdrive.car.tests.test_docs -> openpilot.common.basedir
openpilot.selfdrive.car.docs -> openpilot.common.basedir
@ -75,4 +74,5 @@ ignore_imports =
openpilot.selfdrive.car.card -> cereal
openpilot.selfdrive.car.card -> cereal.messaging
openpilot.selfdrive.car.vin -> cereal.messaging
openpilot.selfdrive.car.car_specific -> openpilot.selfdrive.controls.lib.events
unmatched_ignore_imports_alerting = warn

@ -8,12 +8,12 @@ import functools
import threading
from cereal.messaging import PubMaster
from cereal.services import SERVICE_LIST
from openpilot.common.mock.generators import generate_liveLocationKalman
from openpilot.common.mock.generators import generate_livePose
from openpilot.common.realtime import Ratekeeper
MOCK_GENERATOR = {
"liveLocationKalman": generate_liveLocationKalman
"livePose": generate_livePose
}

@ -1,20 +1,14 @@
from cereal import messaging
LOCATION1 = (32.7174, -117.16277)
LOCATION2 = (32.7558, -117.2037)
LLK_DECIMATION = 10
RENDER_FRAMES = 15
DEFAULT_ITERATIONS = RENDER_FRAMES * LLK_DECIMATION
def generate_liveLocationKalman(location=LOCATION1):
msg = messaging.new_message('liveLocationKalman')
msg.liveLocationKalman.positionGeodetic = {'value': [*location, 0], 'std': [0., 0., 0.], 'valid': True}
msg.liveLocationKalman.positionECEF = {'value': [0., 0., 0.], 'std': [0., 0., 0.], 'valid': True}
msg.liveLocationKalman.calibratedOrientationNED = {'value': [0., 0., 0.], 'std': [0., 0., 0.], 'valid': True}
msg.liveLocationKalman.velocityCalibrated = {'value': [0., 0., 0.], 'std': [0., 0., 0.], 'valid': True}
msg.liveLocationKalman.status = 'valid'
msg.liveLocationKalman.gpsOK = True
def generate_livePose():
msg = messaging.new_message('livePose')
meas = {'x': 0.0, 'y': 0.0, 'z': 0.0, 'xStd': 0.0, 'yStd': 0.0, 'zStd': 0.0, 'valid': True}
msg.livePose.orientationNED = meas
msg.livePose.velocityDevice = meas
msg.livePose.angularVelocityDevice = meas
msg.livePose.accelerationDevice = meas
msg.livePose.inputsOK = True
msg.livePose.posenetOK = True
msg.livePose.sensorsOK = True
return msg

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
if [ -z "$BASEDIR" ]; then
BASEDIR="/data/openpilot"

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
export OMP_NUM_THREADS=1
export MKL_NUM_THREADS=1

@ -1,3 +1,3 @@
#!/usr/bin/bash
#!/usr/bin/env bash
exec ./launch_chffrplus.sh

@ -1 +1 @@
Subproject commit 3c1def1cc57f3fb37399a25d0e8088c70985c5ec
Subproject commit 1cbcc13c35429b06e9d36c55b9ab46df73a8b51a

@ -100,7 +100,7 @@ dev = [
"inputs",
"lru-dict",
"matplotlib",
"metadrive-simulator@git+https://github.com/commaai/metadrive@opencv_headless ; platform_machine != 'aarch64'",
"metadrive-simulator@git+https://github.com/commaai/metadrive@main ; platform_machine != 'aarch64'",
"parameterized >=0.8, <0.9",
#"pprofile",
"pyautogui",

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

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
set -e
set -x

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

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
while read hash submodule ref; do
git -C $submodule fetch --depth 3000 origin master

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
if [ $# -eq 0 ]; then
echo "usage: $0 <pull-request-number>"

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

@ -1,3 +1,3 @@
#!/usr/bin/bash
#!/usr/bin/env bash
nmcli connection modify --temporary esim ipv4.route-metric 1 ipv6.route-metric 1
nmcli con up esim

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
if [ $# -eq 0 ]; then

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

@ -0,0 +1,15 @@
#!/usr/bin/env bash
FAIL=0
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
echo -e "Invalid shebang! Must use '#!/usr/bin/env bash'"
FAIL=1
fi
exit $FAIL

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -e
RED='\033[0;31m'
@ -8,7 +8,7 @@ BOLD='\033[1m'
NC='\033[0m'
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
cd $DIR/../
cd $DIR/../../
FAILED=0
@ -51,6 +51,7 @@ function run_tests() {
run "lint-imports" lint-imports
run "check_added_large_files" python3 -m pre_commit_hooks.check_added_large_files --enforce-all $ALL_FILES --maxkb=120
run "check_shebang_scripts_are_executable" python3 -m pre_commit_hooks.check_shebang_scripts_are_executable $ALL_FILES
run "check_shebang_format" $DIR/check_shebang_format.sh $ALL_FILES
if [[ -z "$FAST" ]]; then
run "mypy" mypy $PYTHON_FILES

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
function fail {
echo $1 >&2

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
echo "compressing training guide images"
optipng -o7 -strip all training/*

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# sudo apt install scour

@ -25,7 +25,6 @@ DT_CTRL = 0.01 # car state and control loop timestep (s)
STD_CARGO_KG = 136.
ButtonType = structs.CarState.ButtonEvent.Type
EventName = car.CarEvent.EventName
AngleRateLimit = namedtuple('AngleRateLimit', ['speed_bp', 'angle_v'])

@ -3,10 +3,9 @@ from openpilot.selfdrive.car import structs
from openpilot.selfdrive.car.interfaces import CarStateBase
from openpilot.selfdrive.car.body.values import DBC
STARTUP_TICKS = 100
class CarState(CarStateBase):
def update(self, cp) -> structs.CarState:
def update(self, cp, *_) -> structs.CarState:
ret = structs.CarState()
ret.wheelSpeeds.fl = cp.vl['MOTORS_DATA']['SPEED_L']

@ -4,6 +4,7 @@ from openpilot.selfdrive.car.interfaces import CarInterfaceBase
from openpilot.selfdrive.car.body.carstate import CarState
from openpilot.selfdrive.car.body.values import SPEED_FROM_RPM
class CarInterface(CarInterfaceBase):
CS: CarState
@ -25,8 +26,3 @@ class CarInterface(CarInterfaceBase):
ret.steerControlType = structs.CarParams.SteerControlType.angle
return ret
def _update(self, c) -> structs.CarState:
ret = self.CS.update(self.cp)
return ret

@ -0,0 +1,254 @@
from cereal import car
import cereal.messaging as messaging
from openpilot.selfdrive.car import DT_CTRL
from openpilot.selfdrive.car.interfaces import MAX_CTRL_SPEED
from openpilot.selfdrive.car.volkswagen.values import CarControllerParams as VWCarControllerParams
from openpilot.selfdrive.car.hyundai.interface import ENABLE_BUTTONS as HYUNDAI_ENABLE_BUTTONS
from openpilot.selfdrive.controls.lib.events import Events
ButtonType = car.CarState.ButtonEvent.Type
GearShifter = car.CarState.GearShifter
EventName = car.CarEvent.EventName
NetworkLocation = car.CarParams.NetworkLocation
# TODO: the goal is to abstract this file into the CarState struct and make events generic
class MockCarState:
def __init__(self):
self.sm = messaging.SubMaster(['gpsLocation', 'gpsLocationExternal'])
def update(self, CS: car.CarState):
self.sm.update(0)
gps_sock = 'gpsLocationExternal' if self.sm.recv_frame['gpsLocationExternal'] > 1 else 'gpsLocation'
CS.vEgo = self.sm[gps_sock].speed
CS.vEgoRaw = self.sm[gps_sock].speed
return CS
class CarSpecificEvents:
def __init__(self, CP: car.CarParams):
self.CP = CP
self.steering_unpressed = 0
self.low_speed_alert = False
self.no_steer_warning = False
self.silent_steer_warning = True
def update(self, CS, CS_prev, CC, CC_prev):
if self.CP.carName in ('body', 'mock'):
events = Events()
elif self.CP.carName in ('tesla', 'subaru'):
events = self.create_common_events(CS.out, CS_prev)
elif self.CP.carName == 'ford':
events = self.create_common_events(CS.out, CS_prev, extra_gears=[GearShifter.manumatic])
elif self.CP.carName == 'nissan':
events = self.create_common_events(CS.out, CS_prev, extra_gears=[GearShifter.brake])
if CS.lkas_enabled:
events.add(EventName.invalidLkasSetting)
elif self.CP.carName == 'mazda':
events = self.create_common_events(CS.out, CS_prev)
if CS.lkas_disabled:
events.add(EventName.lkasDisabled)
elif CS.low_speed_alert:
events.add(EventName.belowSteerSpeed)
elif self.CP.carName == 'chrysler':
events = self.create_common_events(CS.out, CS_prev, extra_gears=[GearShifter.low])
# Low speed steer alert hysteresis logic
if self.CP.minSteerSpeed > 0. and CS.out.vEgo < (self.CP.minSteerSpeed + 0.5):
self.low_speed_alert = True
elif CS.out.vEgo > (self.CP.minSteerSpeed + 1.):
self.low_speed_alert = False
if self.low_speed_alert:
events.add(EventName.belowSteerSpeed)
elif self.CP.carName == 'honda':
events = self.create_common_events(CS.out, CS_prev, pcm_enable=False)
if self.CP.pcmCruise and CS.out.vEgo < self.CP.minEnableSpeed:
events.add(EventName.belowEngageSpeed)
if self.CP.pcmCruise:
# we engage when pcm is active (rising edge)
if CS.out.cruiseState.enabled and not CS_prev.cruiseState.enabled:
events.add(EventName.pcmEnable)
elif not CS.out.cruiseState.enabled and (CC_prev.actuators.accel >= 0. or not self.CP.openpilotLongitudinalControl):
# it can happen that car cruise disables while comma system is enabled: need to
# keep braking if needed or if the speed is very low
if CS.out.vEgo < self.CP.minEnableSpeed + 2.:
# non loud alert if cruise disables below 25mph as expected (+ a little margin)
events.add(EventName.speedTooLow)
else:
events.add(EventName.cruiseDisabled)
if self.CP.minEnableSpeed > 0 and CS.out.vEgo < 0.001:
events.add(EventName.manualRestart)
elif self.CP.carName == 'toyota':
events = self.create_common_events(CS.out, CS_prev)
if self.CP.openpilotLongitudinalControl:
if CS.out.cruiseState.standstill and not CS.out.brakePressed:
events.add(EventName.resumeRequired)
if CS.low_speed_lockout:
events.add(EventName.lowSpeedLockout)
if CS.out.vEgo < self.CP.minEnableSpeed:
events.add(EventName.belowEngageSpeed)
if CC_prev.actuators.accel > 0.3:
# some margin on the actuator to not false trigger cancellation while stopping
events.add(EventName.speedTooLow)
if CS.out.vEgo < 0.001:
# while in standstill, send a user alert
events.add(EventName.manualRestart)
elif self.CP.carName == 'gm':
# The ECM allows enabling on falling edge of set, but only rising edge of resume
events = self.create_common_events(CS.out, CS_prev, extra_gears=[GearShifter.sport, GearShifter.low,
GearShifter.eco, GearShifter.manumatic],
pcm_enable=self.CP.pcmCruise, enable_buttons=(ButtonType.decelCruise,))
if not self.CP.pcmCruise:
if any(b.type == ButtonType.accelCruise and b.pressed for b in CS.out.buttonEvents):
events.add(EventName.buttonEnable)
# Enabling at a standstill with brake is allowed
# TODO: verify 17 Volt can enable for the first time at a stop and allow for all GMs
below_min_enable_speed = CS.out.vEgo < self.CP.minEnableSpeed or CS.moving_backward
if below_min_enable_speed and not (CS.out.standstill and CS.out.brake >= 20 and
self.CP.networkLocation == NetworkLocation.fwdCamera):
events.add(EventName.belowEngageSpeed)
if CS.out.cruiseState.standstill:
events.add(EventName.resumeRequired)
if CS.out.vEgo < self.CP.minSteerSpeed:
events.add(EventName.belowSteerSpeed)
elif self.CP.carName == 'volkswagen':
events = self.create_common_events(CS.out, CS_prev, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic],
pcm_enable=not self.CP.openpilotLongitudinalControl,
enable_buttons=(ButtonType.setCruise, ButtonType.resumeCruise))
# Low speed steer alert hysteresis logic
if (self.CP.minSteerSpeed - 1e-3) > VWCarControllerParams.DEFAULT_MIN_STEER_SPEED and CS.out.vEgo < (self.CP.minSteerSpeed + 1.):
self.low_speed_alert = True
elif CS.out.vEgo > (self.CP.minSteerSpeed + 2.):
self.low_speed_alert = False
if self.low_speed_alert:
events.add(EventName.belowSteerSpeed)
if self.CP.openpilotLongitudinalControl:
if CS.out.vEgo < self.CP.minEnableSpeed + 0.5:
events.add(EventName.belowEngageSpeed)
if CC_prev.enabled and CS.out.vEgo < self.CP.minEnableSpeed:
events.add(EventName.speedTooLow)
if CC.eps_timer_soft_disable_alert:
events.add(EventName.steerTimeLimit)
elif self.CP.carName == 'hyundai':
# On some newer model years, the CANCEL button acts as a pause/resume button based on the PCM state
# To avoid re-engaging when openpilot cancels, check user engagement intention via buttons
# Main button also can trigger an engagement on these cars
allow_enable = any(btn in HYUNDAI_ENABLE_BUTTONS for btn in CS.cruise_buttons) or any(CS.main_buttons)
events = self.create_common_events(CS.out, CS_prev, pcm_enable=self.CP.pcmCruise, allow_enable=allow_enable)
# low speed steer alert hysteresis logic (only for cars with steer cut off above 10 m/s)
if CS.out.vEgo < (self.CP.minSteerSpeed + 2.) and self.CP.minSteerSpeed > 10.:
self.low_speed_alert = True
if CS.out.vEgo > (self.CP.minSteerSpeed + 4.):
self.low_speed_alert = False
if self.low_speed_alert:
events.add(EventName.belowSteerSpeed)
else:
raise ValueError(f"Unsupported car: {self.CP.carName}")
return events
def create_common_events(self, CS, CS_prev, extra_gears=None, pcm_enable=True, allow_enable=True,
enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise)):
events = Events()
if CS.doorOpen:
events.add(EventName.doorOpen)
if CS.seatbeltUnlatched:
events.add(EventName.seatbeltNotLatched)
if CS.gearShifter != GearShifter.drive and (extra_gears is None or
CS.gearShifter not in extra_gears):
events.add(EventName.wrongGear)
if CS.gearShifter == GearShifter.reverse:
events.add(EventName.reverseGear)
if not CS.cruiseState.available:
events.add(EventName.wrongCarMode)
if CS.espDisabled:
events.add(EventName.espDisabled)
if CS.espActive:
events.add(EventName.espActive)
if CS.stockFcw:
events.add(EventName.stockFcw)
if CS.stockAeb:
events.add(EventName.stockAeb)
if CS.vEgo > MAX_CTRL_SPEED:
events.add(EventName.speedTooHigh)
if CS.cruiseState.nonAdaptive:
events.add(EventName.wrongCruiseMode)
if CS.brakeHoldActive and self.CP.openpilotLongitudinalControl:
events.add(EventName.brakeHold)
if CS.parkingBrake:
events.add(EventName.parkBrake)
if CS.accFaulted:
events.add(EventName.accFaulted)
if CS.steeringPressed:
events.add(EventName.steerOverride)
if CS.brakePressed and CS.standstill:
events.add(EventName.preEnableStandstill)
if CS.gasPressed:
events.add(EventName.gasPressedOverride)
if CS.vehicleSensorsInvalid:
events.add(EventName.vehicleSensorsInvalid)
# Handle button presses
for b in CS.buttonEvents:
# Enable OP long on falling edge of enable buttons (defaults to accelCruise and decelCruise, overridable per-port)
if not self.CP.pcmCruise and (b.type in enable_buttons and not b.pressed):
events.add(EventName.buttonEnable)
# Disable on rising and falling edge of cancel for both stock and OP long
if b.type == ButtonType.cancel:
events.add(EventName.buttonCancel)
# Handle permanent and temporary steering faults
self.steering_unpressed = 0 if CS.steeringPressed else self.steering_unpressed + 1
if CS.steerFaultTemporary:
if CS.steeringPressed and (not CS_prev.steerFaultTemporary or self.no_steer_warning):
self.no_steer_warning = True
else:
self.no_steer_warning = False
# if the user overrode recently, show a less harsh alert
if self.silent_steer_warning or CS.standstill or self.steering_unpressed < int(1.5 / DT_CTRL):
self.silent_steer_warning = True
events.add(EventName.steerTempUnavailableSilent)
else:
events.add(EventName.steerTempUnavailable)
else:
self.no_steer_warning = False
self.silent_steer_warning = False
if CS.steerFaultPermanent:
events.add(EventName.steerUnavailable)
# we engage when pcm is active (rising edge)
# enabling can optionally be blocked by the car interface
if pcm_enable:
if CS.cruiseState.enabled and not CS_prev.cruiseState.enabled and allow_enable:
events.add(EventName.pcmEnable)
elif not CS.cruiseState.enabled:
events.add(EventName.pcmDisable)
return events

@ -17,6 +17,7 @@ from openpilot.common.swaglog import cloudlog, ForwardingHandler
from openpilot.selfdrive.pandad import can_capnp_to_list, can_list_to_can_capnp
from openpilot.selfdrive.car import DT_CTRL, carlog, structs
from openpilot.selfdrive.car.can_definitions import CanData, CanRecvCallable, CanSendCallable
from openpilot.selfdrive.car.car_specific import CarSpecificEvents, MockCarState
from openpilot.selfdrive.car.fw_versions import ObdCallback
from openpilot.selfdrive.car.car_helpers import get_car
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
@ -172,6 +173,9 @@ class Car:
self.events = Events()
self.car_events = CarSpecificEvents(self.CP)
self.mock_carstate = MockCarState()
# card is driven by can recv, expected at 100Hz
self.rk = Ratekeeper(100, print_delay_threshold=None)
@ -180,7 +184,10 @@ class Car:
# Update carState from CAN
can_strs = messaging.drain_sock_raw(self.can_sock, wait_for_one=True)
CS = convert_to_capnp(self.CI.update(self.CC_prev, can_capnp_to_list(can_strs)))
CS = convert_to_capnp(self.CI.update(can_capnp_to_list(can_strs)))
if self.CP.carName == 'mock':
CS = self.mock_carstate.update(CS)
self.sm.update(0)
@ -198,7 +205,9 @@ class Car:
def update_events(self, CS: car.CarState) -> car.CarState: # TODO: this is wrong
self.events.clear()
# self.events.add_from_msg(CS.events)
CS.events = self.car_events.update(self.CI.CS, self.CS_prev, self.CI.CC, self.CC_prev).to_msg()
self.events.add_from_msg(CS.events)
if self.CP.notCar:
# wait for everything to init first

@ -1,10 +1,12 @@
from opendbc.can.parser import CANParser
from opendbc.can.can_define import CANDefine
from openpilot.selfdrive.car import structs
from openpilot.selfdrive.car import create_button_events, structs
from openpilot.selfdrive.car.chrysler.values import DBC, STEER_THRESHOLD, RAM_CARS
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.interfaces import CarStateBase
ButtonType = structs.CarState.ButtonEvent.Type
class CarState(CarStateBase):
def __init__(self, CP):
@ -21,14 +23,13 @@ class CarState(CarStateBase):
else:
self.shifter_values = can_define.dv["GEAR"]["PRNDL"]
self.prev_distance_button = 0
self.distance_button = 0
def update(self, cp, cp_cam) -> structs.CarState:
def update(self, cp, cp_cam, *_) -> structs.CarState:
ret = structs.CarState()
self.prev_distance_button = self.distance_button
prev_distance_button = self.distance_button
self.distance_button = cp.vl["CRUISE_BUTTONS"]["ACC_Distance_Dec"]
# lock info
@ -101,6 +102,8 @@ class CarState(CarStateBase):
self.lkas_car_model = cp_cam.vl["DAS_6"]["CAR_MODEL"]
self.button_counter = cp.vl["CRUISE_BUTTONS"]["COUNTER"]
ret.buttonEvents = create_button_events(self.distance_button, prev_distance_button, {1: ButtonType.gapAdjustCruise})
return ret
@staticmethod

@ -1,13 +1,11 @@
#!/usr/bin/env python3
from cereal import car
from panda import Panda
from openpilot.selfdrive.car import create_button_events, get_safety_config, structs
from openpilot.selfdrive.car import get_safety_config, structs
from openpilot.selfdrive.car.chrysler.carstate import CarState
from openpilot.selfdrive.car.chrysler.values import CAR, RAM_HD, RAM_DT, RAM_CARS, ChryslerFlags
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
ButtonType = structs.CarState.ButtonEvent.Type
class CarInterface(CarInterfaceBase):
CS: CarState
@ -78,23 +76,3 @@ class CarInterface(CarInterfaceBase):
ret.enableBsm = 720 in fingerprint[0]
return ret
def _update(self, c) -> structs.CarState:
ret = self.CS.update(self.cp, self.cp_cam)
ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise})
# events
events = self.create_common_events(ret, extra_gears=[structs.CarState.GearShifter.low])
# Low speed steer alert hysteresis logic
if self.CP.minSteerSpeed > 0. and ret.vEgo < (self.CP.minSteerSpeed + 0.5):
self.low_speed_alert = True
elif ret.vEgo > (self.CP.minSteerSpeed + 1.):
self.low_speed_alert = False
if self.low_speed_alert:
events.add(car.CarEvent.EventName.belowSteerSpeed)
# ret.events = events.to_msg()
return ret

@ -40,10 +40,12 @@ def disable_ecu(can_recv, can_send, bus=0, addr=0x7d0, sub_addr=None, com_cont_r
if __name__ == "__main__":
import time
import cereal.messaging as messaging
from openpilot.selfdrive.car.card import can_comm_callbacks
sendcan = messaging.pub_sock('sendcan')
logcan = messaging.sub_sock('can')
can_callbacks = can_comm_callbacks(logcan, sendcan)
time.sleep(1)
# honda bosch radar disable
disabled = disable_ecu(logcan, sendcan, bus=1, addr=0x18DAB0F1, com_cont_req=b'\x28\x83\x03', timeout=0.5, debug=False)
disabled = disable_ecu(*can_callbacks, bus=1, addr=0x18DAB0F1, com_cont_req=b'\x28\x83\x03', timeout=0.5, debug=False)
print(f"disabled: {disabled}")

@ -61,7 +61,7 @@ if __name__ == "__main__":
import argparse
import cereal.messaging as messaging
from openpilot.common.params import Params
from openpilot.selfdrive.car.card import obd_callback
from openpilot.selfdrive.car.card import can_comm_callbacks, obd_callback
parser = argparse.ArgumentParser(description='Get addresses of all ECUs')
parser.add_argument('--debug', action='store_true')
@ -72,6 +72,7 @@ if __name__ == "__main__":
logcan = messaging.sub_sock('can')
sendcan = messaging.pub_sock('sendcan')
can_callbacks = can_comm_callbacks(logcan, sendcan)
# Set up params for pandad
params = Params()
@ -83,7 +84,7 @@ if __name__ == "__main__":
obd_callback(params)(not args.no_obd)
print("Getting ECU addresses ...")
ecu_addrs = _get_all_ecu_addrs(logcan, sendcan, args.bus, args.timeout, debug=args.debug)
ecu_addrs = _get_all_ecu_addrs(*can_callbacks, args.bus, args.timeout, debug=args.debug)
print()
print("Found ECUs on rx addresses:")

@ -1,11 +1,12 @@
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car import structs
from openpilot.selfdrive.car import create_button_events, structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.ford.fordcan import CanBus
from openpilot.selfdrive.car.ford.values import DBC, CarControllerParams, FordFlags
from openpilot.selfdrive.car.interfaces import CarStateBase
ButtonType = structs.CarState.ButtonEvent.Type
GearShifter = structs.CarState.GearShifter
TransmissionType = structs.CarParams.TransmissionType
@ -17,10 +18,9 @@ class CarState(CarStateBase):
if CP.transmissionType == TransmissionType.automatic:
self.shifter_values = can_define.dv["PowertrainData_10"]["TrnRng_D_Rq"]
self.prev_distance_button = 0
self.distance_button = 0
def update(self, cp, cp_cam) -> structs.CarState:
def update(self, cp, cp_cam, *_) -> structs.CarState:
ret = structs.CarState()
# Occasionally on startup, the ABS module recalibrates the steering pinion offset, so we need to block engagement
@ -85,7 +85,7 @@ class CarState(CarStateBase):
ret.rightBlinker = cp.vl["Steering_Data_FD1"]["TurnLghtSwtch_D_Stat"] == 2
# TODO: block this going to the camera otherwise it will enable stock TJA
ret.genericToggle = bool(cp.vl["Steering_Data_FD1"]["TjaButtnOnOffPress"])
self.prev_distance_button = self.distance_button
prev_distance_button = self.distance_button
self.distance_button = cp.vl["Steering_Data_FD1"]["AccButtnGapTogglePress"]
# lock info
@ -105,6 +105,8 @@ class CarState(CarStateBase):
self.acc_tja_status_stock_values = cp_cam.vl["ACCDATA_3"]
self.lkas_status_stock_values = cp_cam.vl["IPMA_Data"]
ret.buttonEvents = create_button_events(self.distance_button, prev_distance_button, {1: ButtonType.gapAdjustCruise})
return ret
@staticmethod

@ -1,15 +1,12 @@
from cereal import car
from panda import Panda
from openpilot.selfdrive.car import create_button_events, get_safety_config, structs
from openpilot.selfdrive.car import get_safety_config, structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.ford.carstate import CarState
from openpilot.selfdrive.car.ford.fordcan import CanBus
from openpilot.selfdrive.car.ford.values import Ecu, FordFlags
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
ButtonType = structs.CarState.ButtonEvent.Type
TransmissionType = structs.CarParams.TransmissionType
GearShifter = structs.CarState.GearShifter
class CarInterface(CarInterfaceBase):
@ -69,14 +66,3 @@ class CarInterface(CarInterfaceBase):
ret.autoResumeSng = ret.minEnableSpeed == -1.
ret.centerToFront = ret.wheelbase * 0.44
return ret
def _update(self, c) -> structs.CarState:
ret = self.CS.update(self.cp, self.cp_cam)
ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise})
events = self.create_common_events(ret, extra_gears=[GearShifter.manumatic])
# ret.events = events.to_msg()
return ret

@ -334,7 +334,7 @@ if __name__ == "__main__":
import cereal.messaging as messaging
from openpilot.common.params import Params
from openpilot.selfdrive.car.vin import get_vin
from openpilot.selfdrive.car.card import obd_callback
from openpilot.selfdrive.car.card import can_comm_callbacks, obd_callback
parser = argparse.ArgumentParser(description='Get firmware version of ECUs')
parser.add_argument('--scan', action='store_true')
@ -345,6 +345,7 @@ if __name__ == "__main__":
logcan = messaging.sub_sock('can')
pandaStates_sock = messaging.sub_sock('pandaStates')
sendcan = messaging.pub_sock('sendcan')
can_callbacks = can_comm_callbacks(logcan, sendcan)
# Set up params for pandad
params = Params()
@ -369,13 +370,13 @@ if __name__ == "__main__":
t = time.time()
print("Getting vin...")
set_obd_multiplexing(True)
vin_rx_addr, vin_rx_bus, vin = get_vin(logcan, sendcan, (0, 1), debug=args.debug)
vin_rx_addr, vin_rx_bus, vin = get_vin(*can_callbacks, (0, 1), debug=args.debug)
print(f'RX: {hex(vin_rx_addr)}, BUS: {vin_rx_bus}, VIN: {vin}')
print(f"Getting VIN took {time.time() - t:.3f} s")
print()
t = time.time()
fw_vers = get_fw_versions(logcan, sendcan, set_obd_multiplexing, query_brand=args.brand, extra=extra, num_pandas=num_pandas, debug=args.debug, progress=True)
fw_vers = get_fw_versions(*can_callbacks, set_obd_multiplexing, query_brand=args.brand, extra=extra, num_pandas=num_pandas, debug=args.debug, progress=True)
_, candidates = match_fw_to_car(fw_vers, vin)
print()

@ -1,16 +1,21 @@
import copy
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car import structs
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.interfaces import CarStateBase
from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, STEER_THRESHOLD
from openpilot.selfdrive.car.gm.values import DBC, AccState, CanBus, CruiseButtons, STEER_THRESHOLD
ButtonType = structs.CarState.ButtonEvent.Type
TransmissionType = structs.CarParams.TransmissionType
NetworkLocation = structs.CarParams.NetworkLocation
STANDSTILL_THRESHOLD = 10 * 0.0311 * CV.KPH_TO_MS
BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.DECEL_SET: ButtonType.decelCruise,
CruiseButtons.MAIN: ButtonType.altButton3, CruiseButtons.CANCEL: ButtonType.cancel}
class CarState(CarStateBase):
def __init__(self, CP):
@ -26,14 +31,13 @@ class CarState(CarStateBase):
self.cam_lka_steering_cmd_counter = 0
self.buttons_counter = 0
self.prev_distance_button = 0
self.distance_button = 0
def update(self, pt_cp, cam_cp, loopback_cp) -> structs.CarState:
def update(self, pt_cp, cam_cp, _, __, loopback_cp) -> structs.CarState:
ret = structs.CarState()
self.prev_cruise_buttons = self.cruise_buttons
self.prev_distance_button = self.distance_button
prev_cruise_buttons = self.cruise_buttons
prev_distance_button = self.distance_button
self.cruise_buttons = pt_cp.vl["ASCMSteeringButton"]["ACCButtons"]
self.distance_button = pt_cp.vl["ASCMSteeringButton"]["DistanceButton"]
self.buttons_counter = pt_cp.vl["ASCMSteeringButton"]["RollingCounter"]
@ -124,6 +128,15 @@ class CarState(CarStateBase):
ret.leftBlindspot = pt_cp.vl["BCMBlindSpotMonitor"]["LeftBSM"] == 1
ret.rightBlindspot = pt_cp.vl["BCMBlindSpotMonitor"]["RightBSM"] == 1
# Don't add event if transitioning from INIT, unless it's to an actual button
if self.cruise_buttons != CruiseButtons.UNPRESS or prev_cruise_buttons != CruiseButtons.INIT:
ret.buttonEvents = [
*create_button_events(self.cruise_buttons, prev_cruise_buttons, BUTTONS_DICT,
unpressed_btn=CruiseButtons.UNPRESS),
*create_button_events(self.distance_button, prev_distance_button,
{1: ButtonType.gapAdjustCruise})
]
return ret
@staticmethod

@ -1,26 +1,19 @@
#!/usr/bin/env python3
import os
from typing import cast
from cereal import car
from math import fabs, exp
from panda import Panda
from openpilot.common.basedir import BASEDIR
from openpilot.selfdrive.car import create_button_events, get_safety_config, get_friction, structs
from openpilot.selfdrive.car import get_safety_config, get_friction, structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.gm.carstate import CarState
from openpilot.selfdrive.car.gm.radar_interface import RADAR_HEADER_MSG
from openpilot.selfdrive.car.gm.values import CAR, CruiseButtons, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus
from openpilot.selfdrive.car.gm.values import CAR, CarControllerParams, EV_CAR, CAMERA_ACC_CAR, CanBus
from openpilot.selfdrive.car.interfaces import CarInterfaceBase, TorqueFromLateralAccelCallbackType, FRICTION_THRESHOLD, LatControlInputs, NanoFFModel
ButtonType = structs.CarState.ButtonEvent.Type
EventName = car.CarEvent.EventName
GearShifter = structs.CarState.GearShifter
TransmissionType = structs.CarParams.TransmissionType
NetworkLocation = structs.CarParams.NetworkLocation
BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.DECEL_SET: ButtonType.decelCruise,
CruiseButtons.MAIN: ButtonType.altButton3, CruiseButtons.CANCEL: ButtonType.cancel}
NON_LINEAR_TORQUE_PARAMS = {
CAR.CHEVROLET_BOLT_EUV: [2.6531724862969748, 1.0, 0.1919764879840985, 0.009054123646805178],
@ -203,39 +196,3 @@ class CarInterface(CarInterfaceBase):
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
return ret
# returns a car.CarState
def _update(self, c) -> structs.CarState:
ret = self.CS.update(self.cp, self.cp_cam, self.cp_loopback)
# Don't add event if transitioning from INIT, unless it's to an actual button
if self.CS.cruise_buttons != CruiseButtons.UNPRESS or self.CS.prev_cruise_buttons != CruiseButtons.INIT:
ret.buttonEvents = [
*create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT,
unpressed_btn=CruiseButtons.UNPRESS),
*create_button_events(self.CS.distance_button, self.CS.prev_distance_button,
{1: ButtonType.gapAdjustCruise})
]
# The ECM allows enabling on falling edge of set, but only rising edge of resume
events = self.create_common_events(ret, extra_gears=[GearShifter.sport, GearShifter.low,
GearShifter.eco, GearShifter.manumatic],
pcm_enable=self.CP.pcmCruise, enable_buttons=(ButtonType.decelCruise,))
if not self.CP.pcmCruise:
if any(b.type == ButtonType.accelCruise and b.pressed for b in ret.buttonEvents):
events.add(EventName.buttonEnable)
# Enabling at a standstill with brake is allowed
# TODO: verify 17 Volt can enable for the first time at a stop and allow for all GMs
below_min_enable_speed = ret.vEgo < self.CP.minEnableSpeed or self.CS.moving_backward
if below_min_enable_speed and not (ret.standstill and ret.brake >= 20 and
self.CP.networkLocation == NetworkLocation.fwdCamera):
events.add(EventName.belowEngageSpeed)
if ret.cruiseState.standstill:
events.add(EventName.resumeRequired)
if ret.vEgo < self.CP.minSteerSpeed:
events.add(EventName.belowSteerSpeed)
# ret.events = events.to_msg()
return ret

@ -3,16 +3,21 @@ from typing import cast
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car import structs
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.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, \
HondaFlags
HondaFlags, CruiseButtons, CruiseSettings
from openpilot.selfdrive.car.interfaces import CarStateBase
TransmissionType = structs.CarParams.TransmissionType
ButtonType = structs.CarState.ButtonEvent.Type
BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.DECEL_SET: ButtonType.decelCruise,
CruiseButtons.MAIN: ButtonType.altButton3, CruiseButtons.CANCEL: ButtonType.cancel}
SETTINGS_BUTTONS_DICT = {CruiseSettings.DISTANCE: ButtonType.gapAdjustCruise, CruiseSettings.LKAS: ButtonType.altButton1}
def get_can_messages(CP, gearbox_msg):
@ -105,16 +110,16 @@ class CarState(CarStateBase):
# However, on cars without a digital speedometer this is not always present (HRV, FIT, CRV 2016, ILX and RDX)
self.dash_speed_seen = False
def update(self, cp, cp_cam, cp_body) -> structs.CarState:
ret = structs.CarState()
def update(self, cp, cp_cam, _, cp_body, __) -> structs.CarState:
ret = structs.CarState.new_message()
# car params
v_weight_v = [0., 1.] # don't trust smooth speed at low values to avoid premature zero snapping
v_weight_bp = [1., 6.] # smooth blending, below ~0.6m/s the smooth speed snaps to zero
# update prevs, update must run once per loop
self.prev_cruise_buttons = self.cruise_buttons
self.prev_cruise_setting = self.cruise_setting
prev_cruise_buttons = self.cruise_buttons
prev_cruise_setting = self.cruise_setting
self.cruise_setting = cp.vl["SCM_BUTTONS"]["CRUISE_SETTING"]
self.cruise_buttons = cp.vl["SCM_BUTTONS"]["CRUISE_BUTTONS"]
@ -259,6 +264,11 @@ class CarState(CarStateBase):
ret.leftBlindspot = cp_body.vl["BSM_STATUS_LEFT"]["BSM_ALERT"] == 1
ret.rightBlindspot = cp_body.vl["BSM_STATUS_RIGHT"]["BSM_ALERT"] == 1
ret.buttonEvents = [
*create_button_events(self.cruise_buttons, prev_cruise_buttons, BUTTONS_DICT),
*create_button_events(self.cruise_setting, prev_cruise_setting, SETTINGS_BUTTONS_DICT),
]
return ret
def get_can_parser(self, CP):

@ -1,23 +1,16 @@
#!/usr/bin/env python3
from cereal import car
from panda import Panda
from openpilot.selfdrive.car import create_button_events, get_safety_config, structs
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.honda.carstate import CarState
from openpilot.selfdrive.car.honda.hondacan import CanBus
from openpilot.selfdrive.car.honda.values import CarControllerParams, CruiseButtons, CruiseSettings, HondaFlags, CAR, HONDA_BOSCH, \
from openpilot.selfdrive.car.honda.values import CarControllerParams, HondaFlags, CAR, HONDA_BOSCH, \
HONDA_NIDEC_ALT_SCM_MESSAGES, HONDA_BOSCH_RADARLESS
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
from openpilot.selfdrive.car.disable_ecu import disable_ecu
ButtonType = structs.CarState.ButtonEvent.Type
EventName = car.CarEvent.EventName
TransmissionType = structs.CarParams.TransmissionType
BUTTONS_DICT = {CruiseButtons.RES_ACCEL: ButtonType.accelCruise, CruiseButtons.DECEL_SET: ButtonType.decelCruise,
CruiseButtons.MAIN: ButtonType.altButton3, CruiseButtons.CANCEL: ButtonType.cancel}
SETTINGS_BUTTONS_DICT = {CruiseSettings.DISTANCE: ButtonType.gapAdjustCruise, CruiseSettings.LKAS: ButtonType.altButton1}
class CarInterface(CarInterfaceBase):
@ -223,36 +216,3 @@ class CarInterface(CarInterfaceBase):
def init(CP, can_recv, can_send):
if CP.carFingerprint in (HONDA_BOSCH - HONDA_BOSCH_RADARLESS) and CP.openpilotLongitudinalControl:
disable_ecu(can_recv, can_send, bus=1, addr=0x18DAB0F1, com_cont_req=b'\x28\x83\x03')
# returns a car.CarState
def _update(self, c) -> structs.CarState:
ret = self.CS.update(self.cp, self.cp_cam, self.cp_body)
ret.buttonEvents = [
*create_button_events(self.CS.cruise_buttons, self.CS.prev_cruise_buttons, BUTTONS_DICT),
*create_button_events(self.CS.cruise_setting, self.CS.prev_cruise_setting, SETTINGS_BUTTONS_DICT),
]
# events
events = self.create_common_events(ret, pcm_enable=False)
if self.CP.pcmCruise and ret.vEgo < self.CP.minEnableSpeed:
events.add(EventName.belowEngageSpeed)
if self.CP.pcmCruise:
# we engage when pcm is active (rising edge)
if ret.cruiseState.enabled and not self.CS.out.cruiseState.enabled:
events.add(EventName.pcmEnable)
elif not ret.cruiseState.enabled and (c.actuators.accel >= 0. or not self.CP.openpilotLongitudinalControl):
# it can happen that car cruise disables while comma system is enabled: need to
# keep braking if needed or if the speed is very low
if ret.vEgo < self.CP.minEnableSpeed + 2.:
# non loud alert if cruise disables below 25mph as expected (+ a little margin)
events.add(EventName.speedTooLow)
else:
events.add(EventName.cruiseDisabled)
if self.CS.CP.minEnableSpeed > 0 and ret.vEgo < 0.001:
events.add(EventName.manualRestart)
# ret.events = events.to_msg()
return ret

@ -4,17 +4,22 @@ import math
from opendbc.can.parser import CANParser
from opendbc.can.can_define import CANDefine
from openpilot.selfdrive.car import structs
from openpilot.selfdrive.car import create_button_events, structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.hyundai.hyundaicanfd import CanBus
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, CAR, DBC, CAN_GEARS, CAMERA_SCC_CAR, \
CANFD_CAR, Buttons, CarControllerParams
from openpilot.selfdrive.car.interfaces import CarStateBase
ButtonType = car.CarState.ButtonEvent.Type
PREV_BUTTON_SAMPLES = 8
CLUSTER_SAMPLE_RATE = 20 # frames
STANDSTILL_THRESHOLD = 12 * 0.03125 * CV.KPH_TO_MS
BUTTONS_DICT = {Buttons.RES_ACCEL: ButtonType.accelCruise, Buttons.SET_DECEL: ButtonType.decelCruise,
Buttons.GAP_DIST: ButtonType.gapAdjustCruise, Buttons.CANCEL: ButtonType.cancel}
class CarState(CarStateBase):
def __init__(self, CP):
@ -52,7 +57,7 @@ class CarState(CarStateBase):
self.params = CarControllerParams(CP)
def update(self, cp, cp_cam) -> structs.CarState:
def update(self, cp, cp_cam, *_) -> structs.CarState:
if self.CP.carFingerprint in CANFD_CAR:
return self.update_canfd(cp, cp_cam)
@ -162,10 +167,13 @@ class CarState(CarStateBase):
self.lkas11 = copy.copy(cp_cam.vl["LKAS11"])
self.clu11 = copy.copy(cp.vl["CLU11"])
self.steer_state = cp.vl["MDPS12"]["CF_Mdps_ToiActive"] # 0 NOT ACTIVE, 1 ACTIVE
self.prev_cruise_buttons = self.cruise_buttons[-1]
prev_cruise_buttons = self.cruise_buttons[-1]
self.cruise_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwState"])
self.main_buttons.extend(cp.vl_all["CLU11"]["CF_Clu_CruiseSwMain"])
if self.CP.openpilotLongitudinalControl:
ret.buttonEvents = create_button_events(self.cruise_buttons[-1], prev_cruise_buttons, BUTTONS_DICT)
return ret
def update_canfd(self, cp, cp_cam) -> structs.CarState:
@ -238,7 +246,7 @@ class CarState(CarStateBase):
if self.CP.flags & HyundaiFlags.EV:
ret.cruiseState.nonAdaptive = cp.vl["MANUAL_SPEED_LIMIT_ASSIST"]["MSLA_ENABLED"] == 1
self.prev_cruise_buttons = self.cruise_buttons[-1]
prev_cruise_buttons = self.cruise_buttons[-1]
self.cruise_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["CRUISE_BUTTONS"])
self.main_buttons.extend(cp.vl_all[self.cruise_btns_msg_canfd]["ADAPTIVE_CRUISE_MAIN_BTN"])
self.buttons_counter = cp.vl[self.cruise_btns_msg_canfd]["COUNTER"]
@ -248,6 +256,9 @@ class CarState(CarStateBase):
self.hda2_lfa_block_msg = copy.copy(cp_cam.vl["CAM_0x362"] if self.CP.flags & HyundaiFlags.CANFD_HDA2_ALT_STEERING
else cp_cam.vl["CAM_0x2a4"])
if self.CP.openpilotLongitudinalControl:
ret.buttonEvents = create_button_events(self.cruise_buttons[-1], prev_cruise_buttons, BUTTONS_DICT)
return ret
def get_can_parser(self, CP):

@ -944,6 +944,7 @@ FW_VERSIONS = {
b'\xf1\x00CV1 MFC AT EUR LHD 1.00 1.05 99210-CV000 211027',
b'\xf1\x00CV1 MFC AT EUR LHD 1.00 1.06 99210-CV000 220328',
b'\xf1\x00CV1 MFC AT EUR RHD 1.00 1.00 99210-CV100 220630',
b'\xf1\x00CV1 MFC AT KOR LHD 1.00 1.00 99210-CV100 220630',
b'\xf1\x00CV1 MFC AT KOR LHD 1.00 1.04 99210-CV000 210823',
b'\xf1\x00CV1 MFC AT KOR LHD 1.00 1.05 99210-CV000 211027',
b'\xf1\x00CV1 MFC AT KOR LHD 1.00 1.06 99210-CV000 220328',

@ -1,21 +1,18 @@
from cereal import car
from panda import Panda
from openpilot.selfdrive.car import create_button_events, get_safety_config, structs
from openpilot.selfdrive.car import get_safety_config, structs
from openpilot.selfdrive.car.hyundai.carstate import CarState
from openpilot.selfdrive.car.hyundai.hyundaicanfd import CanBus
from openpilot.selfdrive.car.hyundai.values import HyundaiFlags, CAR, DBC, CANFD_CAR, CAMERA_SCC_CAR, CANFD_RADAR_SCC_CAR, \
CANFD_UNSUPPORTED_LONGITUDINAL_CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, \
UNSUPPORTED_LONGITUDINAL_CAR, Buttons
CANFD_UNSUPPORTED_LONGITUDINAL_CAR, EV_CAR, HYBRID_CAR, LEGACY_SAFETY_MODE_CAR, \
UNSUPPORTED_LONGITUDINAL_CAR, Buttons
from openpilot.selfdrive.car.hyundai.radar_interface import RADAR_START_ADDR
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
from openpilot.selfdrive.car.disable_ecu import disable_ecu
Ecu = structs.CarParams.Ecu
ButtonType = structs.CarState.ButtonEvent.Type
EventName = car.CarEvent.EventName
ENABLE_BUTTONS = (Buttons.RES_ACCEL, Buttons.SET_DECEL, Buttons.CANCEL)
BUTTONS_DICT = {Buttons.RES_ACCEL: ButtonType.accelCruise, Buttons.SET_DECEL: ButtonType.decelCruise,
Buttons.GAP_DIST: ButtonType.gapAdjustCruise, Buttons.CANCEL: ButtonType.cancel}
class CarInterface(CarInterfaceBase):
@ -152,27 +149,3 @@ class CarInterface(CarInterfaceBase):
# for blinkers
if CP.flags & HyundaiFlags.ENABLE_BLINKERS:
disable_ecu(can_recv, can_send, bus=CanBus(CP).ECAN, addr=0x7B1, com_cont_req=b'\x28\x83\x01')
def _update(self, c) -> structs.CarState:
ret = self.CS.update(self.cp, self.cp_cam)
if self.CS.CP.openpilotLongitudinalControl:
ret.buttonEvents = create_button_events(self.CS.cruise_buttons[-1], self.CS.prev_cruise_buttons, BUTTONS_DICT)
# On some newer model years, the CANCEL button acts as a pause/resume button based on the PCM state
# To avoid re-engaging when openpilot cancels, check user engagement intention via buttons
# Main button also can trigger an engagement on these cars
allow_enable = any(btn in ENABLE_BUTTONS for btn in self.CS.cruise_buttons) or any(self.CS.main_buttons)
events = self.create_common_events(ret, pcm_enable=self.CS.CP.pcmCruise, allow_enable=allow_enable)
# low speed steer alert hysteresis logic (only for cars with steer cut off above 10 m/s)
if ret.vEgo < (self.CP.minSteerSpeed + 2.) and self.CP.minSteerSpeed > 10.:
self.low_speed_alert = True
if ret.vEgo > (self.CP.minSteerSpeed + 4.):
self.low_speed_alert = False
if self.low_speed_alert:
events.add(car.CarEvent.EventName.belowSteerSpeed)
# ret.events = events.to_msg()
return ret

@ -18,11 +18,8 @@ from openpilot.selfdrive.car.can_definitions import CanData, CanRecvCallable, Ca
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.helpers import clip
from openpilot.selfdrive.car.values import PLATFORMS
from openpilot.selfdrive.controls.lib.events import Events
ButtonType = structs.CarState.ButtonEvent.Type
GearShifter = structs.CarState.GearShifter
EventName = car.CarEvent.EventName
V_CRUISE_MAX = 145
MAX_CTRL_SPEED = (V_CRUISE_MAX + 4) * CV.KPH_TO_MS
@ -93,10 +90,6 @@ class CarInterfaceBase(ABC):
self.CP = CP
self.frame = 0
self.steering_unpressed = 0
self.low_speed_alert = False
self.no_steer_warning = False
self.silent_steer_warning = True
self.v_ego_cluster_seen = False
self.CS: CarStateBase = CarState(CP)
@ -105,7 +98,7 @@ class CarInterfaceBase(ABC):
self.cp_adas = self.CS.get_adas_can_parser(CP)
self.cp_body = self.CS.get_body_can_parser(CP)
self.cp_loopback = self.CS.get_loopback_can_parser(CP)
self.can_parsers = [self.cp, self.cp_cam, self.cp_adas, self.cp_body, self.cp_loopback]
self.can_parsers = (self.cp, self.cp_cam, self.cp_adas, self.cp_body, self.cp_loopback)
dbc_name = "" if self.cp is None else self.cp.dbc_name
self.CC: CarControllerBase = CarController(dbc_name, CP)
@ -227,18 +220,17 @@ class CarInterfaceBase(ABC):
tune.torque.latAccelOffset = 0.0
tune.torque.steeringAngleDeadzoneDeg = steering_angle_deadzone_deg
@abstractmethod
def _update(self, c: structs.CarControl) -> structs.CarState:
pass
def _update(self) -> structs.CarState:
return self.CS.update(*self.can_parsers)
def update(self, c: structs.CarControl, can_packets: list[tuple[int, list[CanData]]]) -> structs.CarState:
def update(self, can_packets: list[tuple[int, list[CanData]]]) -> car.CarState:
# parse can
for cp in self.can_parsers:
if cp is not None:
cp.update_strings(can_packets)
# get CarState
ret = self._update(c)
ret = self._update()
ret.canValid = all(cp.can_valid for cp in self.can_parsers if cp is not None)
ret.canTimeout = any(cp.bus_timeout for cp in self.can_parsers if cp is not None)
@ -249,103 +241,20 @@ class CarInterfaceBase(ABC):
self.v_ego_cluster_seen = True
# Many cars apply hysteresis to the ego dash speed
if self.CS is not None:
ret.vEgoCluster = apply_hysteresis(ret.vEgoCluster, self.CS.out.vEgoCluster, self.CS.cluster_speed_hyst_gap)
if abs(ret.vEgo) < self.CS.cluster_min_speed:
ret.vEgoCluster = 0.0
ret.vEgoCluster = apply_hysteresis(ret.vEgoCluster, self.CS.out.vEgoCluster, self.CS.cluster_speed_hyst_gap)
if abs(ret.vEgo) < self.CS.cluster_min_speed:
ret.vEgoCluster = 0.0
if ret.cruiseState.speedCluster == 0:
ret.cruiseState.speedCluster = ret.cruiseState.speed
# copy back for next iteration
if self.CS is not None:
self.CS.out = copy.deepcopy(ret)
# TODO: do we need to deepcopy?
self.CS.out = copy.deepcopy(ret)
return ret
def create_common_events(self, cs_out, extra_gears=None, pcm_enable=True, allow_enable=True,
enable_buttons=(ButtonType.accelCruise, ButtonType.decelCruise)):
events = Events()
if cs_out.doorOpen:
events.add(EventName.doorOpen)
if cs_out.seatbeltUnlatched:
events.add(EventName.seatbeltNotLatched)
if cs_out.gearShifter != GearShifter.drive and (extra_gears is None or
cs_out.gearShifter not in extra_gears):
events.add(EventName.wrongGear)
if cs_out.gearShifter == GearShifter.reverse:
events.add(EventName.reverseGear)
if not cs_out.cruiseState.available:
events.add(EventName.wrongCarMode)
if cs_out.espDisabled:
events.add(EventName.espDisabled)
if cs_out.espActive:
events.add(EventName.espActive)
if cs_out.stockFcw:
events.add(EventName.stockFcw)
if cs_out.stockAeb:
events.add(EventName.stockAeb)
if cs_out.vEgo > MAX_CTRL_SPEED:
events.add(EventName.speedTooHigh)
if cs_out.cruiseState.nonAdaptive:
events.add(EventName.wrongCruiseMode)
if cs_out.brakeHoldActive and self.CP.openpilotLongitudinalControl:
events.add(EventName.brakeHold)
if cs_out.parkingBrake:
events.add(EventName.parkBrake)
if cs_out.accFaulted:
events.add(EventName.accFaulted)
if cs_out.steeringPressed:
events.add(EventName.steerOverride)
if cs_out.brakePressed and cs_out.standstill:
events.add(EventName.preEnableStandstill)
if cs_out.gasPressed:
events.add(EventName.gasPressedOverride)
if cs_out.vehicleSensorsInvalid:
events.add(EventName.vehicleSensorsInvalid)
# Handle button presses
for b in cs_out.buttonEvents:
# Enable OP long on falling edge of enable buttons (defaults to accelCruise and decelCruise, overridable per-port)
if not self.CP.pcmCruise and (b.type in enable_buttons and not b.pressed):
events.add(EventName.buttonEnable)
# Disable on rising and falling edge of cancel for both stock and OP long
if b.type == ButtonType.cancel:
events.add(EventName.buttonCancel)
# Handle permanent and temporary steering faults
self.steering_unpressed = 0 if cs_out.steeringPressed else self.steering_unpressed + 1
if cs_out.steerFaultTemporary:
if cs_out.steeringPressed and (not self.CS.out.steerFaultTemporary or self.no_steer_warning):
self.no_steer_warning = True
else:
self.no_steer_warning = False
# if the user overrode recently, show a less harsh alert
if self.silent_steer_warning or cs_out.standstill or self.steering_unpressed < int(1.5 / DT_CTRL):
self.silent_steer_warning = True
events.add(EventName.steerTempUnavailableSilent)
else:
events.add(EventName.steerTempUnavailable)
else:
self.no_steer_warning = False
self.silent_steer_warning = False
if cs_out.steerFaultPermanent:
events.add(EventName.steerUnavailable)
# we engage when pcm is active (rising edge)
# enabling can optionally be blocked by the car interface
if pcm_enable:
if cs_out.cruiseState.enabled and not self.CS.out.cruiseState.enabled and allow_enable:
events.add(EventName.pcmEnable)
elif not cs_out.cruiseState.enabled:
events.add(EventName.pcmDisable)
return events
class RadarInterfaceBase(ABC):
def __init__(self, CP: structs.CarParams):
self.CP = CP
@ -386,7 +295,7 @@ class CarStateBase(ABC):
self.v_ego_kf = KF1D(x0=x0, A=A, C=C[0], K=K)
@abstractmethod
def update(self, *args) -> structs.CarState:
def update(self, cp, cp_cam, cp_adas, cp_body, cp_loopback) -> structs.CarState:
pass
def update_speed_kf(self, v_ego_raw):

@ -1,10 +1,13 @@
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car import structs
from openpilot.selfdrive.car import create_button_events, structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.interfaces import CarStateBase
from openpilot.selfdrive.car.mazda.values import DBC, LKAS_LIMITS, MazdaFlags
ButtonType = car.CarState.ButtonEvent.Type
class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
@ -18,14 +21,13 @@ class CarState(CarStateBase):
self.lkas_allowed_speed = False
self.lkas_disabled = False
self.prev_distance_button = 0
self.distance_button = 0
def update(self, cp, cp_cam) -> structs.CarState:
def update(self, cp, cp_cam, *_) -> structs.CarState:
ret = structs.CarState()
self.prev_distance_button = self.distance_button
prev_distance_button = self.distance_button
self.distance_button = cp.vl["CRZ_BTNS"]["DISTANCE_LESS"]
ret.wheelSpeeds = self.get_wheel_speeds(
@ -110,6 +112,9 @@ class CarState(CarStateBase):
self.cam_laneinfo = cp_cam.vl["CAM_LANEINFO"]
ret.steerFaultPermanent = cp_cam.vl["CAM_LKAS"]["ERR_BIT_1"] == 1
# TODO: add button types for inc and dec
ret.buttonEvents = create_button_events(self.distance_button, prev_distance_button, {1: ButtonType.gapAdjustCruise})
return ret
@staticmethod

@ -1,13 +1,11 @@
#!/usr/bin/env python3
from cereal import car
from openpilot.selfdrive.car import create_button_events, get_safety_config, structs
from openpilot.selfdrive.car import get_safety_config, structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.mazda.carstate import CarState
from openpilot.selfdrive.car.mazda.values import CAR, LKAS_LIMITS
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
ButtonType = structs.CarState.ButtonEvent.Type
EventName = car.CarEvent.EventName
class CarInterface(CarInterfaceBase):
CS: CarState
@ -25,28 +23,9 @@ class CarInterface(CarInterfaceBase):
CarInterfaceBase.configure_torque_tune(candidate, ret.lateralTuning)
if candidate not in (CAR.MAZDA_CX5_2022, ):
if candidate not in (CAR.MAZDA_CX5_2022,):
ret.minSteerSpeed = LKAS_LIMITS.DISABLE_SPEED * CV.KPH_TO_MS
ret.centerToFront = ret.wheelbase * 0.41
return ret
# returns a car.CarState
def _update(self, c) -> structs.CarState:
ret = self.CS.update(self.cp, self.cp_cam)
# TODO: add button types for inc and dec
ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise})
# events
events = self.create_common_events(ret)
if self.CS.lkas_disabled:
events.add(EventName.lkasDisabled)
elif self.CS.low_speed_alert:
events.add(EventName.belowSteerSpeed)
# ret.events = events.to_msg()
return ret

@ -3,5 +3,5 @@ from openpilot.selfdrive.car.interfaces import CarStateBase
class CarState(CarStateBase):
def update(self, *args) -> car.CarState:
pass
def update(self, *_) -> car.CarState:
return car.CarState.new_message()

@ -1,15 +1,10 @@
#!/usr/bin/env python3
import cereal.messaging as messaging
from openpilot.selfdrive.car import structs
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
# mocked car interface for dashcam mode
class CarInterface(CarInterfaceBase):
def __init__(self, CP, CarController, CarState):
super().__init__(CP, CarController, CarState)
self.speed = 0.
self.sm = messaging.SubMaster(['gpsLocation', 'gpsLocationExternal'])
@staticmethod
def _get_params(ret: structs.CarParams, candidate, fingerprint, car_fw, experimental_long, docs):
@ -20,13 +15,3 @@ class CarInterface(CarInterfaceBase):
ret.steerRatio = 13.
ret.dashcamOnly = True
return ret
def _update(self, c) -> structs.CarState:
self.sm.update(0)
gps_sock = 'gpsLocationExternal' if self.sm.recv_frame['gpsLocationExternal'] > 1 else 'gpsLocation'
ret = structs.CarState()
ret.vEgo = self.sm[gps_sock].speed
ret.vEgoRaw = self.sm[gps_sock].speed
return ret

@ -2,13 +2,16 @@ import copy
from collections import deque
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car import structs
from openpilot.selfdrive.car import create_button_events, structs
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.interfaces import CarStateBase
from openpilot.selfdrive.car.nissan.values import CAR, DBC, CarControllerParams
ButtonType = car.CarState.ButtonEvent.Type
TORQUE_SAMPLES = 12
class CarState(CarStateBase):
def __init__(self, CP):
super().__init__(CP)
@ -20,13 +23,12 @@ class CarState(CarStateBase):
self.steeringTorqueSamples = deque(TORQUE_SAMPLES*[0], TORQUE_SAMPLES)
self.shifter_values = can_define.dv["GEARBOX"]["GEAR_SHIFTER"]
self.prev_distance_button = 0
self.distance_button = 0
def update(self, cp, cp_adas, cp_cam) -> structs.CarState:
def update(self, cp, cp_cam, cp_adas, *_) -> structs.CarState:
ret = structs.CarState()
self.prev_distance_button = self.distance_button
prev_distance_button = self.distance_button
self.distance_button = cp.vl["CRUISE_THROTTLE"]["FOLLOW_DISTANCE_BUTTON"]
if self.CP.carFingerprint in (CAR.NISSAN_ROGUE, CAR.NISSAN_XTRAIL, CAR.NISSAN_ALTIMA):
@ -121,6 +123,8 @@ class CarState(CarStateBase):
self.lkas_hud_msg = copy.copy(cp_adas.vl["PROPILOT_HUD"])
self.lkas_hud_info_msg = copy.copy(cp_adas.vl["PROPILOT_HUD_INFO_MSG"])
ret.buttonEvents = create_button_events(self.distance_button, prev_distance_button, {1: ButtonType.gapAdjustCruise})
return ret
@staticmethod

@ -1,12 +1,9 @@
from cereal import car
from panda import Panda
from openpilot.selfdrive.car import create_button_events, get_safety_config, structs
from openpilot.selfdrive.car import get_safety_config, structs
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
from openpilot.selfdrive.car.nissan.carstate import CarState
from openpilot.selfdrive.car.nissan.values import CAR
ButtonType = structs.CarState.ButtonEvent.Type
class CarInterface(CarInterfaceBase):
CS: CarState
@ -29,18 +26,3 @@ class CarInterface(CarInterfaceBase):
ret.safetyConfigs[0].safetyParam |= Panda.FLAG_NISSAN_ALT_EPS_BUS
return ret
# returns a car.CarState
def _update(self, c) -> structs.CarState:
ret = self.CS.update(self.cp, self.cp_adas, self.cp_cam)
ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise})
events = self.create_common_events(ret, extra_gears=[structs.CarState.GearShifter.brake])
if self.CS.lkas_enabled:
events.add(car.CarEvent.EventName.invalidLkasSetting)
# ret.events = events.to_msg()
return ret

@ -16,7 +16,7 @@ class CarState(CarStateBase):
self.angle_rate_calulator = CanSignalRateCalculator(50)
def update(self, cp, cp_cam, cp_body) -> structs.CarState:
def update(self, cp, cp_cam, _, cp_body, __) -> structs.CarState:
ret = structs.CarState()
throttle_msg = cp.vl["Throttle"] if not (self.CP.flags & SubaruFlags.HYBRID) else cp_body.vl["Throttle_Hybrid"]
@ -52,7 +52,7 @@ class CarState(CarStateBase):
# continuous blinker signals for assisted lane change
ret.leftBlinker, ret.rightBlinker = self.update_blinker_from_lamp(50, cp.vl["Dashlights"]["LEFT_BLINKER"],
cp.vl["Dashlights"]["RIGHT_BLINKER"])
cp.vl["Dashlights"]["RIGHT_BLINKER"])
if self.CP.enableBsm:
ret.leftBlindspot = (cp.vl["BSD_RCTA"]["L_ADJACENT"] == 1) or (cp.vl["BSD_RCTA"]["L_APPROACHING"] == 1)
@ -226,4 +226,3 @@ class CarState(CarStateBase):
]
return CANParser(DBC[CP.carFingerprint]["pt"], messages, CanBus.alt)

@ -97,15 +97,6 @@ class CarInterface(CarInterfaceBase):
return ret
# returns a car.CarState
def _update(self, c) -> structs.CarState:
ret = self.CS.update(self.cp, self.cp_cam, self.cp_body)
# ret.events = self.create_common_events(ret).to_msg()
return ret
@staticmethod
def init(CP, can_recv, can_send):
if CP.flags & SubaruFlags.DISABLE_EYESIGHT:

@ -8,6 +8,7 @@ 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)
@ -21,7 +22,7 @@ class CarState(CarStateBase):
self.acc_state = 0
self.das_control_counters = deque(maxlen=32)
def update(self, cp, cp_cam) -> structs.CarState:
def update(self, cp, cp_cam, *_) -> structs.CarState:
ret = structs.CarState()
# Vehicle speed

@ -40,10 +40,3 @@ class CarInterface(CarInterfaceBase):
ret.steerLimitTimer = 1.0
ret.steerActuatorDelay = 0.25
return ret
def _update(self, c) -> structs.CarState:
ret = self.CS.update(self.cp, self.cp_cam)
# ret.events = self.create_common_events(ret).to_msg()
return ret

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
SCRIPT_DIR=$(dirname "$0")
BASEDIR=$(realpath "$SCRIPT_DIR/../../../")
@ -9,4 +9,4 @@ INTERNAL_SEG_CNT=300
FILEREADER_CACHE=1
INTERNAL_SEG_LIST=selfdrive/car/tests/test_models_segs.txt
cd selfdrive/car/tests && pytest test_models.py test_car_interfaces.py
cd selfdrive/car/tests && pytest test_models.py test_car_interfaces.py

@ -12,6 +12,7 @@ from openpilot.selfdrive.car.structs import CarParams
from openpilot.selfdrive.car.fingerprints import all_known_cars
from openpilot.selfdrive.car.fw_versions import FW_VERSIONS, FW_QUERY_CONFIGS
from openpilot.selfdrive.car.interfaces import get_interface_attr
from openpilot.selfdrive.car.mock.values import CAR as MOCK
from openpilot.selfdrive.controls.lib.latcontrol_angle import LatControlAngle
from openpilot.selfdrive.controls.lib.latcontrol_pid import LatControlPID
from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque
@ -52,7 +53,7 @@ def get_fuzzy_car_interface_args(draw: DrawType) -> dict:
class TestCarInterfaces:
# FIXME: Due to the lists used in carParams, Phase.target is very slow and will cause
# many generated examples to overrun when max_examples > ~20, don't use it
@parameterized.expand([(car,) for car in sorted(all_known_cars())])
@parameterized.expand([(car,) for car in sorted(all_known_cars())] + [MOCK.MOCK])
@settings(max_examples=MAX_EXAMPLES, deadline=None,
phases=(Phase.reuse, Phase.generate, Phase.shrink))
@given(data=st.data())
@ -81,10 +82,12 @@ class TestCarInterfaces:
# Lateral sanity checks
if car_params.steerControlType != CarParams.SteerControlType.angle:
tune = car_params.lateralTuning
# TODO: we use which again, this is wrong
if isinstance(tune, CarParams.LateralPIDTuning):
assert not math.isnan(tune.kf) and tune.kf > 0
assert len(tune.kpV) > 0 and len(tune.kpV) == len(tune.kpBP)
assert len(tune.kiV) > 0 and len(tune.kiV) == len(tune.kiBP)
if car_name != MOCK.MOCK:
assert not math.isnan(tune.kf) and tune.kf > 0
assert len(tune.kpV) > 0 and len(tune.kpV) == len(tune.kpBP)
assert len(tune.kiV) > 0 and len(tune.kiV) == len(tune.kiBP)
elif isinstance(tune, CarParams.LateralTorqueTuning):
assert not math.isnan(tune.kf) and tune.kf > 0
@ -95,14 +98,14 @@ class TestCarInterfaces:
now_nanos = 0
CC = car.CarControl.new_message(**cc_msg)
for _ in range(10):
car_interface.update(CC, [])
car_interface.update([])
car_interface.apply(CC.as_reader(), now_nanos)
now_nanos += DT_CTRL * 1e9 # 10 ms
CC = car.CarControl.new_message(**cc_msg)
CC.enabled = True
for _ in range(10):
car_interface.update(CC, [])
car_interface.update([])
car_interface.apply(CC.as_reader(), now_nanos)
now_nanos += DT_CTRL * 1e9 # 10ms

@ -220,7 +220,7 @@ class TestCarModelBase(unittest.TestCase):
CC = car.CarControl.new_message().as_reader()
for i, msg in enumerate(self.can_msgs):
CS = self.CI.update(CC, can_capnp_to_list((msg.as_builder().to_bytes(),)))
CS = self.CI.update(can_capnp_to_list((msg.as_builder().to_bytes(),)))
self.CI.apply(CC, msg.logMonoTime)
if CS.canValid:
@ -296,7 +296,7 @@ class TestCarModelBase(unittest.TestCase):
msgs_sent = 0
CI = self.CarInterface(self.CP, self.CarController, self.CarState)
for _ in range(round(10.0 / DT_CTRL)): # make sure we hit the slowest messages
CI.update(car_control, [])
CI.update([])
_, sendcan = CI.apply(car_control, now_nanos)
now_nanos += DT_CTRL * 1e9
@ -342,8 +342,6 @@ class TestCarModelBase(unittest.TestCase):
msg_strategy = st.binary(min_size=size, max_size=size)
msgs = data.draw(st.lists(msg_strategy, min_size=20))
CC = car.CarControl.new_message()
for dat in msgs:
# due to panda updating state selectively, only edges are expected to match
# TODO: warm up CarState with real CAN messages to check edge of both sources
@ -361,7 +359,7 @@ class TestCarModelBase(unittest.TestCase):
can = messaging.new_message('can', 1)
can.can = [log.CanData(address=address, dat=dat, src=bus)]
CS = self.CI.update(CC, can_capnp_to_list((can.to_bytes(),)))
CS = self.CI.update(can_capnp_to_list((can.to_bytes(),)))
if self.safety.get_gas_pressed_prev() != prev_panda_gas:
self.assertEqual(CS.gasPressed, self.safety.get_gas_pressed_prev())
@ -396,11 +394,9 @@ class TestCarModelBase(unittest.TestCase):
if self.CP.dashcamOnly:
self.skipTest("no need to check panda safety for dashcamOnly")
CC = car.CarControl.new_message()
# warm up pass, as initial states may be different
for can in self.can_msgs[:300]:
self.CI.update(CC, can_capnp_to_list((can.as_builder().to_bytes(), )))
self.CI.update(can_capnp_to_list((can.as_builder().to_bytes(), )))
for msg in filter(lambda m: m.src in range(64), can.can):
to_send = libpanda_py.make_CANPacket(msg.address, msg.src % 4, msg.dat)
self.safety.safety_rx_hook(to_send)
@ -410,7 +406,7 @@ class TestCarModelBase(unittest.TestCase):
checks = defaultdict(int)
card = Car(CI=self.CI)
for idx, can in enumerate(self.can_msgs):
CS = self.CI.update(CC, can_capnp_to_list((can.as_builder().to_bytes(), )))
CS = self.CI.update(can_capnp_to_list((can.as_builder().to_bytes(), )))
for msg in filter(lambda m: m.src in range(64), can.can):
to_send = libpanda_py.make_CANPacket(msg.address, msg.src % 4, msg.dat)
ret = self.safety.safety_rx_hook(to_send)

@ -2,7 +2,7 @@ import copy
from opendbc.can.can_define import CANDefine
from opendbc.can.parser import CANParser
from openpilot.selfdrive.car import DT_CTRL, structs
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
@ -10,6 +10,7 @@ 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
ButtonType = structs.CarState.ButtonEvent.Type
SteerControlType = structs.CarParams.SteerControlType
# These steering fault definitions seem to be common across LKA (torque) and LTA (angle):
@ -39,7 +40,6 @@ class CarState(CarStateBase):
self.accurate_steer_angle_seen = False
self.angle_offset = FirstOrderFilter(None, 60.0, DT_CTRL, initialized=False)
self.prev_distance_button = 0
self.distance_button = 0
self.pcm_follow_distance = 0
@ -48,7 +48,7 @@ class CarState(CarStateBase):
self.acc_type = 1
self.lkas_hud = {}
def update(self, cp, cp_cam) -> structs.CarState:
def update(self, cp, cp_cam, *_) -> structs.CarState:
ret = structs.CarState()
ret.doorOpen = any([cp.vl["BODY_CONTROL_STATE"]["DOOR_OPEN_FL"], cp.vl["BODY_CONTROL_STATE"]["DOOR_OPEN_FR"],
@ -171,9 +171,10 @@ class CarState(CarStateBase):
if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR):
# distance button is wired to the ACC module (camera or radar)
self.prev_distance_button = self.distance_button
if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR):
self.distance_button = cp_acc.vl["ACC_CONTROL"]["DISTANCE"]
prev_distance_button = self.distance_button
self.distance_button = cp_acc.vl["ACC_CONTROL"]["DISTANCE"]
ret.buttonEvents = create_button_events(self.distance_button, prev_distance_button, {1: ButtonType.gapAdjustCruise})
return ret

@ -1,15 +1,12 @@
from cereal import car
from panda import Panda
from panda.python import uds
from openpilot.selfdrive.car import structs, get_safety_config
from openpilot.selfdrive.car.toyota.carstate import CarState
from openpilot.selfdrive.car.toyota.values import Ecu, CAR, DBC, ToyotaFlags, CarControllerParams, TSS2_CAR, RADAR_ACC_CAR, NO_DSU_CAR, \
MIN_ACC_SPEED, EPS_SCALE, UNSUPPORTED_DSU_CAR, NO_STOP_TIMER_CAR, ANGLE_CONTROL_CAR
from openpilot.selfdrive.car import create_button_events, get_safety_config, structs
MIN_ACC_SPEED, EPS_SCALE, UNSUPPORTED_DSU_CAR, NO_STOP_TIMER_CAR, ANGLE_CONTROL_CAR
from openpilot.selfdrive.car.disable_ecu import disable_ecu
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
ButtonType = structs.CarState.ButtonEvent.Type
EventName = car.CarEvent.EventName
SteerControlType = structs.CarParams.SteerControlType
@ -146,30 +143,3 @@ class CarInterface(CarInterfaceBase):
if CP.flags & ToyotaFlags.DISABLE_RADAR.value:
communication_control = bytes([uds.SERVICE_TYPE.COMMUNICATION_CONTROL, uds.CONTROL_TYPE.ENABLE_RX_DISABLE_TX, uds.MESSAGE_TYPE.NORMAL])
disable_ecu(can_recv, can_send, bus=0, addr=0x750, sub_addr=0xf, com_cont_req=communication_control)
def _update(self, c) -> structs.CarState:
ret = self.CS.update(self.cp, self.cp_cam)
if self.CP.carFingerprint in (TSS2_CAR - RADAR_ACC_CAR):
ret.buttonEvents = create_button_events(self.CS.distance_button, self.CS.prev_distance_button, {1: ButtonType.gapAdjustCruise})
# events
events = self.create_common_events(ret)
if self.CP.openpilotLongitudinalControl:
if ret.cruiseState.standstill and not ret.brakePressed:
events.add(EventName.resumeRequired)
if self.CS.low_speed_lockout:
events.add(EventName.lowSpeedLockout)
if ret.vEgo < self.CP.minEnableSpeed:
events.add(EventName.belowEngageSpeed)
if c.actuators.accel > 0.3:
# some margin on the actuator to not false trigger cancellation while stopping
events.add(EventName.speedTooLow)
if ret.vEgo < 0.001:
# while in standstill, send a user alert
events.add(EventName.manualRestart)
# ret.events = events.to_msg()
return ret

@ -63,6 +63,7 @@ if __name__ == "__main__":
import argparse
import time
import cereal.messaging as messaging
from openpilot.selfdrive.car.card import can_comm_callbacks
parser = argparse.ArgumentParser(description='Get VIN of the car')
parser.add_argument('--debug', action='store_true')
@ -73,7 +74,8 @@ if __name__ == "__main__":
sendcan = messaging.pub_sock('sendcan')
logcan = messaging.sub_sock('can')
can_callbacks = can_comm_callbacks(logcan, sendcan)
time.sleep(1)
vin_rx_addr, vin_rx_bus, vin = get_vin(logcan, sendcan, (args.bus,), args.timeout, args.retry, debug=args.debug)
vin_rx_addr, vin_rx_bus, vin = get_vin(*can_callbacks, (args.bus,), args.timeout, args.retry, debug=args.debug)
print(f'RX: {hex(vin_rx_addr)}, BUS: {vin_rx_bus}, VIN: {vin}')

@ -5,7 +5,7 @@ from openpilot.selfdrive.car import structs
from openpilot.selfdrive.car.interfaces import CarStateBase
from openpilot.selfdrive.car.conversions import Conversions as CV
from openpilot.selfdrive.car.volkswagen.values import DBC, CANBUS, NetworkLocation, TransmissionType, GearShifter, \
CarControllerParams, VolkswagenFlags
CarControllerParams, VolkswagenFlags
class CarState(CarStateBase):
@ -33,9 +33,12 @@ class CarState(CarStateBase):
return button_events
def update(self, pt_cp, cam_cp, ext_cp, trans_type) -> structs.CarState:
def update(self, pt_cp, cam_cp, *_) -> structs.CarState:
ext_cp = pt_cp if self.CP.networkLocation == NetworkLocation.fwdCamera else cam_cp
if self.CP.flags & VolkswagenFlags.PQ:
return self.update_pq(pt_cp, cam_cp, ext_cp, trans_type)
return self.update_pq(pt_cp, cam_cp, ext_cp)
ret = structs.CarState()
# Update vehicle speed and acceleration from ABS wheel speeds.
@ -74,11 +77,11 @@ class CarState(CarStateBase):
ret.parkingBrake = bool(pt_cp.vl["Kombi_01"]["KBI_Handbremse"]) # FIXME: need to include an EPB check as well
# Update gear and/or clutch position data.
if trans_type == TransmissionType.automatic:
if self.CP.transmissionType == TransmissionType.automatic:
ret.gearShifter = self.parse_gear_shifter(self.CCP.shifter_values.get(pt_cp.vl["Getriebe_11"]["GE_Fahrstufe"], None))
elif trans_type == TransmissionType.direct:
elif self.CP.transmissionType == TransmissionType.direct:
ret.gearShifter = self.parse_gear_shifter(self.CCP.shifter_values.get(pt_cp.vl["EV_Gearshift"]["GearPosition"], None))
elif trans_type == TransmissionType.manual:
elif self.CP.transmissionType == TransmissionType.manual:
ret.clutchPressed = not pt_cp.vl["Motor_14"]["MO_Kuppl_schalter"]
if bool(pt_cp.vl["Gateway_72"]["BCM1_Rueckfahrlicht_Schalter"]):
ret.gearShifter = GearShifter.reverse
@ -156,7 +159,7 @@ class CarState(CarStateBase):
self.frame += 1
return ret
def update_pq(self, pt_cp, cam_cp, ext_cp, trans_type) -> structs.CarState:
def update_pq(self, pt_cp, cam_cp, ext_cp) -> structs.CarState:
ret = structs.CarState()
# Update vehicle speed and acceleration from ABS wheel speeds.
ret.wheelSpeeds = self.get_wheel_speeds(
@ -188,9 +191,9 @@ class CarState(CarStateBase):
ret.parkingBrake = bool(pt_cp.vl["Kombi_1"]["Bremsinfo"])
# Update gear and/or clutch position data.
if trans_type == TransmissionType.automatic:
if self.CP.transmissionType == TransmissionType.automatic:
ret.gearShifter = self.parse_gear_shifter(self.CCP.shifter_values.get(pt_cp.vl["Getriebe_1"]["Waehlhebelposition__Getriebe_1_"], None))
elif trans_type == TransmissionType.manual:
elif self.CP.transmissionType == TransmissionType.manual:
ret.clutchPressed = not pt_cp.vl["Motor_1"]["Kupplungsschalter"]
reverse_light = bool(pt_cp.vl["Gate_Komf_1"]["GK1_Rueckfahr"])
if reverse_light:
@ -388,6 +391,7 @@ class MqbExtraSignals:
("SWA_01", 20), # From J1086 Lane Change Assist
]
class PqExtraSignals:
# Additional signal and message lists for optional or bus-portable controllers
fwd_radar_messages = [

@ -883,6 +883,7 @@ FW_VERSIONS = {
b'\xf1\x875QF909144B \xf1\x895582\xf1\x82\x0571G60533A1',
b'\xf1\x875QF909144B \xf1\x895582\xf1\x82\x0571G60733A1',
b'\xf1\x875TA907145D \xf1\x891051\xf1\x82\x001PG60A1P7N',
b'\xf1\x875TA907145F \xf1\x891063\xf1\x82\x002VG60A2VOM',
],
(Ecu.fwdRadar, 0x757, None): [
b'\xf1\x872Q0907572AA\xf1\x890396',

@ -1,29 +1,15 @@
from cereal import car
from panda import Panda
from openpilot.selfdrive.car import get_safety_config, structs
from openpilot.selfdrive.car.interfaces import CarInterfaceBase
from openpilot.selfdrive.car.volkswagen.carcontroller import CarController
from openpilot.selfdrive.car.volkswagen.carstate import CarState
from openpilot.selfdrive.car.volkswagen.values import CAR, CANBUS, CarControllerParams, NetworkLocation, TransmissionType, GearShifter, VolkswagenFlags
ButtonType = structs.CarState.ButtonEvent.Type
EventName = car.CarEvent.EventName
from openpilot.selfdrive.car.volkswagen.values import CAR, NetworkLocation, TransmissionType, VolkswagenFlags
class CarInterface(CarInterfaceBase):
CS: CarState
CC: CarController
def __init__(self, CP, CarController, CarState):
super().__init__(CP, CarController, CarState)
if CP.networkLocation == NetworkLocation.fwdCamera:
self.ext_bus = CANBUS.pt
self.cp_ext = self.cp
else:
self.ext_bus = CANBUS.cam
self.cp_ext = self.cp_cam
@staticmethod
def _get_params(ret: structs.CarParams, candidate: CAR, fingerprint, car_fw, experimental_long, docs):
ret.carName = "volkswagen"
@ -104,33 +90,3 @@ class CarInterface(CarInterfaceBase):
ret.autoResumeSng = ret.minEnableSpeed == -1
return ret
# returns a car.CarState
def _update(self, c) -> structs.CarState:
ret = self.CS.update(self.cp, self.cp_cam, self.cp_ext, self.CP.transmissionType)
events = self.create_common_events(ret, extra_gears=[GearShifter.eco, GearShifter.sport, GearShifter.manumatic],
pcm_enable=not self.CS.CP.openpilotLongitudinalControl,
enable_buttons=(ButtonType.setCruise, ButtonType.resumeCruise))
# Low speed steer alert hysteresis logic
if (self.CP.minSteerSpeed - 1e-3) > CarControllerParams.DEFAULT_MIN_STEER_SPEED and ret.vEgo < (self.CP.minSteerSpeed + 1.):
self.low_speed_alert = True
elif ret.vEgo > (self.CP.minSteerSpeed + 2.):
self.low_speed_alert = False
if self.low_speed_alert:
events.add(EventName.belowSteerSpeed)
if self.CS.CP.openpilotLongitudinalControl:
if ret.vEgo < self.CP.minEnableSpeed + 0.5:
events.add(EventName.belowEngageSpeed)
if c.enabled and ret.vEgo < self.CP.minEnableSpeed:
events.add(EventName.speedTooLow)
if self.CC.eps_timer_soft_disable_alert:
events.add(EventName.steerTimeLimit)
# ret.events = events.to_msg()
return ret

@ -28,6 +28,7 @@ from openpilot.selfdrive.controls.lib.latcontrol_angle import LatControlAngle, S
from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque
from openpilot.selfdrive.controls.lib.longcontrol import LongControl
from openpilot.selfdrive.controls.lib.vehicle_model import VehicleModel
from openpilot.selfdrive.locationd.helpers import PoseCalibrator, Pose
from openpilot.system.hardware import HARDWARE
@ -78,6 +79,11 @@ class Controls:
# Setup sockets
self.pm = messaging.PubMaster(['controlsState', 'carControl', 'onroadEvents'])
if self.params.get_bool("UbloxAvailable"):
self.gps_location_service = "gpsLocationExternal"
else:
self.gps_location_service = "gpsLocation"
self.gps_packets = [self.gps_location_service]
self.sensor_packets = ["accelerometer", "gyroscope"]
self.camera_packets = ["roadCameraState", "driverCameraState", "wideRoadCameraState"]
@ -86,16 +92,16 @@ class Controls:
# TODO: de-couple controlsd with card/conflate on carState without introducing controls mismatches
self.car_state_sock = messaging.sub_sock('carState', timeout=20)
ignore = self.sensor_packets + ['testJoystick']
ignore = self.sensor_packets + self.gps_packets + ['testJoystick']
if SIMULATION:
ignore += ['driverCameraState', 'managerState']
if REPLAY:
# no vipc in replay will make them ignored anyways
ignore += ['roadCameraState', 'wideRoadCameraState']
self.sm = messaging.SubMaster(['deviceState', 'pandaStates', 'peripheralState', 'modelV2', 'liveCalibration',
'carOutput', 'driverMonitoringState', 'longitudinalPlan', 'liveLocationKalman',
'carOutput', 'driverMonitoringState', 'longitudinalPlan', 'livePose',
'managerState', 'liveParameters', 'radarState', 'liveTorqueParameters',
'testJoystick'] + self.camera_packets + self.sensor_packets,
'testJoystick'] + self.camera_packets + self.sensor_packets + self.gps_packets,
ignore_alive=ignore, ignore_avg_freq=ignore+['radarState', 'testJoystick'], ignore_valid=['testJoystick', ],
frequency=int(1/DT_CTRL))
@ -120,6 +126,9 @@ class Controls:
self.AM = AlertManager()
self.events = Events()
self.pose_calibrator = PoseCalibrator()
self.calibrated_pose: Pose|None = None
self.LoC = LongControl(self.CP)
self.VM = VehicleModel(self.CP)
@ -335,11 +344,9 @@ class Controls:
self.logged_comm_issue = None
if not (self.CP.notCar and self.joystick_mode):
if not self.sm['liveLocationKalman'].posenetOK:
if not self.sm['livePose'].posenetOK:
self.events.add(EventName.posenetInvalid)
if not self.sm['liveLocationKalman'].deviceStable:
self.events.add(EventName.deviceFalling)
if not self.sm['liveLocationKalman'].inputsOK:
if not self.sm['livePose'].inputsOK:
self.events.add(EventName.locationdTemporaryError)
if not self.sm['liveParameters'].valid and not TESTING_CLOSET and (not SIMULATION or REPLAY):
self.events.add(EventName.paramsdTemporaryError)
@ -375,10 +382,10 @@ class Controls:
# TODO: fix simulator
if not SIMULATION or REPLAY:
# Not show in first 1 km to allow for driving out of garage. This event shows after 5 minutes
if not self.sm['liveLocationKalman'].gpsOK and self.sm['liveLocationKalman'].inputsOK and (self.distance_traveled > 1500):
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)
if self.sm['liveLocationKalman'].gpsOK:
if gps_ok:
self.distance_traveled = 0
self.distance_traveled += CS.vEgo * DT_CTRL
@ -429,6 +436,13 @@ class Controls:
if ps.safetyModel not in IGNORED_SAFETY_MODES):
self.mismatch_counter += 1
# calibrate the live pose and save it for later use
if self.sm.updated["liveCalibration"]:
self.pose_calibrator.feed_live_calib(self.sm['liveCalibration'])
if self.sm.updated["livePose"]:
device_pose = Pose.from_live_pose(self.sm['livePose'])
self.calibrated_pose = self.pose_calibrator.build_calibrated_pose(device_pose)
return CS
def state_transition(self, CS):
@ -573,7 +587,7 @@ class Controls:
actuators.curvature = self.desired_curvature
actuators.steer, actuators.steeringAngleDeg, lac_log = self.LaC.update(CC.latActive, CS, self.VM, lp,
self.steer_limited, self.desired_curvature,
self.sm['liveLocationKalman'])
self.calibrated_pose) # TODO what if not available
else:
lac_log = log.ControlsState.LateralDebugState.new_message()
if self.sm.recv_frame['testJoystick'] > 0:
@ -650,12 +664,9 @@ class Controls:
# Orientation and angle rates can be useful for carcontroller
# Only calibrated (car) frame is relevant for the carcontroller
orientation_value = list(self.sm['liveLocationKalman'].calibratedOrientationNED.value)
if len(orientation_value) > 2:
CC.orientationNED = orientation_value
angular_rate_value = list(self.sm['liveLocationKalman'].angularVelocityCalibrated.value)
if len(angular_rate_value) > 2:
CC.angularVelocity = angular_rate_value
if self.calibrated_pose is not None:
CC.orientationNED = self.calibrated_pose.orientation.xyz.tolist()
CC.angularVelocity = self.calibrated_pose.angular_velocity.xyz.tolist()
CC.cruiseControl.override = self.enabled and not CC.longActive and self.CP.openpilotLongitudinalControl
CC.cruiseControl.cancel = CS.cruiseState.enabled and (not self.enabled or not self.CP.pcmCruise)

@ -17,7 +17,7 @@ class LatControl(ABC):
self.steer_max = 1.0
@abstractmethod
def update(self, active, CS, VM, params, steer_limited, desired_curvature, llk):
def update(self, active, CS, VM, params, steer_limited, desired_curvature, calibrated_pose):
pass
def reset(self):

@ -11,7 +11,7 @@ class LatControlAngle(LatControl):
super().__init__(CP, CI)
self.sat_check_min_speed = 5.
def update(self, active, CS, VM, params, steer_limited, desired_curvature, llk):
def update(self, active, CS, VM, params, steer_limited, desired_curvature, calibrated_pose):
angle_log = log.ControlsState.LateralAngleState.new_message()
if not active:

@ -17,7 +17,7 @@ class LatControlPID(LatControl):
super().reset()
self.pid.reset()
def update(self, active, CS, VM, params, steer_limited, desired_curvature, llk):
def update(self, active, CS, VM, params, steer_limited, desired_curvature, calibrated_pose):
pid_log = log.ControlsState.LateralPIDState.new_message()
pid_log.steeringAngleDeg = float(CS.steeringAngleDeg)
pid_log.steeringRateDeg = float(CS.steeringRateDeg)

@ -37,7 +37,7 @@ class LatControlTorque(LatControl):
self.torque_params.latAccelOffset = latAccelOffset
self.torque_params.friction = friction
def update(self, active, CS, VM, params, steer_limited, desired_curvature, llk):
def update(self, active, CS, VM, params, steer_limited, desired_curvature, calibrated_pose):
pid_log = log.ControlsState.LateralTorqueState.new_message()
if not active:
output_torque = 0.0
@ -49,8 +49,9 @@ class LatControlTorque(LatControl):
actual_curvature = actual_curvature_vm
curvature_deadzone = abs(VM.calc_curvature(math.radians(self.steering_angle_deadzone_deg), CS.vEgo, 0.0))
else:
actual_curvature_llk = llk.angularVelocityCalibrated.value[2] / CS.vEgo
actual_curvature = interp(CS.vEgo, [2.0, 5.0], [actual_curvature_vm, actual_curvature_llk])
assert calibrated_pose is not None
actual_curvature_pose = calibrated_pose.angular_velocity.yaw / CS.vEgo
actual_curvature = interp(CS.vEgo, [2.0, 5.0], [actual_curvature_vm, actual_curvature_pose])
curvature_deadzone = 0.0
desired_lateral_accel = desired_curvature * CS.vEgo ** 2

@ -10,7 +10,8 @@ from openpilot.selfdrive.controls.lib.latcontrol_pid import LatControlPID
from openpilot.selfdrive.controls.lib.latcontrol_torque import LatControlTorque
from openpilot.selfdrive.controls.lib.latcontrol_angle import LatControlAngle
from openpilot.selfdrive.controls.lib.vehicle_model import VehicleModel
from openpilot.common.mock.generators import generate_liveLocationKalman
from openpilot.selfdrive.locationd.helpers import Pose
from openpilot.common.mock.generators import generate_livePose
class TestLatControl:
@ -31,8 +32,10 @@ class TestLatControl:
params = log.LiveParametersData.new_message()
llk = generate_liveLocationKalman()
lp = generate_livePose()
pose = Pose.from_live_pose(lp.livePose)
for _ in range(1000):
_, _, lac_log = controller.update(True, CS, VM, params, False, 1, llk)
_, _, lac_log = controller.update(True, CS, VM, params, False, 1, pose)
assert lac_log.saturated

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
set -e
PORT=5555

@ -54,7 +54,7 @@ def cycle_alerts(duration=200, is_metric=False):
CS = car.CarState.new_message()
CP = CarInterface.get_non_essential_params("HONDA_CIVIC")
sm = messaging.SubMaster(['deviceState', 'pandaStates', 'roadCameraState', 'modelV2', 'liveCalibration',
'driverMonitoringState', 'longitudinalPlan', 'liveLocationKalman',
'driverMonitoringState', 'longitudinalPlan', 'livePose',
'managerState'] + cameras)
pm = messaging.PubMaster(['controlsState', 'pandaStates', 'deviceState'])

@ -2,6 +2,7 @@ import numpy as np
from typing import Any
from cereal import log
from openpilot.common.transformations.orientation import rot_from_euler, euler_from_rot
def rotate_cov(rot_matrix, cov_in):
@ -70,3 +71,69 @@ class ParameterEstimator:
def get_msg(self, valid: bool, with_points: bool) -> log.Event:
raise NotImplementedError
class Measurement:
x, y, z = (property(lambda self: self.xyz[0]), property(lambda self: self.xyz[1]), property(lambda self: self.xyz[2]))
x_std, y_std, z_std = (property(lambda self: self.xyz_std[0]), property(lambda self: self.xyz_std[1]), property(lambda self: self.xyz_std[2]))
roll, pitch, yaw = x, y, z
roll_std, pitch_std, yaw_std = x_std, y_std, z_std
def __init__(self, xyz: np.ndarray, xyz_std: np.ndarray):
self.xyz: np.ndarray = xyz
self.xyz_std: np.ndarray = xyz_std
@classmethod
def from_measurement_xyz(cls, measurement: log.LivePose.XYZMeasurement) -> 'Measurement':
return cls(
xyz=np.array([measurement.x, measurement.y, measurement.z]),
xyz_std=np.array([measurement.xStd, measurement.yStd, measurement.zStd])
)
class Pose:
def __init__(self, orientation: Measurement, velocity: Measurement, acceleration: Measurement, angular_velocity: Measurement):
self.orientation = orientation
self.velocity = velocity
self.acceleration = acceleration
self.angular_velocity = angular_velocity
@classmethod
def from_live_pose(cls, live_pose: log.LivePose) -> 'Pose':
return Pose(
orientation=Measurement.from_measurement_xyz(live_pose.orientationNED),
velocity=Measurement.from_measurement_xyz(live_pose.velocityDevice),
acceleration=Measurement.from_measurement_xyz(live_pose.accelerationDevice),
angular_velocity=Measurement.from_measurement_xyz(live_pose.angularVelocityDevice)
)
class PoseCalibrator:
def __init__(self):
self.calib_valid = False
self.calib_from_device = np.eye(3)
def _transform_calib_from_device(self, meas: Measurement):
new_xyz = self.calib_from_device @ meas.xyz
new_xyz_std = rotate_std(self.calib_from_device, meas.xyz_std)
return Measurement(new_xyz, new_xyz_std)
def _ned_from_calib(self, orientation: Measurement):
ned_from_device = rot_from_euler(orientation.xyz)
ned_from_calib = ned_from_device @ self.calib_from_device.T
ned_from_calib_euler_meas = Measurement(euler_from_rot(ned_from_calib), np.full(3, np.nan))
return ned_from_calib_euler_meas
def build_calibrated_pose(self, pose: Pose) -> Pose:
ned_from_calib_euler = self._ned_from_calib(pose.orientation)
angular_velocity_calib = self._transform_calib_from_device(pose.angular_velocity)
acceleration_calib = self._transform_calib_from_device(pose.acceleration)
velocity_calib = self._transform_calib_from_device(pose.angular_velocity)
return Pose(ned_from_calib_euler, velocity_calib, acceleration_calib, angular_velocity_calib)
def feed_live_calib(self, live_calib: log.LiveCalibrationData):
calib_rpy = np.array(live_calib.rpyCalib)
device_from_calib = rot_from_euler(calib_rpy)
self.calib_from_device = device_from_calib.T
self.calib_valid = live_calib.calStatus == log.LiveCalibrationData.Status.calibrated

@ -9,10 +9,9 @@ from cereal import car, log
from openpilot.common.params import Params
from openpilot.common.realtime import config_realtime_process, DT_MDL
from openpilot.common.numpy_fast import clip
from openpilot.common.transformations.orientation import rot_from_euler
from openpilot.selfdrive.locationd.models.car_kf import CarKalman, ObservationKind, States
from openpilot.selfdrive.locationd.models.constants import GENERATED_DIR
from openpilot.selfdrive.locationd.helpers import rotate_std
from openpilot.selfdrive.locationd.helpers import PoseCalibrator, Pose
from openpilot.common.swaglog import cloudlog
@ -40,9 +39,8 @@ class ParamsLearner:
self.kf.filter.set_global("stiffness_rear", CP.tireStiffnessRear)
self.active = False
self.calibrated = False
self.calib_from_device = np.eye(3)
self.calibrator = PoseCalibrator()
self.speed = 0.0
self.yaw_rate = 0.0
@ -53,15 +51,12 @@ class ParamsLearner:
def handle_log(self, t, which, msg):
if which == 'livePose':
angular_velocity_device = np.array([msg.angularVelocityDevice.x, msg.angularVelocityDevice.y, msg.angularVelocityDevice.z])
angular_velocity_device_std = np.array([msg.angularVelocityDevice.xStd, msg.angularVelocityDevice.yStd, msg.angularVelocityDevice.zStd])
angular_velocity_calibrated = np.matmul(self.calib_from_device, angular_velocity_device)
angular_velocity_calibrated_std = rotate_std(self.calib_from_device, angular_velocity_device_std)
device_pose = Pose.from_live_pose(msg)
calibrated_pose = self.calibrator.build_calibrated_pose(device_pose)
self.yaw_rate, self.yaw_rate_std = calibrated_pose.angular_velocity.z, calibrated_pose.angular_velocity.z_std
self.yaw_rate, self.yaw_rate_std = angular_velocity_calibrated[2], angular_velocity_calibrated_std[2]
localizer_roll = msg.orientationNED.x
localizer_roll_std = np.radians(1) if np.isnan(msg.orientationNED.xStd) else msg.orientationNED.xStd
localizer_roll, localizer_roll_std = device_pose.orientation.x, device_pose.orientation.x_std
localizer_roll_std = np.radians(1) if np.isnan(localizer_roll_std) else localizer_roll_std
self.roll_valid = (localizer_roll_std < ROLL_STD_MAX) and (ROLL_MIN < localizer_roll < ROLL_MAX) and msg.sensorsOK
if self.roll_valid:
roll = localizer_roll
@ -73,7 +68,7 @@ class ParamsLearner:
roll_std = np.radians(10.0)
self.roll = clip(roll, self.roll - ROLL_MAX_DELTA, self.roll + ROLL_MAX_DELTA)
yaw_rate_valid = msg.angularVelocityDevice.valid and self.calibrated
yaw_rate_valid = msg.angularVelocityDevice.valid and self.calibrator.calib_valid
yaw_rate_valid = yaw_rate_valid and 0 < self.yaw_rate_std < 10 # rad/s
yaw_rate_valid = yaw_rate_valid and abs(self.yaw_rate) < 1 # rad/s
@ -101,9 +96,7 @@ class ParamsLearner:
self.kf.predict_and_observe(t, ObservationKind.STEER_RATIO, np.array([[steer_ratio]]))
elif which == 'liveCalibration':
self.calibrated = msg.calStatus == log.LiveCalibrationData.Status.calibrated
device_from_calib = rot_from_euler(np.array(msg.rpyCalib))
self.calib_from_device = device_from_calib.T
self.calibrator.feed_live_calib(msg)
elif which == 'carState':
self.steering_angle = msg.steeringAngleDeg

@ -8,9 +8,8 @@ from openpilot.common.params import Params
from openpilot.common.realtime import config_realtime_process, DT_MDL
from openpilot.common.filter_simple import FirstOrderFilter
from openpilot.common.swaglog import cloudlog
from openpilot.common.transformations.orientation import rot_from_euler
from openpilot.selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY
from openpilot.selfdrive.locationd.helpers import PointBuckets, ParameterEstimator
from openpilot.selfdrive.locationd.helpers import PointBuckets, ParameterEstimator, PoseCalibrator, Pose
HISTORY = 5 # secs
POINTS_PER_BUCKET = 1500
@ -78,7 +77,7 @@ class TorqueEstimator(ParameterEstimator):
self.offline_friction = CP.lateralTuning.torque.friction
self.offline_latAccelFactor = CP.lateralTuning.torque.latAccelFactor
self.calib_from_device = np.eye(3)
self.calibrator = PoseCalibrator()
self.reset()
@ -175,17 +174,17 @@ class TorqueEstimator(ParameterEstimator):
self.raw_points["vego"].append(msg.vEgo)
self.raw_points["steer_override"].append(msg.steeringPressed)
elif which == "liveCalibration":
device_from_calib = rot_from_euler(np.array(msg.rpyCalib))
self.calib_from_device = device_from_calib.T
self.calibrator.feed_live_calib(msg)
# calculate lateral accel from past steering torque
elif which == "livePose":
if len(self.raw_points['steer_torque']) == self.hist_len:
angular_velocity_device = np.array([msg.angularVelocityDevice.x, msg.angularVelocityDevice.y, msg.angularVelocityDevice.z])
angular_velocity_calibrated = np.matmul(self.calib_from_device, angular_velocity_device)
device_pose = Pose.from_live_pose(msg)
calibrated_pose = self.calibrator.build_calibrated_pose(device_pose)
angular_velocity_calibrated = calibrated_pose.angular_velocity
yaw_rate = angular_velocity_calibrated[2]
roll = msg.orientationNED.x
yaw_rate = angular_velocity_calibrated.yaw
roll = device_pose.orientation.roll
# check lat active up to now (without lag compensation)
lat_active = np.interp(np.arange(t - MIN_ENGAGE_BUFFER, t + self.lag, DT_MDL),
self.raw_points['carControl_t'], self.raw_points['lat_active']).astype(bool)

@ -1,2 +1,2 @@
#!/bin/bash
#!/usr/bin/env bash
clang++ -I /home/batman/one/external/tensorflow/include/ -L /home/batman/one/external/tensorflow/lib -Wl,-rpath=/home/batman/one/external/tensorflow/lib main.cc -ltensorflow

@ -466,6 +466,11 @@ def controlsd_config_callback(params, cfg, lr):
assert controlsState is not None and initialized, "controlsState never initialized"
params.put("ReplayControlsState", controlsState.as_builder().to_bytes())
ublox = params.get_bool("UbloxAvailable")
sub_keys = ({"gpsLocation", } if ublox else {"gpsLocationExternal", })
cfg.pubs = set(cfg.pubs) - sub_keys
def locationd_config_pubsub_callback(params, cfg, lr):
ublox = params.get_bool("UbloxAvailable")
@ -479,9 +484,10 @@ CONFIGS = [
proc_name="controlsd",
pubs=[
"carState", "deviceState", "pandaStates", "peripheralState", "liveCalibration", "driverMonitoringState",
"longitudinalPlan", "liveLocationKalman", "liveParameters", "radarState",
"longitudinalPlan", "livePose", "liveParameters", "radarState",
"modelV2", "driverCameraState", "roadCameraState", "wideRoadCameraState", "managerState",
"testJoystick", "liveTorqueParameters", "accelerometer", "gyroscope", "carOutput"
"testJoystick", "liveTorqueParameters", "accelerometer", "gyroscope", "carOutput",
"gpsLocationExternal", "gpsLocation",
],
subs=["controlsState", "carControl", "onroadEvents"],
ignore=["logMonoTime", "controlsState.startMonoTime", "controlsState.cumLagMs"],

@ -1 +1 @@
6ca7313b9c1337fad1334d9e087cb4984fdce74d
d768496a1a85bfe5b74c99a79203affdf9a0a065

@ -1,10 +1,10 @@
#!/bin/bash
#!/usr/bin/env bash
SCRIPT_DIR=$(dirname "$0")
BASEDIR=$(realpath "$SCRIPT_DIR/../../")
cd $BASEDIR
# tests that our build system's dependencies are configured properly,
# tests that our build system's dependencies are configured properly,
# needs a machine with lots of cores
scons --clean
scons --no-cache --random -j$(nproc)
scons --no-cache --random -j$(nproc)

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
set -e
@ -23,7 +23,7 @@ rm -rf /data/safe_staging/* || true
CONTINUE_PATH="/data/continue.sh"
tee $CONTINUE_PATH << EOF
#!/usr/bin/bash
#!/usr/bin/env bash
sudo abctl --set_success

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
{
#start pulseaudio daemon

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
cd /data/openpilot
exec ./launch_openpilot.sh

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -e

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
#nmcli connection modify --temporary lte gsm.home-only yes
#nmcli connection modify --temporary lte gsm.auto-config yes

@ -96,7 +96,7 @@ class TestPowerDraw:
return now, msg_counts, time.monotonic() - start_time - SAMPLE_TIME
@mock_messages(['liveLocationKalman'])
@mock_messages(['livePose'])
def test_camera_procs(self, subtests):
baseline = get_power()

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import os
import argparse
import threading

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import sys
import termios
import atexit

@ -23,7 +23,7 @@ function op_install() {
echo "Installing op system-wide..."
CMD="\nalias op='"$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )/op.sh" \"\$@\"'\n"
grep "alias op=" "$RC_FILE" &> /dev/null || printf "$CMD" >> $RC_FILE
echo -e " ↳ [${GREEN}${NC}] op installed successfully. Open a new shell to use it.\n"
echo -e " ↳ [${GREEN}${NC}] op installed successfully. Open a new shell to use it."
}
function loge() {
@ -37,7 +37,13 @@ function loge() {
function op_run_command() {
CMD="$@"
echo -e "${BOLD}Running:${NC} $CMD"
echo -e "${BOLD}Running command →${NC} $CMD"
for ((i=0; i<$((19 + ${#CMD})); i++)); do
echo -n "─"
done
echo -e "┘\n"
if [[ -z "$DRY" ]]; then
eval "$CMD"
fi
@ -58,7 +64,7 @@ function op_get_openpilot_dir() {
function op_check_openpilot_dir() {
echo "Checking for openpilot directory..."
if [[ -f "$OPENPILOT_ROOT/launch_openpilot.sh" ]]; then
echo -e " ↳ [${GREEN}${NC}] openpilot found.\n"
echo -e " ↳ [${GREEN}${NC}] openpilot found."
return 0
fi
@ -118,7 +124,7 @@ function op_check_os() {
fi
elif [[ "$OSTYPE" == "darwin"* ]]; then
echo -e " ↳ [${GREEN}${NC}] macOS detected.\n"
echo -e " ↳ [${GREEN}${NC}] macOS detected."
else
echo -e " ↳ [${RED}${NC}] OS type $OSTYPE not supported!"
loge "ERROR_UNKNOWN_OS" "$OSTYPE"
@ -171,7 +177,7 @@ function op_before_cmd() {
result="${result}\n$(( op_check_python ) 2>&1)" || (echo -e "$result" && return 1)
if [[ -z $VERBOSE ]]; then
echo -e "Checking system → [${GREEN}${NC}] system is good."
echo -e "${BOLD}Checking system →${NC} [${GREEN}${NC}]"
else
echo -e "$result"
fi
@ -183,7 +189,6 @@ function op_setup() {
op_check_openpilot_dir
op_check_os
op_check_python
echo "Installing dependencies..."
st="$(date +%s)"
@ -192,33 +197,33 @@ function op_setup() {
elif [[ "$OSTYPE" == "darwin"* ]]; then
SETUP_SCRIPT="tools/mac_setup.sh"
fi
if ! op_run_command "$OPENPILOT_ROOT/$SETUP_SCRIPT"; then
if ! $OPENPILOT_ROOT/$SETUP_SCRIPT; then
echo -e " ↳ [${RED}${NC}] Dependencies installation failed!"
loge "ERROR_DEPENDENCIES_INSTALLATION"
return 1
fi
et="$(date +%s)"
echo -e " ↳ [${GREEN}${NC}] Dependencies installed successfully in $((et - st)) seconds.\n"
echo -e " ↳ [${GREEN}${NC}] Dependencies installed successfully in $((et - st)) seconds."
echo "Getting git submodules..."
st="$(date +%s)"
if ! op_run_command git submodule update --filter=blob:none --jobs 4 --init --recursive; then
if ! git submodule update --filter=blob:none --jobs 4 --init --recursive; then
echo -e " ↳ [${RED}${NC}] Getting git submodules failed!"
loge "ERROR_GIT_SUBMODULES"
return 1
fi
et="$(date +%s)"
echo -e " ↳ [${GREEN}${NC}] Submodules installed successfully in $((et - st)) seconds.\n"
echo -e " ↳ [${GREEN}${NC}] Submodules installed successfully in $((et - st)) seconds."
echo "Pulling git lfs files..."
st="$(date +%s)"
if ! op_run_command git lfs pull; then
if ! git lfs pull; then
echo -e " ↳ [${RED}${NC}] Pulling git lfs files failed!"
loge "ERROR_GIT_LFS"
return 1
fi
et="$(date +%s)"
echo -e " ↳ [${GREEN}${NC}] Files pulled successfully in $((et - st)) seconds.\n"
echo -e " ↳ [${GREEN}${NC}] Files pulled successfully in $((et - st)) seconds."
op_check
}
@ -268,7 +273,7 @@ function op_juggle() {
function op_lint() {
op_before_cmd
op_run_command scripts/lint.sh $@
op_run_command scripts/lint/lint.sh $@
}
function op_test() {
@ -328,8 +333,6 @@ function op_default() {
echo " Don't actually run anything, just print what would be run"
echo -e " ${BOLD}-n, --no-verify${NC}"
echo " Skip environment check before running commands"
echo -e " ${BOLD}-v, --verbose${NC}"
echo " Show the result of all checks before running a command"
echo ""
echo -e "${BOLD}${UNDERLINE}Examples:${NC}"
echo " op setup"
@ -350,7 +353,6 @@ function _op() {
-d | --dir ) shift 1; OPENPILOT_ROOT="$1"; shift 1 ;;
--dry ) shift 1; DRY="1" ;;
-n | --no-verify ) shift 1; NO_VERIFY="1" ;;
-v | --verbose ) shift 1; VERBOSE="1" ;;
-l | --log ) shift 1; LOG_FILE="$1" ; shift 1 ;;
esac

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

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
set -e
cd /sys/kernel/tracing

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
set -e

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
if [ ! -d perfetto ]; then
git clone https://android.googlesource.com/platform/external/perfetto/

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
DEST=tici:/data/openpilot/selfdrive/debug/profiling/perfetto

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

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
curl -LO https://get.perfetto.dev/trace_processor
chmod +x ./trace_processor

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
DEST=tici:/data/openpilot/selfdrive/debug/profiling/perfetto

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# TODO: there's probably a better way to do this

@ -1,4 +1,4 @@
#!/bin/bash
#!/usr/bin/env bash
# install depends
sudo apt update
@ -11,4 +11,4 @@ echo "deb https://download.mono-project.com/repo/ubuntu stable-xenial main" | su
sudo apt update
sudo apt-get install -y mono-complete
echo "Setup successful, you should now be able to run the profiler with cd SnapdragonProfiler and ./run_sdp.sh"
echo "Setup successful, you should now be able to run the profiler with cd SnapdragonProfiler and ./run_sdp.sh"

@ -1,4 +1,4 @@
#!/usr/bin/bash
#!/usr/bin/env bash
set -e
RUBYOPT="-W0" irqtop -d1 -R

@ -1,4 +1,4 @@
#! /bin/bash
#!/usr/bin/env bash
# TODO: remove this file once Rerun has interface to set log message level
set -e

@ -1,4 +1,4 @@
#!/usr/bin/env python
#!/usr/bin/env python3
import argparse
import os
import sys

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

Loading…
Cancel
Save