Hi! We’re running onboard motion magic control on our swerve motors. I’m using the onboard units and have configured the allowable closed loop error to be 1 degree or 72 sensor units (confirmed via Phoenix Tuner). However, the motors still twitch even when within that tolerance. Changing the tolerance to make it bigger doesn’t change the twitching, but it does make the motors stop within a greater tolerance (ie the twitching happens near setpoint ±error – within the error band). I’m not sure if I’m misunderstanding what ConfigAllowableClosedLoopError does – how can I make them not twitch within the tolerance?
The code is here: https://github.com/team2485/frc-2022/blob/develop/src/main/java/frc/robot/subsystems/drive/SwerveModule.java
Here’s all the motor configs:
turningMotorConfig.voltageCompSaturation = Constants.kNominalVoltage;
turningMotorConfig.supplyCurrLimit.currentLimit = kTurningCurrentLimitAmps;
turningMotorConfig.supplyCurrLimit.enable = true;
turningMotorConfig.slot0.kP = kPTurning;
turningMotorConfig.slot0.kD = kDTurning;
turningMotorConfig.slot0.kF = kFTurning;
turningMotorConfig.motionCruiseVelocity = kModuleMaxSpeedTurningPulsesPer100Ms;
turningMotorConfig.motionAcceleration = kModuleMaxAccelerationTurningPulsesPer100MsSquared;
this.m_turningMotor = new WL_TalonFX(turningMotorID);
m_turningMotor.configAllSettings(turningMotorConfig);
m_turningMotor.enableVoltageCompensation(true);
m_turningMotor.configSelectedFeedbackSensor(
TalonFXFeedbackDevice.IntegratedSensor, 0, Constants.kCANTimeoutMs);
m_turningMotor.configIntegratedSensorAbsoluteRange(
AbsoluteSensorRange.Signed_PlusMinus180, Constants.kCANTimeoutMs);
m_turningMotor.setNeutralMode(NeutralMode.Brake);
m_turningMotor.configAllowableClosedloopError(
0, Units.degreesToRadians(1) / kTurningRadiansPerPulse, Constants.kCANTimeoutMs);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_1_General, 255);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_2_Feedback0, 20);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_4_AinTempVbat, 255);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_6_Misc, 255);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_7_CommStatus, 255);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_8_PulseWidth, 255);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_9_MotProfBuffer, 255);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_10_MotionMagic, 255);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_10_Targets, 255);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_11_UartGadgeteer, 255);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_12_Feedback1, 255);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_13_Base_PIDF0, 255);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_14_Turn_PIDF1, 255);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_15_FirmwareApiStatus, 255);
m_turningMotor.setStatusFramePeriod(StatusFrameEnhanced.Status_Brushless_Current, 255);