How to make pid controller shutdown after reaching setpoint

My team want to make autonomous in this year but i don’t know how to step into next step using pid controller(for example turn 90 and then go straight 1 m) and stop pid controller

Where is the PID control? In the roborio? In a smart motor controller like a TalonSRX or SparkMax.

Rio:
Sudo code
PidControler1.dissable

TalonSRX:
_talon.set(Controlmode.percentOutput, 0.0);

Are you using command-based? That will make a huge difference in the answers you get.

We’re using Command-based Java, and all of our autonomous routines are SequentialCommandGroups with embedded ParallelRaceGroups. The ParallelRaceGroups are nice because we can take commands that IsFinished return false (like keeping our shooter spinning at speed) and put them in with something that returns true on some target (like Drive Distance <= 1 m). It also allowed us to put timeouts (WaitCommand) in things we think might stall (like a P-only controlled turn with a not-very-aggressive feed forward that could, in theory, never hit the setpoint).

1 Like

If you’re using PIDController, you call the atSetpoint() method to see if the controller thinks you have reached the target. You can adjust the tolerance with the setTolerance method. You can add a tolerance for the target, and you can optionally set a velocity tolerance to make sure the mechanism has settled on the setpoint.

2 Likes

Yes but it should be placed in loop or smth ? When using while(pid.atsetpoint()==false) pid controller code placed in loop don’t work.

while(pid.atSetpoint()==false){

pid.rotate(90);

}

code
public void move(final double setpoint){

final double sed = MathUtil.clamp(pidEncoder.calculate(encoder1.getDistance(),setpoint),-0.7,0.7);

differentialDrive.arcadeDrive(sed, 0);

}

public void rotate(final double setpoint) {

 final double rot = MathUtil.clamp(pid.calculate(ahrs.getYaw(), setpoint), -0.7, 0.7);

differentialDrive.arcadeDrive(0, rot);

}

using comandbased robot

Only thing I want to add is that you will want to ensure a sufficient amount of time has passed after reaching the setpoint before advancing. The reason for this is if your loop overshoots and it needs to correct itself, this will give the loop time to do so. I’d do something like - check if you’re within X% of the setpoint, if you are start a timer, reset that timer if you’re ever not within X% of the setpoint, and once that timer reaches some value advance.

It may actually be logically easier to check your error directly, since that gives you a numerical tolerance of how far off you are.

Never use a while loop in command based robots.

The scheduler calling the execute() method of your command is basically your while loop.

One simple way we get around this is having our PID driving methods return a boolean value whether we are within our tolerance or not. That way, in simplistic terms our commands look like this:

@Overrride 
public void execute(){
    m_isDone = pidsubsystem.drivepid(setpoint);
}

@Override
public boolean isFinished(){
    return m_isDone;
}

That will have your PID command keep executing until your closed loop error is within your tolerance, at which point you can have your PID command end.

1 Like

and after this , put this commands in autonomousPeriodic or autonomousInit?

To do everything you want, you need a sequential command group.

Here is a link to one of our simple sequential command groups.

What that code will do is try to drive from the initiation line to the port wall and shoot our preloaded balls.

So you would need to make a Turn command that will turn your 90 degrees, and your drive 1 meter command, then inside a command group put them together.

In the new command framework, you can even use the convenient builder methods. For example in your RobotContainer’s getAutonomous() method you could do:

    return new Turn90(drivetrain).andThen(new Drive1Meter(drivetrain));

Something along those lines will get you where you need to go.

This is what the velocity tolerance of PIDController is used for, it makes sure you have settled on the setpoint. If you use a timer you would be guessing how much time it will take for oscillation to stop. You’d likely either guess too short, or you’d end up waisting time waiting while the robot is already stable.

Well, not guessing - you would tune the value of this timer based on observed robot performance during testing, the same way you tune things like Izone. But you’re right - the PIDController class accounts for the rate of change as you enter that setpoint tolerance band, I had just forgotten.

2 Likes

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