View Single Post
  #1   Spotlight this post!  
Unread 26-01-2011, 18:39
mikets's Avatar
mikets mikets is offline
Software Engineer
FRC #0492 (Titan Robotics)
Team Role: Mentor
 
Join Date: Jan 2010
Rookie Year: 2008
Location: Bellevue, WA
Posts: 667
mikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of lightmikets is a glorious beacon of light
Re: PID output to a variable

The PID controller in WPIlib has the following constructor:
Code:
PIDController(float p, float i, float d, PIDSource *source, PIDOutput output, float period = 0.05);
It means it takes a PIDSource and a PIDOutput object pointers. In the PID controller object, it periodically calls the PIDGet() function from the PIDSource object to obtain the input value (your encoders) and applies the PID algorithm to calculate the output. Then it calls the PIDWrite() function from the PIDOutput object to write to the motors.
This means you need to provide the PIDSource and PIDOutput objects when creating the PIDController object. The easiest way to do it is to have your IterativeDemo class inheriting both PIDSource and PIDOutput. Essentially, you are saying IterativeDemo is both PIDSource and PIDOutput as well. Then in the IterativeDemo class, you need to implement PIDGet() and PIDWrite().
If you just need to go straight, you need only one PID controller. Something similiar to the following:
Code:
class IterativeDemo : public IterativeRobot, public PIDSource, public PIDOutput
{
    ...
    double PIDGet()
    {
        return (leftEncoder->GetDistance() + rightEncoder->GetDistance())/2;
    }
 
    void PIDWrite(float output)
    {
        myRobot->TankDrive(output, output);
    }
 
    //
    // Constructor
    //
    IterativeDemo()
    {
        leftEncoder = new PIDEncoder(7,8,true,Encoder::k4X);
        leftEncoder->SetDistancePerPulse(???);
        rightEncoder = new PIDEncoder(9,10,true,Encoder::k4X);
        rightEncoder->SetDistancePerPulse(???);
        driveControl = new PIDController(0.1, 0.01, 0.001, this, this);
        ...
    }
 
    void AutonomousInit()
    {
        driveControl->Enabled();
    }
 
    void AutonomousPeriodic()
    {
        driveControl->SetSetpoint(18);
    }
}
Now if you also want to do PID control turn, that's a lot more challenging
You then need two PID controllers and they are not independent of each other.
__________________

Last edited by mikets : 26-01-2011 at 18:53.
Reply With Quote