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 <frc2/command/sysid/SysIdRoutine.h>
22#include <networktables/StructArrayTopic.h>
23#include <networktables/StructTopic.h>
24#include <units/acceleration.h>
25#include <units/angle.h>
26#include <units/angular_velocity.h>
27#include <units/dimensionless.h>
28#include <units/length.h>
29#include <units/time.h>
30#include <units/velocity.h>
31#include <valkyrie/BaseSubsystem.h>
32#include <valkyrie/controllers/BaseController.h>
33#include <valkyrie/controllers/PIDF.h>
34#include <valkyrie/controllers/ProfiledPIDController.h>
35#include <valkyrie/drivetrain/swerve/SwerveModule.h>
36#include <valkyrie/gyro/Gyro.h>
37#include <valkyrie/util/ConvexPolygon.h>
38#include <valkyrie/util/CoordinateFrames.h>
39#include <valkyrie/util/LockedAccess.h>
40#include <wpi/interpolating_map.h>
41
42namespace valor {
43namespace swerve {
44
45class Swerve : public valor::BaseSubsystem {
46 public:
47 Swerve(std::string name, std::vector<SwerveModule::Config> moduleConfigs, std::shared_ptr<gyro::Gyro> gyro,
48 units::meter_t wheelDiameter, frc2::sysid::Config = frc2::sysid::Config{std::nullopt, std::nullopt, std::nullopt, nullptr});
49
50 void AnalyzeDashboard() override;
51 void LoggablePeriodic() override;
52 void Reset() override;
53
54 void StartOdomThread(units::hertz_t freq);
55
56 void SimulationPeriodic() override;
57
58 void ResetGyro();
59
60 void ApplyRequest(requests::TrackAngularPosition);
61 void ApplyRequest(requests::ApplyChassisSpeeds);
62 void ApplyRequest(requests::ApplyStates);
63
64 inline frc2::CommandPtr SysIdQuasistatic(frc2::sysid::Direction d) { return sysIdRoutine.Quasistatic(d); }
65
66 inline frc2::CommandPtr SysIdDynamic(frc2::sysid::Direction d) { return sysIdRoutine.Dynamic(d); }
67
74 void ResetEncoders();
75
76 double GetSkiddingRatio();
77 bool IsRobotSkidding();
78
79 constexpr std::vector<std::unique_ptr<SwerveModule>>& GetModules() { return swerveModules; }
80
86 units::angular_acceleration::radians_per_second_squared_t GetSmoothedAngularAcceleration();
87 double RotationLerping(double);
88
89 constexpr const auto& GetState() const { return state; }
90
91 constexpr auto& GetState() { return state; }
92
93 protected:
95
96 units::meters_per_second_t maxDriveSpeed;
97 units::radians_per_second_t maxRotationSpeed;
98
99 std::shared_ptr<gyro::Gyro> gyro;
100 ctre::phoenix6::swerve::impl::SwerveDriveKinematics kinematics;
102 kinematics, frc::Rotation2d{}, std::vector<frc::SwerveModulePosition>{}, frc::Pose2d{}};
103 util::Locked<ctre::phoenix6::swerve::impl::SwerveDrivePoseEstimator> calcEstimator{
104 kinematics, frc::Rotation2d{}, std::vector<frc::SwerveModulePosition>{}, frc::Pose2d{}};
105
106 void EnableCarpetGrain(double grainMultiplier, bool roughTowardsRed);
107
108 FrameWrapper<FieldFrame, frc::ChassisSpeeds> VectorLockedSpeeds(FrameWrapper<FieldFrame, frc::ChassisSpeeds> speeds,
109 FrameWrapper<FieldFrame, frc::Rotation2d> heading);
110
111 std::vector<std::unique_ptr<SwerveModule>> swerveModules;
112
113 void UpdateOdometry();
114
115 void SetRotationalLerpMap(wpi::interpolating_map<double, double> _interpolationMap);
116 ConvexPolygon GetPolygon() const;
117
118 static FrameWrapper<FieldFrame, frc::ChassisSpeeds> ReflectDriveSpeeds(FrameWrapper<FieldFrame, frc::ChassisSpeeds> unreflectedSpeeds) {
119 if (frc::DriverStation::GetAlliance().value_or(frc::DriverStation::Alliance::kBlue) == frc::DriverStation::Alliance::kRed) {
120 return frc::ChassisSpeeds{-unreflectedSpeeds->vx, -unreflectedSpeeds->vy, unreflectedSpeeds->omega};
121 }
122 return unreflectedSpeeds;
123 }
124
125 frc::Timer resetOdom;
126
129
130 private:
131 std::vector<frc::SwerveModulePosition> GetModulePositions();
132
133 std::vector<frc::SwerveModuleState> GetModuleStates();
134
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 = false;
143 double carpetGrainMultiplier;
144 bool roughTowardsRed;
145 void CalculateCarpetPose();
146
147 struct {
152
153 std::vector<frc::SwerveModuleState> moduleStates;
154 std::vector<frc::SwerveModulePosition> modulePositions;
155
156 frc::Rotation3d gyroRotation;
157 gyro::Gyro::AngularVelocity3d gyroVelocity;
158 } state;
159
160 frc::Notifier odometryThread{[this] { UpdateOdometry(); }};
161
162 wpi::interpolating_map<double, double> rotationalLerpMap;
163
164 frc2::sysid::SysIdRoutine sysIdRoutine;
165
166 // SwerveSetpointGenerator setpointGenerator;
167 // SwerveSetpoint previousSetpoint;
168};
169
170} // namespace swerve
171} // namespace valor
Abstract class that all Valor subsystem's should implement.
Definition BaseSubsystem.h:49
Definition CoordinateFrames.h:139
Definition ProfiledPIDController.h:12
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)
void UpdateAngularAcceleration()
Updates the calculated angular acceleration of the robot. This function uses the current and previous...
valor::ProfiledPIDController< units::radian, units::radians_per_second > rotationController
Used for requests::TrackAngularPosition.
Definition Swerve.h:128
Definition LockedAccess.h:33
Request structure for commanding a swerve drivetrain using chassis speeds.
Definition Requests.h:48
Request structure for commanding a swerve drivetrain using explicit module states.
Definition Requests.h:151