openpilot v0.9.9 release (#35334)

* openpilot v0.9.9 release

date: 2025-06-05T19:54:08
master commit: 8aadf02b2fd91f4e1285e18c2c7feb32d93b66f5

* AGNOS 12.4 (#35558)

agnos12.4

---------

Co-authored-by: Vehicle Researcher <user@comma.ai>
Co-authored-by: Maxime Desroches <desroches.maxime@gmail.com>
This commit is contained in:
Adeeb Shihadeh
2025-06-17 16:32:08 -07:00
committed by GitHub
parent dd778596b7
commit 100f89a161
1240 changed files with 310104 additions and 30549 deletions
+31 -16
View File
@@ -2,6 +2,8 @@
import argparse
import numpy as np
import matplotlib.pyplot as plt
from functools import partial
from tqdm import tqdm
from typing import NamedTuple
from openpilot.tools.lib.logreader import LogReader
from openpilot.selfdrive.locationd.models.pose_kf import EARTH_G
@@ -20,14 +22,15 @@ class Event(NamedTuple):
timestamp: float # relative to start of route (s)
def find_events(lr: LogReader, qlog: bool = False) -> list[Event]:
def find_events(lr: LogReader, extrapolate: bool = False, qlog: bool = False) -> list[Event]:
min_lat_active = RLOG_MIN_LAT_ACTIVE // QLOG_DECIMATION if qlog else RLOG_MIN_LAT_ACTIVE
min_steering_unpressed = RLOG_MIN_STEERING_UNPRESSED // QLOG_DECIMATION if qlog else RLOG_MIN_STEERING_UNPRESSED
min_requesting_max = RLOG_MIN_REQUESTING_MAX // QLOG_DECIMATION if qlog else RLOG_MIN_REQUESTING_MAX
events = []
# if we test with driver torque safety, max torque can be slightly noisy
steer_threshold = 0.7 if extrapolate else 0.95
start_ts = 0
events = []
# state tracking
steering_unpressed = 0 # frames
@@ -38,7 +41,9 @@ def find_events(lr: LogReader, qlog: bool = False) -> list[Event]:
curvature = 0
v_ego = 0
roll = 0
out_torque = 0
start_ts = 0
for msg in lr:
if msg.which() == 'carControl':
if start_ts == 0:
@@ -47,8 +52,8 @@ def find_events(lr: LogReader, qlog: bool = False) -> list[Event]:
lat_active = lat_active + 1 if msg.carControl.latActive else 0
elif msg.which() == 'carOutput':
# if we test with driver torque safety, max torque can be slightly noisy
requesting_max = requesting_max + 1 if abs(msg.carOutput.actuatorsOutput.torque) > 0.95 else 0
out_torque = msg.carOutput.actuatorsOutput.torque
requesting_max = requesting_max + 1 if abs(out_torque) > steer_threshold else 0
elif msg.which() == 'carState':
steering_unpressed = steering_unpressed + 1 if not msg.carState.steeringPressed else 0
@@ -64,7 +69,8 @@ def find_events(lr: LogReader, qlog: bool = False) -> list[Event]:
# TODO: record max lat accel at the end of the event, need to use the past lat accel as overriding can happen before we detect it
requesting_max = 0
current_lateral_accel = curvature * v_ego ** 2 - roll * EARTH_G
factor = 1 / abs(out_torque)
current_lateral_accel = (curvature * v_ego ** 2 * factor) - roll * EARTH_G
events.append(Event(current_lateral_accel, v_ego, roll, round((msg.logMonoTime - start_ts) * 1e-9, 2)))
print(events[-1])
@@ -75,29 +81,38 @@ if __name__ == '__main__':
parser = argparse.ArgumentParser(description="Find max lateral acceleration events",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument("route")
parser.add_argument("route", nargs='+')
parser.add_argument("-e", "--extrapolate", action="store_true", help="Extrapolates max lateral acceleration events linearly. " +
"This option can be far less accurate.")
args = parser.parse_args()
lr = LogReader(args.route, sort_by_time=True)
qlog = args.route.endswith('/q')
if qlog:
print('WARNING: Treating route as qlog!')
events = []
for route in tqdm(args.route):
try:
lr = LogReader(route, sort_by_time=True)
except Exception:
print(f'Skipping {route}')
continue
print('Finding events...')
events = find_events(lr, qlog=qlog)
qlog = route.endswith('/q')
if qlog:
print('WARNING: Treating route as qlog!')
print('Finding events...')
events += lr.run_across_segments(8, partial(find_events, extrapolate=args.extrapolate, qlog=qlog), disable_tqdm=True)
print()
print(f'Found {len(events)} events')
perc_left_accel = -np.percentile([-ev.lateral_accel for ev in events if ev.lateral_accel < 0], 90)
perc_right_accel = np.percentile([ev.lateral_accel for ev in events if ev.lateral_accel > 0], 90)
perc_left_accel = -np.percentile([-ev.lateral_accel for ev in events if ev.lateral_accel < 0] or [0], 90)
perc_right_accel = np.percentile([ev.lateral_accel for ev in events if ev.lateral_accel > 0] or [0], 90)
CP = lr.first('carParams')
plt.ion()
plt.clf()
plt.suptitle(f'{CP.carFingerprint} - Max lateral acceleration events')
plt.title(args.route)
plt.title(', '.join(args.route))
plt.scatter([ev.speed for ev in events], [ev.lateral_accel for ev in events], label='max lateral accel events')
plt.plot([0, 35], [3, 3], c='r', label='ISO 11270 - 3 m/s^2')
@@ -1,33 +0,0 @@
#!/usr/bin/env python3
import cereal.messaging as messaging
if __name__ == "__main__":
modeld_sock = messaging.sub_sock("modelV2")
last_frame_id = None
start_t: int | None = None
frame_cnt = 0
dropped = 0
while True:
m = messaging.recv_one(modeld_sock)
if m is None:
continue
frame_id = m.modelV2.frameId
t = m.logMonoTime / 1e9
frame_cnt += 1
if start_t is None:
start_t = t
last_frame_id = frame_id
continue
d_frame = frame_id - last_frame_id
dropped += d_frame - 1
expected_num_frames = int((t - start_t) * 20)
frame_drop = 100 * (1 - (expected_num_frames / frame_cnt))
print(f"Num dropped {dropped}, Drop compared to 20Hz: {frame_drop:.2f}%")
last_frame_id = frame_id
+1 -1
View File
@@ -15,7 +15,7 @@ if __name__ == "__main__":
else:
CP = car.CarParams.new_message()
CP.openpilotLongitudinalControl = True
CP.experimentalLongitudinalAvailable = False
CP.alphaLongitudinalAvailable = False
cp_bytes = CP.to_bytes()
for p in ("CarParams", "CarParamsCache", "CarParamsPersistent"):
-20
View File
@@ -1,20 +0,0 @@
#!/usr/bin/env python3
from opendbc.car.fingerprints import eliminate_incompatible_cars, all_legacy_fingerprint_cars
import cereal.messaging as messaging
# rav4 2019 and corolla tss2
fingerprint = {896: 8, 898: 8, 900: 6, 976: 1, 1541: 8, 902: 6, 905: 8, 810: 2, 1164: 8, 1165: 8, 1166: 8, 1167: 8, 1552: 8, 1553: 8, 1556: 8, 1571: 8, 921: 8, 1056: 8, 544: 4, 1570: 8, 1059: 1, 36: 8, 37: 8, 550: 8, 935: 8, 552: 4, 170: 8, 812: 8, 944: 8, 945: 8, 562: 6, 180: 8, 1077: 8, 951: 8, 1592: 8, 1076: 8, 186: 4, 955: 8, 956: 8, 1001: 8, 705: 8, 452: 8, 1788: 8, 464: 8, 824: 8, 466: 8, 467: 8, 761: 8, 728: 8, 1572: 8, 1114: 8, 933: 8, 800: 8, 608: 8, 865: 8, 610: 8, 1595: 8, 934: 8, 998: 5, 1745: 8, 1000: 8, 764: 8, 1002: 8, 999: 7, 1789: 8, 1649: 8, 1779: 8, 1568: 8, 1017: 8, 1786: 8, 1787: 8, 1020: 8, 426: 6, 1279: 8} # noqa: E501
candidate_cars = all_legacy_fingerprint_cars()
for addr, l in fingerprint.items():
dat = messaging.new_message('can', 1)
msg = dat.can[0]
msg.address = addr
msg.dat = " " * l
candidate_cars = eliminate_incompatible_cars(msg, candidate_cars)
print(candidate_cars)