PID controller with VictorSPX

hi guys, I’m working in a PID controller for a victor spx I just want to know which variables I’m missing to complete it.
intake_Motor.getPIDConfigs(new VictorSPXPIDSetConfiguration() );

intake_Motor.config_kP(0, kP); 

intake_Motor.config_kI(1, kI);

intake_Motor.config_kD(2, kD);

intake_Motor.config_IntegralZone(3, kIz);

intake_Motor.config_kF(4, kFF); 

intake_Motor.configClosedLoopPeakOutput(5, 0.5);

A few generic questions to start:

  1. Posting the entirety of the code (preferably in a github repo) will likely be necessary.
  2. Have you looked into the examples for the victor SPX product page? If so, which one is most similar to your situation?
  3. Can you describe the mechanism or drivetrain you’re looking to control?
  4. What is the behavior you are seeing in the system that you do not expect?

More specifically to the code you posted:

  1. What values are you specifically using for your k* gains?
  2. Why are you using slotID’s 0, 1, 2, 3, 4, and 5?

this motor is for the intake mecanism, what I saw is that to take balls, there is a moment where the mecanism can’t take the balls naymore or it have problems to take it.
mmm no I think I haven’t seen it.
this are the values I’m using: private double kP = 1, kI = 0, kD = 0.15, kFF = 0.000015, kMaxOutput = -0.6, kMinOutput = -0.6, maxRPM = 10000;
int kIz = 0;
And I don’t know why but when I put a code in github the othere users can’t see it, however here is the subsystem.
public class Intake extends Subsystem {

private DoubleSolenoid solenoid;

private VictorSPX intake_Motor;

private VictorSPX hopper_Motor1;

private VictorSPX hopper_Motor2;

private double kP = 1, kI = 0, kD = 0.15, kFF = 0.000015, kMaxOutput = -0.6, kMinOutput = -0.6, maxRPM = 10000;

int kIz = 0;

@Override

protected void initDefaultCommand() {

}

public Intake(){

solenoid = RobotMap.doubleSolenoid; 

intake_Motor = RobotMap.intake_MotorVictorSPX; 

hopper_Motor1 = RobotMap.hopper_Motor1Spx; 

hopper_Motor2 = RobotMap.hopper_Motor2Spx; 

intake_Motor.getPIDConfigs(new VictorSPXPIDSetConfiguration() );

intake_Motor.config_kP(0, kP); 

intake_Motor.config_kI(1, kI);

intake_Motor.config_kD(2, kD);

intake_Motor.config_IntegralZone(3, kIz);

intake_Motor.config_kF(4, kFF); 

intake_Motor.configClosedLoopPeakOutput(5, 0.5); 

}

public void take(){

solenoid.set(Value.kForward);

}

public void stop(){

intake_Motor.set(ControlMode.PercentOutput, 0);

}

}

The documentation for the Phoenix library is here: https://phoenix-documentation.readthedocs.io/en/latest/index.html

There are a number of code examples here (Java): https://github.com/CrossTheRoadElec/Phoenix-Examples-Languages/tree/master/Java%20General

Something that I haven’t seen you identify yet, is what your sensor source for measuring the mechanisms position/velocity is. This is an important component for your closed loop controller.

Here’s the CTRE example for a PID based Speed Controller: https://github.com/CrossTheRoadElec/Phoenix-Examples-Languages/blob/master/Java%20General/VelocityClosedLoop/src/main/java/frc/robot/Robot.java

If you notice there’s a section where the motor controller’s feedback sensor is defined. This is how the controller knows how its outputs relate to the desired commanded speed/position.

/* Config sensor used for Primary PID [Velocity] */
 _talon.configSelectedFeedbackSensor(FeedbackDevice.CTRE_MagEncoder_Relative,
                                        Constants.kPIDLoopIdx, 
                                        Constants.kTimeoutMs);

This example uses a TalonSRX with a CTRE MagEncoder wired straight into it.
The VictorSPX your code is utilizing doesn’t have a port on it like the TalonSRX which would allow you to wire an encoder into it.

So your encoder is going to need to be wired into some other CTRE device on the network, or directly into the RIO. If it’s wired into the RIO, the PID controller running locally on the motor controller can’t use it as a data source, and you’ll instead need to write you PID controller on the RIO (not running on the motor controller itself), and just update the motor controller in a PercentOutput manner. The easiest way to get off the ground w/ running your closed loop controller on the RIO is to use the PID classes in WPILib.

There’s a bunch of information on running PID controllers on the RIO, using the WPILib libraries, here:

The advantage of running the close-loop controller on the motor controller is that it offloads some of the work from the roboRIO, and the motor controller has a much faster loop interval - so it’s able to correct for errors as they develop much more quickly.
Running the PID controller on the RIO will likely work fine for your application (speed control of an intake roller).

1 Like

okey thanks