CTRE Phoenix 6 C++ 26.70.0-alpha-2
Loading...
Searching...
No Matches
SwerveDrivetrain.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
15namespace ctre {
16namespace phoenix6 {
17namespace swerve {
18
19/**
20 * \brief Swerve Drive class utilizing CTR Electronics Phoenix 6 API.
21 *
22 * This class handles the kinematics, configuration, and odometry of a
23 * swerve drive utilizing CTR Electronics devices. We recommend using
24 * the Swerve Project Generator in Tuner X to create a template project
25 * that demonstrates how to use this class.
26 *
27 * This class performs pose estimation internally using a separate odometry
28 * thread. Vision measurements can be added using AddVisionMeasurement.
29 * Other odometry APIs such as ResetPose are also available. The resulting
30 * pose estimate can be retrieved along with module states and other
31 * information using GetState. Additionally, the odometry thread synchronously
32 * provides all new state updates to a telemetry function registered with
33 * RegisterTelemetry.
34 *
35 * This class will construct the hardware devices internally, so the user
36 * only specifies the constants (IDs, PID gains, gear ratios, etc).
37 * Getters for these hardware devices are available.
38 *
39 * If using the generator, the order in which modules are constructed is
40 * Front Left, Front Right, Back Left, Back Right. This means if you need
41 * the Back Left module, call \c GetModule(2); to get the third (0-indexed)
42 * module.
43 *
44 * \tparam DriveMotorT Type of the drive motor
45 * \tparam SteerMotorT Type of the steer motor
46 * \tparam EncoderT Type of the steer encoder
47 */
48template <
49 std::derived_from<hardware::traits::CommonTalon> DriveMotorT,
50 std::derived_from<hardware::traits::CommonTalon> SteerMotorT,
51 typename EncoderT
52>
53 requires std::same_as<EncoderT, hardware::CANcoder> ||
54 std::same_as<EncoderT, hardware::CANdi> ||
55 std::same_as<EncoderT, hardware::TalonFXS>
57public:
58 /** \brief Performs swerve module updates in a separate thread to minimize latency. */
60
61 /**
62 * \brief Plain-Old-Data class holding the state of the swerve drivetrain.
63 * This encapsulates most data that is relevant for telemetry or
64 * decision-making from the Swerve Drive.
65 */
67
68 /**
69 * \brief Swerve Module class that encapsulates a swerve module powered by
70 * CTR Electronics devices.
71 *
72 * This class handles the hardware devices and configures them for
73 * swerve module operation using the Phoenix 6 API.
74 *
75 * This class constructs hardware devices internally, so the user
76 * only specifies the constants (IDs, PID gains, gear ratios, etc).
77 * Getters for these hardware devices are available.
78 */
80
81 /**
82 * \brief All constants for a swerve module.
83 */
85
86protected:
87 /** \brief Number of times to attempt config applies. */
88 static constexpr int kNumConfigAttempts = 2;
89
90 /** \brief The underlying drivetrain instance. */
92
93private:
94 std::vector<std::unique_ptr<SwerveModule>> _modules;
95
96 hardware::Pigeon2 _pigeon2;
98
99public:
100 /**
101 * \brief Constructs a CTRE SwerveDrivetrain using the specified constants.
102 *
103 * This constructs the underlying hardware devices, so users should not construct
104 * the devices themselves. If they need the devices, they can access them
105 * through getters in the classes.
106 *
107 * \param drivetrainConstants Drivetrain-wide constants for the swerve drive
108 * \param modules Constants for each specific module
109 */
110 template <std::same_as<SwerveModuleConstants>... ModuleConstants>
111 SwerveDrivetrain(SwerveDrivetrainConstants const &drivetrainConstants, ModuleConstants const &... modules) :
112 SwerveDrivetrain{drivetrainConstants, 0_Hz, modules...}
113 {}
114
115 /**
116 * \brief Constructs a CTRE SwerveDrivetrain using the specified constants.
117 *
118 * This constructs the underlying hardware devices, so users should not construct
119 * the devices themselves. If they need the devices, they can access them
120 * through getters in the classes.
121 *
122 * \param drivetrainConstants Drivetrain-wide constants for the swerve drive
123 * \param odometryUpdateFrequency The frequency to run the odometry loop. If
124 * unspecified or set to 0 Hz, this is 250 Hz on
125 * CAN FD, and 100 Hz on CAN 2.0.
126 * \param modules Constants for each specific module
127 */
128 template <std::same_as<SwerveModuleConstants>... ModuleConstants>
130 SwerveDrivetrainConstants const &drivetrainConstants,
131 wpi::units::hertz_t odometryUpdateFrequency,
132 ModuleConstants const &... modules
133 ) :
134 SwerveDrivetrain{drivetrainConstants, odometryUpdateFrequency, std::array{0.1, 0.1, 0.1}, std::array{0.9, 0.9, 0.9}, modules...}
135 {}
136
137 /**
138 * \brief Constructs a CTRE SwerveDrivetrain using the specified constants.
139 *
140 * This constructs the underlying hardware devices, so users should not construct
141 * the devices themselves. If they need the devices, they can access them
142 * through getters in the classes.
143 *
144 * \param drivetrainConstants Drivetrain-wide constants for the swerve drive
145 * \param odometryUpdateFrequency The frequency to run the odometry loop. If
146 * unspecified or set to 0 Hz, this is 250 Hz on
147 * CAN FD, and 100 Hz on CAN 2.0.
148 * \param odometryStandardDeviation The standard deviation for odometry calculation
149 * in the form [x, y, theta]ᵀ, with units in meters
150 * and radians
151 * \param visionStandardDeviation The standard deviation for vision calculation
152 * in the form [x, y, theta]ᵀ, with units in meters
153 * and radians
154 * \param modules Constants for each specific module
155 */
156 template <std::same_as<SwerveModuleConstants>... ModuleConstants>
158 SwerveDrivetrainConstants const &drivetrainConstants,
159 wpi::units::hertz_t odometryUpdateFrequency,
160 std::array<double, 3> const &odometryStandardDeviation,
161 std::array<double, 3> const &visionStandardDeviation,
162 ModuleConstants const &... modules
163 ) :
165 drivetrainConstants, odometryUpdateFrequency,
166 odometryStandardDeviation, visionStandardDeviation,
167 std::span<SwerveModuleConstants const>{std::array{modules...}}
168 },
169 _modules{CreateModuleArray(drivetrainConstants.Network, modules...)},
170 _pigeon2{drivetrainConstants.Pigeon2Id, drivetrainConstants.Network},
171 _simDrive{_drivetrain.GetModuleLocations(), _pigeon2.GetSimState(), modules...}
172 {
173 if (drivetrainConstants.Pigeon2Configs) {
174 ctre::phoenix::StatusCode retval{};
175 for (int i = 0; i < kNumConfigAttempts; ++i) {
176 retval = GetPigeon2().GetConfigurator().Apply(*drivetrainConstants.Pigeon2Configs);
177 if (retval.IsOK()) break;
178 }
179 if (!retval.IsOK()) {
180 printf("Pigeon2 ID %d failed config with error: %s\n", GetPigeon2().GetDeviceID(), retval.GetName());
181 }
182 }
183 /* do not start thread until after applying Pigeon 2 configs */
184 GetOdometryThread().Start();
185 }
186
187 virtual ~SwerveDrivetrain() = default;
188
189private:
190 template <typename... ModuleConstants>
191 std::vector<std::unique_ptr<SwerveModule>> CreateModuleArray(
192 CANBus canbus,
193 ModuleConstants const &... constants
194 ) {
195 std::vector<std::unique_ptr<SwerveModule>> modules;
196 modules.reserve(sizeof...(ModuleConstants));
197
198 [&]<size_t... Idxs>(std::index_sequence<Idxs...>) {
199 (modules.emplace_back(std::make_unique<SwerveModule>(constants, canbus, _drivetrain.GetModule(Idxs))), ...);
200 }(std::index_sequence_for<ModuleConstants...>{});
201
202 return modules;
203 }
204
205public:
206 /**
207 * \brief Updates all the simulation state variables for this
208 * drivetrain class. User provides the update variables for the simulation.
209 *
210 * \param dt time since last update call
211 * \param supplyVoltage voltage as seen at the motor controllers
212 */
213 virtual void UpdateSimState(wpi::units::second_t dt, wpi::units::volt_t supplyVoltage)
214 {
215 _simDrive.Update(dt, supplyVoltage, _modules);
216 }
217
218 /**
219 * \brief Optimizes the bus utilization of all devices in the swerve drivetrain by
220 * reducing the update frequencies of their status signals. All signals necessary
221 * for drivetrain functionality will remain enabled.
222 *
223 * This is equivalent to calling hardware#ParentDevice#OptimizeBusUtilizationForAll
224 * with all devices in the drivetrain.
225 *
226 * This will wait up to 0.100 seconds (100ms) for each status frame.
227 *
228 * \returns Status code of the first failed optimize call, or OK if all succeeded
229 */
231 {
232 std::vector<hardware::traits::CommonDevice *> devices;
233 devices.reserve(_modules.size() * 3 + 1);
234 devices.push_back(&GetPigeon2());
235 for (auto &module : _modules) {
236 devices.push_back(&module->GetDriveMotor());
237 devices.push_back(&module->GetSteerMotor());
238 devices.push_back(&module->GetEncoder());
239 }
241 }
242
243 /**
244 * \brief Optimizes the bus utilization of all devices in the swerve drivetrain by
245 * reducing the update frequencies of their status signals. All signals necessary
246 * for drivetrain functionality will remain enabled.
247 *
248 * This is equivalent to calling hardware#ParentDevice#OptimizeBusUtilizationForAll
249 * with all devices in the drivetrain.
250 *
251 * This will wait up to 0.100 seconds (100ms) for each status frame.
252 *
253 * \param optimizedFreqHz The update frequency to apply to the optimized status signals. A frequency
254 * of 0 Hz will turn off the signals. Otherwise, the minimum supported signal
255 * frequency is 4 Hz.
256 * \returns Status code of the first failed optimize call, or OK if all succeeded
257 */
258 ctre::phoenix::StatusCode OptimizeBusUtilization(wpi::units::hertz_t optimizedFreqHz)
259 {
260 std::vector<hardware::traits::CommonDevice *> devices;
261 devices.reserve(_modules.size() * 3 + 1);
262 devices.push_back(&GetPigeon2());
263 for (auto &module : _modules) {
264 devices.push_back(&module->GetDriveMotor());
265 devices.push_back(&module->GetSteerMotor());
266 devices.push_back(&module->GetEncoder());
267 }
268 return hardware::ParentDevice::OptimizeBusUtilizationForAll(optimizedFreqHz, devices);
269 }
270
271 /**
272 * \brief Gets whether the drivetrain is on a CAN FD bus.
273 *
274 * \returns true if on CAN FD
275 */
276 bool IsOnCANFD() const
277 {
278 return _drivetrain.IsOnCANFD();
279 }
280
281 /**
282 * \brief Gets the target odometry update frequency.
283 *
284 * \returns Target odometry update frequency
285 */
286 wpi::units::hertz_t GetOdometryFrequency() const
287 {
288 return _drivetrain.GetOdometryFrequency();
289 }
290
291 /**
292 * \brief Gets a reference to the odometry thread.
293 *
294 * \returns Odometry thread
295 */
297 {
298 return _drivetrain.GetOdometryThread();
299 }
300
301 /**
302 * \brief Check if the odometry is currently valid.
303 *
304 * \returns True if odometry is valid
305 */
306 virtual bool IsOdometryValid() const
307 {
308 return _drivetrain.IsOdometryValid();
309 }
310
311 /**
312 * \brief Gets a reference to the kinematics used for the drivetrain.
313 *
314 * \returns Swerve kinematics
315 */
317 {
318 return _drivetrain.GetKinematics();
319 }
320
321 /**
322 * \brief Applies the specified control request to this swerve drivetrain.
323 *
324 * This captures the swerve request by reference, so it must live for
325 * at least as long as the drivetrain. This can be done by storing the
326 * request as a member variable of your drivetrain subsystem or robot.
327 *
328 * \param request Request to apply
329 */
330 template <std::derived_from<requests::SwerveRequest> Request>
331 requires (!std::is_const_v<Request>)
332 void SetControl(Request &request)
333 {
334 _drivetrain.SetControl(
335 [&request](auto const &params, auto modules) mutable {
336 return request.Apply(params, modules);
337 }
338 );
339 }
340
341 /**
342 * \brief Applies the specified control request to this swerve drivetrain.
343 *
344 * \param request Request to apply
345 */
346 template <std::derived_from<requests::SwerveRequest> Request>
347 requires (!std::is_const_v<Request>)
348 void SetControl(Request &&request)
349 {
350 _drivetrain.SetControl(
351 [request=std::move(request)](auto const &params, auto modules) mutable {
352 return request.Apply(params, modules);
353 }
354 );
355 }
356
357 /**
358 * \brief Gets the current state of the swerve drivetrain.
359 * This includes information such as the pose estimate,
360 * module states, and chassis velocity.
361 *
362 * \returns Current state of the drivetrain
363 */
365 {
366 return _drivetrain.GetState();
367 }
368
369 /**
370 * \brief Register the specified lambda to be executed whenever the SwerveDriveState
371 * is updated in the odometry thread.
372 *
373 * It is imperative that this function is cheap, as it will be executed synchronously
374 * with the odometry call; if this takes a long time, it may negatively impact the
375 * odometry of this stack.
376 *
377 * This can also be used for logging data if the function performs logging instead of telemetry.
378 * Additionally, the SwerveDriveState object can be cloned and stored for later processing.
379 *
380 * \param telemetryFunction Function to call for telemetry or logging
381 */
382 virtual void RegisterTelemetry(std::function<void(SwerveDriveState const &)> telemetryFunction)
383 {
384 _drivetrain.RegisterTelemetry(std::move(telemetryFunction));
385 }
386
387 /**
388 * \brief Configures the neutral mode to use for all modules' drive motors.
389 *
390 * This will wait up to 0.100 seconds (100ms) by default.
391 *
392 * \param neutralMode The drive motor neutral mode
393 * \returns Status code of the first failed config call, or OK if all succeeded
394 */
396 {
397 return _drivetrain.ConfigNeutralMode(neutralMode);
398 }
399
400 /**
401 * \brief Configures the neutral mode to use for all modules' drive motors.
402 *
403 * \param neutralMode The drive motor neutral mode
404 * \param timeoutSeconds Maximum amount of time to wait when performing each configuration
405 * \returns Status code of the first failed config call, or OK if all succeeded
406 */
407 virtual ctre::phoenix::StatusCode ConfigNeutralMode(signals::NeutralModeValue neutralMode, wpi::units::second_t timeoutSeconds)
408 {
409 return _drivetrain.ConfigNeutralMode(neutralMode, timeoutSeconds);
410 }
411
412 /**
413 * \brief Zeroes this swerve drive's odometry entirely. To quickly reset
414 * the pose of the robot, use #ResetPose instead.
415 *
416 * This will zero the entire odometry, placing the robot at (0 m, 0 m, 0 rad).
417 *
418 * This will wait up to 0.100 seconds (100ms) for each drive motor.
419 */
420 virtual void TareEverything()
421 {
422 _drivetrain.TareEverything();
423 }
424
425 /**
426 * \brief Resets the rotation of the robot pose to the given value
427 * from the requests#ForwardPerspectiveValue#OperatorPerspective
428 * perspective. This makes the current orientation of the robot minus
429 * `rotation` the X forward for field-centric maneuvers.
430 *
431 * This is equivalent to calling ResetRotation with `rotation +
432 * GetOperatorForwardDirection()`.
433 *
434 * \param rotation Rotation to make the current rotation
435 */
436 virtual void SeedFieldCentric(Rotation2d const &rotation = Rotation2d{})
437 {
438 _drivetrain.SeedFieldCentric(rotation);
439 }
440
441 /**
442 * \brief Resets the pose of the robot. The pose should be from the
443 * requests#ForwardPerspectiveValue#BlueAlliance perspective.
444 *
445 * \param pose Pose to make the current pose
446 */
447 virtual void ResetPose(Pose2d const &pose)
448 {
449 _drivetrain.ResetPose(pose);
450 }
451
452 /**
453 * \brief Resets the translation of the robot pose without affecting rotation.
454 * The translation should be from the requests#ForwardPerspectiveValue#BlueAlliance
455 * perspective.
456 *
457 * \param translation Translation to make the current translation
458 */
459 virtual void ResetTranslation(Translation2d const &translation)
460 {
461 _drivetrain.ResetTranslation(translation);
462 }
463
464 /**
465 * \brief Resets the rotation of the robot pose without affecting translation.
466 * The rotation should be from the requests#ForwardPerspectiveValue#BlueAlliance
467 * perspective.
468 *
469 * \param rotation Rotation to make the current rotation
470 */
471 virtual void ResetRotation(Rotation2d const &rotation)
472 {
473 _drivetrain.ResetRotation(rotation);
474 }
475
476 /**
477 * \brief Takes the requests#ForwardPerspectiveValue#BlueAlliance perpective
478 * direction and treats it as the forward direction for
479 * requests#ForwardPerspectiveValue#OperatorPerspective.
480 * This corresponds to the direction the operator is facing, not the robot.
481 *
482 * - If the operator is in the Blue Alliance Station, this should be 0 degrees.
483 *
484 * - If the operator is in the Red Alliance Station, this should be 180 degrees.
485 *
486 * This does not change the robot pose, which is in the
487 * requests#ForwardPerspectiveValue#BlueAlliance perspective.
488 * As a result, the robot pose may need to be reset using ResetPose.
489 *
490 * \param fieldDirection Heading indicating which direction is forward from
491 * the requests#ForwardPerspectiveValue#BlueAlliance perspective
492 */
493 virtual void SetOperatorForwardDirection(Rotation2d const &fieldDirection)
494 {
495 _drivetrain.SetOperatorForwardDirection(fieldDirection);
496 }
497
498 /**
499 * \brief Returns the requests#ForwardPerspectiveValue#BlueAlliance perpective
500 * direction that is treated as the forward direction for
501 * requests#ForwardPerspectiveValue#OperatorPerspective.
502 *
503 * If the operator is in the Blue Alliance Station, this should be 0 degrees.
504 * If the operator is in the Red Alliance Station, this should be 180 degrees.
505 *
506 * \returns Heading indicating which direction is forward from
507 * the requests#ForwardPerspectiveValue#BlueAlliance perspective
508 */
510 {
511 return _drivetrain.GetOperatorForwardDirection();
512 }
513
514 /**
515 * \brief Adds a vision measurement to the Kalman Filter. This will correct the
516 * odometry pose estimate while still accounting for measurement noise.
517 *
518 * This method can be called as infrequently as you want
519 *
520 * To promote stability of the pose estimate and make it robust to bad vision
521 * data, we recommend only adding vision measurements that are already within
522 * one meter or so of the current pose estimate.
523 *
524 * \param visionRobotPose The pose of the robot as measured by the
525 * vision camera.
526 * \param timestamp The timestamp of the vision measurement in
527 * seconds. Note that you must use a timestamp with an
528 * epoch since system startup (i.e., the epoch of this
529 * timestamp is the same epoch as utils#GetCurrentTime).
530 * This means that you should use utils#GetCurrentTime
531 * as your time source in this case.
532 */
533 virtual void AddVisionMeasurement(Pose2d visionRobotPose, wpi::units::second_t timestamp)
534 {
535 _drivetrain.AddVisionMeasurement(std::move(visionRobotPose), timestamp);
536 }
537
538 /**
539 * \brief Adds a vision measurement to the Kalman Filter. This will correct the
540 * odometry pose estimate while still accounting for measurement noise.
541 *
542 * This method can be called as infrequently as you want.
543 *
544 * To promote stability of the pose estimate and make it robust to bad vision
545 * data, we recommend only adding vision measurements that are already within
546 * one meter or so of the current pose estimate.
547 *
548 * Note that the vision measurement standard deviations passed into this method
549 * will continue to apply to future measurements until a subsequent call to
550 * #SetVisionMeasurementStdDevs or this method.
551 *
552 * \param visionRobotPose The pose of the robot as measured by the
553 * vision camera.
554 * \param timestamp The timestamp of the vision measurement in
555 * seconds. Note that you must use a timestamp with an
556 * epoch since system startup (i.e., the epoch of this
557 * timestamp is the same epoch as utils#GetCurrentTime).
558 * This means that you should use utils#GetCurrentTime
559 * as your time source in this case.
560 * \param visionMeasurementStdDevs Standard deviations of the vision pose
561 * measurement (x position in meters, y position
562 * in meters, and heading in radians). Increase
563 * these numbers to trust the vision pose
564 * measurement less.
565 */
567 Pose2d visionRobotPose,
568 wpi::units::second_t timestamp,
569 std::array<double, 3> visionMeasurementStdDevs)
570 {
571 _drivetrain.AddVisionMeasurement(std::move(visionRobotPose), timestamp, visionMeasurementStdDevs);
572 }
573
574 /**
575 * \brief Sets the pose estimator's trust of global measurements. This might be used to
576 * change trust in vision measurements after the autonomous period, or to change
577 * trust as distance to a vision target increases.
578 *
579 * \param visionMeasurementStdDevs Standard deviations of the vision
580 * measurements. Increase these
581 * numbers to trust global measurements from
582 * vision less. This matrix is in the form [x,
583 * y, theta]ᵀ, with units in meters and radians.
584 */
585 virtual void SetVisionMeasurementStdDevs(std::array<double, 3> visionMeasurementStdDevs)
586 {
587 _drivetrain.SetVisionMeasurementStdDevs(visionMeasurementStdDevs);
588 }
589
590 /**
591 * \brief Sets the pose estimator's trust in robot odometry. This might be used
592 * to change trust in odometry after an impact with the wall or traversing a bump.
593 *
594 * \param stateStdDevs Standard deviations of the pose estimate. Increase these
595 * numbers to trust your state estimate less. This matrix is
596 * in the form [x, y, theta]ᵀ, with units in meters and radians.
597 */
598 virtual void SetStateStdDevs(std::array<double, 3> const &stateStdDevs)
599 {
600 _drivetrain.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 you must use a timestamp
607 * with an epoch since system startup (i.e., the epoch of
608 * this timestamp is the same epoch as utils#GetCurrentTime).
609 * This means that you should use utils#GetCurrentTime
610 * as your time source in this case.
611 * \returns The pose at the given timestamp (or std::nullopt if the buffer is
612 * empty).
613 */
614 virtual std::optional<Pose2d> SamplePoseAt(wpi::units::second_t timestamp) const
615 {
616 return _drivetrain.SamplePoseAt(timestamp);
617 }
618
619 /**
620 * \brief Get a reference to the module at the specified index.
621 * The index corresponds to the module described in the constructor.
622 *
623 * \param index Which module to get
624 * \returns Reference to SwerveModule
625 */
626 SwerveModule &GetModule(size_t index)
627 {
628 return *_modules.at(index);
629 }
630 /**
631 * \brief Get a reference to the module at the specified index.
632 * The index corresponds to the module described in the constructor.
633 *
634 * \param index Which module to get
635 * \returns Reference to SwerveModule
636 */
637 SwerveModule const &GetModule(size_t index) const
638 {
639 return *_modules.at(index);
640 }
641 /**
642 * \brief Get a reference to the full array of modules.
643 * The indexes correspond to the module described in the constructor.
644 *
645 * \returns Reference to the SwerveModule array
646 */
647 std::span<std::unique_ptr<SwerveModule> const> GetModules() const
648 {
649 return _modules;
650 }
651
652 /**
653 * \brief Gets the locations of the swerve modules.
654 *
655 * \returns Reference to the array of swerve module locations
656 */
657 std::vector<Translation2d> const &GetModuleLocations() const { return _drivetrain.GetModuleLocations(); }
658
659 /**
660 * \brief Gets the current orientation of the robot as a wpi#math#Rotation3d from
661 * the Pigeon 2 quaternion values.
662 *
663 * \returns The robot orientation as a wpi#math#Rotation3d
664 */
665 virtual wpi::math::Rotation3d GetRotation3d() const
666 {
667 return _pigeon2.GetRotation3d();
668 }
669
670 /**
671 * \brief Gets this drivetrain's Pigeon 2 reference.
672 *
673 * This should be used only to access signals and change configurations that the
674 * swerve drivetrain does not configure itself.
675 *
676 * \returns This drivetrain's Pigeon 2 reference
677 */
679 {
680 return _pigeon2;
681 }
682 /**
683 * \brief Gets this drivetrain's Pigeon 2 reference.
684 *
685 * This should be used only to access signals and change configurations that the
686 * swerve drivetrain does not configure itself.
687 *
688 * \returns This drivetrain's Pigeon 2 reference
689 */
691 {
692 return _pigeon2;
693 }
694};
695
696}
697}
698}
699
700#include <wpi/util/struct/Struct.hpp>
701
702/** \brief WPILib Struct implementation for ctre#phoenix6#swerve#impl#SwerveDrivetrainImpl#SwerveDriveState. */
703template <>
704struct wpi::util::Struct<ctre::phoenix6::swerve::impl::SwerveDrivetrainImpl::SwerveDriveState, size_t> final {
705private:
707
708public:
709 static std::string_view GetTypeName(size_t numModules);
710 static constexpr size_t GetSize(size_t numModules)
711 {
712 return wpi::util::GetStructSize<ctre::phoenix6::swerve::Pose2d>() +
713 wpi::util::GetStructSize<ctre::phoenix6::swerve::ChassisVelocities>() +
714 numModules * (
715 wpi::util::GetStructSize<ctre::phoenix6::swerve::SwerveModulePosition>() +
716 2 * wpi::util::GetStructSize<ctre::phoenix6::swerve::SwerveModuleVelocity>()
717 ) +
718 wpi::util::GetStructSize<ctre::phoenix6::swerve::Rotation2d>() +
719 2 * wpi::util::GetStructSize<double>() +
720 2 * wpi::util::GetStructSize<int32_t>();
721 }
722 static std::string_view GetSchema(size_t numModules);
723
724 static SwerveDriveState Unpack(std::span<uint8_t const> data, size_t numModules);
725 static void Pack(std::span<uint8_t> data, SwerveDriveState const &value, size_t numModules);
726
727 static void ForEachNested(std::invocable<std::string_view, std::string_view> auto fn, size_t numModules)
728 {
729 wpi::util::ForEachStructSchema<ctre::phoenix6::swerve::Pose2d>(fn);
730 wpi::util::ForEachStructSchema<ctre::phoenix6::swerve::ChassisVelocities>(fn);
731 wpi::util::ForEachStructSchema<ctre::phoenix6::swerve::SwerveModulePosition>(fn);
732 wpi::util::ForEachStructSchema<ctre::phoenix6::swerve::SwerveModuleVelocity>(fn);
733 wpi::util::ForEachStructSchema<ctre::phoenix6::swerve::Rotation2d>(fn);
734 }
735};
736
737static_assert(wpi::util::StructSerializable<ctre::phoenix6::swerve::impl::SwerveDrivetrainImpl::SwerveDriveState, size_t>);
738static_assert(wpi::util::HasNestedStruct<ctre::phoenix6::swerve::impl::SwerveDrivetrainImpl::SwerveDriveState, size_t>);
Class for getting information about an available CAN bus.
Definition CANBus.hpp:142
static ctre::phoenix::StatusCode OptimizeBusUtilizationForAll(Devices &... devices)
Optimizes the bus utilization of the provided devices by reducing the update frequencies of their sta...
Definition ParentDevice.hpp:315
Class description for the Pigeon 2 IMU sensor that measures orientation.
Definition Pigeon2.hpp:28
Simplified swerve drive simulation class.
Definition SimSwerveDrivetrain.hpp:42
virtual ctre::phoenix::StatusCode ConfigNeutralMode(signals::NeutralModeValue neutralMode, wpi::units::second_t timeoutSeconds)
Configures the neutral mode to use for all modules' drive motors.
Definition SwerveDrivetrain.hpp:407
OdometryThread & GetOdometryThread()
Gets a reference to the odometry thread.
Definition SwerveDrivetrain.hpp:296
virtual void UpdateSimState(wpi::units::second_t dt, wpi::units::volt_t supplyVoltage)
Updates all the simulation state variables for this drivetrain class.
Definition SwerveDrivetrain.hpp:213
virtual void ResetTranslation(Translation2d const &translation)
Resets the translation of the robot pose without affecting rotation.
Definition SwerveDrivetrain.hpp:459
virtual void TareEverything()
Zeroes this swerve drive's odometry entirely.
Definition SwerveDrivetrain.hpp:420
ctre::phoenix::StatusCode OptimizeBusUtilization()
Optimizes the bus utilization of all devices in the swerve drivetrain by reducing the update frequenc...
Definition SwerveDrivetrain.hpp:230
impl::SwerveDrivetrainImpl::OdometryThread OdometryThread
Performs swerve module updates in a separate thread to minimize latency.
Definition SwerveDrivetrain.hpp:59
swerve::SwerveModule< DriveMotorT, SteerMotorT, EncoderT > SwerveModule
Swerve Module class that encapsulates a swerve module powered by CTR Electronics devices.
Definition SwerveDrivetrain.hpp:79
virtual std::optional< Pose2d > SamplePoseAt(wpi::units::second_t timestamp) const
Return the pose at a given timestamp, if the buffer is not empty.
Definition SwerveDrivetrain.hpp:614
virtual void SetStateStdDevs(std::array< double, 3 > const &stateStdDevs)
Sets the pose estimator's trust in robot odometry.
Definition SwerveDrivetrain.hpp:598
SwerveModule const & GetModule(size_t index) const
Get a reference to the module at the specified index.
Definition SwerveDrivetrain.hpp:637
ctre::phoenix::StatusCode OptimizeBusUtilization(wpi::units::hertz_t optimizedFreqHz)
Optimizes the bus utilization of all devices in the swerve drivetrain by reducing the update frequenc...
Definition SwerveDrivetrain.hpp:258
SwerveModule & GetModule(size_t index)
Get a reference to the module at the specified index.
Definition SwerveDrivetrain.hpp:626
std::span< std::unique_ptr< SwerveModule > const > GetModules() const
Get a reference to the full array of modules.
Definition SwerveDrivetrain.hpp:647
void SetControl(Request &request)
Applies the specified control request to this swerve drivetrain.
Definition SwerveDrivetrain.hpp:332
virtual void AddVisionMeasurement(Pose2d visionRobotPose, wpi::units::second_t timestamp, std::array< double, 3 > visionMeasurementStdDevs)
Adds a vision measurement to the Kalman Filter.
Definition SwerveDrivetrain.hpp:566
void SetControl(Request &&request)
Applies the specified control request to this swerve drivetrain.
Definition SwerveDrivetrain.hpp:348
virtual bool IsOdometryValid() const
Check if the odometry is currently valid.
Definition SwerveDrivetrain.hpp:306
SwerveDrivetrain(SwerveDrivetrainConstants const &drivetrainConstants, wpi::units::hertz_t odometryUpdateFrequency, ModuleConstants const &... modules)
Constructs a CTRE SwerveDrivetrain using the specified constants.
Definition SwerveDrivetrain.hpp:129
virtual void AddVisionMeasurement(Pose2d visionRobotPose, wpi::units::second_t timestamp)
Adds a vision measurement to the Kalman Filter.
Definition SwerveDrivetrain.hpp:533
virtual wpi::math::Rotation3d GetRotation3d() const
Gets the current orientation of the robot as a wpi::math::Rotation3d from the Pigeon 2 quaternion val...
Definition SwerveDrivetrain.hpp:665
impl::SwerveDriveKinematics const & GetKinematics() const
Gets a reference to the kinematics used for the drivetrain.
Definition SwerveDrivetrain.hpp:316
virtual ctre::phoenix::StatusCode ConfigNeutralMode(signals::NeutralModeValue neutralMode)
Configures the neutral mode to use for all modules' drive motors.
Definition SwerveDrivetrain.hpp:395
SwerveDriveState GetState() const
Gets the current state of the swerve drivetrain.
Definition SwerveDrivetrain.hpp:364
virtual void SeedFieldCentric(Rotation2d const &rotation=Rotation2d{})
Resets the rotation of the robot pose to the given value from the requests::ForwardPerspectiveValue::...
Definition SwerveDrivetrain.hpp:436
virtual void SetOperatorForwardDirection(Rotation2d const &fieldDirection)
Takes the requests::ForwardPerspectiveValue::BlueAlliance perpective direction and treats it as the f...
Definition SwerveDrivetrain.hpp:493
virtual void SetVisionMeasurementStdDevs(std::array< double, 3 > visionMeasurementStdDevs)
Sets the pose estimator's trust of global measurements.
Definition SwerveDrivetrain.hpp:585
virtual void ResetPose(Pose2d const &pose)
Resets the pose of the robot.
Definition SwerveDrivetrain.hpp:447
bool IsOnCANFD() const
Gets whether the drivetrain is on a CAN FD bus.
Definition SwerveDrivetrain.hpp:276
SwerveDrivetrain(SwerveDrivetrainConstants const &drivetrainConstants, ModuleConstants const &... modules)
Constructs a CTRE SwerveDrivetrain using the specified constants.
Definition SwerveDrivetrain.hpp:111
impl::SwerveDrivetrainImpl::SwerveDriveState SwerveDriveState
Plain-Old-Data class holding the state of the swerve drivetrain.
Definition SwerveDrivetrain.hpp:66
SwerveDrivetrain(SwerveDrivetrainConstants const &drivetrainConstants, wpi::units::hertz_t odometryUpdateFrequency, std::array< double, 3 > const &odometryStandardDeviation, std::array< double, 3 > const &visionStandardDeviation, ModuleConstants const &... modules)
Constructs a CTRE SwerveDrivetrain using the specified constants.
Definition SwerveDrivetrain.hpp:157
SwerveModule::Constants SwerveModuleConstants
All constants for a swerve module.
Definition SwerveDrivetrain.hpp:84
virtual void ResetRotation(Rotation2d const &rotation)
Resets the rotation of the robot pose without affecting translation.
Definition SwerveDrivetrain.hpp:471
hardware::Pigeon2 & GetPigeon2()
Gets this drivetrain's Pigeon 2 reference.
Definition SwerveDrivetrain.hpp:678
hardware::Pigeon2 const & GetPigeon2() const
Gets this drivetrain's Pigeon 2 reference.
Definition SwerveDrivetrain.hpp:690
wpi::units::hertz_t GetOdometryFrequency() const
Gets the target odometry update frequency.
Definition SwerveDrivetrain.hpp:286
static constexpr int kNumConfigAttempts
Number of times to attempt config applies.
Definition SwerveDrivetrain.hpp:88
virtual void RegisterTelemetry(std::function< void(SwerveDriveState const &)> telemetryFunction)
Register the specified lambda to be executed whenever the SwerveDriveState is updated in the odometry...
Definition SwerveDrivetrain.hpp:382
impl::SwerveDrivetrainImpl _drivetrain
The underlying drivetrain instance.
Definition SwerveDrivetrain.hpp:91
std::vector< Translation2d > const & GetModuleLocations() const
Gets the locations of the swerve modules.
Definition SwerveDrivetrain.hpp:657
Rotation2d GetOperatorForwardDirection() const
Returns the requests::ForwardPerspectiveValue::BlueAlliance perpective direction that is treated as t...
Definition SwerveDrivetrain.hpp:509
Swerve Module class that encapsulates a swerve module powered by CTR Electronics devices.
Definition SwerveModule.hpp:56
SwerveModuleConstants< typename DriveMotorT::Configuration, typename SteerMotorT::Configuration, typename EncoderT::Configuration > Constants
All constants for a swerve module.
Definition SwerveModule.hpp:66
Class that converts a chassis velocity (dx, dy, and dtheta components) into individual module states ...
Definition SwerveDriveKinematics.hpp:41
Performs swerve module updates in a separate thread to minimize latency.
Definition SwerveDrivetrainImpl.hpp:33
Swerve Drive class utilizing CTR Electronics Phoenix 6 API.
Definition SwerveDrivetrainImpl.hpp:30
Status codes reported by APIs, including OK, warnings, and errors.
Definition StatusCodes.h:28
constexpr const char * GetName() const
Gets the name of this StatusCode.
Definition StatusCodes.h:867
constexpr bool IsOK() const
Definition StatusCodes.h:860
Definition SwerveModule.hpp:28
Definition ExternalFeedbackConfigs.hpp:16
Definition motor_constants.h:14
The state of the motor controller bridge when output is neutral or disabled.
Definition SpnEnums.hpp:1499
Common constants for a swerve drivetrain.
Definition SwerveDrivetrainConstants.hpp:19
Plain-Old-Data class holding the state of the swerve drivetrain.
Definition SwerveDrivetrainImpl.hpp:118
static SwerveDriveState Unpack(std::span< uint8_t const > data, size_t numModules)
static void Pack(std::span< uint8_t > data, SwerveDriveState const &value, size_t numModules)
static constexpr size_t GetSize(size_t numModules)
Definition SwerveDrivetrain.hpp:710
static void ForEachNested(std::invocable< std::string_view, std::string_view > auto fn, size_t numModules)
Definition SwerveDrivetrain.hpp:727