package com.team254.frc2015; import com.team254.frc2015.subsystems.Drive; import com.team254.lib.util.DriveSignal; import com.team254.lib.util.Util; import edu.wpi.first.wpilibj.DriverStation; /** * CheesyDriveHelper implements the calculations used in CheesyDrive, sending * power to the motors. */ public class CheesyDriveHelper { private Drive drive; double oldWheel, quickStopAccumulator; private double throttleDeadband = 0.02; private double wheelDeadband = 0.02; private DriveSignal signal = new DriveSignal(0, 0); public CheesyDriveHelper(Drive drive) { this.drive = drive; } public void cheesyDrive(double throttle, double wheel, boolean isQuickTurn, boolean isHighGear) { if (DriverStation.getInstance().isAutonomous()) { return; } double wheelNonLinearity; wheel = handleDeadband(wheel, wheelDeadband); throttle = handleDeadband(throttle, throttleDeadband); double negInertia = wheel - oldWheel; oldWheel = wheel; if (isHighGear) { wheelNonLinearity = 0.6; // Apply a sin function that's scaled to make it feel better. wheel = Math.sin(Math.PI / 2.0 * wheelNonLinearity * wheel) / Math.sin(Math.PI / 2.0 * wheelNonLinearity); wheel = Math.sin(Math.PI / 2.0 * wheelNonLinearity * wheel) / Math.sin(Math.PI / 2.0 * wheelNonLinearity); } else { wheelNonLinearity = 0.5; // Apply a sin function that's scaled to make it feel better. wheel = Math.sin(Math.PI / 2.0 * wheelNonLinearity * wheel) / Math.sin(Math.PI / 2.0 * wheelNonLinearity); wheel = Math.sin(Math.PI / 2.0 * wheelNonLinearity * wheel) / Math.sin(Math.PI / 2.0 * wheelNonLinearity); wheel = Math.sin(Math.PI / 2.0 * wheelNonLinearity * wheel) / Math.sin(Math.PI / 2.0 * wheelNonLinearity); } double leftPwm, rightPwm, overPower; double sensitivity; double angularPower; double linearPower; // Negative inertia! double negInertiaAccumulator = 0.0; double negInertiaScalar; if (isHighGear) { negInertiaScalar = 4.0; sensitivity = Constants.kDriveSensitivity; } else { if (wheel * negInertia > 0) { negInertiaScalar = 2.5; } else { if (Math.abs(wheel) > 0.65) { negInertiaScalar = 5.0; } else { negInertiaScalar = 3.0; } } sensitivity = .85; // Constants.sensitivityLow.getDouble(); } double negInertiaPower = negInertia * negInertiaScalar; negInertiaAccumulator += negInertiaPower; wheel = wheel + negInertiaAccumulator; if (negInertiaAccumulator > 1) { negInertiaAccumulator -= 1; } else if (negInertiaAccumulator < -1) { negInertiaAccumulator += 1; } else { negInertiaAccumulator = 0; } linearPower = throttle; // Quickturn! if (isQuickTurn) { if (Math.abs(linearPower) < 0.2) { double alpha = 0.1; quickStopAccumulator = (1 - alpha) * quickStopAccumulator + alpha * Util.limit(wheel, 1.0) * 5; } overPower = 1.0; if (isHighGear) { sensitivity = 1.0; } else { sensitivity = 1.0; } angularPower = wheel; } else { overPower = 0.0; angularPower = Math.abs(throttle) * wheel * sensitivity - quickStopAccumulator; if (quickStopAccumulator > 1) { quickStopAccumulator -= 1; } else if (quickStopAccumulator < -1) { quickStopAccumulator += 1; } else { quickStopAccumulator = 0.0; } } rightPwm = leftPwm = linearPower; leftPwm += angularPower; rightPwm -= angularPower; if (leftPwm > 1.0) { rightPwm -= overPower * (leftPwm - 1.0); leftPwm = 1.0; } else if (rightPwm > 1.0) { leftPwm -= overPower * (rightPwm - 1.0); rightPwm = 1.0; } else if (leftPwm < -1.0) { rightPwm += overPower * (-1.0 - leftPwm); leftPwm = -1.0; } else if (rightPwm < -1.0) { leftPwm += overPower * (-1.0 - rightPwm); rightPwm = -1.0; } signal.leftMotor = leftPwm; signal.rightMotor = rightPwm; drive.setOpenLoop(signal); } public double handleDeadband(double val, double deadband) { return (Math.abs(val) > Math.abs(deadband)) ? val : 0.0; } }