How to program Encoders with PID Subsystem

We need help programming our encoders with a PID subsystem because of lack of documentation. We intend to use the encoders for our drive train PID subsystem.

Will you be hooking them up directly to your roboRIO or to a talon SRX?

**What motor controllers will you be using?

Will you be commanding them with CAN or PWM?

What part number encoder?

What type of drive train?

Are you trying to control wheel speed or wheel distance?

Is this for autonomous, Teleop, or both?**

We will be plugging them into the roboRio and we will be using Victors and controlling them with a pwm connections. We will be using a H-drive train system and we want to be able to control the wheel distance and possible the wheel speed. This is for both teleop and autonomous. We are using the am-0180 Andy Mark Encoders.

Good detail.

Do you have specific questions about PID, or do you just need some links to general information?

If we could get both general information and specific help that would be great. We have created an encoder object in our PID subsystem drive train, for testing purposes we have only created one and we are only dealing with one encoder. We are fairly lost on what our P I and ad constants should be and we have only been getting a PID output of one with our encoder.pidGet in our return statement for the returnPIDInput method. I can post a copy of the code we have done so far if it will help.

Here are a bunch of links to PID on chiefdelphi:

Here’s an FRC-specific discussion of PID from WPILib:
http://wpilib.screenstepslive.com/s/3120/m/7952/l/80292-pidsubsystems-for-built-in-pid-control

Posting your code will allow the Java gurus on CD to give specific help.


public class DriveTrain extends PIDSubsystem {
	private Victor leftMotors] = new Victor[2];
	private Victor rightMotors] = new Victor[2];
	private Talon hDriveMotor;
	private double lTarget;
	private double rTarget;
	private double lspeed;
	private double rspeed;
	private final double ACCEL;
	private Encoder encoder;
	
	/**
     * This function is run when the class is initialized and should be
     * used for any initialization code.
     */
	public DriveTrain() {
		super("Drive Train",3,2,0);
		leftMotors[0] = new Victor(RobotMap.leftMotors[0]);
		leftMotors[1] = new Victor(RobotMap.leftMotors[1]);
		rightMotors[0] = new Victor(RobotMap.rightMotors[0]);
		rightMotors[1] = new Victor(RobotMap.rightMotors[1]);
		hDriveMotor = new Talon(RobotMap.hDriveMotor);
		ACCEL = .1;
		rspeed = 0;
		lspeed = 0;
		encoder = new Encoder(RobotMap.encoder[0], RobotMap.encoder[1],false, Encoder.EncodingType.k4X);
		encoder.setDistancePerPulse(4*Math.PI);
	}

	/** Set the default command for a subsystem here.
     * setDefaultCommand(new MySpecialCommand());
     */
	public void initDefaultCommand() {
		
		setDefaultCommand(new HDriveWithJoystick());
	}
public void tankDrive(double leftSpeed, double rightSpeed) {
		for (Victor lv : leftMotors)
			lv.set(leftSpeed);
		for (Victor rv : rightMotors)
			rv.set(rightSpeed);
	}
public void setHDriveMotor(double speed){
		hDriveMotor.set(speed);
	}

	@Override
	protected double returnPIDInput() {
		// TODO Auto-generated method stub
		return encoder.pidGet();
	}

	@Override
	protected void usePIDOutput(double output) {
		// TODO Auto-generated method stub
		tankDrive(output,output);
	}

}

This is our code, we do not know if we are setting up the encoder object correctly or know if we are instantiating the PID correctly outside of this class

The PID Subsystem was designed for a single sensor input and a single output. The way you’re doing it will use a single sensor and send the same output value to both the left and right motors, which would allow you to drive a distance approximately straight. Is that what you want?

If you create an example java project in eclipse and choose GearsBot you can see some samples of PIDSubsystem classes. Look in the subsystem package (folder) and look at Elevator and Wrist. In both cases it shows how to write the PID subsystem uses a potentiometer as the sensor.

Then to control the height of the elevator or the angle of the wrist, look at the commands SetElevatorSetpoint and SetWristSetpoint. The idea is that the PIDController is embedded in the PID Subsystem and the setting of the set point is in the command. The command finishes when the mechanism actual value is at the stepping +/- the tolerance (set in the subsystem).

There is also a video that describes how to write that program from scratch that’s here: WPILib Tutorial Videos posted : WPILib.

Hope that helps.