package com.team254.frc2015.subsystems.controllers;
import com.team254.frc2015.Constants;
import com.team254.frc2015.subsystems.Drive;
import com.team254.lib.trajectory.LegacyTrajectoryFollower;
import com.team254.lib.trajectory.Path;
import com.team254.lib.trajectory.Trajectory;
import com.team254.lib.util.ChezyMath;
import com.team254.lib.util.DriveSignal;
import com.team254.lib.util.Pose;
/**
* DrivePathController.java This controller drives the robot along a specified
* trajectory.
*
* @author Tom Bottiglieri
*/
public class DrivePathController implements Drive.DriveController {
public DrivePathController(Path path) {
init();
loadProfile(path.getLeftWheelTrajectory(), path.getRightWheelTrajectory(), 1.0, 0.0);
}
Trajectory trajectory;
LegacyTrajectoryFollower followerLeft = new LegacyTrajectoryFollower("left");
LegacyTrajectoryFollower followerRight = new LegacyTrajectoryFollower("right");
double direction;
double heading;
double kTurn = -Constants.kDrivePathHeadingFollowKp;
public boolean onTarget() {
return followerLeft.isFinishedTrajectory();
}
private void init() {
followerLeft.configure(Constants.kDrivePositionKp,
Constants.kDrivePositionKi, Constants.kDrivePositionKd,
Constants.kDrivePositionKv, Constants.kDrivePositionKa);
followerRight.configure(Constants.kDrivePositionKp,
Constants.kDrivePositionKi, Constants.kDrivePositionKd,
Constants.kDrivePositionKv, Constants.kDrivePositionKa);
}
private void loadProfile(Trajectory leftProfile, Trajectory rightProfile,
double direction, double heading) {
reset();
followerLeft.setTrajectory(leftProfile);
followerRight.setTrajectory(rightProfile);
this.direction = direction;
this.heading = heading;
}
public void loadProfileNoReset(Trajectory leftProfile,
Trajectory rightProfile) {
followerLeft.setTrajectory(leftProfile);
followerRight.setTrajectory(rightProfile);
}
public void reset() {
followerLeft.reset();
followerRight.reset();
}
public int getFollowerCurrentSegmentNumber() {
return followerLeft.getCurrentSegmentNumber();
}
public int getNumSegments() {
return followerLeft.getNumSegments();
}
public void setTrajectory(Trajectory t) {
this.trajectory = t;
}
public double getGoal() {
return 0;
}
@Override
public DriveSignal update(Pose pose) {
if (onTarget()) {
return new DriveSignal(0, 0);
} else {
double distanceL = direction * pose.getLeftDistance();
double distanceR = direction * pose.getRightDistance();
double speedLeft = direction * followerLeft.calculate(distanceL);
double speedRight = direction * followerRight.calculate(distanceR);
double goalHeading = followerLeft.getHeading();
double observedHeading = -pose.getHeading();
double angleDiffRads = ChezyMath.getDifferenceInAngleRadians(
observedHeading, goalHeading);
double angleDiff = Math.toDegrees(angleDiffRads);
double turn = kTurn * angleDiff;
return new DriveSignal(speedLeft + turn, speedRight - turn);
}
}
@Override
public Pose getCurrentSetpoint() {
return new Pose(followerLeft.getCurrentSegment().pos, 0, 0, 0, -followerLeft.getHeading(), 0);
}
}