2D Swerve Drive Simulation


I created a couple programs on Khan Academy’s Processing Java Script editor that function as 2 dimensional swerve simulations (mostly because I was bored). I thought I’d post the links here in case anyone is interested in learning from them. I used the Ether’s swerve kinematics in both of my programs to determine the speed and angle of each of the pods

The first program I made is a static display, the user inputs X, Y, and R (rotation) commands, and can instantly view the angle and speed of each of swerve pods. It functions basically the same way that Ether’s spreadsheet does. However, on my program you can use the arrow keys as inputs, and I humbly claim that mine is much more colorful :grinning:

Then I made another program (the one depicted in the video) that allows the user to drive the swerve around the screen. Personally I found it very interesting to see how each of the pods interact with each other as the swerve spins while moving. Our team has used swerve for the past two years, but I’ve never been able to actually see how the pods interact when the robot is spinning while moving until I made this simulation.

I’m considering making some sort of interactive game out of this to let people compare the agility of a swerve to a basic tank drive. But it’ll depend on if I can figure out the collisions.

12 Likes

One other thing you may want to do is to add wheel speed for each of the wheels. In particular, you will want to express that as a percentage of 100% speed. Then you can adjust the maximum translation speed and see how that affects how quickly you will be able to spin while translating. If you run the wheels at 100% speed to translate, you will not be able to rotate about the robot centroid. As you decrease the maximum translational speed, you will be able to increase the speed at which you can rotate. In all cases, the wheel that is on the side of the robot that is rotating in the same direction as the translation direction will be the limiting factor (when it reaches 100% speed). This would allow you to predict how fast you can translate and still conduct a 180 degree rotation within a given distance (say the distance from the loading station wall to the rocket). This is a very useful analysis.

2 Likes

Good idea, but I’m not sure my program would behave the way you think it would with those changes.

The way I currently run the program is by taking each of the pods, and treating them like vectors with an angle, and a magnitude (speed). Then I combine the vectors together to get the overall displacement of the drive base, and I translate the drive base that many pixels across the canvas. So none of the wheels actually have any “virtual friction” so to speak, they simply act as vectors that determine the overall translation of the drive base. And because the rate of rotation isn’t (I think) something that can be solved for using only the wheel vectors, the rotation of the drive base in the program isn’t determined by the vector addition. Instead, I just rotate the drive base by a constant multiplied by the rotation input (which is controlled by the ‘q’ and ‘w’ keys). So basically, the drive base will always rotate about its center. Is that the most accurate way to simulate rotation? No. But the main idea behind the program is to give a visual representation of how a swerve works, so I call that good enough.

Before I discovered the vector approach, I tried having each wheel move across the canvas individually, but I couldn’t for the life of me figure out how to make the movement of all four pods transfer to a common structure (the drive frame), so all of the pods would just drive off in separate directions.

OK, so right now you are just considering a unit speed of the robot centroid combined with a unit speed of rotation about that centroid? OK, well that’s fine. You should still be able to calculate what the resultant wheel vector lengths are using your vector math that you used to calculate the individual wheel angles.

Then, you can scale your unit speed (say 0.8) and your unit rotation (say 0.5) and see what the largest speed is that you get when you superimpose a given speed with a given rotational speed. If any given wheel exceeds 1.0, then the amount of rotation (or translation) is too high.

Back in 2015, which was the first time I was a part of the team, we had a swerve simulator very similar to what you have done, except it used inputs from a game controller to drive the simulation. I have not seen our simulator since 2015, but I’m sure we still have it somewhere. We actually drew a complex path on the screen and people could come up to our pits to try and drive the course. You could switch between robot orient and field orient. It was pretty cool. We also had vectors showing the wheel direction, but we also had limits on the wheel speed so that if you were moving slowly, you could rotate faster and if you were translating fast, your rotation was limited.

This was very instructive to me. This season, when we were debating whether to flip the hatches from one side of the robot to the other or have a relatively fixed hatch grabber and rotate the robot, there was a long discussion about how we would have to slow down the robot to be able to turn 180 degrees and that it would be faster to flip the hatch rather than rotate the robot. I would not have understood this tradeoff without that simulator.

Ok, I think I understand what you’re saying now. And I believe that the kinematics I use already do what you’re saying (except drawing the vector lengths, I’ll be sure to add that). Because when you input X, Y, and R, if you input Y = 1.0, X = 0.0, R = 1.0, the total movement vector will come out as about half of the maximum unit speed. And if you input only X or only Y, you’ll get the maximum unit speed in that direction.

Also, instead of limiting the rotational vs translational unit speeds, couldn’t the operator simply try different combinations of the two? Joysticks are analog inputs after all, so the operator could simply go slower when rotating while moving to get a better movement to rotation speed ratio.

If any given wheel exceeds 1.0, then the amount of rotation (or translation) is too high

Doesn’t normalization take care of this? Where you divide all of the wheel speeds by the largest one? Then all of the wheel speeds are always below 1.

Well, there are two ways to approach the problem. One way is to have the translational speed and rotational speed be proportional to the inputs and then cap the amount of input so that you never exceed the motor speed capability with any combination of commands. The other way is to normalize so that the fastest wheel does not exceed the motor limits. When you apply this normalization, the translational speed will be reduced if you add rotation.

So, for your simulation, you could have an indicator of the translational speed and see what happens to the translation speed when you add rotation. The speed will drop from 1.00 to something lower when you apply rotation (the exact amount depends a bit on the geometry of the robot frame as well as the rotational speed).

So, for your simulation, you could have an indicator of the translational speed and see what happens to the translation speed when you add rotation. The speed will drop from 1.00 to something lower when you apply rotation (the exact amount depends a bit on the geometry of the robot frame as well as the rotational speed).

This is exactly what happens with the algorithm I use in the simulation, and in the algorithm we use for our actual drive base.

Well, there are two ways to approach the problem. One way is to have the translational speed and rotational speed be proportional to the inputs and then cap the amount of input so that you never exceed the motor speed capability with any combination of commands. The other way is to normalize so that the fastest wheel does not exceed the motor limits. When you apply this normalization, the translational speed will be reduced if you add rotation.

That makes sense, but just to be clear, is it correct to say that neither method actually increases/decreases the overall speed of the robot while rotating and translating? The first method you mentioned has a sort of adaptive input limiting which allows for optimal translation/rotation ratios, whereas the second method (the one I use) simply takes whatever translation/rotation ratio is given, and normalizes the wheels so they don’t exceed their capabilities to rotate.

What I’m trying clarify is that both methods have the same capability to rotate and translate at the drive base’s maximum unit speed. They simply employ different methods of keeping the wheel speeds within their boundaries. That sound right about right?

In order to rotate while translating without exceeding the speed capabilities of the motors driving the wheels, the translational speed needs to be reduced from the maximum speed that robot is capable of if it is not rotating.

It sounds like you are already aware of this. That’s great.

Where the studies get interesting is when you see what the impact is on the robot being able to get from point A to point B while doing certain maneuvers. Drivers can use this to practice making efficient maneuvers to maximize the speed that can be achieved by minimizing un-necessary rotation or by executing the rotation during the points in the path where you need to slow down to avoid tipping over, etc. Obviously, the more realistic the simulation is, the better you can test these things. But just seeing the impact to the straight line speed by rotating while you translate is probably enough of a lesson to help the drivers think about their driving differently.

I’m probably going to steal that idea for next year. That would be really cool.

Heck, you could even take this idea further and make it so the swerve code you use on your competition bot is the same code that you use in a simulation like this. For a summer project I might make a libGDX game and utilize some of our non-WPI code so we can use actual robot code there and on the robot.

If you’re going to try and do collisions, you should probably use a game engine or library for that. It would make it a lot easier as you add more complex mechanics.

Just an idea that may or may not work for rotating: Picture drawing a line from the center of the robot to each wheel, find the angle between that line and the line that the rotation of the wheel is at. Take the sine of that angle, do that for each wheel, then average them and multiply by the speed.

So for instance, when rotating in place that angle would be 90 degrees for each wheel (or -90) and the sine of that is either 1 or -1. Just from that quick idea, I think it would work. I’m not sure how different it would be from just using the rotation input value.

I’m not sure how different it would be from just using the rotation input value.

I might try that, but I agree that neither method really provides a completely accurate representation of the ratio of rotation speed to translation speed, and there doesn’t seem to be a very straightforward way to solve for that ratio either.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.