package com.team254.frc2015.subsystems.controllers;
import com.team254.frc2015.Constants;
import com.team254.frc2015.subsystems.Drive;
import com.team254.lib.trajectory.TrajectoryFollower;
import com.team254.lib.util.DriveSignal;
import com.team254.lib.util.Pose;
import com.team254.lib.util.SynchronousPID;
import static com.team254.lib.trajectory.TrajectoryFollower.TrajectorySetpoint;
public class DriveStraightController implements Drive.DriveController {
private TrajectoryFollowingPositionController mDistanceController;
private SynchronousPID mTurnPid;
private Pose mSetpointRelativePose;
public DriveStraightController(Pose priorSetpoint, double goalSetpoint, double maxVelocity) {
TrajectoryFollower.TrajectoryConfig config = new TrajectoryFollower.TrajectoryConfig();
config.dt = Constants.kControlLoopsDt;
config.max_acc = Constants.kDriveMaxAccelInchesPerSec2;
config.max_vel = maxVelocity;
mDistanceController = new TrajectoryFollowingPositionController(
Constants.kDrivePositionKp,
Constants.kDrivePositionKi,
Constants.kDrivePositionKd,
Constants.kDrivePositionKv,
Constants.kDrivePositionKa,
Constants.kDriveOnTargetError,
config);
TrajectorySetpoint initialSetpoint = new TrajectorySetpoint();
initialSetpoint.pos = encoderDistance(priorSetpoint);
initialSetpoint.vel = encoderVelocity(priorSetpoint);
mDistanceController.setGoal(initialSetpoint, goalSetpoint);
mTurnPid = new SynchronousPID();
mTurnPid.setPID(
Constants.kDriveStraightKp,
Constants.kDriveStraightKi,
Constants.kDriveStraightKd);
mTurnPid.setSetpoint(priorSetpoint.getHeading());
mSetpointRelativePose = new Pose(
priorSetpoint.getLeftDistance(),
priorSetpoint.getRightDistance(),
0,
0,
priorSetpoint.getHeading(),
priorSetpoint.getHeadingVelocity());
}
@Override
public DriveSignal update(Pose currentPose) {
mDistanceController.update(
(currentPose.getLeftDistance() + currentPose.getRightDistance()) / 2.0,
(currentPose.getLeftVelocity() + currentPose.getRightVelocity()) / 2.0);
double throttle = mDistanceController.get();
double turn = mTurnPid.calculate(currentPose.getHeading());
return new DriveSignal(throttle + turn, throttle - turn);
}
@Override
public Pose getCurrentSetpoint() {
TrajectorySetpoint trajectorySetpoint = mDistanceController.getSetpoint();
double dist = trajectorySetpoint.pos;
double velocity = trajectorySetpoint.vel;
return new Pose(
mSetpointRelativePose.getLeftDistance() + dist,
mSetpointRelativePose.getRightDistance() + dist,
mSetpointRelativePose.getLeftVelocity() + velocity,
mSetpointRelativePose.getRightVelocity() + velocity,
mSetpointRelativePose.getHeading(),
mSetpointRelativePose.getHeadingVelocity());
}
public static double encoderVelocity(Pose pose) {
return (pose.getLeftVelocity() + pose.getRightVelocity()) / 2.0;
}
public static double encoderDistance(Pose pose) {
return (pose.getLeftDistance() + pose.getRightDistance()) / 2.0;
}
@Override
public boolean onTarget() {
return mDistanceController.isOnTarget();
}
}