Team 449 made our first swerve drive a few months ago, and one of the first things we noticed is that when driving straight and spinning at the same time, the robot always skews in the direction of rotation. I’m sure many of you have also encountered this problem - if you’re wondering whether it’s happening because of an error in your code, the short answer is no.
We spent a while trying to debug this issue, and through asking online we settled on the theory that since swerve constant translation + rotation requires time-varying module velocities and headings, and the kinematics don’t include these time variations in velocities and headings.
I put together a simple simulator to attempt to reproduce the skew and validate this theory. This model has a simulation interval for handling physics and a loop interval representing the robot controller. While the model doesn’t use any sort of feed-forward based model to simulate the response of the modules to updated setpoints, it is able to vary the delay between when a linear velocity is commanded and when it is actually assigned to the modules, and can also independently vary the delay between when a heading is commanded and when it is assigned.
The following animation shows four different robot simulations using the first order kinematics: one with no delays, one with only velocity delay, one with only angular delay, and one with both delays. The simulated robots are otherwise identical and are commanded to move to the right at 1m/s and rotate at 1 rad/s. The goal/theoretically perfect pose is shown dashed in orange, while the simulated robot pose is shown in blue.
You can see that skewing occurs in all four cases, with both types of delays causing additional skew. Even in the no-delay case (representing perfect, instantaneous swerve modules), some skew still occurs - this is due to the discretization of the model.
I then solved the second order kinematic equations (derivation in PDF below) and implemented those into the model. This allows the module controller to set the linear acceleration and angular velocity needed to cancel the effect of discretization, and is also a more general solution where you can command specific instantaneous linear and angular robot accelerations in addition to the first-order linear and angular robot velocities.
The following animation shows the four simulations from the previous animation, alongside the four second-order models given the same inputs. The second-order model tracks perfectly in the no-delay case, but it still skews in the other cases that have delay, though not quite as much as the first-order model. It’s also worth noting that the second-order model does not have the same direction wobble as the first order model does.
Finally, adding a simple P-loop on top of this causes all of the models to track well, though the first-order model still has some wobble.
I’m not sure if the second order model is worth implementing on a competition robot, but based on the results of these simulations I think it might be worth a try. In addition to helping reduce skew in teleop, it could also be used to feed the robot linear and angular accelerations from an auto routine, which is currently not possible (as far as I know).
The python simulation can be found here.
And the second order kinematic derivation and equations can be found in the attached PDF. Please let me know if you find any errors or have any questions or insights.
Swerve_Drive_Second_Order_Kinematics.pdf (163.7 KB)