MK3 Swerve Robot Not Field-Oriented. Possible Sensor?

Hey everyone, our Robot has been experiencing a problem where it is not driving in its typical field-oriented control, instead driving robot-relative. I have deployed different previously working versions of our source code on the robot, to no avail.

We are using the Swerve Drive Specialties Mk3 System, with a CTRE MAG Absolute Encoder to track the wheel’s rotation and processing it.

Here is some of our code:

    // NOTE: This is a SwerveModuleState for each individual wheel. The 
    // rotationPWMEncoder is the CTRE encoder that tracks the rotation of 
    // the wheel and processes it. 
    public Rotation2d getTurnAngle() {
        return new Rotation2d(turnAngleRadians());
    }

    public double turnAngleRadians() {
        return offset + (rotationPWMEncoder.get() * 2 * Math.PI);
    }

    public Rotation2d getTurnAngle() {
        return new Rotation2d(turnAngleRadians());
    }

    public void setState(SwerveModuleState state) {
        state = SwerveModuleState.optimize(state, getTurnAngle());

        double turnPower = turnController.calculate(
                turnAngleRadians(),
                state.angle.getRadians()
        );

        driveMotor.set(state.speedMetersPerSecond * errorFactor);
        turnMotor.set(turnPower);
    }

It appears that the sensors are plugged into the correct ports, and the robot did have loctite installed previously. Did anyone else experience something similar to this?

We would have a similar problem when our gyro would lose power.

That could be an interesting possibility for our robot. Maybe our gyro is not reading the correct values? I did test the turning wheels encoders and they seem to read fine so I could try to monitor that too.

Field vs Robot relative would have nothing to do with the encoders on the modules but the gyro used to measure the angle.

Is there any specific way to test if the gyro is functioning correctly? Or should I just put the output from getAngle() to the Dashboard.

Output the gyro’s reported angle to SmartDashboard (you can also use the odometry rotation to get a properly-offset value). Rotate the robot in easy-to-see increments like 90 degrees. See if the output angle’s change and the change on SmartDashboard match.

Hey everyone, I am very sorry for the lack of replies from me. I have not had many opportunities to really test the robot.

After researching the code, our robot doesn’t use any gyroscope readings to actually process which direction it should be turning, instead it is completely relying on the DutyCycleEncoder class, connected to CTRE Absolute Mag Encoders.

After testing the various sensors, all of the wheel encoders are reading values while the Robot is in operation, however the robot is still not driving in field-oriented. I have tried different versions of the code that was once working, with nothing still working.

I am confused on what could cause the Robot to stop driving field-oriented almost out of nowhere. Is there some kind of calibration that needs to be done on the encoders? We had a similar issue where the encoders were working in field-oriented, however they were reading very inaccurate thus causing us to put lock-tite on them.

Has anybody else had similar issues?
Thanks

So you are measuring the angle the robot is facing using the encoders only?

Yes, the turning power of the motor is influenced by the PIDController with the turning angle being calculated from the wheel rotation PWM encoder

Right so each module is using one encoder for its own angle and one for the wheel speed. But that wouldn’t change if the robot is field oriented or not. Field oriented would change how the robot moved based on the angle the entire robot is facing, I can see from the code you posted earlier that is the code for the module. But there should be some code where you create the 4 modules and that is usually where you can set it to be field oriented or not and where it get its input from the gyro to find the angle the entire robot is facing, not the angle of each module.

This is where we control if we are field oriented or not in our SwerveDrive Class.
The this.getRotation2d() gets our gyro angle.

public void drive(double xSpeed, double ySpeed, double turningSpeed){
ChassisSpeeds chassisSpeeds;

xSpeed *= DriveConstants.kTeleDriveMaxSpeedMetersPerSecond;
ySpeed *= DriveConstants.kTeleDriveMaxSpeedMetersPerSecond;

turningSpeed *= DriveConstants.kTeleDriveMaxAngularSpeedRadiansPerSecond;
if (this.isFieldOriented) {
  // Relative to field
  chassisSpeeds = ChassisSpeeds.fromFieldRelativeSpeeds(
      xSpeed, ySpeed, turningSpeed, this.getRotation2d());
} else {
  // Relative to robot
  chassisSpeeds = new ChassisSpeeds(xSpeed, ySpeed, turningSpeed);
}

// 5. Convert chassis speeds to individual module states
SwerveModuleState[] moduleStates = DriveConstants.kDriveKinematics.toSwerveModuleStates(chassisSpeeds);

// 6. Output each module states to wheels
this.setModuleStates(moduleStates);
}

In your code with the chassisSpeeds = ChassisSpeeds.fromFieldRelativeSpeeds( xSpeed, ySpeed, turningSpeed, this.getRotation2d()); part, was the getRotation2D call from a gyroscope, or is it always zero. In our code, we were using the same method, but instead of using getRotation2d we were using a constant zero degree angle.

Robot.swerveDrive.setDefaultCommand(new ArcadeDriveCommand(() ->
                ChassisSpeeds.fromFieldRelativeSpeeds(
                        deadzone(xyStick.getX(), Constants.Chassis.DRIVE_DEAD_ZONE),
                        -deadzone(xyStick.getY(), Constants.Chassis.DRIVE_DEAD_ZONE),
                        -deadzone(zStick.getTwist(), Constants.Chassis.DRIVE_DEAD_ZONE),
                        Rotation2d.fromDegrees(0)
                )
        ));
1 Like

Its the gyro, it needs to know where the gyro is facing in order to convert it to field relative.

1 Like

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