I am a programmer from Team 599. We’re trying to make our angle motors on our MK4i swerve modules (1 NEO drive motor and 1 NEO angle motor per module) respond accurately to our joystick inputs. We’ve tried using a PID controller attached to our angle motor, but it’s causing the wheels to oscillate back and forth and constantly go past the setpoint. In the setDesiredState method in our SwerveModule.java file, we set angle motors to a percent output of either pos. or neg. 0.1 if the encoder from each motor is outside of a certain range from the angle of the desired state. We’re pretty sure that the error is in the setDesiredState method, but we don’t know exactly where the issue is coming from. Below is the link to our GitHub repo. We appreciate any help you can provide. Thank you!
The branch is MathedJavaBot
The directory to the SwerveModule file is “src → java → SwerveModule.java”
I’llLimelight, an integrated vision coprocessor let others handle the swerve and PID parts of this, but I just wanted to confirm this part was accurate. The NEO550 is NOT a good option for a drive motor. Did you mean a regular NEO?
I did not look at your code. However, we used a NEO550 for steering in 2020 and 2022 so I have some insight on the mechanical side that might be helpful.
Are you measuring the steering angle of the module using the absolute encoder on the module itself? I’m assuming that you also added a gearbox between the motor and the steering belt to reduce the faster speed of the NEO 550 (and increase the torque) to something more suitable for steering.
If these are true of your design, your problem could be with the deadband caused by the gearing backlash. You may want to look at the backlash in your gearing between the motor and the module. Since the NEO550 is an outrunner, you can spin the motor by hand to check this. Spin the motor one direction until you see a change in the absolute encoder. Then, spin the motor in the other direction counting how many rotations of the motor it takes until you see a change in the absolute encoder. This motor rotation is the deadband of the steering. This deadband (in terms of motor encoder angle) is likely larger than the NEO steering motors due to the additional stages of gear reduction that you are likely using with the NEO550.
There are two solutions.
ignore the absolute encoder after you initialize and use the motor encoder for all steering inputs.
increase the tolerance around your setpoint to account for this larger deadband.
Those items above may not be true and it could just be a code issue. I just wanted to throw out a potential aspect of the mechanical system that you may not have accounted for since, based on our experience, this could be your issue.
We’ve been ignoring the absolute encoders and using just the relative encoders in the motors. I’m wondering if using NEOs instead of NEO550s affects the deadband you were talking about.
You’re doing the pid control wrong. Calling the motor set() method sets the output as a percent of supply power, and doesn’t use the configured PID values at all. You need to call setReference of the PID controller object from the motor.
We called the PID controller in line 125 of the SwerveModule file, but we commented the line out and resorted to setting the angle motor to be a certain percent output until the encoder read that the motor position is within a certain range of the angle of the desired state (lines 138-143). Once the motor is within that range, the percent output drops to 0. What ends up happening is that the angle motors will keep running and output readings well past 360 deg, even though our angle readings are coming from a Rotation2D object, which should only be from 0 to 360 deg, if I understand it correctly (the getAngle method).
This is what we use to prevent jittering in a module and setting a target angle to the position controller. Also for your PID Controller, I’ve noticed your kD value might be too high. A high kD value can also cause oscillation and your value is set to 0.05 while your kP is 0.15. 0.05 for kD seems excessive compared to the kP parameter to me. Have you tried setting your kD to 0?
Adding on to this - You are using the MK4i modules, so the turn motor should be inverted. Otherwise you can make your P-value negative, but that doesn’t make sense from a tuning perspective.
Yep. We’ve been setting kD to be 0.0 for most of testing (even with kP being 0.001-0.15). We didn’t see any noticeable change in the wheels’ oscillation, however
Ohhhhhhhhhh. Yeah our angle motors aren’t inverted. From what I’m understanding, not inverting them has made the PID controller act all wonky because it’s tuned to act in a direction different to the motor’s positive direction, which is causing the wheels to oscillate