Swerve Drive Spins Forever

We have a Through Bore Encoder that measures the rotation of the wheels and we have it plugged into the data port on top of the SparkMax motor controller with an absolute adaptor plugged into it. We do have the mode in the motor controller set to Default as the alternative encoder.

The encoder keeps trying to go up to the desired position but after around 55 degrees it returns to 0 and never reaches the desired position, therefore making it spin forever.

  private final SparkAbsoluteEncoder absoluteEncoder;
  absoluteEncoder = turningMotor.getAbsoluteEncoder(SparkAbsoluteEncoder.Type.kDutyCycle);

  driveEncoder.setVelocityConversionFactor(ModuleConstants.DRIVING_ENCODER_VELOCITY_FACTOR);
  turningEncoder.setPositionConversionFactor(ModuleConstants.TURNING_ENCODER_POSITION_FACTOR);
  turningEncoder.setVelocityConversionFactor(ModuleConstants.DRIVING_ENCODER_VELOCITY_FACTOR);

  public void setDesiredState(SwerveModuleState desiredState) {
    // Optimize the reference state to avoid spinning further than 90 degrees
    desiredState.angle = desiredState.angle.plus(new Rotation2d(absoluteEnocderOffet));
    SwerveModuleState state =
        SwerveModuleState.optimize(desiredState, new Rotation2d(getAbsoluteEncoderRad()));
    System.out.println(state.angle);

    // Calculate the drive output from the drive PID controller.
    final double driveOutput =
        drivePIDController.calculate(driveEncoder.getVelocity(), state.speedMetersPerSecond * 2);

    // Calculate the turning motor output from the turning PID controller.
    final double turnOutput =
        turningPIDController.calculate(getAbsoluteEncoderRad(), state.angle.getRadians());

    // Calculate the turning motor output from the turning PID controller
    driveMotor.set(driveOutput);
    turningMotor.set(turnOutput / 5);
  }

  public double getAbsoluteEncoderRad() {
    return Math.toDegrees(absoluteEncoder.getPosition());
  }

Constants:

public static final double DRIVING_ENCODER_VELOCITY_FACTOR = ((WHEEL_DIAMETER_METERS * Math.PI) / DRIVING_MOTOR_REDUCTION) / 60.0;
public static final double TURNING_ENCODER_POSITION_FACTOR =  (Math.PI * 2);
state.angle.getRadians() //returns π/2
getAbsoluteEncoderRad() // returns 90
// 90 != π/2, keep spinning

I think this is your error

IMO, it’s easiest to just leave encoder in rotations, and use state.angle.getRotations. No position conversion factors necessary

Why times 2?

Why divided by 5?

To make the drive wheel faster for times 2 and to slow down the turn wheel for dividing by 5.

For the speed, where you’re doubling it, why not just pass in a desired speed that is what you want? You’re going to pass in a slower value, and the drivetrain is going to run twice as fast, why?

Dividing by 5 for your turning motor seems like an indication that your control loop (PID values) are incorrect.

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