Figuring Out Swerve

Hello everyone, I’m the Programming lead from FRC team 9059, COLTech robotics. We have recently finished the construction of our swerve drive test bot, and we have used the CTRE swerve project generator to make a basic program. Me and my team have been looking at swerve programs for months to try to understand them, but we still can’t quite get it. We have managed to figure out some of the “what” (what swerve states are, rotation2d, pose2d, a little about how they interact, etc.) However, we are still quite lost, especially on the “how” of most of the program. We will gladly accept any help or advice, and we greatly appreciate all the great people on this platform. Thank you in advance and have a nice day.
-Team 9059, COLTech Robotics

Edit: Repository Link

2 Likes

do you understand the math behind how the swerve works?
if you don’t then understating the code will be harder.
could you provide some more info on what you don’t understand?
is it the control of the motors?

We have a very rudimentary idea of what the math is doing, which helps a little bit, but we are lost on pretty much everything else. Especially calculating poses and applying them. Additionally, a lot of the logic and calculations are completely alien to us, so we are definitely struggling with the math. We are also very lost when it comes to taking input from the joysticks and translating that to a module state for the motors.

The “how” of swerve programming comes down to understanding how to calculate the speeds and angles for each module to move the robot in the desired way. At a high level, the robot’s motion is usually broken into two components: translational (moving in a direction) and rotational (spinning around its center). When you give the robot a set of inputs—like forward, strafe, and rotation—it needs to figure out how to combine these motions and apply them to the four swerve modules.

This is where a lot of the math comes in, like the ChassisSpeeds and SwerveModuleState objects in WPILib. When you create a ChassisSpeeds object, you’re essentially defining how fast the robot should move in X (forward/backward), Y (side to side), and omega (rotation). The SwerveDriveKinematics class then takes those speeds and calculates the individual speed and angle for each module.

The key is that the kinematics take into account the position of each module relative to the center of the robot. For example, a module on the front-right corner will need to spin at a slightly different speed and angle than a module on the back-left corner when you want to rotate. This is why you set up the Translation2d objects for each module in the kinematics—those positions define the geometry of your swerve drivetrain.

You’ve probably seen the Rotation2d and Pose2d classes a lot. These are super important for keeping track of the robot’s orientation and position on the field. Rotation2d is used to handle angles in a way that’s easier for the code to work with, and Pose2d combines both the robot’s position (X and Y) and its rotation. When you use something like SwerveDriveOdometry, it takes encoder readings and the gyro angle to estimate where the robot is on the field in real-time.

As for controlling the robot, most swerve programs use field-oriented control. This means the robot moves relative to the field, not just itself, which makes it way more intuitive for drivers. To do this, you use the gyro angle to rotate the driver’s inputs (forward, strafe) to match the field’s orientation. That’s why the ChassisSpeeds.fromFieldRelativeSpeeds method is used—it converts your driver inputs into robot-relative motion based on the gyro.

If you’re using the CTRE swerve project generator, a lot of this should already be set up for you, but understanding these pieces will help you tweak and expand the code. One thing I’d recommend is printing out the module states (angle and speed) while driving. Seeing those numbers change as you give different inputs can really help connect the dots.

To get a deeper understanding, I’d highly recommend the Zero to Autonomous videos on swerve—they’re incredibly beginner-friendly while still covering the advanced stuff you’ll need. The WPILib docs on swerve kinematics and odometry are also really helpful, especially for understanding how the math works behind the scenes.

Finally, don’t be afraid to experiment with the code. Try modifying inputs or writing simple tests to see how the modules react. For example, you could create a function that makes the robot spin in place or strafe diagonally and see how the module angles and speeds adjust. It’s a lot of trial and error.

6 Likes

I believe @Keller can help you with this.

I would be happy to help if you need further assistance. You can also inform me if you need help with specific issues in your code.

This article was really helpful for us in understanding the math behind swerve drive: Dominik’s Swerve Drive Programming Blog. I highly recommend checking it out.

When converting joystick inputs to motor outputs, here’s how we approached it:

  • Max Speed Scaling: The joystick values range from -1 to 1, and we scale these values proportionally to the robot’s maximum speed. This ensures the robot’s movement corresponds to the joystick’s position.
  • Deadzone: To avoid unintended movement when the joystick is near its neutral position, we implement a small deadzone where values are treated as zero and also modify it the how the driver likes it.
  • Rounding Up for Max Velocity: To achieve maximum drive velocity even if the joystick isn’t fully pushed to the edge, we round up the joystick values to a threshold. This ensures that near-full joystick inputs still command maximum speed, making it easier for the driver to reach top speeds.

let me know if you want more details on any of these steps.

2 Likes

Thank you so much :smile:
This has taught me more about swerve than months of studying the programs, I really appreciate it.

Thank you so much for the references, we will be getting our resident math lover to take a look :smile:

If it helps, we have much video content and several demo projects as we designed our own swerve code for 2024 season, and will use CTR’s code for 2025.

The video content related to Swerve is here:
https://cheshirerobotics.org/index.php/2023/06/06/swerve-programming/

We also recorded many of our working sessions.

The 2024 season code that is optimized for Phoenix-6 is here:

The actual version we used during the season (it was based on Phoenix-5) is here:

The 2024 code that was rewritten for CTR-specific APIs is here:

The beta 2025 code that is a re-import of the 2024, but rewritten with all 2025 Beta APIs is here:

That one is still work in progress (it compiles, but we did not test it well yet). It uses ALL of the new Beta 2025 - WPI, NI image, CTR, Rev, PathPlanner and PhotonVision. This was a native retrofit. So, all of the API are native to 2025 (meaning - we did not use CTR’s Legacy classes, for instance).

I hope any of this may prove useful to you and your team.