I’m working on a PID control system for the robot that uses PID to accurately maintain an encoder rate based on joystick inputs, but there’s a really strange issue with one of the motors. Note: Im coding it in java through vscode
@Override
public void execute() {
TargetLeftRate = (speedy.getAsDouble() - speedx.getAsDouble())*Constants.maxWheelRate;
TargetRightRate = (speedy.getAsDouble() + speedx.getAsDouble())*Constants.maxWheelRate;
TargetLeftRate = Math.max(-Constants.maxWheelRate, Math.min(Constants.maxWheelRate, TargetLeftRate));
TargetRightRate = Math.max(-Constants.maxWheelRate, Math.min(Constants.maxWheelRate, TargetRightRate));
leftPID.setSetpoint(TargetLeftRate);
rightPID.setSetpoint(TargetRightRate);
if (Math.abs(TargetLeftRate) - Math.abs(m_drive.getLeftEncoderRate()) < 10) {
leftSpeed = leftSpeed + leftPID.calculate(m_drive.getLeftEncoderRate());
} else{
leftSpeed = TargetLeftRate/Math.abs(TargetLeftRate);
}
if (Math.abs(TargetRightRate) - Math.abs(m_drive.getRightEncoderRate()) < 10) {
rightSpeed = rightSpeed + rightPID.calculate(m_drive.getRightEncoderRate());
} else{
rightSpeed = TargetRightRate/Math.abs(TargetRightRate);
}
m_drive.tankDrive(leftSpeed,rightSpeed);
SmartDashboard.putNumber("DrivePID/LeftEncoderRate", m_drive.getLeftEncoderRate());
SmartDashboard.putNumber("DrivePID/RightEncoderRate", m_drive.getRightEncoderRate());
SmartDashboard.putNumber("DrivePID/TargetLeftRate", TargetLeftRate);
SmartDashboard.putNumber("DrivePID/TargetRightRate", TargetRightRate);
SmartDashboard.putBoolean("DrivePID/PIDinUse?", Math.abs(TargetLeftRate) - Math.abs(m_drive.getLeftEncoderRate()) < 5);
SmartDashboard.putNumber("DrivePID/LeftPID", leftPID.calculate(m_drive.getLeftEncoderRate()));
SmartDashboard.putNumber("DrivePID/RightPID", rightPID.calculate(m_drive.getRightEncoderRate()));
}
// Called once the command ends or is interrupted.
@Override
public void end(boolean interrupted) {
m_drive.tankDrive(0, 0);
}
For testing, I’ve suspended the robot so that both wheels are spinning freely.
When I run the code, the right wheel consistently tracks well and maintains low error in all cases. But the left wheel behaves differently depending on direction:
When both wheels rotate in the same direction, the left wheel also maintains low error.
When the wheels rotate in opposite directions (e.g., turning in place), the left wheel shows significantly higher error.
So essentially, the issue only appears when the left motor is running in the opposite direction to the right motor.
I’m trying to figure out what could cause this kind of asymmetric behavior, whether it’s related to PID tuning, motor characteristics, encoder feedback, or something else in the control logic.
Any ideas or things I should check would be appreciated.
