CTRE Phoenix 6 C++ 25.3.0
Loading...
Searching...
No Matches
SwerveDrivetrainImpl.hpp
Go to the documentation of this file.
1/*
2 * Copyright (C) Cross The Road Electronics.  All rights reserved.
3 * License information can be found in CTRE_LICENSE.txt
4 * For support and suggestions contact support@ctr-electronics.com or file
5 * an issue tracker at https://github.com/CrossTheRoadElec/Phoenix-Releases
6 */
7#pragma once
8
14
15#include <atomic>
16#include <thread>
17
18namespace ctre {
19namespace phoenix6 {
20namespace swerve {
21namespace impl {
22
23/**
24 * \brief Swerve Drive class utilizing CTR Electronics Phoenix 6 API.
25 *
26 * This class handles the kinematics and odometry (but not configuration)
27 * of a swerve drive utilizing CTR Electronics devices. Users should
28 * create a high-level SwerveDrivetrain instead of using this directly.
29 */
31public:
32 /** \brief Performs swerve module updates in a separate thread to minimize latency. */
34 protected:
35 static constexpr int START_THREAD_PRIORITY = 1; // Testing shows 1 (minimum realtime) is sufficient for tighter
36 // odometry loops.
37 // If the odometry period is far away from the desired frequency,
38 // increasing this may help
39
41
42 std::thread _thread;
43 std::mutex _threadMtx;
44 std::atomic<bool> _isRunning = false;
45
46 std::vector<BaseStatusSignal *> _allSignals;
47
48 static constexpr int kLowPassTaps = 50;
50 bool _lastTimeValid = false;
51 units::second_t _lastTime{};
52 units::second_t _averageLoopTime{};
53
54 std::atomic<int32_t> _successfulDaqs{};
55 std::atomic<int32_t> _failedDaqs{};
56
59
60 public:
63 {
64 Stop();
65 }
66
67 /**
68 * \brief Starts the odometry thread.
69 */
70 void Start()
71 {
72 std::lock_guard<std::mutex> lock{_threadMtx};
73 if (!_thread.joinable()) {
74 _isRunning.store(true, std::memory_order_relaxed);
75 _thread = std::thread{[this] { Run(); }};
76 }
77 }
78
79 /**
80 * \brief Stops the odometry thread.
81 */
82 void Stop()
83 {
84 std::lock_guard<std::mutex> lock{_threadMtx};
85 if (_thread.joinable()) {
86 _isRunning.store(false, std::memory_order_relaxed);
87 _thread.join();
88 }
89 }
90
91 /**
92 * \brief Check if the odometry is currently valid.
93 *
94 * \returns True if odometry is valid
95 */
96 bool IsOdometryValid() const
97 {
98 return _successfulDaqs.load(std::memory_order_relaxed) > 2;
99 }
100
101 /**
102 * \brief Sets the odometry thread priority to a real time priority under the specified priority level
103 *
104 * \param priority Priority level to set the odometry thread to.
105 * This is a value between 0 and 99, with 99 indicating higher priority and 0 indicating lower priority.
106 */
107 void SetThreadPriority(int priority)
108 {
109 _threadPriorityToSet.store(priority, std::memory_order_relaxed);
110 }
111
112 protected:
113 void Run();
114 };
115
116 /**
117 * \brief Plain-Old-Data class holding the state of the swerve drivetrain.
118 * This encapsulates most data that is relevant for telemetry or
119 * decision-making from the Swerve Drive.
120 */
122 /** \brief The current pose of the robot */
123 Pose2d Pose;
124 /** \brief The current velocity of the robot */
125 ChassisSpeeds Speeds;
126 /** \brief The current module states */
127 std::vector<SwerveModuleState> ModuleStates;
128 /** \brief The target module states */
129 std::vector<SwerveModuleState> ModuleTargets;
130 /** \brief The current module positions */
131 std::vector<SwerveModulePosition> ModulePositions;
132 /** \brief The raw heading of the robot, unaffected by vision updates and odometry resets */
133 Rotation2d RawHeading;
134 /** \brief The timestamp of the state capture, in the timebase of utils#GetCurrentTime() */
135 units::second_t Timestamp;
136 /** \brief The measured odometry update period */
137 units::second_t OdometryPeriod;
138 /** \brief Number of successful data acquisitions */
140 /** \brief Number of failed data acquisitions */
141 int32_t FailedDaqs;
142 };
143
144 /**
145 * \brief Contains everything the control requests need to calculate the module state.
146 */
148 /** \brief The kinematics object used for control */
150 /** \brief The locations of the swerve modules */
151 Translation2d const *moduleLocations;
152 /** \brief The max speed of the robot at 12 V output */
153 units::meters_per_second_t kMaxSpeed;
154
155 /** \brief The forward direction from the operator perspective */
157 /** \brief The current chassis speeds of the robot */
158 ChassisSpeeds currentChassisSpeed;
159 /** \brief The current pose of the robot */
161 /** \brief The timestamp of the current control apply, in the timebase of utils#GetCurrentTime() */
162 units::second_t timestamp;
163 /** \brief The update period of control apply */
164 units::second_t updatePeriod;
165 };
166
167 using SwerveRequestFunc = std::function<ctre::phoenix::StatusCode(ControlParameters const &, std::vector<std::unique_ptr<SwerveModuleImpl>> const &)>;
168
169private:
170 friend class OdometryThread;
171
172 CANBus _canbus;
173
176 StatusSignal<units::degrees_per_second_t> _pigeonAngularVelocity;
177
178 std::vector<std::unique_ptr<SwerveModuleImpl>> _modules;
179
180 std::vector<Translation2d> _moduleLocations;
181 std::vector<SwerveModulePosition> _modulePositions;
182 std::vector<SwerveModuleState> _moduleStates;
183
184 SwerveDriveKinematics _kinematics;
185 SwerveDrivePoseEstimator _odometry;
186
187 Rotation2d _operatorForwardDirection{};
188
189 SwerveRequestFunc _requestToApply = [](auto&, auto&) { return ctre::phoenix::StatusCode::OK; };
190 ControlParameters _requestParameters{};
191
192 mutable std::recursive_mutex _stateLock;
193 SwerveDriveState _cachedState{};
194 std::function<void(SwerveDriveState const &)> _telemetryFunction{};
195
196 bool _isOnCANFD;
197 units::hertz_t _updateFrequency;
198
199 std::unique_ptr<OdometryThread> _odometryThread;
200
201public:
202 /**
203 * \brief Constructs a CTRE SwerveDrivetrainImpl using the specified constants.
204 *
205 * This constructs the underlying hardware devices, which can be accessed through
206 * getters in the classes.
207 *
208 * \param drivetrainConstants Drivetrain-wide constants for the swerve drive
209 * \param modules Constants for each specific module
210 */
211 template <typename DriveMotorConfigsT, typename SteerMotorConfigsT, typename EncoderConfigsT>
213 SwerveDrivetrainConstants const &drivetrainConstants,
215 ) :
216 SwerveDrivetrainImpl{drivetrainConstants, 0_Hz, modules}
217 {}
218
219 /**
220 * \brief Constructs a CTRE SwerveDrivetrainImpl using the specified constants.
221 *
222 * This constructs the underlying hardware devices, which can be accessed through
223 * getters in the classes.
224 *
225 * \param drivetrainConstants Drivetrain-wide constants for the swerve drive
226 * \param odometryUpdateFrequency The frequency to run the odometry loop. If
227 * unspecified or set to 0 Hz, this is 250 Hz on
228 * CAN FD, and 100 Hz on CAN 2.0.
229 * \param modules Constants for each specific module
230 */
231 template <typename DriveMotorConfigsT, typename SteerMotorConfigsT, typename EncoderConfigsT>
233 SwerveDrivetrainConstants const &drivetrainConstants,
234 units::hertz_t odometryUpdateFrequency,
236 ) :
237 SwerveDrivetrainImpl{drivetrainConstants, odometryUpdateFrequency, std::array{0.1, 0.1, 0.1}, std::array{0.9, 0.9, 0.9}, modules}
238 {}
239
240 /**
241 * \brief Constructs a CTRE SwerveDrivetrainImpl using the specified constants.
242 *
243 * This constructs the underlying hardware devices, which can be accessed through
244 * getters in the classes.
245 *
246 * \param drivetrainConstants Drivetrain-wide constants for the swerve drive
247 * \param odometryUpdateFrequency The frequency to run the odometry loop. If
248 * unspecified or set to 0 Hz, this is 250 Hz on
249 * CAN FD, and 100 Hz on CAN 2.0.
250 * \param odometryStandardDeviation The standard deviation for odometry calculation
251 * in the form [x, y, theta]ᵀ, with units in meters
252 * and radians
253 * \param visionStandardDeviation The standard deviation for vision calculation
254 * in the form [x, y, theta]ᵀ, with units in meters
255 * and radians
256 * \param modules Constants for each specific module
257 */
258 template <typename DriveMotorConfigsT, typename SteerMotorConfigsT, typename EncoderConfigsT>
260 SwerveDrivetrainConstants const &drivetrainConstants,
261 units::hertz_t odometryUpdateFrequency,
262 std::array<double, 3> const &odometryStandardDeviation,
263 std::array<double, 3> const &visionStandardDeviation,
265 );
266
267 /**
268 * \brief Gets whether the drivetrain is on a CAN FD bus.
269 *
270 * \returns true if on CAN FD
271 */
272 bool IsOnCANFD() const { return _isOnCANFD; }
273
274 /**
275 * \brief Gets the target odometry update frequency.
276 *
277 * \returns Target odometry update frequency
278 */
279 units::hertz_t GetOdometryFrequency() const { return _updateFrequency; }
280
281 /**
282 * \brief Gets a reference to the odometry thread.
283 *
284 * \returns Odometry thread
285 */
286 OdometryThread &GetOdometryThread() { return *_odometryThread; }
287
288 /**
289 * \brief Check if the odometry is currently valid.
290 *
291 * \returns True if odometry is valid
292 */
293 bool IsOdometryValid() const
294 {
295 return _odometryThread->IsOdometryValid();
296 }
297
298 /**
299 * \brief Gets a reference to the kinematics used for the drivetrain.
300 *
301 * \returns Swerve kinematics
302 */
303 SwerveDriveKinematics const &GetKinematics() const { return _kinematics; }
304
305 /**
306 * \brief Applies the specified control function to this swerve drivetrain.
307 *
308 * \param request Request function to apply
309 */
311 {
312 std::lock_guard<std::recursive_mutex> lock{_stateLock};
313 if (request) {
314 _requestToApply = std::move(request);
315 } else {
316 _requestToApply = [](auto&, auto&) { return ctre::phoenix::StatusCode::OK; };
317 }
318 }
319
320 /**
321 * \brief Immediately runs the provided temporary control function.
322 *
323 * This is used to accelerate non-native swerve requests and
324 * can only be called from the odometry thread. Otherwise,
325 * SetControl should be used instead.
326 *
327 * \param request Request function to invoke
328 */
330 {
331 std::lock_guard<std::recursive_mutex> lock{_stateLock};
332 return request(_requestParameters, _modules);
333 }
334
335 /**
336 * \brief Gets the current state of the swerve drivetrain.
337 * This includes information such as the pose estimate,
338 * module states, and chassis speeds.
339 *
340 * \returns Current state of the drivetrain
341 */
343 {
344 std::lock_guard<std::recursive_mutex> lock{_stateLock};
345 return _cachedState;
346 }
347
348 /**
349 * \brief Register the specified lambda to be executed whenever the SwerveDriveState
350 * is updated in the odometry thread.
351 *
352 * It is imperative that this function is cheap, as it will be executed synchronously
353 * with the odometry call; if this takes a long time, it may negatively impact the
354 * odometry of this stack.
355 *
356 * This can also be used for logging data if the function performs logging instead of telemetry.
357 * Additionally, the SwerveDriveState object can be cloned and stored for later processing.
358 *
359 * \param telemetryFunction Function to call for telemetry or logging
360 */
361 void RegisterTelemetry(std::function<void(SwerveDriveState const &)> telemetryFunction)
362 {
363 std::lock_guard<std::recursive_mutex> lock{_stateLock};
364 _telemetryFunction = std::move(telemetryFunction);
365 }
366
367 /**
368 * \brief Configures the neutral mode to use for all modules' drive motors.
369 *
370 * \param neutralMode The drive motor neutral mode
371 * \returns Status code of the first failed config call, or OK if all succeeded
372 */
374 {
376 for (auto &module : _modules) {
377 auto status = module->ConfigNeutralMode(neutralMode);
378 if (retval.IsOK()) {
379 retval = status;
380 }
381 }
382 return retval;
383 }
384
385 /**
386 * \brief Zero's this swerve drive's odometry entirely.
387 *
388 * This will zero the entire odometry, and place the robot at 0,0
389 */
391 {
392 std::lock_guard<std::recursive_mutex> lock{_stateLock};
393
394 for (size_t i = 0; i < _modules.size(); ++i) {
395 _modules[i]->ResetPosition();
396 _modulePositions[i] = _modules[i]->GetPosition(true);
397 }
398 _odometry.ResetPosition({_pigeonYaw.GetValue()}, _modulePositions, Pose2d{});
399 /* We need to update our cached pose immediately to prevent race conditions */
400 _cachedState.Pose = _odometry.GetEstimatedPosition();
401 }
402
403 /**
404 * \brief Resets the rotation of the robot pose to 0 from the
405 * requests#ForwardPerspectiveValue#OperatorPerspective perspective.
406 * This makes the current orientation of the robot X forward for
407 * field-centric maneuvers.
408 *
409 * This is equivalent to calling ResetRotation with the operator
410 * perspective rotation.
411 */
413 {
414 ResetRotation(_operatorForwardDirection);
415 }
416
417 /**
418 * \brief Resets the pose of the robot. The pose should be from the
419 * requests#ForwardPerspectiveValue#BlueAlliance perspective.
420 *
421 * \param pose Pose to make the current pose
422 */
423 void ResetPose(Pose2d const &pose)
424 {
425 std::lock_guard<std::recursive_mutex> lock{_stateLock};
426
427 _odometry.ResetPose(pose);
428 /* We need to update our cached pose immediately to prevent race conditions */
429 _cachedState.Pose = _odometry.GetEstimatedPosition();
430 }
431
432 /**
433 * \brief Resets the translation of the robot pose without affecting rotation.
434 * The translation should be from the requests#ForwardPerspectiveValue#BlueAlliance
435 * perspective.
436 *
437 * \param translation Translation to make the current translation
438 */
439 void ResetTranslation(Translation2d const &translation)
440 {
441 std::lock_guard<std::recursive_mutex> lock{_stateLock};
442
443 _odometry.ResetTranslation(translation);
444 /* We need to update our cached pose immediately to prevent race conditions */
445 _cachedState.Pose = _odometry.GetEstimatedPosition();
446 }
447
448 /**
449 * \brief Resets the rotation of the robot pose without affecting translation.
450 * The rotation should be from the requests#ForwardPerspectiveValue#BlueAlliance
451 * perspective.
452 *
453 * \param rotation Rotation to make the current rotation
454 */
455 void ResetRotation(Rotation2d const &rotation)
456 {
457 std::lock_guard<std::recursive_mutex> lock{_stateLock};
458
459 _odometry.ResetRotation(rotation);
460 /* We need to update our cached pose immediately to prevent race conditions */
461 _cachedState.Pose = _odometry.GetEstimatedPosition();
462 }
463
464 /**
465 * \brief Takes the requests#ForwardPerspectiveValue#BlueAlliance perpective
466 * direction and treats it as the forward direction for
467 * requests#ForwardPerspectiveValue#OperatorPerspective.
468 *
469 * If the operator is in the Blue Alliance Station, this should be 0 degrees.
470 * If the operator is in the Red Alliance Station, this should be 180 degrees.
471 *
472 * This does not change the robot pose, which is in the
473 * requests#ForwardPerspectiveValue#BlueAlliance perspective.
474 * As a result, the robot pose may need to be reset using ResetPose.
475 *
476 * \param fieldDirection Heading indicating which direction is forward from
477 * the requests#ForwardPerspectiveValue#BlueAlliance perspective
478 */
479 void SetOperatorPerspectiveForward(Rotation2d fieldDirection)
480 {
481 std::lock_guard<std::recursive_mutex> lock{_stateLock};
482 _operatorForwardDirection = fieldDirection;
483 }
484
485 /**
486 * \brief Returns the requests#ForwardPerspectiveValue#BlueAlliance perpective
487 * direction that is treated as the forward direction for
488 * requests#ForwardPerspectiveValue#OperatorPerspective.
489 *
490 * If the operator is in the Blue Alliance Station, this should be 0 degrees.
491 * If the operator is in the Red Alliance Station, this should be 180 degrees.
492 *
493 * \returns Heading indicating which direction is forward from
494 * the requests#ForwardPerspectiveValue#BlueAlliance perspective
495 */
497 {
498 std::lock_guard<std::recursive_mutex> lock{_stateLock};
499 return _operatorForwardDirection;
500 }
501
502 /**
503 * \brief Adds a vision measurement to the Kalman Filter. This will correct the
504 * odometry pose estimate while still accounting for measurement noise.
505 *
506 * This method can be called as infrequently as you want, as long as you are
507 * calling impl#SwerveDrivePoseEstimator#Update every loop.
508 *
509 * To promote stability of the pose estimate and make it robust to bad vision
510 * data, we recommend only adding vision measurements that are already within
511 * one meter or so of the current pose estimate.
512 *
513 * \param visionRobotPose The pose of the robot as measured by the
514 * vision camera.
515 * \param timestamp The timestamp of the vision measurement in
516 * seconds. Note that if you don't use your
517 * own time source by calling
518 * impl#SwerveDrivePoseEstimator#UpdateWithTime,
519 * then you must use a timestamp with an epoch
520 * since system startup (i.e., the epoch of this
521 * timestamp is the same epoch as utils#GetCurrentTime).
522 * This means that you should use utils#GetCurrentTime
523 * as your time source in this case.
524 */
525 void AddVisionMeasurement(Pose2d visionRobotPose, units::second_t timestamp)
526 {
527 std::lock_guard<std::recursive_mutex> lock{_stateLock};
528 _odometry.AddVisionMeasurement(visionRobotPose, timestamp);
529 }
530
531 /**
532 * \brief Adds a vision measurement to the Kalman Filter. This will correct the
533 * odometry pose estimate while still accounting for measurement noise.
534 *
535 * This method can be called as infrequently as you want, as long as you are
536 * calling impl#SwerveDrivePoseEstimator#Update every loop.
537 *
538 * To promote stability of the pose estimate and make it robust to bad vision
539 * data, we recommend only adding vision measurements that are already within
540 * one meter or so of the current pose estimate.
541 *
542 * Note that the vision measurement standard deviations passed into this method
543 * will continue to apply to future measurements until a subsequent call to
544 * #SetVisionMeasurementStdDevs or this method.
545 *
546 * \param visionRobotPose The pose of the robot as measured by the
547 * vision camera.
548 * \param timestamp The timestamp of the vision measurement in
549 * seconds. Note that if you don't use your
550 * own time source by calling
551 * impl#SwerveDrivePoseEstimator#UpdateWithTime,
552 * then you must use a timestamp with an epoch
553 * since system startup (i.e., the epoch of this
554 * timestamp is the same epoch as utils#GetCurrentTime).
555 * This means that you should use utils#GetCurrentTime
556 * as your time source in this case.
557 * \param visionMeasurementStdDevs Standard deviations of the vision pose
558 * measurement (x position in meters, y position
559 * in meters, and heading in radians). Increase
560 * these numbers to trust the vision pose
561 * measurement less.
562 */
564 Pose2d visionRobotPose,
565 units::second_t timestamp,
566 std::array<double, 3> const &visionMeasurementStdDevs)
567 {
568 std::lock_guard<std::recursive_mutex> lock{_stateLock};
569 _odometry.AddVisionMeasurement(visionRobotPose, timestamp, visionMeasurementStdDevs);
570 }
571
572 /**
573 * \brief Sets the pose estimator's trust of global measurements. This might be used to
574 * change trust in vision measurements after the autonomous period, or to change
575 * trust as distance to a vision target increases.
576 *
577 * \param visionMeasurementStdDevs Standard deviations of the vision
578 * measurements. Increase these
579 * numbers to trust global measurements from
580 * vision less. This matrix is in the form [x,
581 * y, theta]ᵀ, with units in meters and radians.
582 */
583 void SetVisionMeasurementStdDevs(std::array<double, 3> const &visionMeasurementStdDevs)
584 {
585 std::lock_guard<std::recursive_mutex> lock{_stateLock};
586 _odometry.SetVisionMeasurementStdDevs(visionMeasurementStdDevs);
587 }
588
589 /**
590 * \brief Sets the pose estimator's trust in robot odometry. This might be used
591 * to change trust in odometry after an impact with the wall or traversing a bump.
592 *
593 * \param stateStdDevs Standard deviations of the pose estimate. Increase these
594 * numbers to trust your state estimate less. This matrix is
595 * in the form [x, y, theta]ᵀ, with units in meters and radians.
596 */
597 void SetStateStdDevs(std::array<double, 3> const &stateStdDevs)
598 {
599 std::lock_guard<std::recursive_mutex> lock{_stateLock};
600 _odometry.SetStateStdDevs(stateStdDevs);
601 }
602
603 /**
604 * \brief Return the pose at a given timestamp, if the buffer is not empty.
605 *
606 * \param timestamp The pose's timestamp. Note that if you don't use your
607 * own time source by calling
608 * impl#SwerveDrivePoseEstimator#UpdateWithTime,
609 * then you must use a timestamp with an epoch
610 * since system startup (i.e., the epoch of this
611 * timestamp is the same epoch as utils#GetCurrentTime).
612 * This means that you should use utils#GetCurrentTime
613 * as your time source in this case.
614 * \returns The pose at the given timestamp (or std::nullopt if the buffer is
615 * empty).
616 */
617 std::optional<Pose2d> SamplePoseAt(units::second_t timestamp)
618 {
619 std::lock_guard<std::recursive_mutex> lock{_stateLock};
620 return _odometry.SampleAt(timestamp);
621 }
622
623 /**
624 * \brief Get a reference to the module at the specified index.
625 * The index corresponds to the module described in the constructor.
626 *
627 * \param index Which module to get
628 * \returns Reference to SwerveModuleImpl
629 */
630 SwerveModuleImpl &GetModule(size_t index) { return *_modules[index]; }
631 /**
632 * \brief Get a reference to the module at the specified index.
633 * The index corresponds to the module described in the constructor.
634 *
635 * \param index Which module to get
636 * \returns Reference to SwerveModuleImpl
637 */
638 SwerveModuleImpl const &GetModule(size_t index) const { return *_modules[index]; }
639 /**
640 * \brief Get a reference to the full array of modules.
641 * The indexes correspond to the module described in the constructor.
642 *
643 * \returns Reference to the SwerveModuleImpl array
644 */
645 std::vector<std::unique_ptr<SwerveModuleImpl>> const &GetModules() const { return _modules; }
646
647 /**
648 * \brief Gets the locations of the swerve modules.
649 *
650 * \returns Reference to the array of swerve module locations
651 */
652 std::vector<Translation2d> const &GetModuleLocations() const { return _moduleLocations; }
653
654 /**
655 * \brief Gets this drivetrain's Pigeon 2 reference.
656 *
657 * This should be used only to access signals and change configurations that the
658 * swerve drivetrain does not configure itself.
659 *
660 * \returns This drivetrain's Pigeon 2 reference
661 */
663};
664
665}
666}
667}
668}
Class for getting information about an available CAN bus.
Definition CANBus.hpp:19
Represents a status signal with data of type T, and operations available to retrieve information abou...
Definition StatusSignal.hpp:656
T GetValue() const
Gets the cached value from this status signal.
Definition StatusSignal.hpp:758
Class description for the Pigeon 2 IMU sensor that measures orientation.
Definition CorePigeon2.hpp:1116
The state of the motor controller bridge when output is neutral or disabled.
Definition SpnEnums.hpp:2303
This class implements a linear, digital filter.
Definition LinearFilter.hpp:78
static LinearFilter< T > MovingAverage(int taps)
Creates a K-tap FIR moving average filter of the form: y[n] = 1/k (x[k] + x[k-1] + … + x[0])
Definition LinearFilter.hpp:160
Class that converts a chassis velocity (dx, dy, and dtheta components) into individual module states ...
Definition SwerveDriveKinematics.hpp:42
This class wraps Swerve Drive Odometry to fuse latency-compensated vision measurements with swerve dr...
Definition SwerveDrivePoseEstimator.hpp:142
void ResetPosition(Rotation2d const &gyroAngle, WheelPositions wheelPositions, Pose2d const &pose)
Resets the robot's position on the field.
Definition SwerveDrivePoseEstimator.hpp:290
void AddVisionMeasurement(Pose2d const &visionRobotPose, units::second_t timestamp)
Adds a vision measurement to the Kalman Filter.
Pose2d GetEstimatedPosition() const
Gets the estimated robot pose.
Definition SwerveDrivePoseEstimator.hpp:342
void ResetTranslation(Translation2d const &translation)
Resets the robot's translation.
Definition SwerveDrivePoseEstimator.hpp:316
void ResetPose(Pose2d const &pose)
Resets the robot's pose.
Definition SwerveDrivePoseEstimator.hpp:303
std::optional< Pose2d > SampleAt(units::second_t timestamp) const
Return the pose at a given timestamp, if the buffer is not empty.
void SetStateStdDevs(std::array< double, 3 > const &stateStdDevs)
Sets the pose estimator's trust in robot odometry.
Definition SwerveDrivePoseEstimator.hpp:254
void ResetRotation(Rotation2d const &rotation)
Resets the robot's rotation.
Definition SwerveDrivePoseEstimator.hpp:329
void SetVisionMeasurementStdDevs(std::array< double, 3 > const &visionMeasurementStdDevs)
Sets the pose estimator's trust in vision measurements.
Definition SwerveDrivePoseEstimator.hpp:272
Performs swerve module updates in a separate thread to minimize latency.
Definition SwerveDrivetrainImpl.hpp:33
std::thread _thread
Definition SwerveDrivetrainImpl.hpp:42
std::atomic< bool > _isRunning
Definition SwerveDrivetrainImpl.hpp:44
std::vector< BaseStatusSignal * > _allSignals
Definition SwerveDrivetrainImpl.hpp:46
bool IsOdometryValid() const
Check if the odometry is currently valid.
Definition SwerveDrivetrainImpl.hpp:96
units::second_t _lastTime
Definition SwerveDrivetrainImpl.hpp:51
void Stop()
Stops the odometry thread.
Definition SwerveDrivetrainImpl.hpp:82
std::atomic< int > _threadPriorityToSet
Definition SwerveDrivetrainImpl.hpp:57
static constexpr int START_THREAD_PRIORITY
Definition SwerveDrivetrainImpl.hpp:35
LinearFilter< units::second_t > _lowPass
Definition SwerveDrivetrainImpl.hpp:49
std::atomic< int32_t > _failedDaqs
Definition SwerveDrivetrainImpl.hpp:55
void Start()
Starts the odometry thread.
Definition SwerveDrivetrainImpl.hpp:70
bool _lastTimeValid
Definition SwerveDrivetrainImpl.hpp:50
units::second_t _averageLoopTime
Definition SwerveDrivetrainImpl.hpp:52
SwerveDrivetrainImpl * _drivetrain
Definition SwerveDrivetrainImpl.hpp:40
void SetThreadPriority(int priority)
Sets the odometry thread priority to a real time priority under the specified priority level.
Definition SwerveDrivetrainImpl.hpp:107
std::atomic< int32_t > _successfulDaqs
Definition SwerveDrivetrainImpl.hpp:54
std::mutex _threadMtx
Definition SwerveDrivetrainImpl.hpp:43
static constexpr int kLowPassTaps
Definition SwerveDrivetrainImpl.hpp:48
int _lastThreadPriority
Definition SwerveDrivetrainImpl.hpp:58
Swerve Drive class utilizing CTR Electronics Phoenix 6 API.
Definition SwerveDrivetrainImpl.hpp:30
void TareEverything()
Zero's this swerve drive's odometry entirely.
Definition SwerveDrivetrainImpl.hpp:390
std::function< ctre::phoenix::StatusCode(ControlParameters const &, std::vector< std::unique_ptr< SwerveModuleImpl > > const &)> SwerveRequestFunc
Definition SwerveDrivetrainImpl.hpp:167
void SetControl(SwerveRequestFunc &&request)
Applies the specified control function to this swerve drivetrain.
Definition SwerveDrivetrainImpl.hpp:310
std::vector< Translation2d > const & GetModuleLocations() const
Gets the locations of the swerve modules.
Definition SwerveDrivetrainImpl.hpp:652
units::hertz_t GetOdometryFrequency() const
Gets the target odometry update frequency.
Definition SwerveDrivetrainImpl.hpp:279
SwerveDriveState GetState() const
Gets the current state of the swerve drivetrain.
Definition SwerveDrivetrainImpl.hpp:342
void AddVisionMeasurement(Pose2d visionRobotPose, units::second_t timestamp, std::array< double, 3 > const &visionMeasurementStdDevs)
Adds a vision measurement to the Kalman Filter.
Definition SwerveDrivetrainImpl.hpp:563
void SeedFieldCentric()
Resets the rotation of the robot pose to 0 from the requests::ForwardPerspectiveValue::OperatorPerspe...
Definition SwerveDrivetrainImpl.hpp:412
SwerveModuleImpl const & GetModule(size_t index) const
Get a reference to the module at the specified index.
Definition SwerveDrivetrainImpl.hpp:638
SwerveDrivetrainImpl(SwerveDrivetrainConstants const &drivetrainConstants, units::hertz_t odometryUpdateFrequency, span< SwerveModuleConstants< DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT > const > modules)
Constructs a CTRE SwerveDrivetrainImpl using the specified constants.
Definition SwerveDrivetrainImpl.hpp:232
bool IsOdometryValid() const
Check if the odometry is currently valid.
Definition SwerveDrivetrainImpl.hpp:293
void ResetRotation(Rotation2d const &rotation)
Resets the rotation of the robot pose without affecting translation.
Definition SwerveDrivetrainImpl.hpp:455
hardware::core::CorePigeon2 & GetPigeon2()
Gets this drivetrain's Pigeon 2 reference.
Definition SwerveDrivetrainImpl.hpp:662
void RegisterTelemetry(std::function< void(SwerveDriveState const &)> telemetryFunction)
Register the specified lambda to be executed whenever the SwerveDriveState is updated in the odometry...
Definition SwerveDrivetrainImpl.hpp:361
void SetVisionMeasurementStdDevs(std::array< double, 3 > const &visionMeasurementStdDevs)
Sets the pose estimator's trust of global measurements.
Definition SwerveDrivetrainImpl.hpp:583
void SetStateStdDevs(std::array< double, 3 > const &stateStdDevs)
Sets the pose estimator's trust in robot odometry.
Definition SwerveDrivetrainImpl.hpp:597
SwerveDrivetrainImpl(SwerveDrivetrainConstants const &drivetrainConstants, span< SwerveModuleConstants< DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT > const > modules)
Constructs a CTRE SwerveDrivetrainImpl using the specified constants.
Definition SwerveDrivetrainImpl.hpp:212
std::vector< std::unique_ptr< SwerveModuleImpl > > const & GetModules() const
Get a reference to the full array of modules.
Definition SwerveDrivetrainImpl.hpp:645
ctre::phoenix::StatusCode ConfigNeutralMode(signals::NeutralModeValue neutralMode)
Configures the neutral mode to use for all modules' drive motors.
Definition SwerveDrivetrainImpl.hpp:373
SwerveDrivetrainImpl(SwerveDrivetrainConstants const &drivetrainConstants, units::hertz_t odometryUpdateFrequency, std::array< double, 3 > const &odometryStandardDeviation, std::array< double, 3 > const &visionStandardDeviation, span< SwerveModuleConstants< DriveMotorConfigsT, SteerMotorConfigsT, EncoderConfigsT > const > modules)
Constructs a CTRE SwerveDrivetrainImpl using the specified constants.
SwerveDriveKinematics const & GetKinematics() const
Gets a reference to the kinematics used for the drivetrain.
Definition SwerveDrivetrainImpl.hpp:303
SwerveModuleImpl & GetModule(size_t index)
Get a reference to the module at the specified index.
Definition SwerveDrivetrainImpl.hpp:630
void SetOperatorPerspectiveForward(Rotation2d fieldDirection)
Takes the requests::ForwardPerspectiveValue::BlueAlliance perpective direction and treats it as the f...
Definition SwerveDrivetrainImpl.hpp:479
Rotation2d GetOperatorForwardDirection() const
Returns the requests::ForwardPerspectiveValue::BlueAlliance perpective direction that is treated as t...
Definition SwerveDrivetrainImpl.hpp:496
OdometryThread & GetOdometryThread()
Gets a reference to the odometry thread.
Definition SwerveDrivetrainImpl.hpp:286
std::optional< Pose2d > SamplePoseAt(units::second_t timestamp)
Return the pose at a given timestamp, if the buffer is not empty.
Definition SwerveDrivetrainImpl.hpp:617
bool IsOnCANFD() const
Gets whether the drivetrain is on a CAN FD bus.
Definition SwerveDrivetrainImpl.hpp:272
ctre::phoenix::StatusCode RunTempRequest(SwerveRequestFunc &&request) const
Immediately runs the provided temporary control function.
Definition SwerveDrivetrainImpl.hpp:329
void ResetPose(Pose2d const &pose)
Resets the pose of the robot.
Definition SwerveDrivetrainImpl.hpp:423
void ResetTranslation(Translation2d const &translation)
Resets the translation of the robot pose without affecting rotation.
Definition SwerveDrivetrainImpl.hpp:439
void AddVisionMeasurement(Pose2d visionRobotPose, units::second_t timestamp)
Adds a vision measurement to the Kalman Filter.
Definition SwerveDrivetrainImpl.hpp:525
Swerve Module class that encapsulates a swerve module powered by CTR Electronics devices.
Definition SwerveModuleImpl.hpp:60
Definition span.hpp:134
Status codes reported by APIs, including OK, warnings, and errors.
Definition StatusCodes.h:27
static constexpr int OK
No Error.
Definition StatusCodes.h:34
constexpr bool IsOK() const
Definition StatusCodes.h:864
Definition MotionMagicExpoTorqueCurrentFOC.hpp:18
Definition span.hpp:401
Common constants for a swerve drivetrain.
Definition SwerveDrivetrainConstants.hpp:19
All constants for a swerve module.
Definition SwerveModuleConstants.hpp:154
Contains everything the control requests need to calculate the module state.
Definition SwerveDrivetrainImpl.hpp:147
units::second_t timestamp
The timestamp of the current control apply, in the timebase of utils::GetCurrentTime()
Definition SwerveDrivetrainImpl.hpp:162
units::meters_per_second_t kMaxSpeed
The max speed of the robot at 12 V output.
Definition SwerveDrivetrainImpl.hpp:153
units::second_t updatePeriod
The update period of control apply.
Definition SwerveDrivetrainImpl.hpp:164
ChassisSpeeds currentChassisSpeed
The current chassis speeds of the robot.
Definition SwerveDrivetrainImpl.hpp:158
impl::SwerveDriveKinematics * kinematics
The kinematics object used for control.
Definition SwerveDrivetrainImpl.hpp:149
Pose2d currentPose
The current pose of the robot.
Definition SwerveDrivetrainImpl.hpp:160
Rotation2d operatorForwardDirection
The forward direction from the operator perspective.
Definition SwerveDrivetrainImpl.hpp:156
Translation2d const * moduleLocations
The locations of the swerve modules.
Definition SwerveDrivetrainImpl.hpp:151
Plain-Old-Data class holding the state of the swerve drivetrain.
Definition SwerveDrivetrainImpl.hpp:121
std::vector< SwerveModuleState > ModuleStates
The current module states.
Definition SwerveDrivetrainImpl.hpp:127
int32_t SuccessfulDaqs
Number of successful data acquisitions.
Definition SwerveDrivetrainImpl.hpp:139
ChassisSpeeds Speeds
The current velocity of the robot.
Definition SwerveDrivetrainImpl.hpp:125
units::second_t Timestamp
The timestamp of the state capture, in the timebase of utils::GetCurrentTime()
Definition SwerveDrivetrainImpl.hpp:135
std::vector< SwerveModulePosition > ModulePositions
The current module positions.
Definition SwerveDrivetrainImpl.hpp:131
Pose2d Pose
The current pose of the robot.
Definition SwerveDrivetrainImpl.hpp:123
std::vector< SwerveModuleState > ModuleTargets
The target module states.
Definition SwerveDrivetrainImpl.hpp:129
int32_t FailedDaqs
Number of failed data acquisitions.
Definition SwerveDrivetrainImpl.hpp:141
Rotation2d RawHeading
The raw heading of the robot, unaffected by vision updates and odometry resets.
Definition SwerveDrivetrainImpl.hpp:133
units::second_t OdometryPeriod
The measured odometry update period.
Definition SwerveDrivetrainImpl.hpp:137