51template <
size_t NumModules>
 
   53    : 
public Kinematics<wpi::array<SwerveModuleState, NumModules>,
 
   54                        wpi::array<SwerveModulePosition, NumModules>> {
 
   67  template <std::convertible_to<Translation2d>... ModuleTranslations>
 
   68    requires(
sizeof...(ModuleTranslations) == NumModules)
 
   71    for (
size_t i = 0; i < NumModules; i++) {
 
   73      m_inverseKinematics.template block<2, 3>(i * 2, 0) <<
 
   74        1, 0, (-m_modules[i].Y()).value(),
 
   75        0, 1, (+m_modules[i].X()).value();
 
   79    m_forwardKinematics = m_inverseKinematics.householderQr();
 
 
   87      : m_modules{modules}, m_moduleHeadings(
wpi::empty_array) {
 
   88    for (
size_t i = 0; i < NumModules; i++) {
 
   90      m_inverseKinematics.template block<2, 3>(i * 2, 0) <<
 
   91        1, 0, (-m_modules[i].Y()).value(),
 
   92        0, 1, (+m_modules[i].X()).value();
 
   96    m_forwardKinematics = m_inverseKinematics.householderQr();
 
 
  109  template <std::convertible_to<Rotation2d>... ModuleHeadings>
 
  110    requires(
sizeof...(ModuleHeadings) == NumModules)
 
  122    for (
size_t i = 0; i < NumModules; i++) {
 
  123      m_moduleHeadings[i] = moduleHeadings[i];
 
 
  163    if (chassisSpeeds.
vx == 0_mps && chassisSpeeds.
vy == 0_mps &&
 
  164        chassisSpeeds.
omega == 0_rad_per_s) {
 
  165      for (
size_t i = 0; i < NumModules; i++) {
 
  166        moduleStates[i] = {0_mps, m_moduleHeadings[i]};
 
  173    if (centerOfRotation != m_previousCoR) {
 
  174      for (
size_t i = 0; i < NumModules; i++) {
 
  176      m_inverseKinematics.template block<2, 3>(i * 2, 0) =
 
  178          {1, 0, (-m_modules[i].Y() + centerOfRotation.Y()).value()},
 
  179          {0, 1, (+m_modules[i].X() - centerOfRotation.X()).value()}};
 
  182      m_previousCoR = centerOfRotation;
 
  185    Eigen::Vector3d chassisSpeedsVector{chassisSpeeds.
vx.value(),
 
  186                                        chassisSpeeds.
vy.value(),
 
  187                                        chassisSpeeds.
omega.value()};
 
  190        m_inverseKinematics * chassisSpeedsVector;
 
  192    for (
size_t i = 0; i < NumModules; i++) {
 
  193      units::meters_per_second_t x{moduleStateMatrix(i * 2, 0)};
 
  194      units::meters_per_second_t y{moduleStateMatrix(i * 2 + 1, 0)};
 
  197      auto rotation = speed > 1e-6_mps ? Rotation2d{x.value(), y.value()}
 
  198                                       : m_moduleHeadings[i];
 
  200      moduleStates[i] = {speed, rotation};
 
  201      m_moduleHeadings[i] = rotation;
 
 
  224  template <std::convertible_to<SwerveModuleState>... ModuleStates>
 
  225    requires(
sizeof...(ModuleStates) == NumModules)
 
  245                                    moduleStates)
 const override {
 
  248    for (
size_t i = 0; i < NumModules; ++i) {
 
  250      moduleStateMatrix(i * 2, 0) = 
module.speed.value() * module.angle.Cos();
 
  251      moduleStateMatrix(i * 2 + 1, 0) =
 
  252          module.speed.value() * module.angle.Sin();
 
  255    Eigen::Vector3d chassisSpeedsVector =
 
  256        m_forwardKinematics.solve(moduleStateMatrix);
 
  258    return {units::meters_per_second_t{chassisSpeedsVector(0)},
 
  259            units::meters_per_second_t{chassisSpeedsVector(1)},
 
  260            units::radians_per_second_t{chassisSpeedsVector(2)}};
 
 
  276  template <std::convertible_to<SwerveModulePosition>... ModuleDeltas>
 
  277    requires(
sizeof...(ModuleDeltas) == NumModules)
 
  300    for (
size_t i = 0; i < NumModules; ++i) {
 
  302      moduleDeltaMatrix(i * 2, 0) =
 
  303          module.distance.value() * module.angle.Cos();
 
  304      moduleDeltaMatrix(i * 2 + 1, 0) =
 
  305          module.distance.value() * module.angle.Sin();
 
  308    Eigen::Vector3d chassisDeltaVector =
 
  309        m_forwardKinematics.solve(moduleDeltaMatrix);
 
  311    return {units::meter_t{chassisDeltaVector(0)},
 
  312            units::meter_t{chassisDeltaVector(1)},
 
  313            units::radian_t{chassisDeltaVector(2)}};
 
 
  321    for (
size_t i = 0; i < NumModules; i++) {
 
  322      result[i] = {end[i].distance - start[i].distance, end[i].angle};
 
 
  349      units::meters_per_second_t attainableMaxSpeed) {
 
  350    auto& states = *moduleStates;
 
  353                                          [](
const auto& a, 
const auto& b) {
 
  354                                            return units::math::abs(a.speed) <
 
  355                                                   units::math::abs(b.speed);
 
  359    if (realMaxSpeed > attainableMaxSpeed) {
 
  360      for (
auto& module : states) {
 
  361        module.speed = module.speed / realMaxSpeed * attainableMaxSpeed;
 
 
  395      units::meters_per_second_t attainableMaxModuleSpeed,
 
  396      units::meters_per_second_t attainableMaxRobotTranslationSpeed,
 
  397      units::radians_per_second_t attainableMaxRobotRotationSpeed) {
 
  398    auto& states = *moduleStates;
 
  402                                          [](
const auto& a, 
const auto& b) {
 
  403                                            return units::math::abs(a.speed) <
 
  404                                                   units::math::abs(b.speed);
 
  408    if (attainableMaxRobotTranslationSpeed == 0_mps ||
 
  409        attainableMaxRobotRotationSpeed == 0_rad_per_s ||
 
  410        realMaxSpeed == 0_mps) {
 
  414    auto translationalK =
 
  416        attainableMaxRobotTranslationSpeed;
 
  419                       attainableMaxRobotRotationSpeed;
 
  425    for (
auto& module : states) {
 
  426      module.speed = module.speed * scale;
 
 
  433      double t)
 const override {
 
  436    for (
size_t i = 0; i < NumModules; ++i) {
 
  437      result[i] = start[i].Interpolate(end[i], t);
 
 
  449  Eigen::HouseholderQR<Matrixd<NumModules * 2, 3>> m_forwardKinematics;
 
 
  455template <
typename ModuleTranslation, 
typename... ModuleTranslations>
 
#define WPILIB_DLLEXPORT
Definition SymbolExports.h:36
#define EXPORT_TEMPLATE_DECLARE(export)
Definition SymbolExports.hpp:92
Helper class that converts a chassis velocity (dx, dy, and dtheta components) into individual wheel s...
Definition Kinematics.h:25
Helper class that converts a chassis velocity (dx, dy, and dtheta components) into individual module ...
Definition SwerveDriveKinematics.h:54
wpi::array< SwerveModuleState, NumModules > ToSwerveModuleStates(const ChassisSpeeds &chassisSpeeds, const Translation2d ¢erOfRotation=Translation2d{}) const
Performs inverse kinematics to return the module states from a desired chassis velocity.
Definition SwerveDriveKinematics.h:158
wpi::array< SwerveModulePosition, NumModules > Interpolate(const wpi::array< SwerveModulePosition, NumModules > &start, const wpi::array< SwerveModulePosition, NumModules > &end, double t) const override
Performs interpolation between two values.
Definition SwerveDriveKinematics.h:430
const wpi::array< Translation2d, NumModules > & GetModules() const
Definition SwerveDriveKinematics.h:442
SwerveDriveKinematics(const SwerveDriveKinematics &)=default
void ResetHeadings(ModuleHeadings &&... moduleHeadings)
Reset the internal swerve module headings.
Definition SwerveDriveKinematics.h:111
void ResetHeadings(wpi::array< Rotation2d, NumModules > moduleHeadings)
Reset the internal swerve module headings.
Definition SwerveDriveKinematics.h:121
ChassisSpeeds ToChassisSpeeds(const wpi::array< SwerveModuleState, NumModules > &moduleStates) const override
Performs forward kinematics to return the resulting chassis state from the given module states.
Definition SwerveDriveKinematics.h:244
static void DesaturateWheelSpeeds(wpi::array< SwerveModuleState, NumModules > *moduleStates, units::meters_per_second_t attainableMaxSpeed)
Renormalizes the wheel speeds if any individual speed is above the specified maximum.
Definition SwerveDriveKinematics.h:347
SwerveDriveKinematics(ModuleTranslations &&... moduleTranslations)
Constructs a swerve drive kinematics object.
Definition SwerveDriveKinematics.h:69
Twist2d ToTwist2d(ModuleDeltas &&... moduleDeltas) const
Performs forward kinematics to return the resulting Twist2d from the given module position deltas.
Definition SwerveDriveKinematics.h:278
SwerveDriveKinematics(const wpi::array< Translation2d, NumModules > &modules)
Definition SwerveDriveKinematics.h:85
wpi::array< SwerveModuleState, NumModules > ToWheelSpeeds(const ChassisSpeeds &chassisSpeeds) const override
Performs inverse kinematics to return the wheel speeds from a desired chassis velocity.
Definition SwerveDriveKinematics.h:207
static void DesaturateWheelSpeeds(wpi::array< SwerveModuleState, NumModules > *moduleStates, ChassisSpeeds desiredChassisSpeed, units::meters_per_second_t attainableMaxModuleSpeed, units::meters_per_second_t attainableMaxRobotTranslationSpeed, units::radians_per_second_t attainableMaxRobotRotationSpeed)
Renormalizes the wheel speeds if any individual speed is above the specified maximum,...
Definition SwerveDriveKinematics.h:392
ChassisSpeeds ToChassisSpeeds(ModuleStates &&... moduleStates) const
Performs forward kinematics to return the resulting chassis state from the given module states.
Definition SwerveDriveKinematics.h:226
Twist2d ToTwist2d(wpi::array< SwerveModulePosition, NumModules > moduleDeltas) const
Performs forward kinematics to return the resulting Twist2d from the given module position deltas.
Definition SwerveDriveKinematics.h:296
Twist2d ToTwist2d(const wpi::array< SwerveModulePosition, NumModules > &start, const wpi::array< SwerveModulePosition, NumModules > &end) const override
Performs forward kinematics to return the resulting Twist2d from the given change in wheel positions.
Definition SwerveDriveKinematics.h:316
Represents a translation in 2D space.
Definition Translation2d.h:29
Container for values which represent quantities of a given unit.
Definition base.h:1930
This class is a wrapper around std::array that does compile time size checking.
Definition array.h:26
static void ReportUsage(MathUsageId id, int count)
Definition MathShared.h:75
constexpr UnitType abs(const UnitType x) noexcept
Compute absolute value.
Definition math.h:726
constexpr UnitTypeLhs hypot(const UnitTypeLhs &x, const UnitTypeRhs &y)
Computes the square root of the sum-of-squares of x and y.
Definition math.h:508
Eigen::Matrix< double, Rows, Cols, Options, MaxRows, MaxCols > Matrixd
Definition EigenCore.h:21
SwerveDriveKinematics(ModuleTranslation, ModuleTranslations...) -> SwerveDriveKinematics< 1+sizeof...(ModuleTranslations)>
constexpr UnitTypeLhs max(const UnitTypeLhs &lhs, const UnitTypeRhs &rhs)
Definition base.h:3422
constexpr UnitTypeLhs min(const UnitTypeLhs &lhs, const UnitTypeRhs &rhs)
Definition base.h:3414
@ kKinematics_SwerveDrive
Foonathan namespace.
Definition ntcore_cpp.h:26
constexpr empty_array_t empty_array
Definition array.h:16
Represents the speed of a robot chassis.
Definition ChassisSpeeds.h:25
units::meters_per_second_t vx
Velocity along the x-axis.
Definition ChassisSpeeds.h:29
units::meters_per_second_t vy
Velocity along the y-axis.
Definition ChassisSpeeds.h:34
units::radians_per_second_t omega
Represents the angular velocity of the robot frame.
Definition ChassisSpeeds.h:39
Represents the position of one swerve module.
Definition SwerveModulePosition.h:18
Represents the state of one swerve module.
Definition SwerveModuleState.h:18
A change in distance along a 2D arc since the last pose update.
Definition Twist2d.h:22