Issues with NEO Angle Motor Rotation for Swerve

Hello,

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’ll 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?

2 Likes

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.

  1. ignore the absolute encoder after you initialize and use the motor encoder for all steering inputs.
  2. 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.

Good luck.

1 Like

Yes I did. Thank you for clarifying that. I’ll change it in the post.

This sounds like the P coefficient of the PID controller is too high.

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.

We’ve been going between 0.001 and 0.15, but for some reason we still get the same oscillation no matter what our P-value is.

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.

See: SparkMaxPIDController (FRC-REVLib API)

You should do this for both drive and spin to use the built in pid controllers

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).

It might be an inversion issue. For our team, our swerve angle motors always oscillate whenever there is a bad invert.

1 Like
Rotation2d angle =
      (Math.abs(desiredState.speedMetersPerSecond) <= (Constants.Swerve.maxSpeed * 0.01)) ?
      getAngle() : 
      desiredState.angle;

    angleController.setReference(angle.getDegrees(), ControlType.kPosition);

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.

1 Like

you know ayush a video would really help yk

I’ll get one today

1 Like

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

Update:

  • We inverted the angle motors and implemented a PID controller in the turning.
  • I set kD to 0.0
  • The SparkMax for the Back-Right angle motor says it’s not connected, even though the motor still moves
  • Forward and backward motion work but when moving left or right, the wheels neither drive nor rotate
  • With rotation, the wheels spin for a while but eventually get to what looks to be the correct position
  • The Back-Right motor sometimes doesn’t drive
  • I have a video of the wheels but am not sure how to post it on here

All the new code is in the same branch as before and in the SwerveModule.java file

Ah, makes sense. Thanks!

video

Latest update Video

problem we are still having

  1. When reaching a setpoint, the angle motors turn too much and complete multiple revolutions before settling in the desired position.
1 Like