Working MK3 swerve

Working Mk3 swerve

Swerve for team 1710 has been a long and coming thing. In personally working on both SDS’s MK2’s and MK3’s from a programming perspective, I have found there to be far fewer resources when it comes to working examples. Something I found to be extremely useful, this summer when our team was trying to get our first swerve bot up and running, was SDS’s out-of-the-box MK2 code. This allowed us to test and troubleshoot our build, and electrical system right out of the gate. However, I have yet to find this kind of out-of-the-box code for SDS’s MK3 modules. This was entirely true until about a week ago when this post was made. Although much of the footwork was already done by the WPI library and @Zach_O, in testing we found that an important step was missed.

An important part in getting swerve to work is aligning the wheels and recording their individual offsets into the code so that they all point in the correct direction. By the nature of the mag encoders commonly used in the MK3 modules, it is unlikely that the magnets will be placed perfectly in the 0 position relative to the sensor. In short, you need to be able to calibrate each individual wheel. I made two other minor changes like using Kauali lab’s NavX as a gyroscope and allowing for mid-match recalibration of the gyroscope using the left-bumper.

So ta-da: here is the code
Check the readme for instructions and feel free to ask questions.

Much thanks to @Zach_O and the work he did that allowed us to complete the project so quickly.

Here are some pictures and videos of the bot!

Video 1
Video 2

For more on the design, build, and history of the project check out this


Hey! A few notes on this -

The integratedSensorOffsetDegrees isn’t what you want to use here. You’re not interfacing with the integrated sensor in the TalonFX - you’re using the CANCoder as your sensor. You should use the magnetOffsetDegrees on a CANCoderConfiguration to set the offset. I believe that allows you to avoid storing that offset variable in your swerve module object and you can use the CANCoder’s getAbsolutePosition method without having to do any addition. I haven’t tested this (I don’t have any swerve modules), so if you’d like to try it and report back, that would be helpful.

Not setting the CANCoder’s offset this way/using the offset only in-memory will cause the PID controllers on the TalonFX to read a different value then you’re reading in your code. Hopefully it makes sense why this would be an issue and why integratedSensorOffsetDegrees isn’t doing anything for you in this setup.

I also opted to use the Rotation2d class to represent the offset for the module, since it allows teams to talk in radians or degrees when instantiating their swerve module objects. It reduces some of the sharp edges in the implementation presented above.

I’ve updated my code example to reflect these changes - here’s the link to the individual commit that talks about the suggestions above

Edit: I’m also unsure why you’d want to change the max speed for the swerve modules. Did you gear your MK3 modules differently than they ship? The free speeds for the modules are 13.6 ft/sec or 16.2 ft/sec, depending on the gear ratio you buy. I’m curious where that 20 ft/sec value came from.


Another KC swerve team to add to the list. Though I’m not sure the extent of the list. I can say 2410, 4522, and 6886 for certain. We only ever made it to a crab (2 steering motors, 4 wheels), which didn’t hold up as well I think yours could for competitions.

Both code and mechanical design has converged a lot in last 2-3 years, and while games might not have specific swerve advantages, there will be more even for slight advantages in more future games. It is the smart move I think to get manufactured modules, unless you are well equipped to machine yourself, though even that is getting less of a barrier with 3d printed modules.

Getting this all together and running is a awesome milestone. I remember how impressed by the turning wheels and swerve (or crab in our case) movements, that our engineering mentor was, that you could see it on his face. That alone made it feel like a great accomplishment, and I think that is the same for any doing this and seeing it actual working. So pretty cool 1710!


Thank you for the feedback! The use of magnetOffsetDegrees is clearly a more intuitive way of doing things and I will test those changes ASAP. As for bumping up the max speed, I was just playing around with values and probably forgot to change it back. Again I really appreciate the feedback and your contribution to the community.

1 Like

Yes, we are very excited! We were very inspired by 1108 and 2410 in particular. I remember playing against 2410 in 2018 at Heartland and then being on there alliance a few weeks later at cedar falls. Am I correct in remembering the in motor-in-wheel design from 1108? It was a very unique design and we were inspired by the ingenuity!

2410 alum here. I was on the team from 2017 to 2020 for which we did swerve for the 2017/18/19 games. When I designed the drivetrain/chassis on the 2020 robot, we made the decision to move to a six wheel drop West Coast Drive for sake of programming and other reasons. I’d be happy to talk more about the transition, but I don’t regret switching back.

Swerve is extremely nice to have, but the programming complexity can be really annoying, and problems can quickly shut you down. Wheels can become unzeroed with motor slop, and field oriented control is almost essential through the use of a gyro (these also introduce issues). At OKC 2019, we had to drive robot oriented for the first half of quals or so because the speaker bass was sending the gyro into a 5+ minute locking bootloop each time we turned the robot on in queue.

TL;DR: Swerve is great, but be prepared to encounter really annoying issues that take a while to fix. This is why I encourage teams to explore it in the offseason and/or times where it won’t impact their schedule significantly.


Interesting, what kind of encoder/potentiometer did you all use to zero the turning motors? I’m sure @hudsonh can speak more as to how our turning has been working.

We went with the MA3 Encoders for our MK2 robot (US Digital® | Products | MA3 | Miniature Absolute Magnetic Shaft Encoder). With MK2 we ran into a lot of trouble with the zeroing. MK3 has been a substantial improvement. The magnet for the encoder is directly embedded into the main shaft and the encoder itself rests above it. The MK2 modules have an encoder with a gear interface. The MK3 Interface has significantly less points of failure. Here are the Cancoders we got Cross the Road Electronics.

We also experienced some motor slop/backlash with the MK2 modules. This seems to be due to the multiple gears on the main center driving shaft. The MK3’s however have a single machined gear in the middle which, even after testing, have negligible backlash. I’ll be sure to update this post if the backlash shows over time with more wear and tear on the gears.

We will have to look more into the gyro issues. The bass from the music messed up your gyros? We’ll have to test with some FRC classics and see if we can reproduce the issue.

Thanks for the reply!

We used a Pigeon IMU and the MA3 Shaft Encoder, however this was with the Andymark Swerve and Steer modules, not the Swerve Drive Specialties ones.

The subwoofers were right next to the queue and the arena was on top of a parking garage, so you could feel the vibrations standing on HAB Level 1. The solution to the locking bootloop was to turn the robot on and do a 5-10 second hands-off period similar to a CPR defib. Tapping the cart or working on the robot while it was calibrating was often enough to mess it up. Once we pinpointed the issue to this, we were really careful and diligent when initializing everything.


Also here is our incident report form: MK3IncidentReport - Google Sheets. The purpose of this form is to document repeated failures so we can be more diligent about addressing them.

1 Like

We are trying to use ZackOrr code to get our MK3 swerve running. We can get the drive wheels moving correctly but the swerve motors never move. Any ideas? We are using CANcoders, Talon 500s, and a Pigeon.

Hello! Thank you for posting such a great resource on swerve. It has really helped out our team, but we are having a few issues with the code and we aren’t sure if we are doing something wrong. We followed the steps in your read me and we think we got all the offsets but yet our wheels still don’t align properly. What we did was that we cloned the repo added ours id’s and commented out the lines of code we were told to comment out (some lines were shifted a bit but we found them) we put the wheels where they would be when our alignment code and then moved the wheels to there spots and got the numbers and put them into the offsets in the code, when we try to move the robot all the wheels are going which way.

Can help us out?

Thanks in advance!

Are the wheels just driving in the wrong direction or are all the angles off?

Also, are you using MKIII modules?

A pigeon? is that a motor controller?

It’s an IMU

We are using the MK3 modules, while driving forward backwards, and side to side our wheels seem to be aligned properly. But once we try to rotate where all the wheels are supposed to be angled they are mostly facing different directions and are not spinning the right direction.

My guess would be you have your front and CAN id’s mixed around. Make sure that the front left is the actual front left front right is the front right etc. all relative to the same “front” of the robot.

You can also check what’s where in terms of CAN Id’s using CTRE’s Phoenix tuner to blink the motors controllers. Compare the blinking motors to where you think they should be relative to the front.

1 Like

We double checked all our motor ID’s , and encoder ID’s through phoenix tuner and every thing came back correct, any other suggestions?

Try posting a video. might be able to diagnose a bit better that way

Thanks for your help, we have resolved the issue by setting all the module offset’s to zero and kept changing the values of the offset of each module by trial and error until we reached a 45 degree angle.
Thanks again for your help and support.

Here is a video of our robot working!