As mentioned, here is the test code we used to learn about encoder-based control of a single talon. Now that we got this simplified code to work, we can move on to more realistic usages.
Code:
import com.ctre.CANTalon;
import com.ctre.CANTalon.FeedbackDevice;
import edu.wpi.first.wpilibj.command.Command;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import org.usfirst.frc.team5976.robot.subsystems.DriveTrain;
/**
* Drive the given distance straight (negative values go backwards).
*/
public class DriveStraight extends Command {
private DriveTrain driveTrain;
private CANTalon talon;
private double numberOfRevs;
private int allowableError = 10;
private int stableCount;
private final int requiredNumberOfCounts = 10;
private double previousError;
public DriveStraight(double distanceInInches, DriveTrain driveTrain) {
this.driveTrain = driveTrain;
talon = driveTrain.talon;
numberOfRevs = distanceInInches / (Math.PI * 6);
talon.setControlMode(CANTalon.TalonControlMode.Position.value);
//This should be setting the set point to move encoder ticks
talon.set(0);
talon.setFeedbackDevice(FeedbackDevice.QuadEncoder);
talon.configEncoderCodesPerRev(360);
talon.setProfile(0);
talon.configNominalOutputVoltage(+0.0f, -0.0f);
talon.configPeakOutputVoltage(+6.0f, -6.0f);
talon.setAllowableClosedLoopErr(allowableError);
talon.setPosition(0);
talon.enableControl();
}
protected void initialize() {
// Get everything in a safe starting state.
driveTrain.reset();
talon.reset();
talon.enable();
talon.setPosition(0);
System.out.println("Encoder start position: " + talon.getPosition());
System.out.println("Talon control mode: " + talon.getControlMode());
System.out.println("Number of Revolutions: " + numberOfRevs);
talon.set(numberOfRevs);
previousError = 100000; // something big to start with
stableCount = 0;
}
protected void execute() {
}
protected boolean isFinished() {
double currentError = driveTrain.talon.getError();
System.out.println("Encoder position: " + talon.getPosition()+
" |EP " + talon.getEncPosition() +
" |CErr " + currentError + " |PErr " + previousError + " |Count " + stableCount +
" |SetP " + talon.getSetpoint());
if (previousError == currentError) {
stableCount++;
if (stableCount >= requiredNumberOfCounts) return true;
}
else {
stableCount = 0;
previousError = currentError;
}
return false;
}
protected void end() {
System.out.println("Encoder stop position: " + talon.getPosition()+ " | " + talon.getEncPosition());
}
// Called when another command which requires one or more of the same subsystems is scheduled to run
protected void interrupted() {
end();
}
}
Sample output from running this example looks like this below. We noted the current error (CErr) of 1440 corresponds to the number of quad encoder pulses expected for one full revolution. Also note the value returned from the talon's getPosition() method is updating with every pass but the value returned by getEncPosition() (EP in the output) is updated less frequently. Also, noted is that getPosition's value in in terms of revolutions and getEncPosition's is in terms of pulses.
P = 2 I = 0 D = 50 Ramp = 4
Talon control mode: Position
Number of Revolutions: 1.0
Encoder position: 0.0 |EP 0 |CErr 1440.0 |PErr -9.0 |Count 2 |SetP 1.0 |T Time: 20
Encoder position: 0.0 |EP 0 |CErr 1440.0 |PErr 1440.0 |Count 0 |SetP 1.0 |T Time: 20
Encoder position: 0.001388888888888889 |EP 0 |CErr 1438.0 |PErr 1440.0 |Count 1 |SetP 1.0 |T Time: 20
Encoder position: 0.005555555555555556 |EP 0 |CErr 1424.0 |PErr 1438.0 |Count 0 |SetP 1.0 |T Time: 20
Encoder position: 0.022222222222222223 |EP 0 |CErr 1392.0 |PErr 1424.0 |Count 0 |SetP 1.0 |T Time: 22
Encoder position: 0.05 |EP 0 |CErr 1370.0 |PErr 1392.0 |Count 0 |SetP 1.0 |T Time: 18
Encoder position: 0.0875 |EP 126 |CErr 1314.0 |PErr 1370.0 |Count 0 |SetP 1.0 |T Time: 21
Encoder position: 0.13680555555555557 |EP 126 |CErr 1239.0 |PErr 1314.0 |Count 0 |SetP 1.0 |T Time: 19
Encoder position: 0.19444444444444445 |EP 126 |CErr 1151.0 |PErr 1239.0 |Count 0 |SetP 1.0 |T Time: 21
Encoder position: 0.25833333333333336 |EP 126 |CErr 1054.0 |PErr 1151.0 |Count 0 |SetP 1.0 |T Time: 24
Encoder position: 0.32569444444444445 |EP 126 |CErr 1003.0 |PErr 1054.0 |Count 0 |SetP 1.0 |T Time: 15
Encoder position: 0.3972222222222222 |EP 126 |CErr 898.0 |PErr 1003.0 |Count 0 |SetP 1.0 |T Time: 20
Encoder position: 0.46944444444444444 |EP 645 |CErr 789.0 |PErr 898.0 |Count 0 |SetP 1.0 |T Time: 21