diff --git a/RELEASES.md b/RELEASES.md index 56cffeebe7..a749158cb4 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -2,6 +2,8 @@ Version 0.8.17 (2022-XX-XX) ======================== * New driving model * Internal feature space accuracy increased tenfold during training, this makes the model dramatically more accurate. +* torqued + * Learn torque parameters live for each car as opposed to using platform average values, which improves lateral control Version 0.8.16 (2022-08-26) ======================== diff --git a/common/params.cc b/common/params.cc index a64c2f133b..63208879b2 100644 --- a/common/params.cc +++ b/common/params.cc @@ -144,6 +144,8 @@ std::unordered_map keys = { {"LastUpdateException", CLEAR_ON_MANAGER_START}, {"LastUpdateTime", PERSISTENT}, {"LiveParameters", PERSISTENT}, + {"LiveTorqueCarParams", PERSISTENT}, + {"LiveTorqueParameters", PERSISTENT | DONT_LOG}, {"NavDestination", CLEAR_ON_MANAGER_START | CLEAR_ON_IGNITION_OFF}, {"NavSettingTime24h", PERSISTENT}, {"NavSettingLeftSide", PERSISTENT}, diff --git a/release/files_common b/release/files_common index be0a4f0f03..fa4fa997c4 100644 --- a/release/files_common +++ b/release/files_common @@ -240,6 +240,7 @@ selfdrive/locationd/models/live_kf.cc selfdrive/locationd/models/constants.py selfdrive/locationd/models/gnss_helpers.py +selfdrive/locationd/torqued.py selfdrive/locationd/calibrationd.py system/logcatd/.gitignore diff --git a/selfdrive/car/interfaces.py b/selfdrive/car/interfaces.py index 87720f8754..a789fc6cad 100644 --- a/selfdrive/car/interfaces.py +++ b/selfdrive/car/interfaces.py @@ -167,6 +167,7 @@ class CarInterfaceBase(ABC): tune.torque.friction = params['FRICTION'] tune.torque.latAccelFactor = params['LAT_ACCEL_FACTOR'] tune.torque.latAccelOffset = 0.0 + tune.torque.steeringAngleDeadzoneDeg = steering_angle_deadzone_deg @abstractmethod def _update(self, c: car.CarControl) -> car.CarState: diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index 3087535291..8b41e305f1 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -104,7 +104,7 @@ class Controls: ignore += ['roadCameraState'] self.sm = messaging.SubMaster(['deviceState', 'pandaStates', 'peripheralState', 'modelV2', 'liveCalibration', 'driverMonitoringState', 'longitudinalPlan', 'lateralPlan', 'liveLocationKalman', - 'managerState', 'liveParameters', 'radarState'] + self.camera_packets + joystick_packet, + 'managerState', 'liveParameters', 'radarState', 'liveTorqueParameters'] + self.camera_packets + joystick_packet, ignore_alive=ignore, ignore_avg_freq=['radarState', 'longitudinalPlan']) # set alternative experiences from parameters @@ -578,6 +578,12 @@ class Controls: sr = max(params.steerRatio, 0.1) self.VM.update_params(x, sr) + # Update Torque Params + if self.CP.lateralTuning.which() == 'torque': + torque_params = self.sm['liveTorqueParameters'] + if self.sm.all_checks(['liveTorqueParameters']) and torque_params.useParams: + self.LaC.update_live_torque_params(torque_params.latAccelFactorFiltered, torque_params.latAccelOffsetFiltered, torque_params.frictionCoefficientFiltered) + lat_plan = self.sm['lateralPlan'] long_plan = self.sm['longitudinalPlan'] diff --git a/selfdrive/controls/lib/latcontrol_torque.py b/selfdrive/controls/lib/latcontrol_torque.py index f65a58275b..fa1bb480f1 100644 --- a/selfdrive/controls/lib/latcontrol_torque.py +++ b/selfdrive/controls/lib/latcontrol_torque.py @@ -51,7 +51,7 @@ class LatControlTorque(LatControl): desired_lateral_accel = desired_curvature * CS.vEgo ** 2 # desired rate is the desired rate of change in the setpoint, not the absolute desired curvature - #desired_lateral_jerk = desired_curvature_rate * CS.vEgo ** 2 + # desired_lateral_jerk = desired_curvature_rate * CS.vEgo ** 2 actual_lateral_accel = actual_curvature * CS.vEgo ** 2 lateral_accel_deadzone = curvature_deadzone * CS.vEgo ** 2 diff --git a/selfdrive/locationd/torqued.py b/selfdrive/locationd/torqued.py new file mode 100755 index 0000000000..9f07008214 --- /dev/null +++ b/selfdrive/locationd/torqued.py @@ -0,0 +1,290 @@ +#!/usr/bin/env python3 +import os +import sys +import signal +import numpy as np +from collections import deque, defaultdict + +import cereal.messaging as messaging +from cereal import car, log +from common.params import Params +from common.realtime import config_realtime_process, DT_MDL +from common.filter_simple import FirstOrderFilter +from system.swaglog import cloudlog +from selfdrive.controls.lib.vehicle_model import ACCELERATION_DUE_TO_GRAVITY +from selfdrive.car.toyota.values import CAR as TOYOTA + +HISTORY = 5 # secs +POINTS_PER_BUCKET = 1500 +MIN_POINTS_TOTAL = 4000 +FIT_POINTS_TOTAL = 2000 +MIN_VEL = 15 # m/s +FRICTION_FACTOR = 1.5 # ~85% of data coverage +FACTOR_SANITY = 0.3 +FRICTION_SANITY = 0.5 +STEER_MIN_THRESHOLD = 0.02 +MIN_FILTER_DECAY = 50 +MAX_FILTER_DECAY = 250 +LAT_ACC_THRESHOLD = 1 +STEER_BUCKET_BOUNDS = [(-0.5, -0.3), (-0.3, -0.2), (-0.2, -0.1), (-0.1, 0), (0, 0.1), (0.1, 0.2), (0.2, 0.3), (0.3, 0.5)] +MIN_BUCKET_POINTS = [100, 300, 500, 500, 500, 500, 300, 100] +MAX_RESETS = 5.0 +MAX_INVALID_THRESHOLD = 10 +MIN_ENGAGE_BUFFER = 2 # secs + +VERSION = 1 # bump this to invalidate old parameter caches +ALLOWED_FINGERPRINTS = [TOYOTA.COROLLA_TSS2, TOYOTA.COROLLA, TOYOTA.COROLLAH_TSS2] + + +def slope2rot(slope): + sin = np.sqrt(slope**2 / (slope**2 + 1)) + cos = np.sqrt(1 / (slope**2 + 1)) + return np.array([[cos, -sin], [sin, cos]]) + + +class npqueue: + def __init__(self, maxlen, rowsize): + self.maxlen = maxlen + self.arr = np.empty((0, rowsize)) + + def __len__(self): + return len(self.arr) + + def append(self, pt): + if len(self.arr) < self.maxlen: + self.arr = np.append(self.arr, [pt], axis=0) + else: + self.arr[:-1] = self.arr[1:] + self.arr[-1] = pt + + +class PointBuckets: + def __init__(self, x_bounds, min_points): + self.x_bounds = x_bounds + self.buckets = {bounds: npqueue(maxlen=POINTS_PER_BUCKET, rowsize=3) for bounds in x_bounds} + self.buckets_min_points = {bounds: min_point for bounds, min_point in zip(x_bounds, min_points)} + + def bucket_lengths(self): + return [len(v) for v in self.buckets.values()] + + def __len__(self): + return sum(self.bucket_lengths()) + + def is_valid(self): + return all(len(v) >= min_pts for v, min_pts in zip(self.buckets.values(), self.buckets_min_points.values())) and (self.__len__() >= MIN_POINTS_TOTAL) + + def add_point(self, x, y): + for bound_min, bound_max in self.x_bounds: + if (x >= bound_min) and (x < bound_max): + self.buckets[(bound_min, bound_max)].append([x, 1.0, y]) + break + + def get_points(self, num_points=None): + points = np.concatenate([x.arr for x in self.buckets.values() if len(x) > 0]) + if num_points is None: + return points + return points[np.random.choice(np.arange(len(points)), min(len(points), num_points), replace=False)] + + def load_points(self, points): + for x, y in points: + self.add_point(x, y) + + +class TorqueEstimator: + def __init__(self, CP): + self.hist_len = int(HISTORY / DT_MDL) + self.lag = CP.steerActuatorDelay + .2 # from controlsd + + self.offline_friction = 0.0 + self.offline_latAccelFactor = 0.0 + self.resets = 0.0 + self.use_params = CP.carFingerprint in ALLOWED_FINGERPRINTS + + if CP.lateralTuning.which() == 'torque': + self.offline_friction = CP.lateralTuning.torque.friction + self.offline_latAccelFactor = CP.lateralTuning.torque.latAccelFactor + + self.reset() + + initial_params = { + 'latAccelFactor': self.offline_latAccelFactor, + 'latAccelOffset': 0.0, + 'frictionCoefficient': self.offline_friction, + 'points': [] + } + self.decay = MIN_FILTER_DECAY + self.min_lataccel_factor = (1.0 - FACTOR_SANITY) * self.offline_latAccelFactor + self.max_lataccel_factor = (1.0 + FACTOR_SANITY) * self.offline_latAccelFactor + self.min_friction = (1.0 - FRICTION_SANITY) * self.offline_friction + self.max_friction = (1.0 + FRICTION_SANITY) * self.offline_friction + + # try to restore cached params + params = Params() + params_cache = params.get("LiveTorqueCarParams") + torque_cache = params.get("LiveTorqueParameters") + if params_cache is not None and torque_cache is not None: + try: + cache_ltp = log.Event.from_bytes(torque_cache).liveTorqueParameters + cache_CP = car.CarParams.from_bytes(params_cache) + if self.get_restore_key(cache_CP, cache_ltp.version) == self.get_restore_key(CP, VERSION): + initial_params = { + 'latAccelFactor': cache_ltp.latAccelFactorFiltered, + 'latAccelOffset': cache_ltp.latAccelOffsetFiltered, + 'frictionCoefficient': cache_ltp.frictionCoefficientFiltered, + 'points': cache_ltp.points + } + self.decay = cache_ltp.decay + self.filtered_points.load_points(initial_params['points']) + cloudlog.info("restored torque params from cache") + except Exception: + cloudlog.exception("failed to restore cached torque params") + params.remove("LiveTorqueCarParams") + params.remove("LiveTorqueParameters") + + self.filtered_params = {} + for param in initial_params: + self.filtered_params[param] = FirstOrderFilter(initial_params[param], self.decay, DT_MDL) + + def get_restore_key(self, CP, version): + a, b = None, None + if CP.lateralTuning.which() == 'torque': + a = CP.lateralTuning.torque.friction + b = CP.lateralTuning.torque.latAccelFactor + return (CP.carFingerprint, CP.lateralTuning.which(), a, b, version) + + def reset(self): + self.resets += 1.0 + self.invalid_values_tracker = 0.0 + self.decay = MIN_FILTER_DECAY + self.raw_points = defaultdict(lambda: deque(maxlen=self.hist_len)) + self.filtered_points = PointBuckets(x_bounds=STEER_BUCKET_BOUNDS, min_points=MIN_BUCKET_POINTS) + + def estimate_params(self): + points = self.filtered_points.get_points(FIT_POINTS_TOTAL) + # total least square solution as both x and y are noisy observations + # this is empirically the slope of the hysteresis parallelogram as opposed to the line through the diagonals + try: + _, _, v = np.linalg.svd(points, full_matrices=False) + slope, offset = -v.T[0:2, 2] / v.T[2, 2] + _, spread = np.matmul(points[:, [0, 2]], slope2rot(slope)).T + friction_coeff = np.std(spread) * FRICTION_FACTOR + except np.linalg.LinAlgError as e: + cloudlog.exception(f"Error computing live torque params: {e}") + slope = offset = friction_coeff = np.nan + return slope, offset, friction_coeff + + def update_params(self, params): + self.decay = min(self.decay + DT_MDL, MAX_FILTER_DECAY) + for param, value in params.items(): + self.filtered_params[param].update(value) + self.filtered_params[param].update_alpha(self.decay) + + def is_sane(self, latAccelFactor, latAccelOffset, friction): + if any([val is None or np.isnan(val) for val in [latAccelFactor, latAccelOffset, friction]]): + return False + return (self.max_friction >= friction >= self.min_friction) and\ + (self.max_lataccel_factor >= latAccelFactor >= self.min_lataccel_factor) + + def handle_log(self, t, which, msg): + if which == "carControl": + self.raw_points["carControl_t"].append(t + self.lag) + self.raw_points["steer_torque"].append(-msg.actuatorsOutput.steer) + self.raw_points["active"].append(msg.latActive) + elif which == "carState": + self.raw_points["carState_t"].append(t + self.lag) + self.raw_points["vego"].append(msg.vEgo) + self.raw_points["steer_override"].append(msg.steeringPressed) + elif which == "liveLocationKalman": + if len(self.raw_points['steer_torque']) == self.hist_len: + yaw_rate = msg.angularVelocityCalibrated.value[2] + roll = msg.orientationNED.value[0] + active = np.interp(np.arange(t - MIN_ENGAGE_BUFFER, t, DT_MDL), self.raw_points['carControl_t'], self.raw_points['active']).astype(bool) + steer_override = np.interp(np.arange(t - MIN_ENGAGE_BUFFER, t, DT_MDL), self.raw_points['carState_t'], self.raw_points['steer_override']).astype(bool) + vego = np.interp(t, self.raw_points['carState_t'], self.raw_points['vego']) + steer = np.interp(t, self.raw_points['carControl_t'], self.raw_points['steer_torque']) + lateral_acc = (vego * yaw_rate) - (np.sin(roll) * ACCELERATION_DUE_TO_GRAVITY) + if all(active) and (not any(steer_override)) and (vego > MIN_VEL) and (abs(steer) > STEER_MIN_THRESHOLD) and (abs(lateral_acc) <= LAT_ACC_THRESHOLD): + self.filtered_points.add_point(float(steer), float(lateral_acc)) + + def get_msg(self, valid=True, with_points=False): + msg = messaging.new_message('liveTorqueParameters') + msg.valid = valid + liveTorqueParameters = msg.liveTorqueParameters + liveTorqueParameters.version = VERSION + liveTorqueParameters.useParams = self.use_params + + if self.filtered_points.is_valid(): + latAccelFactor, latAccelOffset, friction_coeff = self.estimate_params() + liveTorqueParameters.latAccelFactorRaw = float(latAccelFactor) + liveTorqueParameters.latAccelOffsetRaw = float(latAccelOffset) + liveTorqueParameters.frictionCoefficientRaw = float(friction_coeff) + + if self.is_sane(latAccelFactor, latAccelOffset, friction_coeff): + liveTorqueParameters.liveValid = True + self.update_params({'latAccelFactor': latAccelFactor, 'latAccelOffset': latAccelOffset, 'frictionCoefficient': friction_coeff}) + self.invalid_values_tracker = max(0.0, self.invalid_values_tracker - 0.5) + else: + cloudlog.exception("live torque params are numerically unstable") + liveTorqueParameters.liveValid = False + self.invalid_values_tracker += 1.0 + # Reset when ~10 invalid over 5 secs + if self.invalid_values_tracker > MAX_INVALID_THRESHOLD: + # Do not reset the filter as it may cause a drastic jump, just reset points + self.reset() + else: + liveTorqueParameters.liveValid = False + + if with_points: + liveTorqueParameters.points = self.filtered_points.get_points()[:, [0, 2]].tolist() + + liveTorqueParameters.latAccelFactorFiltered = float(self.filtered_params['latAccelFactor'].x) + liveTorqueParameters.latAccelOffsetFiltered = float(self.filtered_params['latAccelOffset'].x) + liveTorqueParameters.frictionCoefficientFiltered = float(self.filtered_params['frictionCoefficient'].x) + liveTorqueParameters.totalBucketPoints = len(self.filtered_points) + liveTorqueParameters.decay = self.decay + liveTorqueParameters.maxResets = self.resets + return msg + + +def main(sm=None, pm=None): + config_realtime_process([0, 1, 2, 3], 5) + + if sm is None: + sm = messaging.SubMaster(['carControl', 'carState', 'liveLocationKalman'], poll=['liveLocationKalman']) + + if pm is None: + pm = messaging.PubMaster(['liveTorqueParameters']) + + params = Params() + CP = car.CarParams.from_bytes(params.get("CarParams", block=True)) + estimator = TorqueEstimator(CP) + + def cache_params(sig, frame): + signal.signal(sig, signal.SIG_DFL) + cloudlog.warning("caching torque params") + + params = Params() + params.put("LiveTorqueCarParams", CP.as_builder().to_bytes()) + + msg = estimator.get_msg(with_points=True) + params.put("LiveTorqueParameters", msg.to_bytes()) + + sys.exit(0) + if "REPLAY" not in os.environ: + signal.signal(signal.SIGINT, cache_params) + + while True: + sm.update() + if sm.all_checks(): + for which in sm.updated.keys(): + if sm.updated[which]: + t = sm.logMonoTime[which] * 1e-9 + estimator.handle_log(t, which, sm[which]) + + # 4Hz driven by liveLocationKalman + if sm.frame % 5 == 0: + pm.send('liveTorqueParameters', estimator.get_msg(valid=sm.all_checks())) + + +if __name__ == "__main__": + main() diff --git a/selfdrive/manager/process_config.py b/selfdrive/manager/process_config.py index 7702b96eaa..06efdbb960 100644 --- a/selfdrive/manager/process_config.py +++ b/selfdrive/manager/process_config.py @@ -38,6 +38,7 @@ procs = [ NativeProcess("locationd", "selfdrive/locationd", ["./locationd"]), NativeProcess("boardd", "selfdrive/boardd", ["./boardd"], enabled=False), PythonProcess("calibrationd", "selfdrive.locationd.calibrationd"), + PythonProcess("torqued", "selfdrive.locationd.torqued"), PythonProcess("controlsd", "selfdrive.controls.controlsd"), PythonProcess("deleter", "selfdrive.loggerd.deleter", offroad=True), PythonProcess("dmonitoringd", "selfdrive.monitoring.dmonitoringd", enabled=(not PC or WEBCAM), callback=driverview), diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index b4e3f62656..038b0cf468 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -229,6 +229,15 @@ def calibration_rcv_callback(msg, CP, cfg, fsm): return recv_socks, fsm.frame == 0 or msg.which() == 'cameraOdometry' +def torqued_rcv_callback(msg, CP, cfg, fsm): + # should_recv always true to increment frame + recv_socks = [] + frame = fsm.frame + 1 # incrementing hasn't happened yet in SubMaster + if msg.which() == 'liveLocationKalman' and (frame % 5) == 0: + recv_socks = ["liveTorqueParameters"] + return recv_socks, fsm.frame == 0 or msg.which() == 'liveLocationKalman' + + def ublox_rcv_callback(msg): msg_class, msg_id = msg.ubloxRaw[2:4] if (msg_class, msg_id) in {(1, 7 * 16)}: @@ -251,8 +260,10 @@ CONFIGS = [ proc_name="controlsd", pub_sub={ "can": ["controlsState", "carState", "carControl", "sendcan", "carEvents", "carParams"], - "deviceState": [], "pandaStates": [], "peripheralState": [], "liveCalibration": [], "driverMonitoringState": [], "longitudinalPlan": [], "lateralPlan": [], "liveLocationKalman": [], "liveParameters": [], "radarState": [], - "modelV2": [], "driverCameraState": [], "roadCameraState": [], "wideRoadCameraState": [], "managerState": [], "testJoystick": [], + "deviceState": [], "pandaStates": [], "peripheralState": [], "liveCalibration": [], "driverMonitoringState": [], + "longitudinalPlan": [], "lateralPlan": [], "liveLocationKalman": [], "liveParameters": [], "radarState": [], + "modelV2": [], "driverCameraState": [], "roadCameraState": [], "wideRoadCameraState": [], "managerState": [], + "testJoystick": [], "liveTorqueParameters": [], }, ignore=["logMonoTime", "valid", "controlsState.startMonoTime", "controlsState.cumLagMs"], init_callback=fingerprint, @@ -374,6 +385,18 @@ CONFIGS = [ tolerance=NUMPY_TOLERANCE, fake_pubsubmaster=True, ), + ProcessConfig( + proc_name="torqued", + pub_sub={ + "liveLocationKalman": ["liveTorqueParameters"], + "carState": [], "controlsState": [], + }, + ignore=["logMonoTime"], + init_callback=get_car_params, + should_recv_callback=torqued_rcv_callback, + tolerance=NUMPY_TOLERANCE, + fake_pubsubmaster=True, + ), ] diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index afde6ec422..7b24c04c98 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -d14f1a61a4bfde810128a6bb703aa543268fa4a9 \ No newline at end of file +deb07ca8c5dc021e57e81307764a84aa3d7aef32 \ No newline at end of file diff --git a/selfdrive/test/process_replay/regen.py b/selfdrive/test/process_replay/regen.py index 4e1cbfd30d..d565e36390 100755 --- a/selfdrive/test/process_replay/regen.py +++ b/selfdrive/test/process_replay/regen.py @@ -269,11 +269,11 @@ def regen_segment(lr, frs=None, outdir=FAKEDATA, disable_tqdm=False): return seg_path -def regen_and_save(route, sidx, upload=False, use_route_meta=False, outdir=FAKEDATA, disable_tqdm=False): +def regen_and_save(route, sidx, upload=False, use_route_meta=True, outdir=FAKEDATA, disable_tqdm=False): if use_route_meta: - r = Route(args.route) - lr = LogReader(r.log_paths()[args.seg]) - fr = FrameReader(r.camera_paths()[args.seg]) + r = Route(route) + lr = LogReader(r.log_paths()[sidx]) + fr = FrameReader(r.camera_paths()[sidx]) else: lr = LogReader(f"cd:/{route.replace('|', '/')}/{sidx}/rlog.bz2") fr = FrameReader(f"cd:/{route.replace('|', '/')}/{sidx}/fcamera.hevc") diff --git a/selfdrive/test/process_replay/regen_all.py b/selfdrive/test/process_replay/regen_all.py index f10d7ea03a..f69d07eb69 100755 --- a/selfdrive/test/process_replay/regen_all.py +++ b/selfdrive/test/process_replay/regen_all.py @@ -3,11 +3,12 @@ import argparse import concurrent.futures import os import random +import traceback from tqdm import tqdm from selfdrive.test.process_replay.helpers import OpenpilotPrefix from selfdrive.test.process_replay.regen import regen_and_save -from selfdrive.test.process_replay.test_processes import FAKEDATA, original_segments as segments +from selfdrive.test.process_replay.test_processes import FAKEDATA, source_segments as segments from tools.lib.route import SegmentName @@ -16,11 +17,15 @@ def regen_job(segment, upload, disable_tqdm): sn = SegmentName(segment[1]) fake_dongle_id = 'regen' + ''.join(random.choice('0123456789ABCDEF') for _ in range(11)) try: - relr = regen_and_save(sn.route_name.canonical_name, sn.segment_num, upload=upload, use_route_meta=False, outdir=os.path.join(FAKEDATA, fake_dongle_id), disable_tqdm=disable_tqdm) + relr = regen_and_save(sn.route_name.canonical_name, sn.segment_num, upload=upload, use_route_meta=False, + outdir=os.path.join(FAKEDATA, fake_dongle_id), disable_tqdm=disable_tqdm) relr = '|'.join(relr.split('/')[-2:]) return f' ("{segment[0]}", "{relr}"), ' except Exception as e: - return f" {segment} failed: {str(e)}" + err = f" {segment} failed: {str(e)}" + err += traceback.format_exc() + err += "\n\n" + return err if __name__ == "__main__": diff --git a/selfdrive/test/process_replay/test_processes.py b/selfdrive/test/process_replay/test_processes.py index 0f118971c6..ee892a2fd9 100755 --- a/selfdrive/test/process_replay/test_processes.py +++ b/selfdrive/test/process_replay/test_processes.py @@ -15,22 +15,22 @@ from system.version import get_commit from tools.lib.filereader import FileReader from tools.lib.logreader import LogReader -original_segments = [ +source_segments = [ ("BODY", "937ccb7243511b65|2022-05-24--16-03-09--1"), # COMMA.BODY ("HYUNDAI", "02c45f73a2e5c6e9|2021-01-01--19-08-22--1"), # HYUNDAI.SONATA - ("HYUNDAI", "d824e27e8c60172c|2022-08-19--17-58-07--2"), # HYUNDAI.KIA_EV6 + ("HYUNDAI", "d824e27e8c60172c|2022-09-13--11-26-50--2"), # HYUNDAI.KIA_EV6 ("TOYOTA", "0982d79ebb0de295|2021-01-04--17-13-21--13"), # TOYOTA.PRIUS (INDI) ("TOYOTA2", "0982d79ebb0de295|2021-01-03--20-03-36--6"), # TOYOTA.RAV4 (LQR) ("TOYOTA3", "f7d7e3538cda1a2a|2021-08-16--08-55-34--6"), # TOYOTA.COROLLA_TSS2 ("HONDA", "eb140f119469d9ab|2021-06-12--10-46-24--27"), # HONDA.CIVIC (NIDEC) ("HONDA2", "7d2244f34d1bbcda|2021-06-25--12-25-37--26"), # HONDA.ACCORD (BOSCH) ("CHRYSLER", "4deb27de11bee626|2021-02-20--11-28-55--8"), # CHRYSLER.PACIFICA - ("RAM", "2f4452b03ccb98f0|2022-07-07--08-01-56--3"), # CHRYSLER.RAM_1500 - ("SUBARU", "4d70bc5e608678be|2021-01-15--17-02-04--5"), # SUBARU.IMPREZA + ("RAM", "2f4452b03ccb98f0|2022-09-07--13-55-08--10"), # CHRYSLER.RAM_1500 + ("SUBARU", "341dccd5359e3c97|2022-09-12--10-35-33--3"), # SUBARU.OUTBACK ("GM", "0c58b6a25109da2b|2021-02-23--16-35-50--11"), # GM.VOLT ("NISSAN", "35336926920f3571|2021-02-12--18-38-48--46"), # NISSAN.XTRAIL ("VOLKSWAGEN", "de9592456ad7d144|2021-06-29--11-00-15--6"), # VOLKSWAGEN.GOLF - ("MAZDA", "bd6a637565e91581|2021-10-30--15-14-53--2"), # MAZDA.CX9_2021 + ("MAZDA", "bd6a637565e91581|2021-10-30--15-14-53--4"), # MAZDA.CX9_2021 # Enable when port is tested and dashcamOnly is no longer set #("TESLA", "bb50caf5f0945ab1|2021-06-19--17-20-18--3"), # TESLA.AP2_MODELS diff --git a/selfdrive/test/test_onroad.py b/selfdrive/test/test_onroad.py index 55e1ef161a..b29ca5d35b 100755 --- a/selfdrive/test/test_onroad.py +++ b/selfdrive/test/test_onroad.py @@ -36,6 +36,7 @@ PROCS = { "./_dmonitoringmodeld": 5.0, "selfdrive.thermald.thermald": 3.87, "selfdrive.locationd.calibrationd": 2.0, + "selfdrive.locationd.torqued": 5.0, "./_soundd": 1.0, "selfdrive.monitoring.dmonitoringd": 4.0, "./proclogd": 1.54, diff --git a/selfdrive/test/update_ci_routes.py b/selfdrive/test/update_ci_routes.py index 99a63b8dfd..a1e8c35f6b 100755 --- a/selfdrive/test/update_ci_routes.py +++ b/selfdrive/test/update_ci_routes.py @@ -4,7 +4,7 @@ import subprocess from azure.storage.blob import BlockBlobService # pylint: disable=import-error from selfdrive.car.tests.routes import routes as test_car_models_routes -from selfdrive.test.process_replay.test_processes import original_segments as replay_segments +from selfdrive.test.process_replay.test_processes import source_segments as replay_segments from xx.chffr.lib import azureutil # pylint: disable=import-error from xx.chffr.lib.storage import _DATA_ACCOUNT_PRODUCTION, _DATA_ACCOUNT_CI, _DATA_BUCKET_PRODUCTION # pylint: disable=import-error