Merge remote-tracking branch 'comma/master' into sync-20250309

# Conflicts:
#	.github/workflows/ui_preview.yaml
#	common/params_keys.h
#	msgq_repo
#	opendbc_repo
#	panda
#	selfdrive/ui/qt/offroad/firehose.h
#	selfdrive/ui/tests/test_ui/run.py
#	system/manager/process_config.py
This commit is contained in:
DevTekVE
2025-03-09 14:53:03 +01:00
119 changed files with 1382 additions and 1337 deletions
+1 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env expect
spawn adb shell
expect "#"
send "cd usr/comma\r"
send "cd data/openpilot\r"
send "export TERM=xterm-256color\r"
send "su comma\r"
send "clear\r"
+3 -3
View File
@@ -7,7 +7,7 @@ from opendbc.car.fingerprints import MIGRATION
from opendbc.car.values import PLATFORMS
def generate_dbc_json() -> str:
def generate_dbc_dict() -> dict[str, str]:
dbc_map = {}
for platform in PLATFORMS.values():
if platform != "MOCK":
@@ -24,7 +24,7 @@ def generate_dbc_json() -> str:
if MIGRATION[m] in dbc_map:
dbc_map[m] = dbc_map[MIGRATION[m]]
return json.dumps(dict(sorted(dbc_map.items())), indent=2)
return dbc_map
if __name__ == "__main__":
@@ -35,5 +35,5 @@ if __name__ == "__main__":
args = parser.parse_args()
with open(args.out, 'w') as f:
f.write(generate_dbc_json())
f.write(json.dumps(dict(sorted(generate_dbc_dict().items())), indent=2))
print(f"Generated and written to {args.out}")
+36 -3
View File
@@ -57,7 +57,21 @@ Traceback (most recent call last):
AssertionError: 1 is not false : panda safety doesn't agree with openpilot: {'gasPressed': 116}
```
### [tools/car_porting/examples/subaru_steer_temp_fault.ipynb](/tools/car_porting/examples/subaru_steer_temp_fault.ipynb)
## Jupyter notebooks
To use these notebooks, install Jupyter within your [openpilot virtual environment](/tools/README.md).
```bash
uv pip install jupyter ipykernel
```
Launching:
```bash
jupyter notebook
```
### [examples/subaru_steer_temp_fault.ipynb](/tools/car_porting/examples/subaru_steer_temp_fault.ipynb)
An example of searching through a database of segments for a specific condition, and plotting the results.
@@ -65,7 +79,7 @@ An example of searching through a database of segments for a specific condition,
*a plot of the steer_warning vs steering angle, where we can see it is clearly caused by a large steering angle change*
### [tools/car_porting/examples/subaru_long_accel.ipynb](/tools/car_porting/examples/subaru_long_accel.ipynb)
### [examples/subaru_long_accel.ipynb](/tools/car_porting/examples/subaru_long_accel.ipynb)
An example of plotting the response of an actuator when it is active.
@@ -73,7 +87,7 @@ An example of plotting the response of an actuator when it is active.
*a plot of the brake_pressure vs acceleration, where we can see it is a fairly linear response.*
### [tools/car_porting/examples/ford_vin_fingerprint.ipynb](/tools/car_porting/examples/ford_vin_fingerprint.ipynb)
### [examples/ford_vin_fingerprint.ipynb](/tools/car_porting/examples/ford_vin_fingerprint.ipynb)
In this example, we use the public comma car segments database to check if vin fingerprinting is feasible for ford.
@@ -94,3 +108,22 @@ vin: 5LM5J7XC8MGXXXXXX real platform: FORD EXPLORER 6TH GEN determi
vin: 3FTTW8E31PRXXXXXX real platform: FORD MAVERICK 1ST GEN determined platform: mock correct: False
vin: 3FTTW8E99NRXXXXXX real platform: FORD MAVERICK 1ST GEN determined platform: mock correct: False
```
### [examples/find_segments_with_message.ipynb](/tools/car_porting/examples/find_segments_with_message.ipynb)
Searches for segments where a set of given CAN message IDs are present. In the example, we search for all messages
used for CAN-based ignition detection.
```
Match found: 46b21f1c5f7aa885/2024-01-23--15-19-34/20/s JEEP GRAND CHEROKEE V6 2018 ['VW CAN Ign']
Match found: a63a23c3e628f288/2023-11-05--18-36-20/8/s JEEP GRAND CHEROKEE V6 2018 ['VW CAN Ign']
Match found: ce31b7a998781ba8/2024-01-19--07-05-29/23/s JEEP GRAND CHEROKEE 2019 ['VW CAN Ign']
Match found: e1dfba62a4e33f7b/2023-12-25--19-31-00/4/s JEEP GRAND CHEROKEE 2019 ['VW CAN Ign']
Match found: e1dfba62a4e33f7b/2024-01-10--14-33-57/2/s JEEP GRAND CHEROKEE 2019 ['VW CAN Ign']
Match found: ae679616266f4096/2023-12-05--15-43-46/4/s RAM HD 5TH GEN ['Tesla 3/Y CAN Ign']
Match found: ae679616266f4096/2023-11-18--17-49-42/3/s RAM HD 5TH GEN ['Tesla 3/Y CAN Ign']
Match found: ae679616266f4096/2024-01-03--21-57-09/25/s RAM HD 5TH GEN ['Tesla 3/Y CAN Ign']
Match found: 6dae2984cc53cd7f/2023-12-10--11-53-15/17/s FORD BRONCO SPORT 1ST GEN ['Rivian CAN Ign']
Match found: 6dae2984cc53cd7f/2023-12-03--17-31-17/29/s FORD BRONCO SPORT 1ST GEN ['Rivian CAN Ign']
Match found: 6dae2984cc53cd7f/2023-11-27--23-29-07/1/s FORD BRONCO SPORT 1ST GEN ['Rivian CAN Ign']
```
@@ -0,0 +1,232 @@
{
"cells": [
{
"cell_type": "code",
"execution_count": 85,
"id": "facb8edc-9924-491a-a4dd-fe6135b0c6c4",
"metadata": {},
"outputs": [],
"source": [
"# Import all cars from opendbc\n",
"\n",
"from opendbc.car import structs\n",
"from opendbc.car.values import PLATFORMS as TEST_PLATFORMS\n",
"\n",
"# Example: add additional platforms/segments to test outside of commaCarSegments\n",
"\n",
"EXTRA_SEGMENTS = {\n",
" # \"81dd9e9fe256c397/0000001f--97c42cf98d\", # Volkswagen ID.4 test route, new car port, not in public dataset\n",
"}"
]
},
{
"cell_type": "code",
"execution_count": 86,
"id": "ed1c8aec-c274-4c61-b83d-711ea194bf86",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Searching 221 platforms\n",
"No segments available for DODGE_DURANGO\n",
"No segments available for FORD_RANGER_MK2\n",
"No segments available for HOLDEN_ASTRA\n",
"No segments available for CADILLAC_ATS\n",
"No segments available for CHEVROLET_MALIBU\n",
"No segments available for CADILLAC_XT4\n",
"No segments available for CHEVROLET_VOLT_2019\n",
"No segments available for CHEVROLET_TRAVERSE\n",
"No segments available for GMC_YUKON\n",
"No segments available for HONDA_ODYSSEY_CHN\n",
"No segments available for HYUNDAI_KONA_2022\n",
"No segments available for HYUNDAI_NEXO_1ST_GEN\n",
"No segments available for GENESIS_GV70_ELECTRIFIED_1ST_GEN\n",
"No segments available for GENESIS_G80_2ND_GEN_FL\n",
"No segments available for RIVIAN_R1_GEN1\n",
"No segments available for SUBARU_FORESTER_HYBRID\n",
"No segments available for TESLA_MODEL_3\n",
"No segments available for TESLA_MODEL_Y\n",
"No segments available for TOYOTA_RAV4_PRIME\n",
"No segments available for TOYOTA_SIENNA_4TH_GEN\n",
"No segments available for LEXUS_LC_TSS2\n",
"No segments available for VOLKSWAGEN_CADDY_MK3\n",
"No segments available for VOLKSWAGEN_CRAFTER_MK2\n",
"No segments available for VOLKSWAGEN_JETTA_MK6\n",
"Searching 577 segments\n"
]
}
],
"source": [
"import random\n",
"\n",
"from openpilot.tools.lib.logreader import LogReader\n",
"from openpilot.tools.lib.comma_car_segments import get_comma_car_segments_database\n",
"\n",
"\n",
"MAX_SEGS_PER_PLATFORM = 3 # Increase this to search more segments\n",
"\n",
"database = get_comma_car_segments_database()\n",
"TEST_SEGMENTS = []\n",
"\n",
"print(f\"Searching {len(TEST_PLATFORMS)} platforms\")\n",
"\n",
"for platform in TEST_PLATFORMS:\n",
" if platform not in database:\n",
" print(f\"No segments available for {platform}\")\n",
" continue\n",
" \n",
" all_segments = database[platform]\n",
" NUM_SEGMENTS = min(len(all_segments), MAX_SEGS_PER_PLATFORM)\n",
" TEST_SEGMENTS.extend(random.sample(all_segments, NUM_SEGMENTS))\n",
"\n",
"TEST_SEGMENTS.extend(EXTRA_SEGMENTS)\n",
"\n",
"print(f\"Searching {len(TEST_SEGMENTS)} segments\")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0c75e8f2-4f5f-4f89-b8db-5223a6534a9f",
"metadata": {},
"outputs": [
{
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "27a243c33de44498b2b946190df44b23",
"version_major": 2,
"version_minor": 0
},
"text/plain": [
"segments searched: 0%| | 0/577 [00:00<?, ?it/s]"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"Match found: 0f53b336851e1384/2023-11-20--09-44-03/12/s CHRYSLER PACIFICA HYBRID 2018 ['VW CAN Ign']\n",
"Match found: 7620ad20d3cefc64/2023-10-28--08-14-40/3/s CHRYSLER PACIFICA HYBRID 2018 ['VW CAN Ign']\n",
"Match found: 00d247a9bb1f9196/2023-11-06--13-33-17/9/s CHRYSLER PACIFICA HYBRID 2018 ['VW CAN Ign']\n",
"Match found: 120a432f63cb0de2/2023-10-30--20-01-34/1/s CHRYSLER PACIFICA HYBRID 2019 ['VW CAN Ign']\n",
"Match found: b70b56b76a6217f2/2023-12-19--08-30-22/35/s CHRYSLER PACIFICA HYBRID 2019 ['VW CAN Ign']\n",
"Match found: 97e388680a6716ed/2024-01-17--10-15-13/9/s CHRYSLER PACIFICA HYBRID 2019 ['VW CAN Ign']\n",
"Match found: 2137b01aa0ca63f9/2024-01-06--22-06-14/70/s CHRYSLER PACIFICA 2018 ['VW CAN Ign']\n",
"Match found: 8fc6a1b72c8b1357/2023-11-06--07-50-05/8/s CHRYSLER PACIFICA 2018 ['VW CAN Ign']\n",
"Match found: 7e705eb5c27a49cc/2024-01-18--16-51-20/3/s CHRYSLER PACIFICA 2018 ['VW CAN Ign']\n",
"Match found: 12208e5acdc97eb3/2024-01-20--14-46-24/12/s CHRYSLER PACIFICA 2020 ['VW CAN Ign']\n",
"Match found: 12208e5acdc97eb3/2023-11-30--12-01-09/2/s CHRYSLER PACIFICA 2020 ['VW CAN Ign']\n",
"Match found: 9cad19e0efce3650/2024-01-26--10-24-52/27/s CHRYSLER PACIFICA 2020 ['VW CAN Ign']\n",
"Match found: 9db428338427dec2/2023-11-05--18-40-09/21/s JEEP GRAND CHEROKEE V6 2018 ['VW CAN Ign']\n",
"Match found: d50ada8ee55a5e74/2023-12-11--13-38-09/0/s JEEP GRAND CHEROKEE V6 2018 ['VW CAN Ign']\n",
"Match found: 900dfa83b4addfe6/2023-12-30--19-20-08/28/s JEEP GRAND CHEROKEE V6 2018 ['VW CAN Ign']\n",
"Match found: 20acda0eb23d7f23/2024-01-19--17-33-26/41/s JEEP GRAND CHEROKEE 2019 ['VW CAN Ign']\n",
"Match found: 1cc3b46843cad2ca/2024-01-10--20-20-54/24/s JEEP GRAND CHEROKEE 2019 ['VW CAN Ign']\n",
"Match found: 2d9b6425552c52c1/2023-12-07--10-31-46/22/s JEEP GRAND CHEROKEE 2019 ['VW CAN Ign']\n",
"Match found: ae679616266f4096/2023-12-04--13-13-56/16/s RAM HD 5TH GEN ['Tesla 3/Y CAN Ign']\n",
"Match found: ae679616266f4096/2024-01-08--07-58-12/65/s RAM HD 5TH GEN ['Tesla 3/Y CAN Ign']\n",
"Match found: ae679616266f4096/2023-12-05--15-43-46/25/s RAM HD 5TH GEN ['Tesla 3/Y CAN Ign']\n",
"Match found: 6dae2984cc53cd7f/2024-01-09--21-41-11/4/s FORD BRONCO SPORT 1ST GEN ['Rivian CAN Ign']\n",
"Match found: 440a155809ba2b6d/2023-12-30--08-51-53/2/s FORD BRONCO SPORT 1ST GEN ['Rivian CAN Ign']\n",
"Match found: 6dae2984cc53cd7f/2024-01-06--10-11-07/1/s FORD BRONCO SPORT 1ST GEN ['Rivian CAN Ign']\n",
"Match found: a4218e6416dfd978/2023-11-27--13-48-46/19/s FORD ESCAPE 4TH GEN ['Rivian CAN Ign']\n",
"Match found: a4218e6416dfd978/2023-11-10--14-13-14/0/s FORD ESCAPE 4TH GEN ['Rivian CAN Ign']\n",
"Match found: a4218e6416dfd978/2023-11-27--13-48-46/4/s FORD ESCAPE 4TH GEN ['Rivian CAN Ign']\n",
"Match found: 8a732841c3a8d5ef/2023-12-10--19-02-33/3/s FORD EXPLORER 6TH GEN ['Rivian CAN Ign']\n",
"Match found: 0b91b433b9332780/2023-12-28--14-02-49/4/s FORD EXPLORER 6TH GEN ['Rivian CAN Ign']\n",
"Match found: 8a732841c3a8d5ef/2023-11-09--07-28-12/1/s FORD EXPLORER 6TH GEN ['Rivian CAN Ign']\n",
"Match found: e886087f430e7fe7/2023-11-05--19-59-40/59/s FORD FOCUS 4TH GEN ['Rivian CAN Ign']\n",
"Match found: e886087f430e7fe7/2023-11-05--19-59-40/82/s FORD FOCUS 4TH GEN ['Rivian CAN Ign']\n",
"Match found: e886087f430e7fe7/2023-11-05--19-59-40/106/s FORD FOCUS 4TH GEN ['Rivian CAN Ign']\n"
]
}
],
"source": [
"from openpilot.tools.lib.logreader import LogReader\n",
"from tqdm.notebook import tqdm, tnrange\n",
"\n",
"# Example search for CAN ignition messages\n",
"# Be careful when filtering by bus, account for odd harness arrangements on Honda/HKG\n",
"\n",
"BUSES_TO_SEARCH = [0, 1, 2]\n",
"\n",
"# Support for external Red Panda\n",
"EXTERNAL_PANDA_BUSES = [bus + 4 for bus in BUSES_TO_SEARCH]\n",
"\n",
"MESSAGES_TO_FIND = {\n",
" 0x1F1: \"GM CAN Ign\",\n",
" 0x152: \"Rivian CAN Ign\",\n",
" 0x221: \"Tesla 3/Y CAN Ign\",\n",
" 0x9E: \"Mazda CAN Ign\",\n",
" 0x3C0: \"VW CAN Ign\",\n",
"}\n",
"\n",
"progress_bar = tnrange(len(TEST_SEGMENTS), desc=\"segments searched\")\n",
"\n",
"for segment in TEST_SEGMENTS:\n",
" lr = LogReader(segment)\n",
" CP = lr.first(\"carParams\")\n",
" if CP is None:\n",
" progress_bar.update()\n",
" continue\n",
"\n",
" can_packets = [msg for msg in lr if msg.which() == \"can\"]\n",
" matched_messages = set()\n",
"\n",
" for packet in can_packets:\n",
" for msg in packet.can:\n",
" if msg.address in MESSAGES_TO_FIND and msg.src in (BUSES_TO_SEARCH + EXTERNAL_PANDA_BUSES):\n",
" # print(msg)\n",
" matched_messages.add(msg.address)\n",
"\n",
" if len(matched_messages) > 0:\n",
" message_names = [MESSAGES_TO_FIND[message] for message in matched_messages]\n",
" print(f\"Match found: {segment:<45} {CP.carFingerprint:<38} {message_names}\")\n",
"\n",
" progress_bar.update()\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7724dd97-f62e-4fd3-9f64-63d49be669d2",
"metadata": {},
"outputs": [],
"source": []
},
{
"cell_type": "code",
"execution_count": null,
"id": "9f393e00-8efd-40fb-a41e-d312531a83e8",
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.12.0"
}
},
"nbformat": 4,
"nbformat_minor": 5
}
+5 -5
View File
@@ -13,6 +13,7 @@ from functools import partial
from opendbc.car.fingerprints import MIGRATION
from openpilot.common.basedir import BASEDIR
from openpilot.common.swaglog import cloudlog
from openpilot.tools.cabana.dbc.generate_dbc_json import generate_dbc_dict
from openpilot.tools.lib.logreader import LogReader, ReadMode, save_log
from openpilot.selfdrive.test.process_replay.migration import migrate_all
@@ -75,7 +76,7 @@ def start_juggler(fn=None, dbc=None, layout=None, route_or_segment_name=None, pl
def process(can, lr):
return [d for d in lr if can or d.which() not in ['can', 'sendcan']]
return [d for d in lr if can or d.which() not in ['can', 'sendcan'] and not d.which().startswith('customReserved')]
def juggle_route(route_or_segment_name, can, layout, dbc, should_migrate):
@@ -90,11 +91,10 @@ def juggle_route(route_or_segment_name, can, layout, dbc, should_migrate):
if dbc is None:
try:
CP = lr.first('carParams')
platform = CP.carFingerprint
DBC = __import__(f"opendbc.car.{CP.brand}.values", fromlist=['DBC']).DBC
dbc = DBC[MIGRATION.get(CP.carFingerprint, CP.carFingerprint)]['pt']
platform = MIGRATION.get(CP.carFingerprint, CP.carFingerprint)
dbc = generate_dbc_dict()[platform]
except Exception:
cloudlog.error("Failed to get DBC name from logs!")
cloudlog.exception("Failed to get DBC name from logs!")
with tempfile.NamedTemporaryFile(suffix='.rlog', dir=juggle_dir) as tmp:
save_log(tmp.name, all_data, compress=False)
@@ -24,7 +24,7 @@
<range left="0.000450" top="1.050000" right="2483.624998" bottom="-1.050000"/>
<limitY/>
<curve color="#0097ff" name="/carState/steeringPressed"/>
<curve color="#d62728" name="/carOutput/actuatorsOutput/steer"/>
<curve color="#d62728" name="/carOutput/actuatorsOutput/torque"/>
</plot>
</DockArea>
<DockArea name="...">
@@ -24,8 +24,8 @@
<plot flip_x="false" style="Lines" flip_y="false" mode="TimeSeries">
<range top="1.082031" right="269.643117" left="0.000140" bottom="-1.050781"/>
<limitY/>
<curve color="#9467bd" name="/carOutput/actuatorsOutput/steer">
<transform alias="/carOutput/actuatorsOutput/steer[Scale/Offset]" name="Scale/Offset">
<curve color="#9467bd" name="/carOutput/actuatorsOutput/torque">
<transform alias="/carOutput/actuatorsOutput/torque[Scale/Offset]" name="Scale/Offset">
<options value_scale="-1" time_offset="0" value_offset="0"/>
</transform>
</curve>
@@ -114,8 +114,8 @@
<plot flip_x="false" style="Lines" flip_y="false" mode="TimeSeries">
<range top="1.082031" right="269.643117" left="0.000140" bottom="-1.050781"/>
<limitY/>
<curve color="#9467bd" name="/carOutput/actuatorsOutput/steer">
<transform alias="/carOutput/actuatorsOutput/steer[Scale/Offset]" name="Scale/Offset">
<curve color="#9467bd" name="/carOutput/actuatorsOutput/torque">
<transform alias="/carOutput/actuatorsOutput/torque[Scale/Offset]" name="Scale/Offset">
<options value_scale="-1.0" time_offset="0" value_offset="0"/>
</transform>
</curve>
+2 -2
View File
@@ -58,8 +58,8 @@ Mock openpilot components by publishing logged messages.
Options:
-h, --help Displays this help.
-a, --allow <allow> whitelist of services to send
-b, --block <block> blacklist of services to send
-a, --allow <allow> whitelist of services to send (comma-separated)
-b, --block <block> blacklist of services to send (comma-separated)
-c, --cache <n> cache <n> segments in memory. default is 5
-s, --start <seconds> start from <seconds>
-x <speed> playback <speed>. between 0.2 - 3
+3 -3
View File
@@ -11,10 +11,10 @@
#include "tools/replay/util.h"
const std::string helpText =
R"(Usage: replay [options]
R"(Usage: replay [options] [route]
Options:
-a, --allow Whitelist of services to send
-b, --block Blacklist of services to send
-a, --allow Whitelist of services to send (comma-separated)
-b, --block Blacklist of services to send (comma-separated)
-c, --cache Cache <n> segments in memory. Default is 5
-s, --start Start from <seconds>
-x, --playback Playback <speed>
+2 -3
View File
@@ -8,7 +8,6 @@ import numpy as np
import pygame
import cereal.messaging as messaging
from openpilot.common.numpy_fast import clip
from openpilot.common.basedir import BASEDIR
from openpilot.common.transformations.camera import DEVICE_CAMERAS
from openpilot.tools.replay.lib.ui_helpers import (UP,
@@ -152,11 +151,11 @@ def ui_thread(addr):
plot_arr[-1, name_to_arr_idx['angle_steers_k']] = angle_steers_k
plot_arr[-1, name_to_arr_idx['gas']] = sm['carState'].gas
# TODO gas is deprecated
plot_arr[-1, name_to_arr_idx['computer_gas']] = clip(sm['carControl'].actuators.accel/4.0, 0.0, 1.0)
plot_arr[-1, name_to_arr_idx['computer_gas']] = np.clip(sm['carControl'].actuators.accel/4.0, 0.0, 1.0)
plot_arr[-1, name_to_arr_idx['user_brake']] = sm['carState'].brake
plot_arr[-1, name_to_arr_idx['steer_torque']] = sm['carControl'].actuators.torque * ANGLE_SCALE
# TODO brake is deprecated
plot_arr[-1, name_to_arr_idx['computer_brake']] = clip(-sm['carControl'].actuators.accel/4.0, 0.0, 1.0)
plot_arr[-1, name_to_arr_idx['computer_brake']] = np.clip(-sm['carControl'].actuators.accel/4.0, 0.0, 1.0)
plot_arr[-1, name_to_arr_idx['v_ego']] = sm['carState'].vEgo
plot_arr[-1, name_to_arr_idx['v_cruise']] = sm['carState'].cruiseState.speed
plot_arr[-1, name_to_arr_idx['a_ego']] = sm['carState'].aEgo
+2 -2
View File
@@ -49,7 +49,7 @@ class SteeringAccuracyTool:
active = sm['controlsState'].active
steer = sm['carOutput'].actuatorsOutput.torque
standstill = sm['carState'].standstill
steer_limited = abs(sm['carControl'].actuators.torque - sm['carControl'].actuatorsOutput.torque) > 1e-2
steer_limited_by_controls = abs(sm['carControl'].actuators.torque - sm['carControl'].actuatorsOutput.torque) > 1e-2
overriding = sm['carState'].steeringPressed
changing_lanes = sm['modelV2'].meta.laneChangeState != 0
model_points = sm['modelV2'].position.y
@@ -77,7 +77,7 @@ class SteeringAccuracyTool:
self.speed_group_stats[group][angle_abs]["steer"] += abs(steer)
if len(model_points):
self.speed_group_stats[group][angle_abs]["dpp"] += abs(model_points[0])
if steer_limited:
if steer_limited_by_controls:
self.speed_group_stats[group][angle_abs]["limited"] += 1
if control_state.saturated:
self.speed_group_stats[group][angle_abs]["saturated"] += 1