From 3652dff77a1220b3482c99b34f1309defa5c31d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20R=C4=85czy?= Date: Thu, 13 Mar 2025 02:51:25 -0400 Subject: [PATCH 01/21] paramsd: allow uncalibrated values while calibrating (#34852) * Use uncalibrated values * Use calib_valid * Move valids together * Add calibration valid field * Add migration block for new field * No paramsdTemporaryError while calibrating * comment * Fix static issues * Update ref commit * Comment * Remove redundant field * check for calstatus in selfdrived * Remove comment * Update ref commit --- selfdrive/locationd/paramsd.py | 10 +++++----- selfdrive/selfdrived/selfdrived.py | 2 +- selfdrive/test/process_replay/ref_commit | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/selfdrive/locationd/paramsd.py b/selfdrive/locationd/paramsd.py index 258fc97e5a..3819fba080 100755 --- a/selfdrive/locationd/paramsd.py +++ b/selfdrive/locationd/paramsd.py @@ -52,14 +52,14 @@ class ParamsLearner: device_pose = Pose.from_live_pose(msg) calibrated_pose = self.calibrator.build_calibrated_pose(device_pose) - yaw_rate_valid = msg.angularVelocityDevice.valid and self.calibrator.calib_valid + yaw_rate_valid = msg.angularVelocityDevice.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 if yaw_rate_valid: self.yaw_rate, self.yaw_rate_std = calibrated_pose.angular_velocity.z, calibrated_pose.angular_velocity.z_std else: # This is done to bound the yaw rate estimate when localizer values are invalid or calibrating - self.yaw_rate, self.yaw_rate_std = 0.0, np.radians(1) + self.yaw_rate, self.yaw_rate_std = 0.0, np.radians(10.0) 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 @@ -225,13 +225,13 @@ def main(): liveParameters.posenetValid = True liveParameters.sensorValid = sensors_valid liveParameters.steerRatio = float(x[States.STEER_RATIO].item()) - liveParameters.steerRatioValid = min_sr <= liveParameters.steerRatio <= max_sr liveParameters.stiffnessFactor = float(x[States.STIFFNESS].item()) - liveParameters.stiffnessFactorValid = 0.2 <= liveParameters.stiffnessFactor <= 5.0 liveParameters.roll = float(roll) liveParameters.angleOffsetAverageDeg = float(angle_offset_average) - liveParameters.angleOffsetAverageValid = bool(avg_offset_valid) liveParameters.angleOffsetDeg = float(angle_offset) + liveParameters.steerRatioValid = min_sr <= liveParameters.steerRatio <= max_sr + liveParameters.stiffnessFactorValid = 0.2 <= liveParameters.stiffnessFactor <= 5.0 + liveParameters.angleOffsetAverageValid = bool(avg_offset_valid) liveParameters.angleOffsetValid = bool(total_offset_valid) liveParameters.valid = all(( liveParameters.angleOffsetAverageValid, diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index 8b7db19c9a..b81882723e 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -305,7 +305,7 @@ class SelfdriveD: self.events.add(EventName.posenetInvalid) 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): + if not self.sm['liveParameters'].valid and cal_status == log.LiveCalibrationData.Status.calibrated and not TESTING_CLOSET and (not SIMULATION or REPLAY): self.events.add(EventName.paramsdTemporaryError) # conservative HW alert. if the data or frequency are off, locationd will throw an error diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index cfd179fb79..86bdc46fea 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -37041a45841e83f0641ef1e87c0e567181d47172 \ No newline at end of file +98672ccf23dc08fcd08b53cae3ec305c04219fe8 \ No newline at end of file From 1cd6ca467d0549db55bf65aeb896ca8f6c299c3c Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 14 Mar 2025 01:40:26 +0800 Subject: [PATCH 02/21] pandad: forward debug logs to cloudlog (#34859) forward debug logs to cloudlog --- selfdrive/pandad/panda.cc | 19 +++++++++++++++++++ selfdrive/pandad/panda.h | 2 ++ selfdrive/pandad/pandad.cc | 8 ++++++++ 3 files changed, 29 insertions(+) diff --git a/selfdrive/pandad/panda.cc b/selfdrive/pandad/panda.cc index 7b5fc9a999..93e139f0ec 100644 --- a/selfdrive/pandad/panda.cc +++ b/selfdrive/pandad/panda.cc @@ -66,6 +66,25 @@ void Panda::set_alternative_experience(uint16_t alternative_experience) { handle->control_write(0xdf, alternative_experience, 0); } +std::string Panda::serial_read(int port_number) { + std::string ret; + char buffer[USBPACKET_MAX_SIZE] = {}; + + while (true) { + int bytes_read = handle->control_read(0xe0, port_number, 0, (unsigned char *)buffer, USBPACKET_MAX_SIZE); + if (bytes_read <= 0) { + break; + } + ret.append(buffer, bytes_read); + } + + return ret; +} + +void Panda::set_uart_baud(int uart, int rate) { + handle->control_write(0xe4, uart, int(rate / 300)); +} + cereal::PandaState::PandaType Panda::get_hw_type() { unsigned char hw_query[1] = {0}; diff --git a/selfdrive/pandad/panda.h b/selfdrive/pandad/panda.h index 6ae2c77755..5cbce44f28 100644 --- a/selfdrive/pandad/panda.h +++ b/selfdrive/pandad/panda.h @@ -64,6 +64,8 @@ public: cereal::PandaState::PandaType get_hw_type(); void set_safety_model(cereal::CarParams::SafetyModel safety_model, uint16_t safety_param=0U); void set_alternative_experience(uint16_t alternative_experience); + std::string serial_read(int port_number = 0); + void set_uart_baud(int uart, int rate); void set_fan_speed(uint16_t fan_speed); uint16_t get_fan_speed(); void set_ir_pwr(uint16_t ir_pwr); diff --git a/selfdrive/pandad/pandad.cc b/selfdrive/pandad/pandad.cc index e6ef4a4072..db7dd387e0 100644 --- a/selfdrive/pandad/pandad.cc +++ b/selfdrive/pandad/pandad.cc @@ -452,6 +452,14 @@ void pandad_run(std::vector &pandas) { send_peripheral_state(peripheral_panda, &pm); } + // Forward logs from pandas to cloudlog if available + for (auto *panda : pandas) { + std::string log = panda->serial_read(); + if (!log.empty()) { + LOGD("%s", log.c_str()); + } + } + rk.keepTime(); } From c0b6d5823642717a7033395e002066f7be564475 Mon Sep 17 00:00:00 2001 From: Dean Lee Date: Fri, 14 Mar 2025 01:42:22 +0800 Subject: [PATCH 03/21] setup: fix dangling pointer Issue in curl header setup (#34860) fix dangling pointer in curl header setup --- selfdrive/ui/qt/setup/setup.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/selfdrive/ui/qt/setup/setup.cc b/selfdrive/ui/qt/setup/setup.cc index aff9b015b3..dfa9e12b4e 100644 --- a/selfdrive/ui/qt/setup/setup.cc +++ b/selfdrive/ui/qt/setup/setup.cc @@ -48,7 +48,8 @@ void Setup::download(QString url) { auto version = util::read_file("/VERSION"); struct curl_slist *list = NULL; - list = curl_slist_append(list, ("X-openpilot-serial: " + Hardware::get_serial()).c_str()); + std::string header = "X-openpilot-serial: " + Hardware::get_serial(); + list = curl_slist_append(list, header.c_str()); char tmpfile[] = "/tmp/installer_XXXXXX"; FILE *fp = fdopen(mkstemp(tmpfile), "wb"); From bd2f0017ff51d86c8269751fa5b612dbcc85c17c Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 13 Mar 2025 20:49:55 -0700 Subject: [PATCH 04/21] ignore --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 1fb751e2d5..72070dbc55 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -232,6 +232,7 @@ lint.ignore = [ "B024", "NPY002", # new numpy random syntax is worse "UP038", # (x, y) -> x|y for isinstance + "C420", ] line-length = 160 target-version ="py311" From a8bb9cfe410fa1916dfb26634d25cfef4ffcb02e Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Thu, 13 Mar 2025 20:50:51 -0700 Subject: [PATCH 05/21] Revert "ignore" This reverts commit bd2f0017ff51d86c8269751fa5b612dbcc85c17c. --- pyproject.toml | 1 - 1 file changed, 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 72070dbc55..1fb751e2d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -232,7 +232,6 @@ lint.ignore = [ "B024", "NPY002", # new numpy random syntax is worse "UP038", # (x, y) -> x|y for isinstance - "C420", ] line-length = 160 target-version ="py311" From 02519b7a6e6c8fdc446bd1d76143ce0992d9d6da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kacper=20R=C4=85czy?= Date: Fri, 14 Mar 2025 18:24:41 -0400 Subject: [PATCH 06/21] process_replay: refactor migrate_deviceState (#34864) * Refactor migrate_deviceState * Fix again --- selfdrive/test/process_replay/migration.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/selfdrive/test/process_replay/migration.py b/selfdrive/test/process_replay/migration.py index 2d42d31619..fd13c4f239 100644 --- a/selfdrive/test/process_replay/migration.py +++ b/selfdrive/test/process_replay/migration.py @@ -241,14 +241,16 @@ def migrate_gpsLocation(msgs): @migration(inputs=["deviceState", "initData"]) def migrate_deviceState(msgs): + init_data = next((m.initData for _, m in msgs if m.which() == 'initData'), None) + device_state = next((m.deviceState for _, m in msgs if m.which() == 'deviceState'), None) + if init_data is None or device_state is None: + return [], [], [] + ops = [] - dt = None for i, msg in msgs: - if msg.which() == 'initData': - dt = msg.initData.deviceType if msg.which() == 'deviceState': n = msg.as_builder() - n.deviceState.deviceType = dt + n.deviceState.deviceType = init_data.deviceType ops.append((i, n.as_reader())) return ops, [], [] From 7ab558a7894ecf85b8ec73e986080986825310c9 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 14 Mar 2025 16:09:23 -0700 Subject: [PATCH 07/21] run_process_on_route: support multiple processes (#34867) support multiple procs --- selfdrive/debug/run_process_on_route.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/selfdrive/debug/run_process_on_route.py b/selfdrive/debug/run_process_on_route.py index 45665e8a48..2ccb0fb3e7 100755 --- a/selfdrive/debug/run_process_on_route.py +++ b/selfdrive/debug/run_process_on_route.py @@ -10,21 +10,21 @@ if __name__ == "__main__": formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument("--fingerprint", help="The fingerprint to use") parser.add_argument("route", help="The route name to use") - parser.add_argument("process", help="The process to run") + parser.add_argument("process", nargs='+', help="The process(s) to run") args = parser.parse_args() - cfg = [c for c in CONFIGS if c.proc_name == args.process][0] + cfgs = [c for c in CONFIGS if c.proc_name in args.process] lr = LogReader(args.route) inputs = list(lr) - outputs = replay_process(cfg, inputs, fingerprint=args.fingerprint) + outputs = replay_process(cfgs, inputs, fingerprint=args.fingerprint) # Remove message generated by the process under test and merge in the new messages produces = {o.which() for o in outputs} inputs = [i for i in inputs if i.which() not in produces] outputs = sorted(inputs + outputs, key=lambda x: x.logMonoTime) - fn = f"{args.route.replace('/', '_')}_{args.process}.zst" + fn = f"{args.route.replace('/', '_')}_{'_'.join(args.process)}.zst" print(f"Saving log to {fn}") save_log(fn, outputs) From 07edc54db65690d95b53876221164dd571898b0d Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 14 Mar 2025 16:16:10 -0700 Subject: [PATCH 08/21] bump opendbc (#34868) bump --- opendbc_repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/opendbc_repo b/opendbc_repo index eca696984e..de96aaf51b 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit eca696984e467b909814ea1e594163ceea03ab3a +Subproject commit de96aaf51b60be02b4978b15fbf3b6dd0d829cfd From 349d569dfa08b036169e12539d2dcf0e47167f8b Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 14 Mar 2025 17:21:02 -0700 Subject: [PATCH 09/21] radard: radar errors are captured in valid flag (#34870) * already set valid from this * clean up --- selfdrive/controls/radard.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index 0267166795..9f5bea53ff 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -231,7 +231,7 @@ class RadarD: self.tracks[ids].update(rpt[0], rpt[1], rpt[2], v_lead, rpt[3]) # *** publish radarState *** - self.radar_state_valid = sm.all_checks() and len(rr.errors) == 0 + self.radar_state_valid = sm.all_checks() self.radar_state = log.RadarState.new_message() self.radar_state.mdMonoTime = sm.logMonoTime['modelV2'] self.radar_state.radarErrors = list(rr.errors) From e1eac057cabd2fa6a4841e9d3428ff9e14beb958 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Fri, 14 Mar 2025 19:30:09 -0700 Subject: [PATCH 10/21] camerad: fix rare BPS startup issues (#34871) * repros * handle old frames * cleanup * more freq * fix request id skipping --------- Co-authored-by: Comma Device --- system/camerad/cameras/spectra.cc | 21 ++++++++++++++++++--- system/camerad/cameras/spectra.h | 14 ++++++++++---- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/system/camerad/cameras/spectra.cc b/system/camerad/cameras/spectra.cc index 3005a4a550..247b0dd215 100644 --- a/system/camerad/cameras/spectra.cc +++ b/system/camerad/cameras/spectra.cc @@ -237,7 +237,7 @@ SpectraCamera::SpectraCamera(SpectraMaster *master, const CameraConfig &config) : m(master), enabled(config.enabled), cc(config) { - ife_buf_depth = (cc.output_type == ISP_RAW_OUTPUT) ? 4 : VIPC_BUFFER_COUNT; + ife_buf_depth = VIPC_BUFFER_COUNT; assert(ife_buf_depth < MAX_IFE_BUFS); } @@ -1330,7 +1330,16 @@ bool SpectraCamera::handle_camera_event(const cam_req_mgr_message *event_data) { uint64_t timestamp = event_data->u.frame_msg.timestamp; // timestamped in the kernel's SOF IRQ callback //LOGD("handle cam %d ts %lu req id %lu frame id %lu", cc.camera_num, timestamp, request_id, frame_id_raw); - if (stress_test("skipping SOF event")) return false; + // if there's a lag, some more frames could have already come in before + // we cleared the queue, so we'll still get them with valid (> 0) request IDs. + if (timestamp < last_requeue_ts) { + LOGD("skipping frame: ts before requeue / cam %d ts %lu req id %lu frame id %lu", cc.camera_num, timestamp, request_id, frame_id_raw); + return false; + } + + if (stress_test("skipping SOF event")) { + return false; + } if (!validateEvent(request_id, frame_id_raw)) { return false; @@ -1381,7 +1390,7 @@ bool SpectraCamera::validateEvent(uint64_t request_id, uint64_t frame_id_raw) { if (request_id != request_id_last + 1) { LOGE("camera %d requests skipped %ld -> %ld", cc.camera_num, request_id_last, request_id); - clearAndRequeue(request_id_last + 1); + clearAndRequeue(request_id + 1); return false; } } @@ -1392,6 +1401,7 @@ void SpectraCamera::clearAndRequeue(uint64_t from_request_id) { // clear everything, then queue up a fresh set of frames LOGW("clearing and requeuing camera %d from %lu", cc.camera_num, from_request_id); clear_req_queue(); + last_requeue_ts = nanos_since_boot(); for (uint64_t id = from_request_id; id < from_request_id + ife_buf_depth; ++id) { enqueue_frame(id); } @@ -1402,6 +1412,11 @@ bool SpectraCamera::waitForFrameReady(uint64_t request_id) { int buf_idx = request_id % ife_buf_depth; assert(sync_objs_ife[buf_idx]); + if (stress_test("sync sleep time")) { + util::sleep_for(350); + return false; + } + auto waitForSync = [&](uint32_t sync_obj, int timeout_ms, const char *sync_type) { struct cam_sync_wait sync_wait = {}; sync_wait.sync_obj = sync_obj; diff --git a/system/camerad/cameras/spectra.h b/system/camerad/cameras/spectra.h index 21f1970326..13cb13f98f 100644 --- a/system/camerad/cameras/spectra.h +++ b/system/camerad/cameras/spectra.h @@ -181,6 +181,7 @@ public: int sync_objs_ife[MAX_IFE_BUFS] = {}; int sync_objs_bps[MAX_IFE_BUFS] = {}; uint64_t request_id_last = 0; + uint64_t last_requeue_ts = 0; uint64_t frame_id_raw_last = 0; int invalid_request_count = 0; bool skip_expected = true; @@ -202,11 +203,16 @@ private: inline static bool first_frame_synced = false; // a mode for stressing edge cases: realignment, sync failures, etc. - inline bool stress_test(const char* log) { - static double prob = std::stod(util::getenv("SPECTRA_ERROR_PROB", "-1"));; - bool triggered = (prob > 0) && ((static_cast(rand()) / RAND_MAX) < prob); + inline bool stress_test(std::string log) { + static double last_trigger = 0; + static double prob = std::stod(util::getenv("SPECTRA_ERROR_PROB", "-1")); + static double dt = std::stod(util::getenv("SPECTRA_ERROR_DT", "1")); + bool triggered = (prob > 0) && \ + ((static_cast(rand()) / RAND_MAX) < prob) && \ + (millis_since_boot() - last_trigger) > dt; if (triggered) { - LOGE("stress test (cam %d): %s", cc.camera_num, log); + last_trigger = millis_since_boot(); + LOGE("stress test (cam %d): %s", cc.camera_num, log.c_str()); } return triggered; } From 811272dc28f82229586d6ffe90ea1dbddac8959b Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 14 Mar 2025 19:37:27 -0700 Subject: [PATCH 11/21] radarState: check average frequency (#34872) * always check radarState freq since it polls on modelV2 and sends at a fixed rate * fine * can just check this since valid is all_checks on liveTracks, and liveTracks.valid is len(errors) as well full circle --- selfdrive/controls/plannerd.py | 2 +- selfdrive/selfdrived/selfdrived.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/selfdrive/controls/plannerd.py b/selfdrive/controls/plannerd.py index a74b40e15f..bec7eede0b 100755 --- a/selfdrive/controls/plannerd.py +++ b/selfdrive/controls/plannerd.py @@ -20,7 +20,7 @@ def main(): longitudinal_planner = LongitudinalPlanner(CP) pm = messaging.PubMaster(['longitudinalPlan', 'driverAssistance']) sm = messaging.SubMaster(['carControl', 'carState', 'controlsState', 'liveParameters', 'radarState', 'modelV2', 'selfdriveState'], - poll='modelV2', ignore_avg_freq=['radarState']) + poll='modelV2') while True: sm.update() diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index b81882723e..93f8f59133 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -80,7 +80,7 @@ class SelfdriveD: 'managerState', 'liveParameters', 'radarState', 'liveTorqueParameters', 'controlsState', 'carControl', 'driverAssistance', 'alertDebug'] + \ self.camera_packets + self.sensor_packets + self.gps_packets, - ignore_alive=ignore, ignore_avg_freq=ignore+['radarState',], + ignore_alive=ignore, ignore_avg_freq=ignore, ignore_valid=ignore, frequency=int(1/DT_CTRL)) # read params @@ -269,7 +269,7 @@ class SelfdriveD: self.events.add(EventName.cameraFrameRate) if not REPLAY and self.rk.lagging: self.events.add(EventName.selfdrivedLagging) - if len(self.sm['radarState'].radarErrors) or ((not self.rk.lagging or REPLAY) and not self.sm.all_checks(['radarState'])): + if not self.sm.valid['radarState']: self.events.add(EventName.radarFault) if not self.sm.valid['pandaStates']: self.events.add(EventName.usbError) From 714348e17e145c1dc97cc08a11280f63cbe376f2 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 14 Mar 2025 20:40:28 -0700 Subject: [PATCH 12/21] liveTracks: bool error fields (#34869) * bool fields * liveTracks.valid is already set using errors * fix * clean up * same but diff * fix * fix * fix test * clean up * rm radarErrors * whoops * no struct * Revert "no struct" This reverts commit ed8ec02493673f850800344c73c969508fc38991. * bump * update --- cereal/log.capnp | 2 +- opendbc_repo | 2 +- selfdrive/car/card.py | 2 +- selfdrive/car/tests/test_models.py | 2 +- selfdrive/controls/radard.py | 1 - selfdrive/controls/tests/test_leads.py | 2 +- selfdrive/test/process_replay/ref_commit | 2 +- 7 files changed, 6 insertions(+), 7 deletions(-) diff --git a/cereal/log.capnp b/cereal/log.capnp index 78b511ca64..1cc37cf642 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -728,7 +728,6 @@ struct PeripheralState { struct RadarState @0x9a185389d6fdd05f { mdMonoTime @6 :UInt64; carStateMonoTime @11 :UInt64; - radarErrors @12 :List(Car.RadarData.Error); leadOne @3 :LeadData; leadTwo @4 :LeadData; @@ -762,6 +761,7 @@ struct RadarState @0x9a185389d6fdd05f { calPercDEPRECATED @9 :Int8; canMonoTimesDEPRECATED @10 :List(UInt64); cumLagMsDEPRECATED @5 :Float32; + radarErrorsDEPRECATED @12 :List(Car.RadarData.ErrorDEPRECATED); } struct LiveCalibrationData { diff --git a/opendbc_repo b/opendbc_repo index de96aaf51b..5d74dd6e73 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit de96aaf51b60be02b4978b15fbf3b6dd0d829cfd +Subproject commit 5d74dd6e7344900805c58eb2fb2b5a8d52e83050 diff --git a/selfdrive/car/card.py b/selfdrive/car/card.py index f00cbe55e1..8a21df3340 100755 --- a/selfdrive/car/card.py +++ b/selfdrive/car/card.py @@ -227,7 +227,7 @@ class Car: if RD is not None: tracks_msg = messaging.new_message('liveTracks') - tracks_msg.valid = len(RD.errors) == 0 + tracks_msg.valid = not any(RD.errors.to_dict().values()) tracks_msg.liveTracks = RD self.pm.send('liveTracks', tracks_msg) diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 9a042ed372..9885358e71 100644 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -219,7 +219,7 @@ class TestCarModelBase(unittest.TestCase): for i, msg in enumerate(self.can_msgs[self.elm_frame:]): rr: structs.RadarData | None = RI.update(msg) if rr is not None and i > 50: - error_cnt += structs.RadarData.Error.canError in rr.errors + error_cnt += rr.errors.canError self.assertEqual(error_cnt, 0) def test_panda_safety_rx_checks(self): diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index 9f5bea53ff..f91c53431d 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -234,7 +234,6 @@ class RadarD: self.radar_state_valid = sm.all_checks() self.radar_state = log.RadarState.new_message() self.radar_state.mdMonoTime = sm.logMonoTime['modelV2'] - self.radar_state.radarErrors = list(rr.errors) self.radar_state.carStateMonoTime = sm.logMonoTime['carState'] if len(sm['modelV2'].velocity.x): diff --git a/selfdrive/controls/tests/test_leads.py b/selfdrive/controls/tests/test_leads.py index 89582d1e64..77384fea20 100644 --- a/selfdrive/controls/tests/test_leads.py +++ b/selfdrive/controls/tests/test_leads.py @@ -26,6 +26,6 @@ class TestLeads: msgs = [m for _ in range(3) for m in single_iter_pkg()] out = replay_process_with_name("card", msgs, fingerprint=TOYOTA.TOYOTA_COROLLA_TSS2) states = [m for m in out if m.which() == "liveTracks"] - failures = [not state.valid and len(state.liveTracks.errors) for state in states] + failures = [not state.valid for state in states] assert len(states) == 0 or all(failures) diff --git a/selfdrive/test/process_replay/ref_commit b/selfdrive/test/process_replay/ref_commit index 86bdc46fea..353b8fa7ce 100644 --- a/selfdrive/test/process_replay/ref_commit +++ b/selfdrive/test/process_replay/ref_commit @@ -1 +1 @@ -98672ccf23dc08fcd08b53cae3ec305c04219fe8 \ No newline at end of file +e9d57157494480637a8ffb52257d2b660a48be67 \ No newline at end of file From 4e7c605a7948ec4928f79beb37fb6dc0638e7bf2 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 14 Mar 2025 21:08:30 -0700 Subject: [PATCH 13/21] Ford: radar is invalid while in reverse (#34866) * temp unavailable * fix * replay multiple * clean up * bump * rename * reason is in liveTracks * more rename * bump * fix * bump * fix * need to totally ignore it, or it will throw commIssues for radarErrors or not alive * this is just simpler -- good thing kept struct * rm --- cereal/log.capnp | 2 ++ opendbc_repo | 2 +- selfdrive/controls/radard.py | 1 + selfdrive/selfdrived/events.py | 5 +++++ selfdrive/selfdrived/selfdrived.py | 4 ++++ 5 files changed, 13 insertions(+), 1 deletion(-) diff --git a/cereal/log.capnp b/cereal/log.capnp index 1cc37cf642..7b6076311f 100644 --- a/cereal/log.capnp +++ b/cereal/log.capnp @@ -59,6 +59,7 @@ struct OnroadEvent @0xc4fa6047f024e718 { pcmEnable @23; pcmDisable @24; radarFault @25; + radarTempUnavailable @93; brakeHold @26; parkBrake @27; manualRestart @28; @@ -728,6 +729,7 @@ struct PeripheralState { struct RadarState @0x9a185389d6fdd05f { mdMonoTime @6 :UInt64; carStateMonoTime @11 :UInt64; + radarErrors @13 :Car.RadarData.Error; leadOne @3 :LeadData; leadTwo @4 :LeadData; diff --git a/opendbc_repo b/opendbc_repo index 5d74dd6e73..96896d3509 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 5d74dd6e7344900805c58eb2fb2b5a8d52e83050 +Subproject commit 96896d35098464661de5c96f075bf5053eeefede diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index f91c53431d..84420e3584 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -234,6 +234,7 @@ class RadarD: self.radar_state_valid = sm.all_checks() self.radar_state = log.RadarState.new_message() self.radar_state.mdMonoTime = sm.logMonoTime['modelV2'] + self.radar_state.radarErrors = rr.errors self.radar_state.carStateMonoTime = sm.logMonoTime['carState'] if len(sm['modelV2'].velocity.x): diff --git a/selfdrive/selfdrived/events.py b/selfdrive/selfdrived/events.py index d89418e177..ee2c418b6e 100755 --- a/selfdrive/selfdrived/events.py +++ b/selfdrive/selfdrived/events.py @@ -832,6 +832,11 @@ EVENTS: dict[int, dict[str, Alert | AlertCallbackType]] = { ET.NO_ENTRY: NoEntryAlert("Radar Error: Restart the Car"), }, + EventName.radarTempUnavailable: { + ET.SOFT_DISABLE: soft_disable_alert("Radar Temporarily Unavailable"), + ET.NO_ENTRY: NoEntryAlert("Radar Temporarily Unavailable"), + }, + # Every frame from the camera should be processed by the model. If modeld # is not processing frames fast enough they have to be dropped. This alert is # thrown when over 20% of frames are dropped. diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index 93f8f59133..fdf1b77871 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -270,6 +270,10 @@ class SelfdriveD: if not REPLAY and self.rk.lagging: self.events.add(EventName.selfdrivedLagging) if not self.sm.valid['radarState']: + if self.sm['radarState'].radarErrors.radarUnavailableTemporary: + self.events.add(EventName.radarTempUnavailable) + else: + self.events.add(EventName.radarFault) self.events.add(EventName.radarFault) if not self.sm.valid['pandaStates']: self.events.add(EventName.usbError) From 5c3020844e2abaae7ce25236723c61ce658b22d8 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Fri, 14 Mar 2025 22:37:49 -0700 Subject: [PATCH 14/21] car interfaces: each specify their own dependencies (#34874) * remove these * fix * oops * clean up * nl * bump --- opendbc_repo | 2 +- selfdrive/car/card.py | 4 ++-- selfdrive/car/tests/test_car_interfaces.py | 4 ++-- selfdrive/car/tests/test_models.py | 10 +++++----- selfdrive/controls/controlsd.py | 4 ++-- selfdrive/controls/lib/tests/test_latcontrol.py | 4 ++-- selfdrive/test/process_replay/process_replay.py | 2 +- 7 files changed, 15 insertions(+), 15 deletions(-) diff --git a/opendbc_repo b/opendbc_repo index 96896d3509..b46e6340c1 160000 --- a/opendbc_repo +++ b/opendbc_repo @@ -1 +1 @@ -Subproject commit 96896d35098464661de5c96f075bf5053eeefede +Subproject commit b46e6340c15428ef72435b163ce03ffe66ffe563 diff --git a/selfdrive/car/card.py b/selfdrive/car/card.py index 8a21df3340..607f5590c4 100755 --- a/selfdrive/car/card.py +++ b/selfdrive/car/card.py @@ -15,7 +15,7 @@ from opendbc.car import DT_CTRL, structs from opendbc.car.can_definitions import CanData, CanRecvCallable, CanSendCallable from opendbc.car.carlog import carlog from opendbc.car.fw_versions import ObdCallback -from opendbc.car.car_helpers import get_car, get_radar_interface +from opendbc.car.car_helpers import get_car, interfaces from opendbc.car.interfaces import CarInterfaceBase, RadarInterfaceBase from opendbc.safety import ALTERNATIVE_EXPERIENCE from openpilot.selfdrive.pandad import can_capnp_to_list, can_list_to_can_capnp @@ -99,7 +99,7 @@ class Car: cached_params = _cached_params self.CI = get_car(*self.can_callbacks, obd_callback(self.params), experimental_long_allowed, num_pandas, cached_params) - self.RI = get_radar_interface(self.CI.CP) + self.RI = interfaces[self.CI.CP.carFingerprint].RadarInterface(self.CI.CP) self.CP = self.CI.CP # continue onto next fingerprinting step in pandad diff --git a/selfdrive/car/tests/test_car_interfaces.py b/selfdrive/car/tests/test_car_interfaces.py index ca96884d7c..e0cd5a1e91 100644 --- a/selfdrive/car/tests/test_car_interfaces.py +++ b/selfdrive/car/tests/test_car_interfaces.py @@ -34,14 +34,14 @@ class TestCarInterfaces: phases=(Phase.reuse, Phase.generate, Phase.shrink)) @given(data=st.data()) def test_car_interfaces(self, car_name, data): - CarInterface, CarController, CarState, RadarInterface = interfaces[car_name] + CarInterface = interfaces[car_name] args = get_fuzzy_car_interface_args(data.draw) car_params = CarInterface.get_params(car_name, args['fingerprints'], args['car_fw'], experimental_long=args['experimental_long'], docs=False) car_params = car_params.as_reader() - car_interface = CarInterface(car_params, CarController, CarState) + car_interface = CarInterface(car_params) assert car_params assert car_interface diff --git a/selfdrive/car/tests/test_models.py b/selfdrive/car/tests/test_models.py index 9885358e71..906fa99320 100644 --- a/selfdrive/car/tests/test_models.py +++ b/selfdrive/car/tests/test_models.py @@ -151,8 +151,8 @@ class TestCarModelBase(unittest.TestCase): # if relay is expected to be open in the route cls.openpilot_enabled = cls.car_safety_mode_frame is not None - cls.CarInterface, cls.CarController, cls.CarState, cls.RadarInterface = interfaces[cls.platform] - cls.CP = cls.CarInterface.get_params(cls.platform, cls.fingerprint, car_fw, experimental_long, docs=False) + cls.CarInterface = interfaces[cls.platform] + cls.CP = cls.CarInterface.get_params(cls.platform, cls.fingerprint, car_fw, experimental_long, docs=False) assert cls.CP assert cls.CP.carFingerprint == cls.platform @@ -163,7 +163,7 @@ class TestCarModelBase(unittest.TestCase): del cls.can_msgs def setUp(self): - self.CI = self.CarInterface(self.CP.copy(), self.CarController, self.CarState) + self.CI = self.CarInterface(self.CP.copy()) assert self.CI # TODO: check safetyModel is in release panda build @@ -210,7 +210,7 @@ class TestCarModelBase(unittest.TestCase): self.assertEqual(can_invalid_cnt, 0) def test_radar_interface(self): - RI = self.RadarInterface(self.CP) + RI = self.CarInterface.RadarInterface(self.CP) assert RI # Since OBD port is multiplexed to bus 1 (commonly radar bus) while fingerprinting, @@ -273,7 +273,7 @@ class TestCarModelBase(unittest.TestCase): def test_car_controller(car_control): now_nanos = 0 msgs_sent = 0 - CI = self.CarInterface(self.CP, self.CarController, self.CarState) + CI = self.CarInterface(self.CP) for _ in range(round(10.0 / DT_CTRL)): # make sure we hit the slowest messages CI.update([]) _, sendcan = CI.apply(car_control, now_nanos) diff --git a/selfdrive/controls/controlsd.py b/selfdrive/controls/controlsd.py index dcc1c74794..f6fabfc421 100755 --- a/selfdrive/controls/controlsd.py +++ b/selfdrive/controls/controlsd.py @@ -9,7 +9,7 @@ from openpilot.common.params import Params from openpilot.common.realtime import config_realtime_process, Priority, Ratekeeper from openpilot.common.swaglog import cloudlog -from opendbc.car.car_helpers import get_car_interface +from opendbc.car.car_helpers import interfaces from opendbc.car.vehicle_model import VehicleModel from openpilot.selfdrive.controls.lib.drive_helpers import clip_curvature from openpilot.selfdrive.controls.lib.latcontrol import LatControl, MIN_LATERAL_CONTROL_SPEED @@ -33,7 +33,7 @@ class Controls: self.CP = messaging.log_from_bytes(self.params.get("CarParams", block=True), car.CarParams) cloudlog.info("controlsd got CarParams") - self.CI = get_car_interface(self.CP) + self.CI = interfaces[self.CP.carFingerprint](self.CP) self.sm = messaging.SubMaster(['liveParameters', 'liveTorqueParameters', 'modelV2', 'selfdriveState', 'liveCalibration', 'livePose', 'longitudinalPlan', 'carState', 'carOutput', diff --git a/selfdrive/controls/lib/tests/test_latcontrol.py b/selfdrive/controls/lib/tests/test_latcontrol.py index 564c93be0d..a01f013ddd 100644 --- a/selfdrive/controls/lib/tests/test_latcontrol.py +++ b/selfdrive/controls/lib/tests/test_latcontrol.py @@ -17,9 +17,9 @@ class TestLatControl: @parameterized.expand([(HONDA.HONDA_CIVIC, LatControlPID), (TOYOTA.TOYOTA_RAV4, LatControlTorque), (NISSAN.NISSAN_LEAF, LatControlAngle)]) def test_saturation(self, car_name, controller): - CarInterface, CarController, CarState, RadarInterface = interfaces[car_name] + CarInterface = interfaces[car_name] CP = CarInterface.get_non_essential_params(car_name) - CI = CarInterface(CP, CarController, CarState) + CI = CarInterface(CP) VM = VehicleModel(CP) controller = controller(CP.as_reader(), CI) diff --git a/selfdrive/test/process_replay/process_replay.py b/selfdrive/test/process_replay/process_replay.py index 34ca98fdc2..16761225d3 100755 --- a/selfdrive/test/process_replay/process_replay.py +++ b/selfdrive/test/process_replay/process_replay.py @@ -342,7 +342,7 @@ def card_fingerprint_callback(rc, pm, msgs, fingerprint): def get_car_params_callback(rc, pm, msgs, fingerprint): params = Params() if fingerprint: - CarInterface, _, _, _ = interfaces[fingerprint] + CarInterface = interfaces[fingerprint] CP = CarInterface.get_non_essential_params(fingerprint) else: can = DummySocket() From fb7b9c0f9420d228f03362970ebcfb7237095cf3 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 15 Mar 2025 14:02:03 -0700 Subject: [PATCH 15/21] camerad: log failed sync time (#34878) * camerad: log failed sync time * mv --------- Co-authored-by: Comma Device --- system/camerad/cameras/spectra.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/system/camerad/cameras/spectra.cc b/system/camerad/cameras/spectra.cc index 247b0dd215..d12dbb2444 100644 --- a/system/camerad/cameras/spectra.cc +++ b/system/camerad/cameras/spectra.cc @@ -266,7 +266,7 @@ int SpectraCamera::clear_req_queue() { req_mgr_flush_request.link_hdl = link_handle; req_mgr_flush_request.flush_type = CAM_REQ_MGR_FLUSH_TYPE_ALL; int ret = do_cam_control(m->video0_fd, CAM_REQ_MGR_FLUSH_REQ, &req_mgr_flush_request, sizeof(req_mgr_flush_request)); - LOGD("flushed all req: %d", ret); + LOGD("flushed all req: %d", ret); // returns a "time until timeout" on clearing the workq for (int i = 0; i < MAX_IFE_BUFS; ++i) { destroySyncObjectAt(i); @@ -1418,11 +1418,13 @@ bool SpectraCamera::waitForFrameReady(uint64_t request_id) { } auto waitForSync = [&](uint32_t sync_obj, int timeout_ms, const char *sync_type) { + double st = millis_since_boot(); struct cam_sync_wait sync_wait = {}; sync_wait.sync_obj = sync_obj; sync_wait.timeout_ms = stress_test(sync_type) ? 1 : timeout_ms; bool ret = do_sync_control(m->cam_sync_fd, CAM_SYNC_WAIT, &sync_wait, sizeof(sync_wait)) == 0; - if (!ret) LOGE("camera %d %s failed", cc.camera_num, sync_type); + double et = millis_since_boot(); + if (!ret) LOGE("camera %d %s failed after %.2fms", cc.camera_num, sync_type, et-st); return ret; }; @@ -1434,6 +1436,7 @@ bool SpectraCamera::waitForFrameReady(uint64_t request_id) { // BPS is typically 7ms success = waitForSync(sync_objs_bps[buf_idx], 50, "BPS sync"); } + return success; } From 519ea9dcab2affdd3edcd10401675fee8dbdeaff Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 15 Mar 2025 15:55:29 -0700 Subject: [PATCH 16/21] Make model daemons Python processes (#34880) --- system/manager/process.py | 6 +++++- system/manager/process_config.py | 6 ++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/system/manager/process.py b/system/manager/process.py index 0e9c9b9804..6c233c21ab 100644 --- a/system/manager/process.py +++ b/system/manager/process.py @@ -221,8 +221,12 @@ class PythonProcess(ManagerProcess): if self.proc is not None: return + # TODO: this is just a workaround for this tinygrad check: + # https://github.com/tinygrad/tinygrad/blob/ac9c96dae1656dc220ee4acc39cef4dd449aa850/tinygrad/device.py#L26 + name = self.name if "modeld" not in self.name else "MainProcess" + cloudlog.info(f"starting python {self.module}") - self.proc = Process(name=self.name, target=self.launcher, args=(self.module, self.name)) + self.proc = Process(name=name, target=self.launcher, args=(self.module, self.name)) self.proc.start() self.watchdog_seen = False self.shutting_down = False diff --git a/system/manager/process_config.py b/system/manager/process_config.py index 96315eeb29..6e048c339e 100644 --- a/system/manager/process_config.py +++ b/system/manager/process_config.py @@ -75,10 +75,8 @@ procs = [ PythonProcess("micd", "system.micd", iscar), PythonProcess("timed", "system.timed", always_run, enabled=not PC), - # TODO: Make python process once TG allows opening QCOM from child pro - # https://github.com/tinygrad/tinygrad/blob/ac9c96dae1656dc220ee4acc39cef4dd449aa850/tinygrad/device.py#L26 - NativeProcess("modeld", "selfdrive/modeld", ["./modeld.py"], only_onroad), - NativeProcess("dmonitoringmodeld", "selfdrive/modeld", ["./dmonitoringmodeld.py"], driverview, enabled=(WEBCAM or not PC)), + PythonProcess("modeld", "selfdrive.modeld.modeld", only_onroad), + PythonProcess("dmonitoringmodeld", "selfdrive.modeld.dmonitoringmodeld", driverview, enabled=(WEBCAM or not PC)), NativeProcess("sensord", "system/sensord", ["./sensord"], only_onroad, enabled=not PC), NativeProcess("ui", "selfdrive/ui", ["./ui"], always_run, watchdog_max_dt=(5 if not PC else None)), From 561d33d81e4cf64d22897bc8ca1e09c19d205312 Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 15 Mar 2025 20:55:03 -0700 Subject: [PATCH 17/21] remove '-release' suffix --- release/build_release.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/release/build_release.sh b/release/build_release.sh index 735ef5e043..220da05c17 100755 --- a/release/build_release.sh +++ b/release/build_release.sh @@ -40,8 +40,6 @@ rm -f panda/board/obj/panda.bin.signed rm -f panda/board/obj/panda_h7.bin.signed VERSION=$(cat common/version.h | awk -F[\"-] '{print $2}') -echo "#define COMMA_VERSION \"$VERSION-release\"" > common/version.h - echo "[-] committing version $VERSION T=$SECONDS" git add -f . git commit -a -m "openpilot v$VERSION release" From c0b39d328db4e467a67557e63fd67cd64177da0e Mon Sep 17 00:00:00 2001 From: Adeeb Shihadeh Date: Sat, 15 Mar 2025 22:08:43 -0700 Subject: [PATCH 18/21] fix typo --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index 8a5638bc84..071622f89a 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -6,7 +6,7 @@ Version 0.9.8 (2025-02-28) ======================== * New driving model * Model now gates applying positive acceleration in Chill mode -* New driving monitoring model +* New driver monitoring model * Reduced false positives related to passengers * Image processing pipeline moved to the ISP * More GPU time for bigger driving models From abc1c5fb959810a654c6115e80b29fb18fc4bb19 Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Sat, 15 Mar 2025 22:21:58 -0700 Subject: [PATCH 19/21] selfdrived: add canError for radar can errors (#34873) radar can invalid --- selfdrive/selfdrived/selfdrived.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/selfdrive/selfdrived/selfdrived.py b/selfdrive/selfdrived/selfdrived.py index fdf1b77871..c7320f9350 100755 --- a/selfdrive/selfdrived/selfdrived.py +++ b/selfdrive/selfdrived/selfdrived.py @@ -270,7 +270,9 @@ class SelfdriveD: if not REPLAY and self.rk.lagging: self.events.add(EventName.selfdrivedLagging) if not self.sm.valid['radarState']: - if self.sm['radarState'].radarErrors.radarUnavailableTemporary: + if self.sm['radarState'].radarErrors.canError: + self.events.add(EventName.canError) + elif self.sm['radarState'].radarErrors.radarUnavailableTemporary: self.events.add(EventName.radarTempUnavailable) else: self.events.add(EventName.radarFault) From 9571fc56079bf13f6ca74ed9cb0eb98c7b8755eb Mon Sep 17 00:00:00 2001 From: Shane Smiskol Date: Sat, 15 Mar 2025 23:49:22 -0700 Subject: [PATCH 20/21] radard: use a filter for aLeadTau (#34883) use a filter --- selfdrive/controls/radard.py | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/selfdrive/controls/radard.py b/selfdrive/controls/radard.py index 84420e3584..98fce1cb26 100755 --- a/selfdrive/controls/radard.py +++ b/selfdrive/controls/radard.py @@ -6,6 +6,7 @@ from typing import Any import capnp from cereal import messaging, log, car +from openpilot.common.filter_simple import FirstOrderFilter from openpilot.common.params import Params from openpilot.common.realtime import DT_MDL, Priority, config_realtime_process from openpilot.common.swaglog import cloudlog @@ -51,7 +52,7 @@ class Track: def __init__(self, identifier: int, v_lead: float, kalman_params: KalmanParams): self.identifier = identifier self.cnt = 0 - self.aLeadTau = _LEAD_ACCEL_TAU + self.aLeadTau = FirstOrderFilter(_LEAD_ACCEL_TAU, 0.45, DT_MDL) self.K_A = kalman_params.A self.K_C = kalman_params.C self.K_K = kalman_params.K @@ -74,17 +75,12 @@ class Track: # Learn if constant acceleration if abs(self.aLeadK) < 0.5: - self.aLeadTau = _LEAD_ACCEL_TAU + self.aLeadTau.x = _LEAD_ACCEL_TAU else: - self.aLeadTau *= 0.9 + self.aLeadTau.update(0.0) self.cnt += 1 - def reset_a_lead(self, aLeadK: float, aLeadTau: float): - self.kf = KF1D([[self.vLead], [aLeadK]], self.K_A, self.K_C, self.K_K) - self.aLeadK = aLeadK - self.aLeadTau = aLeadTau - def get_RadarState(self, model_prob: float = 0.0): return { "dRel": float(self.dRel), @@ -93,7 +89,7 @@ class Track: "vLead": float(self.vLead), "vLeadK": float(self.vLeadK), "aLeadK": float(self.aLeadK), - "aLeadTau": float(self.aLeadTau), + "aLeadTau": float(self.aLeadTau.x), "status": True, "fcw": self.is_potential_fcw(model_prob), "modelProb": model_prob, From d1042df6322c28168ee2edb5fa4aec6d632ef09a Mon Sep 17 00:00:00 2001 From: eFini Date: Mon, 17 Mar 2025 11:39:50 +0800 Subject: [PATCH 21/21] Multilang: Update ZH translations (#34889) update zh translations --- selfdrive/ui/translations/main_zh-CHS.ts | 20 +++++++++++--------- selfdrive/ui/translations/main_zh-CHT.ts | 20 +++++++++++--------- 2 files changed, 22 insertions(+), 18 deletions(-) diff --git a/selfdrive/ui/translations/main_zh-CHS.ts b/selfdrive/ui/translations/main_zh-CHS.ts index f78d8dcdff..4cc2d401eb 100644 --- a/selfdrive/ui/translations/main_zh-CHS.ts +++ b/selfdrive/ui/translations/main_zh-CHS.ts @@ -315,28 +315,30 @@ openpilot learns to drive by watching humans, like you, drive. Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode. - + openpilot 通过观察人类驾驶(包括您)来学习如何驾驶。 + +“训练数据上传模式”允许您最大化上传训练数据,以改进 openpilot 的驾驶模型。更多数据意味着更强大的模型,也就意味着更优秀的“实验模式”。 Firehose Mode: ACTIVE - + 训练数据上传模式:激活中 ACTIVE - + 激活中 <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network - + <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>未激活</span>:请连接至不限流量的网络 For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.<br><br>Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.<br><br><br><b>Frequently Asked Questions</b><br><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><br><i>Do all of my segments get pulled in Firehose Mode?</i> No, we selectively pull a subset of your segments.<br><br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><br><i>Does it matter which software I run?</i> Yes, only upstream openpilot (and particular forks) are able to be used for training. - + 为了达到最佳效果,请每周将您的设备带回室内,并连接到优质的 USB-C 充电器和 Wi-Fi。<br><br>Firehose 模式在行驶时也能运行,但需连接到移动热点或使用不限流量的 SIM 卡。<br><br><br><b>常见问题</b><br><br><i>我开车的方式或地点有影响吗?</i>不会,请像平常一样驾驶即可。<br><br><i>Firehose 模式会上传所有的驾驶片段吗?</i>不会,我们会选择性地上传部分片段。<br><br><i>什么是好的 USB-C 充电器?</i>任何快速手机或笔记本电脑充电器都应该适用。<br><br><i>我使用的软件版本有影响吗?</i>有的,只有官方 openpilot(以及特定的分支)可以用于训练。 <b>%n segment(s)</b> of your driving is in the training dataset so far. - - + + <b>目前已有 %n 段</b> 您的驾驶数据被纳入训练数据集。 @@ -995,11 +997,11 @@ This may take up to a minute. Welcome to openpilot - + 欢迎使用 openpilot You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing. - + 您必须接受《条款与条件》才能使用 openpilot。在继续之前,请先阅读最新条款:<span style='color: #465BEA;'>https://comma.ai/terms</span>。 diff --git a/selfdrive/ui/translations/main_zh-CHT.ts b/selfdrive/ui/translations/main_zh-CHT.ts index 8547c90410..78519f2647 100644 --- a/selfdrive/ui/translations/main_zh-CHT.ts +++ b/selfdrive/ui/translations/main_zh-CHT.ts @@ -315,28 +315,30 @@ openpilot learns to drive by watching humans, like you, drive. Firehose Mode allows you to maximize your training data uploads to improve openpilot's driving models. More data means bigger models, which means better Experimental Mode. - + openpilot 透過觀察人類駕駛(包括您)來學習如何駕駛。 + +「訓練資料上傳模式」可讓您最大化上傳訓練數據,以改進 openpilot 的駕駛模型。更多數據代表更強大的模型,也就意味著更優秀的「實驗模式」。 Firehose Mode: ACTIVE - + 訓練資料上傳模式:啟用中 ACTIVE - + 啟用中 <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>INACTIVE</span>: connect to unmetered network - + <span stylesheet='font-size: 60px; font-weight: bold; color: #e74c3c;'>未啟用</span>:請連接至不限流量的網路 For maximum effectiveness, bring your device inside and connect to a good USB-C adapter and Wi-Fi weekly.<br><br>Firehose Mode can also work while you're driving if connected to a hotspot or unlimited SIM card.<br><br><br><b>Frequently Asked Questions</b><br><br><i>Does it matter how or where I drive?</i> Nope, just drive as you normally would.<br><br><i>Do all of my segments get pulled in Firehose Mode?</i> No, we selectively pull a subset of your segments.<br><br><i>What's a good USB-C adapter?</i> Any fast phone or laptop charger should be fine.<br><br><i>Does it matter which software I run?</i> Yes, only upstream openpilot (and particular forks) are able to be used for training. - + 為了達到最佳效果,請每週將您的裝置帶回室內,並連接至優質的 USB-C 充電器與 Wi-Fi。<br><br>訓練資料上傳模式在行駛時也能運作,但需連接至行動熱點或使用不限流量的 SIM 卡。<br><br><br><b>常見問題</b><br><br><i>我開車的方式或地點有影響嗎?</i> 不會,請像平常一樣駕駛即可。<br><br><i>訓練資料上傳模式會上傳所有的駕駛片段嗎?</i>不會,我們會選擇性地上傳部分片段。<br><br><i>什麼是好的 USB-C 充電器?</i>任何快速手機或筆電充電器都應該適用。<br><br><i>我使用的軟體版本有影響嗎?</i>有的,只有官方 openpilot(以及特定的分支)可以用於訓練。 <b>%n segment(s)</b> of your driving is in the training dataset so far. - - + + <b>目前已有 %n 段</b> 您的駕駛數據被納入訓練資料集。 @@ -995,11 +997,11 @@ This may take up to a minute. Welcome to openpilot - + 歡迎使用 openpilot You must accept the Terms and Conditions to use openpilot. Read the latest terms at <span style='color: #465BEA;'>https://comma.ai/terms</span> before continuing. - + 您必須接受《條款與條件》才能使用 openpilot。在繼續之前,請先閱讀最新條款:<span style='color: #465BEA;'>https://comma.ai/terms</span>。