Go to Post Engineering literature? Is that like jumbo shrimp, military intelligence, or legal brief? You know, an oxymoron? - Richard Wallace [more]
Home
Go Back   Chief Delphi > Technical > Programming > Java
CD-Media   CD-Spy  
portal register members calendar search Today's Posts Mark Forums Read FAQ rules

 
Reply
Thread Tools Rating: Thread Rating: 46 votes, 5.00 average. Display Modes
  #1   Spotlight this post!  
Unread 12-05-2014, 11:46
ArzaanK ArzaanK is offline
Registered User
FRC #1325 (Inverse Paradox)
Team Role: Programmer
 
Join Date: Jan 2013
Rookie Year: 2012
Location: Mississauga, Ontario, Canada
Posts: 40
ArzaanK is an unknown quantity at this point
Turning Robot with PID Feedback from Gyro

Hello Chief Delphi.

For our planned off season events, our team would like to be able to use a gyroscope to turn our robot via a PID loop. We have got the gyro to work, but we cannot get the PID loop to work. The robot continuously turns, not stopping at the desired setpoint.

We confirmed the gyro works to our standard by making a command that prints the robots heading to the SmartDashboard.

The code that we are using for the PID Loop was mostly auto generated by Robot builder with a few exceptions, which are:

-The "setAbsoluteTolerance" is given a value of 3.0,
-The "returnPIDInput" function returns the getAngle() method instead of the
pidGet() method. (I'm not exactly sure what the pidGet() method does).
-The "usePIDOutput" function controls all six of our drive motors.

Please see the code posted below:

DriveTrain.java (The PID subsystem file).
Code:
package org.usfirst.frc1325.DrivetrainWithPIDControl.subsystems;
import org.usfirst.frc1325.DrivetrainWithPIDControl.RobotMap;
import org.usfirst.frc1325.DrivetrainWithPIDControl.commands.*;
import edu.wpi.first.wpilibj.*;
import edu.wpi.first.wpilibj.command.PIDSubsystem;
import edu.wpi.first.wpilibj.livewindow.LiveWindow;
/**
 *
 */
public class DriveTrain extends PIDSubsystem {
    
    SpeedController frontRight = RobotMap.driveTrainFrontRight;
    SpeedController middleRight = RobotMap.driveTrainMiddleRight;
    SpeedController rearRight = RobotMap.driveTrainRearRight;
    SpeedController frontLeft = RobotMap.driveTrainFrontLeft;
    SpeedController middleLeft = RobotMap.driveTrainMiddleLeft;
    SpeedController rearLeft = RobotMap.driveTrainRearLeft;
    Gyro gyro = RobotMap.driveTrainGyro;
    
    public DriveTrain() {
       
        super("DriveTrain", 1.0, 0.0, 0.0);
        setAbsoluteTolerance(3.0);
        getPIDController().setContinuous(false);
        LiveWindow.addActuator("Drive Train", "PIDSubsystem Controller", getPIDController());
    
    }
    
    public void initDefaultCommand() {
    
        // Set the default command for a subsystem here.
        //setDefaultCommand(new MySpecialCommand());
    }
    public double getGyroAngle(){
        return gyro.getAngle();
    }
    public void resetGyro(){
        gyro.reset();
    }
    protected double returnPIDInput() {
        // Return your input value for the PID loop
        // e.g. a sensor, like a potentiometer:
        // yourPot.getAverageVoltage() / kYourMaxVoltage
        return gyro.getAngle();
    }
    
    protected void usePIDOutput(double output) {
        // Use output to drive your system, like a motor
        // e.g. yourMotor.set(output);
        frontRight.pidWrite(output);
        middleRight.pidWrite(output);
        rearRight.pidWrite(output);
        frontLeft.pidWrite(output);
        middleLeft.pidWrite(output);
        rearLeft.pidWrite(output);
    }
}
TurnRobot.java (The setpoint command)

Code:

package org.usfirst.frc1325.DrivetrainWithPIDControl.commands;

import edu.wpi.first.wpilibj.command.Command;
import org.usfirst.frc1325.DrivetrainWithPIDControl.Robot;

/**
 *
 */
public class  TurnRobot extends Command {

    public TurnRobot() {
        // BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=REQUIRES
        requires(Robot.driveTrain);
        // END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=REQUIRES
    }

    // Called just before this Command runs the first time
    protected void initialize() {
        // BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=INITIALIZE
        Robot.driveTrain.enable();
        Robot.driveTrain.setSetpoint(-90.0);
        // END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=INITIALIZE
    }

    // Called repeatedly when this Command is scheduled to run
    protected void execute() {
    }

    // Make this return true when this Command no longer needs to run execute()
    protected boolean isFinished() {
        // BEGIN AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=ISFINISHED
        return Robot.driveTrain.onTarget();
        // END AUTOGENERATED CODE, SOURCE=ROBOTBUILDER ID=ISFINISHED
    }

    // Called once after isFinished returns true
    protected void end() {
        Robot.driveTrain.disable();
    }

    // Called when another command which requires one or more of the same
    // subsystems is scheduled to run
    protected void interrupted() {
        end();
        
    }
}
If any of you see any problems, or have any suggestions to get our PID loop working, we would greatly appreciate it.

Thanks,
__________________
Arzaan Khairulla
Programmer/Driver
2013 Greater Toronto Regional East Winners with 1114 and 2056
2013 Galileo Division

Last edited by ArzaanK : 12-05-2014 at 11:57. Reason: Accidentally posted wrong code.
Reply With Quote
  #2   Spotlight this post!  
Unread 12-05-2014, 11:50
notmattlythgoe's Avatar
notmattlythgoe notmattlythgoe is online now
Flywheel Police
AKA: Matthew Lythgoe
FRC #2363 (Triple Helix)
Team Role: Mentor
 
Join Date: Feb 2010
Rookie Year: 2009
Location: Newport News, VA
Posts: 1,722
notmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond repute
Re: Turning Robot with PID Feedback from Gyro

You posted the subsystem in both sets of code instead of the command in the second one.
Reply With Quote
  #3   Spotlight this post!  
Unread 12-05-2014, 11:58
ArzaanK ArzaanK is offline
Registered User
FRC #1325 (Inverse Paradox)
Team Role: Programmer
 
Join Date: Jan 2013
Rookie Year: 2012
Location: Mississauga, Ontario, Canada
Posts: 40
ArzaanK is an unknown quantity at this point
Re: Turning Robot with PID Feedback from Gyro

I fixed the problem. Thanks notmattlythgoe.
__________________
Arzaan Khairulla
Programmer/Driver
2013 Greater Toronto Regional East Winners with 1114 and 2056
2013 Galileo Division
Reply With Quote
  #4   Spotlight this post!  
Unread 12-05-2014, 12:31
notmattlythgoe's Avatar
notmattlythgoe notmattlythgoe is online now
Flywheel Police
AKA: Matthew Lythgoe
FRC #2363 (Triple Helix)
Team Role: Mentor
 
Join Date: Feb 2010
Rookie Year: 2009
Location: Newport News, VA
Posts: 1,722
notmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond reputenotmattlythgoe has a reputation beyond repute
Re: Turning Robot with PID Feedback from Gyro

Have you tried printing the angle from the returnPIDInput() method?

Could you be turning the opposite direction that you want to be? If you turn right and that causes the angle to count up you'll never get to -90. You'll probably also want to set your setpoint to something like

Code:
Robot.driveTrain.setSetpoint(-90.0 + Robot.driveTrain.getGyroAngle());
That way it'll always turn 90 degrees from your currently angle.
Reply With Quote
  #5   Spotlight this post!  
Unread 12-05-2014, 14:01
Thad House Thad House is offline
Volunteer, WPILib Contributor
no team (Waiting for 2021)
Team Role: Mentor
 
Join Date: Feb 2011
Rookie Year: 2010
Location: Thousand Oaks, California
Posts: 1,099
Thad House has a reputation beyond reputeThad House has a reputation beyond reputeThad House has a reputation beyond reputeThad House has a reputation beyond reputeThad House has a reputation beyond reputeThad House has a reputation beyond reputeThad House has a reputation beyond reputeThad House has a reputation beyond reputeThad House has a reputation beyond reputeThad House has a reputation beyond reputeThad House has a reputation beyond repute
Re: Turning Robot with PID Feedback from Gyro

It's been a while since I've done a PID loop for a drivetrain, but I think with a P of 1.0 your drive will always be turning at full power. That is because the drive accepts an input from -1 to 1, and the PID loop starts by multiplying the error by the P, which will make the output be greater then 1 whenever you are more then 1 degree off. Also, you do need to limit the PID output to be between -1 and 1 because thats the range motor outputs want.

Most likely the robot is turning the wrong way compared to the Gyro, just like notmattlythgoe said. To fix this you could return the negative gyro output, or reverse the PID output.
__________________
All statements made are my own and not the feelings of any of my affiliated teams.
Teams 1510 and 2898 - Student 2010-2012
Team 4488 - Mentor 2013-2016
Co-developer of RobotDotNet, a .NET port of the WPILib.
Reply With Quote
  #6   Spotlight this post!  
Unread 12-05-2014, 14:01
krieck's Avatar
krieck krieck is offline
Registered User
AKA: Keith
FRC #2846 (Firebears)
Team Role: Mentor
 
Join Date: Jan 2012
Rookie Year: 2012
Location: Minnesota
Posts: 49
krieck is an unknown quantity at this point
Re: Turning Robot with PID Feedback from Gyro

Inside the DriveTrain class, you should probably set "continuous" to "true". This indicates that when the PID input goes below its minimum, it rolls over to the maximum value.
Reply With Quote
  #7   Spotlight this post!  
Unread 12-05-2014, 14:27
ArzaanK ArzaanK is offline
Registered User
FRC #1325 (Inverse Paradox)
Team Role: Programmer
 
Join Date: Jan 2013
Rookie Year: 2012
Location: Mississauga, Ontario, Canada
Posts: 40
ArzaanK is an unknown quantity at this point
Re: Turning Robot with PID Feedback from Gyro

Quote:
Have you tried printing the angle from the returnPIDInput() method?
Could you be turning the opposite direction that you want to be? If you turn right and that causes the angle to count up you'll never get to -90.
Our robot turns left when the PID Loop is enabled giving us negative angles. (This is why the gyro was set to -90.0 instead of 90.0). Also, after I disabled the PID command, I checked the reading on the gyro (I have a button on the dashboard that prints out the Gyro Angle), it was somewhere around -1000 degrees. However, I will try printing the angle from the returnPIDInput() method to see what angles I get.

Quote:
a P of 1.0 your drive will always be turning at full power.
I will take that into account. So if I want the robot to turn at half speed I set P to 0.5, correct?
__________________
Arzaan Khairulla
Programmer/Driver
2013 Greater Toronto Regional East Winners with 1114 and 2056
2013 Galileo Division
Reply With Quote
  #8   Spotlight this post!  
Unread 12-05-2014, 14:47
Jared Russell's Avatar
Jared Russell Jared Russell is offline
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,078
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: Turning Robot with PID Feedback from Gyro

Quote:
Originally Posted by ArzaanK View Post
I will take that into account. So if I want the robot to turn at half speed I set P to 0.5, correct?
PID gains have real world units attached to them. They aren't just made up numbers.

Consider a simple P controller. It has the form:

Code:
output = Kp * error
What are the units of Kp? Rearrange the equation.

Code:
Kp = output / error
So Kp is a ratio between your output (in this case, the "turn" power from -1 to 1) and your error (in this case, degrees).

Commanding an output of -1 or +1 is like commanding a full speed turn with your joysticks during teleop. For most robots, that's probably pretty fast. Probably way, way too fast to accurately turn only 1 degree.

I would start with a really tiny gain and then move up from there. Try (1/90) or so. This would give full power when you are 90 degrees (or more) off of your goal, half power at 45 degrees off, etc.

What you will likely see is that your robot moves in the general direction of your goal, but stops a little short or overshoots a bit. At this point, you can try upping your P gain, or adding Ki or Kd gains (and by the way, the same principle applies: These gains also have units, and their units involve time as well). You may also find that limiting the maximum output of your PID controller is necessary to prevent overshoots (for example, no matter what, never go more than 50% of top speed).
Reply With Quote
Reply


Thread Tools
Display Modes Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump


All times are GMT -5. The time now is 12:55.

The Chief Delphi Forums are sponsored by Innovation First International, Inc.


Powered by vBulletin® Version 3.6.4
Copyright ©2000 - 2017, Jelsoft Enterprises Ltd.
Copyright © Chief Delphi