Valkyrie 2026
Loading...
Searching...
No Matches
Swerve.h
1#pragma once
2
3#include <deque>
4#include <memory>
5#include <string>
6#include <vector>
7
8#include <Eigen/Core>
9#include <choreo/Choreo.h>
10#include <ctre/phoenix6/swerve/impl/SwerveDrivePoseEstimator.hpp>
11#include <frc/DriverStation.h>
12#include <frc/EigenCore.h>
13#include <frc/Notifier.h>
14#include <frc/controller/ProfiledPIDController.h>
15#include <frc/estimator/SwerveDrivePoseEstimator.h>
16#include <frc/geometry/Pose2d.h>
17#include <frc/kinematics/ChassisSpeeds.h>
18#include <frc/kinematics/SwerveDriveKinematics.h>
19#include <frc/trajectory/TrapezoidProfile.h>
20#include <frc2/command/InstantCommand.h>
21#include <networktables/StructArrayTopic.h>
22#include <networktables/StructTopic.h>
23#include <units/acceleration.h>
24#include <units/angle.h>
25#include <units/angular_velocity.h>
26#include <units/dimensionless.h>
27#include <units/length.h>
28#include <units/time.h>
29#include <units/velocity.h>
30#include <wpi/interpolating_map.h>
31
32#include "valkyrie/BaseSubsystem.h"
33#include "valkyrie/controllers/BaseController.h"
34#include "valkyrie/controllers/PIDF.h"
35#include "valkyrie/drivetrain/swerve/SwerveModule.h"
36#include "valkyrie/gyro/Gyro.h"
37#include "valkyrie/util/CoordinateFrames.h"
38#include "valkyrie/util/LockedAccess.h"
39
40namespace valor {
41namespace swerve {
42
43class Swerve : public valor::BaseSubsystem {
44 public:
45 Swerve(std::string name, std::vector<std::pair<std::unique_ptr<BaseController>, std::unique_ptr<BaseController>>> modules,
46 std::shared_ptr<gyro::Gyro> gyro, units::meter_t module_radius, units::meter_t _wheelDiameter, std::vector<int> moduleCoordsX,
47 std::vector<int> moduleCoordsY, units::meter_t driveBaseRadius);
48
49 void AnalyzeDashboard() override;
50 void LoggablePeriodic() override;
51 void Reset() override;
52
53 void SimulationPeriodic() override;
54
55 void ResetGyro();
56
57 void ApplyRequest(requests::ApplyChassisSpeeds);
58 void ApplyRequest(requests::ApplyStates);
59
66 void ResetEncoders();
67
72 std::vector<frc::SwerveModulePosition> GetModulePositions();
73
78 std::vector<frc::SwerveModuleState> GetModuleStates();
79
80 double GetSkiddingRatio();
81 bool IsRobotSkidding();
82
83 constexpr std::vector<std::unique_ptr<SwerveModule>>& GetModules() { return swerveModules; }
84
90 units::angular_acceleration::radians_per_second_squared_t GetSmoothedAngularAcceleration();
91 double RotationLerping(double);
92 void FollowTrajectory(const choreo::SwerveSample& sample);
93
94 constexpr units::meter_t GetDriveBaseRadius() const { return driveBaseRadius; };
95
96 constexpr const auto& GetState() const { return state; }
97
98 constexpr auto& GetState() { return state; }
99
100 protected:
101 FrameWrapper<FieldFrame, frc::ChassisSpeeds> commandedSpeeds;
102
103 units::meters_per_second_t maxDriveSpeed;
104 units::radians_per_second_t maxRotationSpeed;
105
106 std::shared_ptr<gyro::Gyro> gyro;
107 std::unique_ptr<ctre::phoenix6::swerve::impl::SwerveDriveKinematics> kinematics;
108 util::Locked<std::unique_ptr<ctre::phoenix6::swerve::impl::SwerveDrivePoseEstimator>> rawEstimator;
109 util::Locked<std::unique_ptr<ctre::phoenix6::swerve::impl::SwerveDrivePoseEstimator>> calcEstimator;
110
111 bool toast;
112
113 void EnableCarpetGrain(double grainMultiplier, bool roughTowardsRed);
114
115 FrameWrapper<FieldFrame, frc::ChassisSpeeds> VectorLockedSpeeds(FrameWrapper<FieldFrame, frc::ChassisSpeeds> speeds,
116 FrameWrapper<FieldFrame, frc::Rotation2d> heading);
117
118 std::vector<std::unique_ptr<SwerveModule>> swerveModules;
119
120 void StartOdomThread(units::hertz_t freq);
121 void UpdateOdometry();
122
123 void SetRotationalLerpMap(wpi::interpolating_map<double, double> _interpolationMap);
124
125 static FrameWrapper<FieldFrame, frc::ChassisSpeeds> ReflectDriveSpeeds(FrameWrapper<FieldFrame, frc::ChassisSpeeds> unreflectedSpeeds) {
126 if (frc::DriverStation::GetAlliance().value_or(frc::DriverStation::Alliance::kBlue) == frc::DriverStation::Alliance::kRed) {
127 return frc::ChassisSpeeds{-unreflectedSpeeds->vx, -unreflectedSpeeds->vy, unreflectedSpeeds->omega};
128 }
129 return unreflectedSpeeds;
130 }
131
132 frc::Timer resetOdom;
133
134 private:
135 std::deque<units::angular_acceleration::radians_per_second_squared_t> yawRateBuffer; // TODO Replace with a moving average filter
136
137 static constexpr size_t ACCEL_BUFFER_SIZE = 10; // need to adjust // TODO: Replace with an actual moving average filter
138 units::angular_velocity::radians_per_second_t lastYawRate = 0_rad_per_s; // TODO: Replace with a moving average filter
139
140 units::angular_acceleration::radians_per_second_squared_t angularAcceleration = 0_rad_per_s_sq;
141
142 bool useCarpetGrain;
143 double carpetGrainMultiplier;
144 bool roughTowardsRed;
145 void CalculateCarpetPose();
146
147 struct {
148 FrameWrapper<FieldFrame, frc::Pose2d> rawPose;
149 FrameWrapper<FieldFrame, frc::Pose2d> calculatedPose;
150 FrameWrapper<FieldFrame, frc::ChassisSpeeds> fieldSpeeds;
151 FrameWrapper<RobotFrame, frc::ChassisSpeeds> robotSpeeds;
152
153 std::vector<frc::SwerveModuleState> moduleStates;
154
155 frc::Rotation3d gyroRotation;
156 gyro::Gyro::AngularVelocity3d gyroVelocity;
157 } state;
158
159 units::meter_t driveBaseRadius;
160
161 frc::Notifier odometryThread{[this] { UpdateOdometry(); }};
162
163 frc::PIDController xChoreoController{10.0, 0.0, 0.0};
164 frc::PIDController yChoreoController{10.0, 0.0, 0.0};
165 frc::PIDController headingChoreoController{7.5, 0.0, 0.0};
166
167 wpi::interpolating_map<double, double> rotationalLerpMap;
168
169 // SwerveSetpointGenerator setpointGenerator;
170 // SwerveSetpoint previousSetpoint;
171};
172
173} // namespace swerve
174} // namespace valor
Abstract class that all Valor subsystem's should implement.
Definition BaseSubsystem.h:51
Definition CoordinateFrames.h:139
void LoggablePeriodic() override
Periodic callback for logging updates.
void AnalyzeDashboard() override
Synchronize dashboard data (both read and write).
void Reset() override
Reset all subsystem state.
void ResetOdometry(FrameWrapper< FieldFrame, frc::Pose2d > pose)
std::vector< frc::SwerveModulePosition > GetModulePositions()
Retrieves the current position of each swerve module.
void UpdateAngularAcceleration()
Updates the calculated angular acceleration of the robot. This function uses the current and previous...
std::vector< frc::SwerveModuleState > GetModuleStates()
Retrieves the current state (speed and angle) of each swerve module.
Request structure for commanding a swerve drivetrain using chassis speeds.
Definition Requests.h:49
Request structure for commanding a swerve drivetrain using explicit module states.
Definition Requests.h:145