Mini-Project 5: Integrating a COTS Swerve Module
Take a COTS swerve module from box to driving: pick a module and ratio, mount it square, run SysId, and stand up a SwerveDrive with WPILib kinematics.
Sign in to track progress, earn XP, and save lessons.
The goal
Go from a boxed COTS swerve module to a driving drivetrain. Modern FRC swerve is almost entirely COTS, so the project is integration, not invention.
Step 1 — Pick a module and motors
Good current options:
- REV 3in MAXSwerve (REV-21-3005) with a NEO 2.0 or Kraken X60 drive motor and a NEO 550 steer motor. The 15T Spline Input Kit (REV-21-3009) adapts a NEO 2.0 or Kraken X60 to the module (the Kraken needs the included spacer plate).
- SDS MK4i / MK4n / MK5n: the MK5n steering ratio is 287:11 (~26.09:1). Its drive motor is a Kraken X60 (or REV NEO V1.1 / NEO Vortex) and its steer motor is a compact Kraken X44.
- WCP Swerve X2 / X2S: built around the Kraken X60 for drive (the X2S adds a Kraken X44 for steer). The older WCP Swerve X also runs a Kraken X60.
Pick a drive gear ratio by trading top speed vs pushing force. Faster ratios give a higher free speed but lower traction-limited acceleration; most teams land near a 5:1-6:1 drive reduction for a ~15-17 ft/s robot.
Step 2 — Mount it square
All four modules must be parallel and square to the frame. A few degrees of toe causes scrub, wasted current, and a robot that fights itself. Use the manufacturer's mounting holes and a machined or laser-cut bellypan; do not hand-drill module mounts. Record each module's CANcoder/absolute steer offset so wheels zero pointing forward.
Step 3 — Characterize with SysId
The drive motors closely obey V = kS*sgn(v) + kV*v + kA*a. Run a SysId quasistatic + dynamic routine to get kS, kV, kA per WPILib. These feed your drive feedforward so the robot tracks commanded speeds and drives straight (mismatched wheel kV is a top cause of veering).
Step 4 — Stand up kinematics
SwerveDriveKinematics kin = new SwerveDriveKinematics(
fl, fr, bl, br); // Translation2d module locations from robot center
ChassisSpeeds speeds = new ChassisSpeeds(vx, vy, omega);
SwerveModuleState[] states = kin.toSwerveModuleStates(speeds);
SwerveDriveKinematics.desaturateWheelSpeeds(states, MAX_SPEED);
for (int i = 0; i < 4; i++) modules[i].setDesiredState(states[i]);
Always call desaturateWheelSpeeds so a high omega + vy command never exceeds a module's max speed and de-syncs the drive.
Step 5 — First-drive checklist
- Push the robot by hand and watch each module's reported angle/velocity flip sign correctly.
- With wheels off the ground, drive +X slowly; confirm all four wheels point and spin forward.
- Verify steer absolute offsets, then drive field-relative with a fresh gyro zero.
- Set drive current limits (e.g. 40-60 A) to stay under the 120 A main breaker during a full-speed push.
Key takeaways
- Modern swerve is a COTS integration task: choose module (REV MAXSwerve / SDS MK4i-MK5n / WCP Swerve X2) and drive ratio for your speed-vs-traction target.
- Mount all four modules parallel and square off a machined bellypan; record absolute steer offsets so wheels zero forward.
- Characterize drive with SysId (kS/kV/kA) and always desaturateWheelSpeeds so combined translation+rotation commands stay achievable.
Go deeper
Lesson quiz
RequiredAnswer all 3 questions correctly to complete this lesson.
1.Why is integrating a modern COTS swerve module framed as integration rather than invention?
2.Why must all four swerve modules be mounted parallel and square to the frame off a machined or laser-cut bellypan?
3.Why does the lesson insist you always call SwerveDriveKinematics.desaturateWheelSpeeds before commanding the modules?
Answer every question to submit.