CTRE Phoenix 6 C++ 26.0.0-beta-1
Loading...
Searching...
No Matches
SwerveDriveKinematics.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
10#include <memory>
11#include <span>
12#include <vector>
13
14namespace ctre {
15namespace phoenix6 {
16namespace swerve {
17namespace impl {
18
19/**
20 * \brief Class that converts a chassis velocity (dx, dy, and dtheta components)
21 * into individual module states (speed and angle).
22 *
23 * The inverse kinematics (converting from a desired chassis velocity to
24 * individual module states) uses the relative locations of the modules with
25 * respect to the center of rotation. The center of rotation for inverse
26 * kinematics is also variable. This means that you can set your set your center
27 * of rotation in a corner of the robot to perform special evasion maneuvers.
28 *
29 * Forward kinematics (converting an array of module states into the overall
30 * chassis motion) is performs the exact opposite of what inverse kinematics
31 * does. Since this is an overdetermined system (more equations than variables),
32 * we use a least-squares approximation.
33 *
34 * The inverse kinematics: [moduleStates] = [moduleLocations] * [chassisSpeeds]
35 * We take the Moore-Penrose pseudoinverse of [moduleLocations] and then
36 * multiply by [moduleStates] to get our chassis speeds.
37 *
38 * Forward kinematics is also used for odometry -- determining the position of
39 * the robot on the field using encoders and a gyro.
40 */
42 size_t m_numModules;
43 std::vector<Translation2d> m_moduleLocations;
44
45 struct KinematicsMatrices;
46 std::unique_ptr<KinematicsMatrices> m_matrices;
47
48 std::vector<Rotation2d> m_lastModuleHeading;
49 Translation2d m_lastCOR{};
50
51public:
52 using WheelSpeeds = std::vector<SwerveModuleState>;
53 using WheelPositions = std::vector<SwerveModulePosition>;
54
55 /**
56 * \brief Constructs a swerve drive kinematics object. This takes in a variable
57 * number of module locations as Translation2ds. The order in which you pass
58 * in the module locations is the same order that you will receive the module
59 * states when performing inverse kinematics. It is also expected that you
60 * pass in the module states in the same order when calling the forward
61 * kinematics methods.
62 *
63 * \param moduleLocations The locations of the modules relative to the
64 * physical center of the robot.
65 */
66 SwerveDriveKinematics(std::vector<Translation2d> moduleLocations);
67
71
74
75 /**
76 * \brief Reset the internal swerve module headings.
77 *
78 * \param moduleHeadings The swerve module headings. The order of the module
79 * headings should be same as passed into the constructor of this class.
80 */
81 void ResetHeadings(std::span<Rotation2d const> moduleHeadings)
82 {
83 for (size_t i = 0; i < m_numModules && i < moduleHeadings.size(); ++i) {
84 m_lastModuleHeading[i] = moduleHeadings[i];
85 }
86 }
87
88 /**
89 * \brief Performs inverse kinematics to return the module states from a desired
90 * chassis velocity. This method is often used to convert joystick values into
91 * module speeds and angles.
92 *
93 * This function also supports variable centers of rotation. During normal
94 * operations, the center of rotation is usually the same as the physical
95 * center of the robot; therefore, the argument is defaulted to that use case.
96 * However, if you wish to change the center of rotation for evasive
97 * maneuvers, vision alignment, or for any other use case, you can do so.
98 *
99 * In the case that the desired chassis speeds are zero (i.e. the robot will
100 * be stationary), the previously calculated module angle will be maintained.
101 *
102 * \param chassisSpeeds The desired chassis speed.
103 * \param centerOfRotation The center of rotation. For example, if you set the
104 * center of rotation at one corner of the robot and provide a chassis speed
105 * that only has a dtheta component, the robot will rotate around that corner.
106 *
107 * \returns A vector containing the module states. Use caution because these
108 * module states are not normalized. Sometimes, a user input may cause one of
109 * the module speeds to go above the attainable max velocity. Use the
110 * DesaturateWheelSpeeds(WheelSpeeds*, units::meters_per_second_t) function to
111 * rectify this issue.
112 */
113 WheelSpeeds ToSwerveModuleStates(ChassisSpeeds const &chassisSpeeds, Translation2d const &centerOfRotation = Translation2d{});
114
115 /**
116 * \brief Performs forward kinematics to return the resulting chassis state from the
117 * given module states. This method is often used for odometry -- determining
118 * the robot's position on the field using data from the real-world speed and
119 * angle of each module on the robot.
120 *
121 * \param moduleStates The state of the modules as a std::vector of type
122 * SwerveModuleState as measured from respective encoders and gyros. The
123 * order of the swerve module states should be same as passed into the
124 * constructor of this class.
125 *
126 * \returns The resulting chassis speed.
127 */
128 ChassisSpeeds ToChassisSpeeds(WheelSpeeds const &moduleStates) const;
129
130 /**
131 * \brief Performs forward kinematics to return the resulting Twist2d from the
132 * given module position deltas. This method is often used for odometry --
133 * determining the robot's position on the field using data from the
134 * real-world position delta and angle of each module on the robot.
135 *
136 * \param moduleDeltas The latest change in position of the modules (as a
137 * SwerveModulePosition type) as measured from respective encoders and gyros.
138 * The order of the swerve module states should be same as passed into the
139 * constructor of this class.
140 *
141 * \returns The resulting Twist2d.
142 */
143 Twist2d ToTwist2d(WheelPositions const &moduleDeltas) const;
144
145 /**
146 * \brief Performs forward kinematics to return the resulting Twist2d from the given
147 * change in wheel positions. This method is often used for odometry --
148 * determining the robot's position on the field using changes in the distance
149 * driven by each wheel on the robot.
150 *
151 * \param start The starting distances driven by the wheels.
152 * \param end The ending distances driven by the wheels.
153 *
154 * \returns The resulting Twist2d in the robot's movement.
155 */
156 Twist2d ToTwist2d(WheelPositions const &start, WheelPositions const &end) const
157 {
158 WheelPositions result(m_numModules);
159 for (size_t i = 0; i < m_numModules && i < std::min(start.size(), end.size()); ++i) {
160 result[i] = {end[i].distance - start[i].distance, end[i].angle};
161 }
162 return ToTwist2d(result);
163 }
164
165 /**
166 * \brief Performs interpolation between two values.
167 *
168 * \param start The value to start at.
169 * \param end The value to end at.
170 * \param t How far between the two values to interpolate. This should be
171 * bounded to [0, 1].
172 * \returns The interpolated value.
173 */
174 WheelPositions Interpolate(WheelPositions const &start, WheelPositions const &end, double t) const
175 {
176 WheelPositions result(m_numModules);
177 for (size_t i = 0; i < m_numModules && i < std::min(start.size(), end.size()); ++i) {
178 result[i] = start[i].Interpolate(end[i], t);
179 }
180 return result;
181 }
182
183 /**
184 * \brief Renormalizes the wheel speeds if any individual speed is above the
185 * specified maximum.
186 *
187 * Sometimes, after inverse kinematics, the requested speed
188 * from one or more modules may be above the max attainable speed for the
189 * driving motor on that module. To fix this issue, one can reduce all the
190 * wheel speeds to make sure that all requested module speeds are at-or-below
191 * the absolute threshold, while maintaining the ratio of speeds between
192 * modules.
193 *
194 * \param moduleStates Reference to vector of module states. The vector will be
195 * mutated with the normalized speeds!
196 * \param attainableMaxSpeed The absolute max speed that a module can reach.
197 */
198 static void DesaturateWheelSpeeds(WheelSpeeds *moduleStates, units::meters_per_second_t attainableMaxSpeed);
199};
200
201}
202}
203}
204}
Class that converts a chassis velocity (dx, dy, and dtheta components) into individual module states ...
Definition SwerveDriveKinematics.hpp:41
SwerveDriveKinematics(std::vector< Translation2d > moduleLocations)
Constructs a swerve drive kinematics object.
Twist2d ToTwist2d(WheelPositions const &start, WheelPositions const &end) const
Performs forward kinematics to return the resulting Twist2d from the given change in wheel positions.
Definition SwerveDriveKinematics.hpp:156
std::vector< SwerveModulePosition > WheelPositions
Definition SwerveDriveKinematics.hpp:53
SwerveDriveKinematics & operator=(SwerveDriveKinematics const &)
static void DesaturateWheelSpeeds(WheelSpeeds *moduleStates, units::meters_per_second_t attainableMaxSpeed)
Renormalizes the wheel speeds if any individual speed is above the specified maximum.
ChassisSpeeds ToChassisSpeeds(WheelSpeeds const &moduleStates) const
Performs forward kinematics to return the resulting chassis state from the given module states.
WheelPositions Interpolate(WheelPositions const &start, WheelPositions const &end, double t) const
Performs interpolation between two values.
Definition SwerveDriveKinematics.hpp:174
WheelSpeeds ToSwerveModuleStates(ChassisSpeeds const &chassisSpeeds, Translation2d const &centerOfRotation=Translation2d{})
Performs inverse kinematics to return the module states from a desired chassis velocity.
void ResetHeadings(std::span< Rotation2d const > moduleHeadings)
Reset the internal swerve module headings.
Definition SwerveDriveKinematics.hpp:81
SwerveDriveKinematics(SwerveDriveKinematics const &)
SwerveDriveKinematics & operator=(SwerveDriveKinematics &&)
Twist2d ToTwist2d(WheelPositions const &moduleDeltas) const
Performs forward kinematics to return the resulting Twist2d from the given module position deltas.
std::vector< SwerveModuleState > WheelSpeeds
Definition SwerveDriveKinematics.hpp:52
Definition motor_constants.h:14