WPILibC++ 2023.4.3
MecanumDrivePoseEstimator.h
Go to the documentation of this file.
1// Copyright (c) FIRST and other WPILib contributors.
2// Open Source Software; you can modify and/or share it under the terms of
3// the WPILib BSD license file in the root directory of this project.
4
5#pragma once
6
7#include <functional>
8
9#include <wpi/SymbolExports.h>
10#include <wpi/array.h>
11
12#include "frc/EigenCore.h"
13#include "frc/geometry/Pose2d.h"
18#include "units/time.h"
19
20namespace frc {
21/**
22 * This class wraps Mecanum Drive Odometry to fuse latency-compensated
23 * vision measurements with mecanum drive encoder velocity measurements. It will
24 * correct for noisy measurements and encoder drift. It is intended to be an
25 * easy drop-in for MecanumDriveOdometry.
26 *
27 * Update() should be called every robot loop. If your loops are faster or
28 * slower than the default of 20 ms, then you should change the nominal delta
29 * time by specifying it in the constructor.
30 *
31 * AddVisionMeasurement() can be called as infrequently as you want; if you
32 * never call it, then this class will behave mostly like regular encoder
33 * odometry.
34 */
36 public:
37 /**
38 * Constructs a MecanumDrivePoseEstimator with default standard deviations
39 * for the model and vision measurements.
40 *
41 * The default standard deviations of the model states are
42 * 0.1 meters for x, 0.1 meters for y, and 0.1 radians for heading.
43 * The default standard deviations of the vision measurements are
44 * 0.45 meters for x, 0.45 meters for y, and 0.45 radians for heading.
45 *
46 * @param kinematics A correctly-configured kinematics object for your
47 * drivetrain.
48 * @param gyroAngle The current gyro angle.
49 * @param wheelPositions The distance measured by each wheel.
50 * @param initialPose The starting pose estimate.
51 */
53 const Rotation2d& gyroAngle,
54 const MecanumDriveWheelPositions& wheelPositions,
55 const Pose2d& initialPose);
56
57 /**
58 * Constructs a MecanumDrivePoseEstimator.
59 *
60 * @param kinematics A correctly-configured kinematics object for your
61 * drivetrain.
62 * @param gyroAngle The current gyro angle.
63 * @param wheelPositions The distance measured by each wheel.
64 * @param initialPose The starting pose estimate.
65 * @param stateStdDevs Standard deviations of the pose estimate (x position in
66 * meters, y position in meters, and heading in radians). Increase these
67 * numbers to trust your state estimate less.
68 * @param visionMeasurementStdDevs Standard deviations of the vision pose
69 * measurement (x position in meters, y position in meters, and heading in
70 * radians). Increase these numbers to trust the vision pose measurement
71 * less.
72 */
74 MecanumDriveKinematics& kinematics, const Rotation2d& gyroAngle,
75 const MecanumDriveWheelPositions& wheelPositions,
76 const Pose2d& initialPose, const wpi::array<double, 3>& stateStdDevs,
77 const wpi::array<double, 3>& visionMeasurementStdDevs);
78
79 /**
80 * Sets the pose estimator's trust in vision measurements. This might be used
81 * to change trust in vision measurements after the autonomous period, or to
82 * change trust as distance to a vision target increases.
83 *
84 * @param visionMeasurementStdDevs Standard deviations of the vision pose
85 * measurement (x position in meters, y position in meters, and heading in
86 * radians). Increase these numbers to trust the vision pose measurement
87 * less.
88 */
90 const wpi::array<double, 3>& visionMeasurementStdDevs);
91
92 /**
93 * Resets the robot's position on the field.
94 *
95 * The gyroscope angle does not need to be reset in the user's robot code.
96 * The library automatically takes care of offsetting the gyro angle.
97 *
98 * @param gyroAngle The angle reported by the gyroscope.
99 * @param wheelPositions The distances measured at each wheel.
100 * @param pose The position on the field that your robot is at.
101 */
102 void ResetPosition(const Rotation2d& gyroAngle,
103 const MecanumDriveWheelPositions& wheelPositions,
104 const Pose2d& pose);
105
106 /**
107 * Gets the estimated robot pose.
108 *
109 * @return The estimated robot pose in meters.
110 */
112
113 /**
114 * Add a vision measurement to the Kalman Filter. This will correct
115 * the odometry pose estimate while still accounting for measurement noise.
116 *
117 * This method can be called as infrequently as you want, as long as you are
118 * calling Update() every loop.
119 *
120 * To promote stability of the pose estimate and make it robust to bad vision
121 * data, we recommend only adding vision measurements that are already within
122 * one meter or so of the current pose estimate.
123 *
124 * @param visionRobotPose The pose of the robot as measured by the vision
125 * camera.
126 * @param timestamp The timestamp of the vision measurement in seconds. Note
127 * that if you don't use your own time source by calling UpdateWithTime()
128 * then you must use a timestamp with an epoch since FPGA startup (i.e.,
129 * the epoch of this timestamp is the same epoch as
130 * frc::Timer::GetFPGATimestamp().) This means that you should use
131 * frc::Timer::GetFPGATimestamp() as your time source or sync the epochs.
132 */
133 void AddVisionMeasurement(const Pose2d& visionRobotPose,
134 units::second_t timestamp);
135
136 /**
137 * Adds a vision measurement to the Kalman Filter. This will correct
138 * the odometry pose estimate while still accounting for measurement noise.
139 *
140 * This method can be called as infrequently as you want, as long as you are
141 * calling Update() every loop.
142 *
143 * To promote stability of the pose estimate and make it robust to bad vision
144 * data, we recommend only adding vision measurements that are already within
145 * one meter or so of the current pose estimate.
146 *
147 * Note that the vision measurement standard deviations passed into this
148 * method will continue to apply to future measurements until a subsequent
149 * call to SetVisionMeasurementStdDevs() or this method.
150 *
151 * @param visionRobotPose The pose of the robot as measured by the vision
152 * camera.
153 * @param timestamp The timestamp of the vision measurement in seconds. Note
154 * that if you don't use your own time source by calling UpdateWithTime(),
155 * then you must use a timestamp with an epoch since FPGA startup (i.e.,
156 * the epoch of this timestamp is the same epoch as
157 * frc::Timer::GetFPGATimestamp(). This means that you should use
158 * frc::Timer::GetFPGATimestamp() as your time source in this case.
159 * @param visionMeasurementStdDevs Standard deviations of the vision pose
160 * measurement (x position in meters, y position in meters, and heading in
161 * radians). Increase these numbers to trust the vision pose measurement
162 * less.
163 */
165 const Pose2d& visionRobotPose, units::second_t timestamp,
166 const wpi::array<double, 3>& visionMeasurementStdDevs) {
167 SetVisionMeasurementStdDevs(visionMeasurementStdDevs);
168 AddVisionMeasurement(visionRobotPose, timestamp);
169 }
170
171 /**
172 * Updates the pose estimator with wheel encoder and gyro information. This
173 * should be called every loop.
174 *
175 * @param gyroAngle The current gyro angle.
176 * @param wheelPositions The distances measured at each wheel.
177 * @return The estimated pose of the robot in meters.
178 */
179 Pose2d Update(const Rotation2d& gyroAngle,
180 const MecanumDriveWheelPositions& wheelPositions);
181
182 /**
183 * Updates the pose estimator with wheel encoder and gyro information. This
184 * should be called every loop.
185 *
186 * @param currentTime Time at which this method was called, in seconds.
187 * @param gyroAngle The current gyroscope angle.
188 * @param wheelPositions The distances measured at each wheel.
189 * @return The estimated pose of the robot in meters.
190 */
191 Pose2d UpdateWithTime(units::second_t currentTime,
192 const Rotation2d& gyroAngle,
193 const MecanumDriveWheelPositions& wheelPositions);
194
195 private:
196 struct InterpolationRecord {
197 // The pose observed given the current sensor inputs and the previous pose.
198 Pose2d pose;
199
200 // The current gyroscope angle.
201 Rotation2d gyroAngle;
202
203 // The distances measured at each wheel.
204 MecanumDriveWheelPositions wheelPositions;
205
206 /**
207 * Checks equality between this InterpolationRecord and another object.
208 *
209 * @param other The other object.
210 * @return Whether the two objects are equal.
211 */
212 bool operator==(const InterpolationRecord& other) const = default;
213
214 /**
215 * Checks inequality between this InterpolationRecord and another object.
216 *
217 * @param other The other object.
218 * @return Whether the two objects are not equal.
219 */
220 bool operator!=(const InterpolationRecord& other) const = default;
221
222 /**
223 * Interpolates between two InterpolationRecords.
224 *
225 * @param endValue The end value for the interpolation.
226 * @param i The interpolant (fraction).
227 *
228 * @return The interpolated state.
229 */
230 InterpolationRecord Interpolate(MecanumDriveKinematics& kinematics,
231 InterpolationRecord endValue,
232 double i) const;
233 };
234
235 static constexpr units::second_t kBufferDuration = 1.5_s;
236
237 MecanumDriveKinematics& m_kinematics;
238 MecanumDriveOdometry m_odometry;
240 Eigen::Matrix3d m_visionK = Eigen::Matrix3d::Zero();
241
242 TimeInterpolatableBuffer<InterpolationRecord> m_poseBuffer{
243 kBufferDuration, [this](const InterpolationRecord& start,
244 const InterpolationRecord& end, double t) {
245 return start.Interpolate(this->m_kinematics, end, t);
246 }};
247};
248
249} // namespace frc
#define WPILIB_DLLEXPORT
Definition: SymbolExports.h:36
Helper class that converts a chassis velocity (dx, dy, and dtheta components) into individual wheel s...
Definition: MecanumDriveKinematics.h:42
Class for mecanum drive odometry.
Definition: MecanumDriveOdometry.h:26
This class wraps Mecanum Drive Odometry to fuse latency-compensated vision measurements with mecanum ...
Definition: MecanumDrivePoseEstimator.h:35
void SetVisionMeasurementStdDevs(const wpi::array< double, 3 > &visionMeasurementStdDevs)
Sets the pose estimator's trust in vision measurements.
void AddVisionMeasurement(const Pose2d &visionRobotPose, units::second_t timestamp, const wpi::array< double, 3 > &visionMeasurementStdDevs)
Adds a vision measurement to the Kalman Filter.
Definition: MecanumDrivePoseEstimator.h:164
Pose2d UpdateWithTime(units::second_t currentTime, const Rotation2d &gyroAngle, const MecanumDriveWheelPositions &wheelPositions)
Updates the pose estimator with wheel encoder and gyro information.
Pose2d GetEstimatedPosition() const
Gets the estimated robot pose.
MecanumDrivePoseEstimator(MecanumDriveKinematics &kinematics, const Rotation2d &gyroAngle, const MecanumDriveWheelPositions &wheelPositions, const Pose2d &initialPose)
Constructs a MecanumDrivePoseEstimator with default standard deviations for the model and vision meas...
void AddVisionMeasurement(const Pose2d &visionRobotPose, units::second_t timestamp)
Add a vision measurement to the Kalman Filter.
Pose2d Update(const Rotation2d &gyroAngle, const MecanumDriveWheelPositions &wheelPositions)
Updates the pose estimator with wheel encoder and gyro information.
MecanumDrivePoseEstimator(MecanumDriveKinematics &kinematics, const Rotation2d &gyroAngle, const MecanumDriveWheelPositions &wheelPositions, const Pose2d &initialPose, const wpi::array< double, 3 > &stateStdDevs, const wpi::array< double, 3 > &visionMeasurementStdDevs)
Constructs a MecanumDrivePoseEstimator.
void ResetPosition(const Rotation2d &gyroAngle, const MecanumDriveWheelPositions &wheelPositions, const Pose2d &pose)
Resets the robot's position on the field.
Represents a 2D pose containing translational and rotational elements.
Definition: Pose2d.h:25
A rotation in a 2D coordinate frame represented by a point on the unit circle (cosine and sine).
Definition: Rotation2d.h:26
static EIGEN_DEPRECATED const end_t end
Definition: IndexedViewHelper.h:181
Definition: AprilTagFieldLayout.h:22
bool operator==(const Value &lhs, const Value &rhs)
constexpr bool operator!=(const UNIT_LIB_DEFAULT_TYPE lhs, const Units &rhs) noexcept
Definition: base.h:2716
constexpr empty_array_t empty_array
Definition: array.h:15
Represents the wheel speeds for a mecanum drive drivetrain.
Definition: MecanumDriveWheelPositions.h:15