View Single Post
  #2   Spotlight this post!  
Unread 05-04-2010, 10:52
Jared Russell's Avatar
Jared Russell Jared Russell is online now
Taking a year (mostly) off
FRC #0254 (The Cheesy Poofs), FRC #0341 (Miss Daisy)
Team Role: Engineer
 
Join Date: Nov 2002
Rookie Year: 2001
Location: San Francisco, CA
Posts: 3,077
Jared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond reputeJared Russell has a reputation beyond repute
Re: Encoder with PIDController Help

Your understanding of PIDController seems to be correct - it takes PIDSources, crunches the numbers in a separate thread, and asynchronously writes to PIDOutputs.

What makes this tricky is that the WPILib PIDController writes its output to a PIDOutput, but RobotDrive does not implement PIDOutput. Likewise, Encoder doesn't implement PIDSource (because it would be ambiguous to do so - do you want to measure speed or distance?).

There are several possible solutions to this problem.

First, we need to turn the encoder's distance measurement into a PIDSource. You could re-write the WPILib Encoder class, but in general I try not to mess with a library unless I absolutely need to. Instead, how about a wrapper class?

Code:
class DistanceEncoder extends PIDSource
{
public:
  DistanceEncoder(Encoder *baseEncoder)
  {
    m_baseEncoder = baseEncoder;
  {

  double pidGet()
  {
    return m_baseEncoder->GetDistance();
  }

private:
  Encoder* m_baseEncoder;
};
Similarly, you can wrap RobotDrive in another PIDOutput class:

Code:
class RobotDriveOutput extends PIDOutput
{
public:
  RobotDriveOutput(RobotDrive* baseDrive)
  {
    m_baseDrive = baseDrive;
  }

  void pidWrite(double output)
  {
    m_baseDrive->Drive(output, 0.0);
  }

private:
  RobotDrive* m_baseDrive;
};
Then you can put it all together like you said.

*Note: there are many ways to do this; this is only one. Also, I banged out the above code from memory, so there might be syntax and/or API errors, but you should get the point.
Reply With Quote