Rotational drift when trying to drive in a straight line

Hey everyone, I’ve been contemplating an issue related to the MAX swerve drive and was wondering if anyone might be able to provide some insights. Last year, the team I was on was running max swerve and had just been using the template code provided by REV and this made it extremely easy to work with swerve as a team that had never done so before, but there’s been one thing that has kind of been bothering me and I can’t quite seem to locate its origin. Essentially any time the robot drives in a straight line, it starts to rotate to the right when driving away from you in field relative mode and vice versa when driving towards you ands its a minor thing where it may only roatate around 40 degrees after driving a full fields length but its just one more thing to deal with when driving or setting up autonomous routines. I thought at first it might have just been a motor problem but then again the drive motors are all velocity controlled with characterization having been done meaning in my mind that all the wheels should be able to reach the same speed even if their are inefficiencies in one of the modules. Additionally the problem persisted when replacing all the swerve modules and even after puting vortexes on leading me to believe its something software or calibration related. And I would assume the method of calibration for the absolute encoders that uses REV’s calibration piece, which tightly fits up around the frame of the robot, wouldn’t be so much less accurate then the cancoder setup that things like the mk4i’s that it could cause such an isue but maybe I’m wrong. That would leave software which coming from REV’s swerve template looks as though there aren’t any issues but that would be the last thing i could think, where maybe I need to better tune a PID loop or something of the sort but otherwise any ideas for a potential solution would be great. Thanks!

1 Like

I would look into this, specifically wpilib’s chassisspeeds.discretize(). I can give you help with implementation too if you need.

We piloted the MAXServe last year, and loved the performance, but the gyro we were using (the one that is coded into the MAXSwerve example, the ADIS16470_IMU) had some pretty nasty drift, similar to the problem you’re describing.
If you’re using that Gyro, I’d suggest switching to something more robust. We went with the NavX2, and it works great for us.
Just be aware, that the power provided from the roborio port isn’t enough for the NavX2, you’ll need to plug in the mini-usb b to a USB port on your Rio.

Best of luck!

For clarification, we too are using the navx2 but I am curious about the power distribution part you mentioned. We were using the MXP connector on the bottom of the navX for power and communication with the rio which appeared to work for all of last season as long as things were taped down to remain secure. Have you run into issues using the MXP connector and if not do you use something like I2C to send data and then provide power over USB? Also for further clarification, by rotational drift our experience wasn’t with drift in the gyro but the robot would roatate when given a straight input but still follow its field relative direction. So the robot itself would move in a straight line but the heading would independently drift to the right while the robot’s translation followed a linear-ish line.

We use the MXP connector for communication and power, but also run a USB cable for additional power. I unfortunately don’t have the resource I had found online that suggested that solution, but our bot behaved better with it plugged into both USB and MXP.

I remember that we had an issue before plugging in the navx usb port, but I don’t remember what the issue was. It doesn’t sound similar to yours as explained.

The second-order kinematics is something I’ve been looking at recently and while I’m at it might I ask if you found it to make a noticeable difference during autonomous as its one less thing to fix with a PID loop? But to address the problem at hand, the issue isn’t that the direction of translation skews while turning but instead that when I drive in a straight line the rotation which should be 0, is non zero. For example, if I were to follow a taped line on the floor say 50 feet, only moving the robot in the y direction without providing any rotation input, if my heading at the beginning was 0 degrees, by the end of the path, the heading is 40 to 50 degrees to the right and when I drive backward in the y direction back to my starting point the robot then rotates back 40 or 50 degrees such that it faces that same initial heading as its beginning position and its this drift when not providing any input that I can’t seem to track down.

You aren’t by chance using c++ are you? We recently discovered that the rev example code has the module order messed up in the swerve drive odometry object. Changing that, adding second order kinematics, and changing the deadzone to be circular solved (i could swear we had the same issue) for us.

2nd order kinematics didn’t seem towork well when i had it in YAGSL. I couldn’t reduce the drift any more or less than ChassisSpeeds.discretize()

We are using the java template so I don’t believe the odometrey of the robot should be screwed up as odometrey currently appears to be “working” . Also second order kinematics would only play a role in the case that you are providing an input for rotation or am I mistaken on that front?

By second order kinematics im referring to ChassisSpeeds.discretize, sorry I know thats technically inaccurate. OTOH ChassisSpeeds.discretize will prevent any skew whatsoever for us so we never explored anything more

1 Like

You are correct, although our odometry was working fine also so I would still check to make 100% sure the order is correct, just in case

Did you ever end up implementing something along the lines of the twist solution that 254 uses and if so would you have any advice on implementing it?

So to clarify, the chassisSpeeds.discetize reduced both skew when applying both a translational speed and rotational speed as well as preventing the rotational drift when driving in a linear line for you guys?

I’m not sure which change did it or if it was a combination of the bunch to be completely honest.

My team has seen this same exact issue.
I think it must be due to the right side drive wheels traveling slower on average than the left side, but as you say even when correcting for this with feedback control its still an issue sometimes.

We’re using MK4i modules with 8 Falcons, however, and wrote the swerve code ourself from examples, utilizing WPILib’s swerve kinematics (in C++).

It seems like it could be something fundamental either in our controls, or a discrepancy in one of the modules, either mechanically or electrically.

I suspect that the original poster is talking about a scenario where the robot inadvertently rotating while attempting to drive in a straight line without rotating. Second order kinematics, a better gyro, and discretization don’t address this scenario - all of those things are intended to improve the outcome of trying to drive in a straight line while intentionally rotating.

My team has made many, many swerve drives and every time we have the same issue that the OP is describing. As much as we’ve tried, we’ve never been able to completely eliminate it. As best as we can tell, it happens when there are subtle electrical or mechanical differences between your modules. For example, if one module accelerates just a tiny bit slower than the rest, or slips a little on startup, or doesn’t have perfect angle calibration, or doesn’t reach the exact same final speed as the others, this will happen.

There are three partial solutions to this problem that we’ve done:

  1. Try very hard to get the output of each motor to be the same. Some System Characterization and manual tuning will help a lot here.
  2. Use software to enforce driving straight. In particular, whenever the driver stops turning intentionally, we capture the current orientation. Then, whenever the driver is not intentionally turning, we run a PID algorithm whose setpoint is the last intentional orientation, whose input is the current orientation provided by the gyro, and whose output is a rotation term that gets added to the kinematics equation.
  3. Ignore it. In my experience, this problem seems to bother programmers more than it actually bothers drivers, who subconsciously compensate for it. This doesn’t help you with autonomous, per se, but if you are trying to turn to a particular angle during autonomous, use 2

We typically implement 1 and 2, or 1 and 3, and it works “well enough”, albeit unsatisfyingly imperfectly.

I have always wondered, though, if the “pro” teams have a better solution to this problem. Does anyone else have any better ideas?

2 Likes

Do you have a code example of creating a PID algorithm for the orientation that I can look at for reference?

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