Understanding Swerve Drive

So some members of our team has started getting interested in creating and experiencing with a swerve drive module. We want to get our mentor to approve it so we started doing some research, so far we designed a pretty solid concept, but I’ve wanted to ask some questions about the actual code for the Swerve module (because I’m more of the programmer guy).
So I know the math is kinda simple - calculating 2d motion vectors to calculate the angle the wheels have to turn at, but looking at some swerve teams’ codes I got kind of confused.

Generally speaking - why is it so hard to program a swerve module? I mean is it so much different than using regular motors and encoders? What does it even take to code a swerve drive?

I know this is written pretty dull and vague but I want the grasp of the general idea of it. thanks for your kind help in advance.

1 Like

Chief Delphi should not allow oxymorons.

3 Likes

Well I’m sorry if it sounds confusing but there’s a difference between knowing the math and understanding of the programming side (the teams I reference are 1323 and 2910, which specialize in swerve). It’s kind of hard to read through an entire github repository, and from what I did get to read it was a lot to referencing between different files so I got confused - so I came here to ask about it.

2 Likes

The actual math to compute wheel angles and velocities is fairly trivial. The more complicated parts involve making sure you’re optimizing how the module moves.

So, if we create a drive base wherein we treat forward as 0 degrees and we are moving along at 100% throttle at 0 degrees and we want to go backwards the naive solution would result in a 180 degree traversal of your module.

Once you account for this, the next big confusing part is field centric - I cheated on 323’s code and instead transformed the user input because it was easier to test and only required a single matrix multiply to do.

public static Vector2d TransformFieldCentric(double x, double y, double headingDegrees){
    Vector2d control = new Vector2d(x,y);
    control.rotate(headingDegrees);
    return control;
  }

It’s the equivalent of
\begin{bmatrix}cos(\theta) & sin(\theta)\\-sin(\theta) & cos(\theta)\end{bmatrix} * \begin{matrix} [x & y]\end{matrix}

Where \theta is the current heading of the robot.

Realistically, it SHOULD use a Vec3D but because the it doesn’t use the desired rotation at all, why bother? If I refactor this stuff this offseason I’d consider adding it in just so I can use Vec3D through the whole code base though.

Those were the places that took me a while to resolve. If you have more specific questions I’m more than willing to help - I haven’t dug into 1323/2910’s code recently though.

3 Likes

Well thanks. But why rotate the wheels 180 degrees when you can simply give negative force to the motors? Is it by any means faster?
And even after your explanation it sounds rather easier than it probably is, I just wonder why is it such a big deal to code a swerve module?

That’s EXACTLY what you should do, reversing the drive velocity is way faster. But how do you catch that? It’s all just layers of complexity on top of rather simple math.

1 Like

Exactly and so I was wondering what’s the big fuss about programming a swerve drive. Then again it might be harder than it sounds but I just don’t get why is my mentor so harsh on the matter, he make it sound impossible but from theoretical speaking it’s a challenge but not that impossible.
and as for that question you need to see where the controller is pointing at, check the shortest route (one of the 2) and see how many degrees you need to spin the wheel, then calculate the vector. Is that right?

There’s a lot of little things that make it a pain -

  • Zeroing modules - This is a mixture of electrical, mechanical, and software.
  • Ensuring your sensors are all operating in the correct directions to work together. I had a super fun issue that took John and I a couple days to figure out wherein the gyro had positive as one direction and the wheels the other which meant that our field centric driving was VERY wrong. Obvious in hindsight but hard to debug.
  • Autonomous - There’s a LOT of places for error to creep in for driving paths in autonomous.
  • Probably any of a dozen small gotchas Im missing or forgot

It also just eats time - Im a professional software engineer, it took me a few weeks of nights and weekends during build 2018 to get the drive code working. (Mind you, there were complicating factors like me being 1000 miles away and not being able to test code)

I REALLY don’t suggest trying it in season, as an off season project? Not bad, spend a couple off-seasons iterating and then run it.

1 Like

Alright. Thanks a bunch.

Right now we, Team 2073, are starting our venture into Swerve drive. We have no intent to field a robot using it until we are completely comfortable with the intricacies and gotchas related to Swerve.
We have chosen to work on designing our own module based of the best ideas of both the WCP Swerve module and the MK2 module the 2910 uses.

To keep our coding simple, we are going to prototype and use a single module as a power assist/drive unit for our Big A$$ steel robot cart that was made for us several years back by a sponsor. Once we have the mechanics figured out, we will start with basic drive code running on a Teensy 3.5 with control input from a Wii Nunchuck.

That version will not have nor need a gyro, thus Field centric drive will not be an issue.

The next iteration will be to migrate the control system to a roboRio and use an X-Box control.

After that, we will look into building a 4 module test platform and delve into full swerve control with gyro etc.

We have no timeline for this project. It may be one year, it may be three. We’ll just see how it progresses.

Sounds kind of nice but then again in the post I mentioned that we already designed a pretty solid module (based on some research we did) - it’s quite compact and light, not that hard mechanically. I just wanted to ask for a general explanation of the coding part but I wish you the best of luck!

I think @Sriram_Neravati was just joking: he was indirectly complimenting you by implying that

is not necessarily “simple math,” regardless of whether or not it is.

Oh sorry I must have mistook it. Thanks for letting me know.

The devil is definitely in the details with swerve drive programming. Let’s say you are currently rotating while moving linearly, so the wheels are all pointing in different directions. Then you want to stop rotating and just move linearly. The wheels will all rotate to the desired position independently, and get to to the target angle at slightly different times. This will cause the robot to twist a little bit in hard to predict ways. You don’t need to account for this, per se, and you’ll generally be fine. But it leads to a suboptimal driving experience. Alternately, you could actively track the angle that you were facing when you stopped rotating by doing a PID on that angle with the input being the current angle, the setpoint being the original angle, and the output being the rotation speed into the main math equations. This adds a pretty big complication to the code but if you do it it makes it a smidge easier to drive.

There are several things like this that are not strictly necessary but improve the driving. Without these things swerve drive can look a bit clunky and awkward. With them it can be very smooth and organic.

Alrighty, thanks.

Yes, good for you! I have no clue how swerve is programmed.