diff --git a/wpimath/src/main/java/edu/wpi/first/math/estimator/DifferentialDrivePoseEstimator.java b/wpimath/src/main/java/edu/wpi/first/math/estimator/DifferentialDrivePoseEstimator.java index 9a0aebd799..ea8fc2f6bb 100644 --- a/wpimath/src/main/java/edu/wpi/first/math/estimator/DifferentialDrivePoseEstimator.java +++ b/wpimath/src/main/java/edu/wpi/first/math/estimator/DifferentialDrivePoseEstimator.java @@ -216,9 +216,14 @@ public class DifferentialDrivePoseEstimator { * @param gyroAngle The angle reported by the gyroscope. */ public void resetPosition(Pose2d poseMeters, Rotation2d gyroAngle) { - m_previousAngle = poseMeters.getRotation(); + // Reset state estimate and error covariance + m_observer.reset(); + m_latencyCompensator.reset(); + m_observer.setXhat(fillStateVector(poseMeters, 0.0, 0.0)); + m_gyroOffset = getEstimatedPosition().getRotation().minus(gyroAngle); + m_previousAngle = poseMeters.getRotation(); } /** 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 52ebb5c063..bc55cbb714 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 @@ -22,6 +22,11 @@ public class KalmanFilterLatencyCompensator(); } + /** Clears the observer snapshot buffer. */ + public void reset() { + m_pastObserverSnapshots.clear(); + } + /** * Add past observer states to the observer snapshots list. * @@ -51,18 +56,18 @@ public class KalmanFilterLatencyCompensator void applyPastGlobalMeasurement( Nat rows, KalmanTypeFilter observer, double nominalDtSeconds, - Matrix globalMeasurement, + Matrix y, BiConsumer, Matrix> globalMeasurementCorrect, - double globalMeasurementTimestampSeconds) { + double timestampSeconds) { if (m_pastObserverSnapshots.isEmpty()) { // State map was empty, which means that we got a past measurement right at startup. The only // thing we can really do is ignore the measurement. @@ -77,7 +82,7 @@ public class KalmanFilterLatencyCompensator(&m_observer, m_nominalDt, - PoseTo3dVector(visionRobotPose), - m_visionCorrect, timestamp); + m_latencyCompensator.ApplyPastGlobalMeasurement<3>( + &m_observer, m_nominalDt, PoseTo3dVector(visionRobotPose), + m_visionCorrect, timestamp); } Pose2d DifferentialDrivePoseEstimator::Update( diff --git a/wpimath/src/main/native/cpp/estimator/MecanumDrivePoseEstimator.cpp b/wpimath/src/main/native/cpp/estimator/MecanumDrivePoseEstimator.cpp index 44453b390f..5d6967e3ea 100644 --- a/wpimath/src/main/native/cpp/estimator/MecanumDrivePoseEstimator.cpp +++ b/wpimath/src/main/native/cpp/estimator/MecanumDrivePoseEstimator.cpp @@ -60,10 +60,12 @@ void frc::MecanumDrivePoseEstimator::SetVisionMeasurementStdDevs( void frc::MecanumDrivePoseEstimator::ResetPosition( const Pose2d& pose, const Rotation2d& gyroAngle) { - // Set observer state. + // Reset state estimate and error covariance + m_observer.Reset(); + m_latencyCompensator.Reset(); + m_observer.SetXhat(PoseTo3dVector(pose)); - // Calculate offsets. m_gyroOffset = pose.Rotation() - gyroAngle; m_previousAngle = pose.Rotation(); } @@ -75,9 +77,9 @@ Pose2d frc::MecanumDrivePoseEstimator::GetEstimatedPosition() const { void frc::MecanumDrivePoseEstimator::AddVisionMeasurement( const Pose2d& visionRobotPose, units::second_t timestamp) { - m_latencyCompensator.ApplyPastMeasurement<3>(&m_observer, m_nominalDt, - PoseTo3dVector(visionRobotPose), - m_visionCorrect, timestamp); + m_latencyCompensator.ApplyPastGlobalMeasurement<3>( + &m_observer, m_nominalDt, PoseTo3dVector(visionRobotPose), + m_visionCorrect, timestamp); } Pose2d frc::MecanumDrivePoseEstimator::Update( diff --git a/wpimath/src/main/native/include/frc/estimator/KalmanFilterLatencyCompensator.h b/wpimath/src/main/native/include/frc/estimator/KalmanFilterLatencyCompensator.h index 57d8a09754..f7e5588c8b 100644 --- a/wpimath/src/main/native/include/frc/estimator/KalmanFilterLatencyCompensator.h +++ b/wpimath/src/main/native/include/frc/estimator/KalmanFilterLatencyCompensator.h @@ -34,6 +34,19 @@ class KalmanFilterLatencyCompensator { localMeasurements(localY) {} }; + /** + * Clears the observer snapshot buffer. + */ + void Reset() { m_pastObserverSnapshots.clear(); } + + /** + * Add past observer states to the observer snapshots list. + * + * @param observer The observer. + * @param u The input at the timestamp. + * @param localY The local output at the timestamp + * @param timestamp The timesnap of the state. + */ void AddObserverState(const KalmanFilterType& observer, Eigen::Matrix u, Eigen::Matrix localY, @@ -48,8 +61,19 @@ class KalmanFilterLatencyCompensator { } } + /** + * Add past global measurements (such as from vision)to the estimator. + * + * @param observer The observer to apply the past global + * measurement. + * @param nominalDt The nominal timestep. + * @param y The measurement. + * @param globalMeasurementCorrect The function take calls correct() on the + * observer. + * @param timestamp The timestamp of the measurement. + */ template - void ApplyPastMeasurement( + void ApplyPastGlobalMeasurement( KalmanFilterType* observer, units::second_t nominalDt, Eigen::Matrix y, std::function& u, diff --git a/wpimath/src/main/native/include/frc/estimator/SwerveDrivePoseEstimator.h b/wpimath/src/main/native/include/frc/estimator/SwerveDrivePoseEstimator.h index 950c3fb983..e0f0ae2286 100644 --- a/wpimath/src/main/native/include/frc/estimator/SwerveDrivePoseEstimator.h +++ b/wpimath/src/main/native/include/frc/estimator/SwerveDrivePoseEstimator.h @@ -125,10 +125,12 @@ class SwerveDrivePoseEstimator { * @param gyroAngle The angle reported by the gyroscope. */ void ResetPosition(const Pose2d& pose, const Rotation2d& gyroAngle) { - // Set observer state. + // Reset state estimate and error covariance + m_observer.Reset(); + m_latencyCompensator.Reset(); + m_observer.SetXhat(PoseTo3dVector(pose)); - // Calculate offsets. m_gyroOffset = pose.Rotation() - gyroAngle; m_previousAngle = pose.Rotation(); } @@ -184,7 +186,7 @@ class SwerveDrivePoseEstimator { */ void AddVisionMeasurement(const Pose2d& visionRobotPose, units::second_t timestamp) { - m_latencyCompensator.ApplyPastMeasurement<3>( + m_latencyCompensator.ApplyPastGlobalMeasurement<3>( &m_observer, m_nominalDt, PoseTo3dVector(visionRobotPose), m_visionCorrect, timestamp); }