Greetings, all.
My team has requested that we programmers code an automated lift this year, because of the fine control required to consistently pick up totes during a match. We decided to use a PID control loop, since it would help us hone in on the positions we want on the lift, and consistently reach those positions.
However, once the lift reaches that spot, I have it cut off, to prevent it from oscillating back and forth around the spot. Unfortunately, this has a side effect of having the lift fall down under the weight of the totes. Is there a way to fix this, code-wise?
Finally, I personally have been wrestling with automation and PID control for all 4 years of my time on the team, and I still have trouble implementing it. I understand (most) of the logic behind it, but I am only somewhat familiar with the calculus behind it, and any help in actually writing a PID loop into a program would be incredibly useful.
For reference:
We code in C++.
The lift uses one Talon SR speed controller.
The PID loop receives input from a 10-turn potentiometer, and outputs to the motor.
Code:
Talon *lifter = new Talon(6); //lift motor
AnalogPotentiometer *pot = new AnalogPotentiometer(0, 360, 0); //potentiometer
PIDController *autolift = new PIDController(0,1, 0.001, 0.0, pot, lifter); //PID controller
void LiftParameters() //sets parameters for the lift PID control loop
{
autolift->SetAbsoluteTolerance(0.5);
autolift->SetOutputRange(0.4, -0.4);
autolift->SetSetpoint(325.0);
}
void PLift() //PID control loop for automating the lift
{
if(rstick->GetRawButton(1))
{
PID = true;
autolift->SetOutputRange(0.4, -0.4);
autolift->Enable();
autolift->SetSetpoint(325.0); //ground level
//lift = true;
}
else if(rstick->GetRawButton(2))
{
PID = true;
autolift->SetOutputRange(0.4, -0.4);
autolift->Enable();
autolift->SetSetpoint(234.0); //1st position
}
else if(rstick->GetRawButton(3))
{
PID = true;
autolift->SetOutputRange(0.4, -0.4);
autolift->Enable();
autolift->SetSetpoint(300.0); //second position
}
else if(rstick->GetRawButton(4))
{
PID = true;
autolift->SetOutputRange(0.4, -0.4);
autolift->Enable();
autolift->SetSetpoint(340.0); //third position
}
if(autolift->OnTarget())
{
autolift->Disable();
autolift->SetOutputRange(0.25, -0.25);
PID = false;
}
if(rstick->GetRawButton(9))
{
autolift->Disable();
PID = false;
}
}