NavX: Trying to rotate to angle without PID


             double turnDegrees = ahrs->GetYaw();
      
             while(codriver.GetRawButton(12) == 1)
             {
            	 if(turnDegrees > -10 && turnDegrees < 10 && centered == FALSE )
            	 {
            		 myRobot.Drive(0.0, 0.0);
            		 centered = TRUE;

            	 }
            	 else if (turnDegrees < -11 && turnDegrees > -180 && centered == FALSE)
            	 {
            		 myRobot.Drive(0.4, 1.0);
            		 centered = FALSE;
            	 }
            	 else if (turnDegrees > 11 && turnDegrees < 180 && centered == FALSE)
            	 {
            		 myRobot.Drive(-0.4, 1.0);
            		 centered = FALSE;
            	 }
             }

This is code I have come up with so far any suggestions would help.
Thank You!!

What’s wrong with it and why don’t you want to use PID?

Nothing, we just cant mount encoders on the drive train or use Talon SRX’s to get that feedback.

You can do PID without encoders. PID only requires a feedback, the source of which can be any kind of sensor, including a gyroscope. The NavX has an example for this kind of thing here

When trying to call it in RobotInit it throws an error saying

PIDController.h:39:3: note: no known conversion for argument 6 from ‘Robot*’ to ‘PIDOutput*’
PIDController.h:37:3: note: PIDController::PIDController(float, float, float, PIDSource*, PIDOutput*, float)
PIDController(float p, float i, float d, PIDSource *source, PIDOutput *output,
^
PIDController.h:37:3: note: candidate expects 6 arguments, 7 provided

This is how I call it

turnController = new PIDController(kP, kI, kD, kF, ahrs, this, period = .05);

It looks like argument 6 is out of place. You’re using “this” in robotinit, which from the error message I assume passes an object of type Robot. I don’t think you want that there, considering PIDController is looking for a float. You also have 7 arguments where there should be 6, which makes me think you have an extra argument in there. What is kF? argument 4 should be of type PIDSource.

kF is the optional constructor for the feed forward constant

I pushed the NavX rotate to angle example to my code but now i’m receiving another error. No matter what I put in the PIDOutput space it is coming out as not being able to convert it.


RobotDrive myRobot;

turnController = new PIDController(kP, kI, kD, ahrs, myRobot);

Based on the error message, I would say something is preventing it from overloading properly then.

Can you post your code, and the error message? Please keep in mind that in order for this to work, myRobot needs to implement the PIDOutput interface, so my best guess is myRobot is an instance of a class which does not implement the PIDOutput interface - but it’s hard to tell with only this information.

I’m pretty sure there is a turn to angle example with the navx
http://www.pdocs.kauailabs.com/navx-mxp/examples/

You can either create a new tiny class specifically to be used as your PIDOutput class, or you can have your robot class be that class too by using a line like this on your Robot class definition.

public class Robot extends SampleRobot implements PIDOutput {

Then you need to implement pidWrite() which tells the PID what you want to do with the output.

In your case, copying a line from above I assume you will want this:

@Override
  /* This function is invoked periodically by the PID Controller, */
  /* based upon navX-MXP yaw angle input and PID Coefficients.    */
  
public void pidWrite(double output) {
      Drive( output, 1.0 );
}

If the error between your setpoint and the gyro angle was 90 degrees or more you would want full 1.0 power, so I would start with a P constant of 1.0 / 90. So 0.01 should be a good starting place.

When you set your gyro up, here are some other suggestions straight from their example:


      turnController.setInputRange(-180.0f,  180.0f);
      turnController.setOutputRange(-1.0, 1.0);
      turnController.setAbsoluteTolerance(2.0);
      turnController.setContinuous(true);

Last, if you are trying to go to 0, then call

turnController.setSetpoint( 0.0 );

and to turn the controller on use,

turnController.enable();

I have since fixed the problem, I needed to add the PIDOutput class in my code.
What I had to put:

Class Robot: public PIDOutput, public Sample Robot