Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 18 additions & 2 deletions selfdrive/boardd/boardd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,10 @@ void can_recv_thread(std::vector<Panda *> pandas) {
uint64_t next_frame_time = nanos_since_boot() + dt;
std::vector<can_frame> raw_can_data;

// Track consecutive missed cycles for adaptive recovery
int consecutive_missed = 0;
const int MAX_CONSECUTIVE_MISSED = 5;

while (!do_exit && check_all_connected(pandas)) {
bool comms_healthy = true;
raw_can_data.clear();
Expand All @@ -300,10 +304,22 @@ void can_recv_thread(std::vector<Panda *> pandas) {
int64_t remaining = next_frame_time - cur_time;
if (remaining > 0) {
std::this_thread::sleep_for(std::chrono::nanoseconds(remaining));
consecutive_missed = 0;
} else {
if (ignition) {
if ((int)-1*remaining/dt > 1){
LOGW("missed cycles (%d) %lld", (int)-1*remaining/dt, remaining);
int missed = (int)(-1 * remaining / dt);
if (missed > 1) {
consecutive_missed++;
LOGW("missed cycles (%d) %lld [consecutive: %d]", missed, remaining, consecutive_missed);
}
// When too many consecutive cycles are missed (common on Android USB host
// with slow ROMs), skip ahead to prevent cascading timing failure.
// Without this, the loop keeps trying to catch up and never recovers.
if (consecutive_missed >= MAX_CONSECUTIVE_MISSED) {
LOGW("too many consecutive missed cycles (%d), resetting timing", consecutive_missed);
next_frame_time = cur_time;
consecutive_missed = 0;
continue;
}
}
next_frame_time = cur_time;
Expand Down