diff --git a/wpimath/src/main/java/edu/wpi/first/math/estimator/KalmanFilterLatencyCompensator.java b/wpimath/src/main/java/edu/wpi/first/math/estimator/KalmanFilterLatencyCompensator.java index 50a83b5c63..89f35e5eb3 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/estimator/KalmanFilterLatencyCompensator.java +++ b/wpimath/src/main/java/edu/wpi/first/math/estimator/KalmanFilterLatencyCompensator.java @@ -74,15 +74,18 @@ public class KalmanFilterLatencyCompensatorfirst) { + return; + } + + // If the first snapshot has same timestamp as the global measurement, use + // that snapshot + indexOfClosestEntry = 0; + } else if (it == m_pastObserverSnapshots.cend()) { + // If all snapshots are older than the global measurement, use the newest + // snapshot + indexOfClosestEntry = m_pastObserverSnapshots.size() - 1; + } else { + // Index of snapshot taken after the global measurement + int nextIdx = std::distance(m_pastObserverSnapshots.cbegin(), it); + + // Index of snapshot taken before the global measurement. Since we already + // handled the case where the index points to the first snapshot, this + // computation is guaranteed to be nonnegative. + int prevIdx = nextIdx - 1; + + // Find the snapshot closest in time to global measurement + units::second_t prevTimeDiff = + units::math::abs(timestamp - m_pastObserverSnapshots[prevIdx].first); + units::second_t nextTimeDiff = + units::math::abs(timestamp - m_pastObserverSnapshots[nextIdx].first); + indexOfClosestEntry = prevTimeDiff < nextTimeDiff ? prevIdx : nextIdx; + } units::second_t lastTimestamp = m_pastObserverSnapshots[indexOfClosestEntry].first - nominalDt;