Skip to content

Commit

Permalink
Remove linearization on chain and make it use an equation. Will event…
Browse files Browse the repository at this point in the history
…ually be the demise of #97
  • Loading branch information
GalexY727 committed Jan 31, 2024
1 parent 72e57ba commit 69c284e
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 37 deletions.
12 changes: 3 additions & 9 deletions src/main/java/frc/robot/subsystems/Climb.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

import com.revrobotics.CANSparkBase.IdleMode;

import edu.wpi.first.math.Pair;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.geometry.Rotation3d;
import edu.wpi.first.wpilibj2.command.Command;
Expand All @@ -12,7 +13,6 @@
import frc.robot.util.Neo;
import frc.robot.util.Constants.ClimbConstants;
import frc.robot.util.Constants.NTConstants;
import frc.robot.util.Constants.FieldConstants.ChainPosition;
import monologue.Logged;

public class Climb extends SubsystemBase implements Logged {
Expand Down Expand Up @@ -56,15 +56,9 @@ public void setPosition(double pos1, double pos2) {
);
}

public Command toTop(ChainPosition chainPosition) {
public Command toTop(Pair<Double, Double> chainHeights) {

if (chainPosition == ChainPosition.LEFT) {
return runOnce(() -> this.setPosition(ClimbConstants.ALMOST_HIGH_LIMIT, ClimbConstants.HIGH_LIMIT));
} else if (chainPosition == ChainPosition.RIGHT) {
return runOnce(() -> this.setPosition(ClimbConstants.HIGH_LIMIT, ClimbConstants.ALMOST_HIGH_LIMIT));
} else {
return runOnce(() -> this.setPosition(ClimbConstants.HIGH_LIMIT, ClimbConstants.HIGH_LIMIT));
}
return runOnce(() -> setPosition(chainHeights.getFirst(), chainHeights.getSecond()));

}

Expand Down
32 changes: 21 additions & 11 deletions src/main/java/frc/robot/util/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,10 @@
import edu.wpi.first.math.controller.PIDController;
import edu.wpi.first.math.controller.ProfiledPIDController;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.math.geometry.Rotation3d;
import edu.wpi.first.math.geometry.Transform3d;
import edu.wpi.first.math.geometry.Translation2d;
import edu.wpi.first.math.interpolation.InterpolatingTreeMap;
import edu.wpi.first.math.interpolation.InverseInterpolator;
Expand Down Expand Up @@ -188,6 +191,9 @@ public static final class ClimbConstants {
public static final double HIGH_LIMIT = 3.0;
public static final double ROCK_BOTTOM = 0.0;
public static final double ALMOST_HIGH_LIMIT = 2.5;

public static final double DISTANCE_FROM_ORIGIN_METERS = 0.3048;
public static final double EXTENSION_LIMIT_METERS = Units.feetToMeters(3.65);
}

public static final class AutoConstants {
Expand Down Expand Up @@ -364,6 +370,7 @@ public static final class FieldConstants {
public static final double ALLOWABLE_ERROR_METERS = Units.inchesToMeters(2);
public static final double FIELD_WIDTH_METERS = 16.5410515;
public static final double FIELD_HEIGHT_METERS = 8.2112312;
public static final double CHAIN_HEIGHT_METERS = 8.2112312;

public static Optional<Alliance> ALLIANCE = Optional.empty();

Expand All @@ -384,7 +391,7 @@ public static enum GameMode {
// 1 4
// 0 3
// @formatter:on
public static Pose2d[] CHAIN_POSITIONS = new Pose2d[] {
public static final Pose2d[] CHAIN_POSITIONS = new Pose2d[] {
// All points are in meters and radians
// All relative to the blue origin
// Blue Stage
Expand All @@ -397,14 +404,23 @@ public static enum GameMode {
new Pose2d(12.2, 5, Rotation2d.fromDegrees(-120))
};

public static final Pose3d[] CHAIN_POSE3DS = new Pose3d[] {
new Pose3d(CHAIN_POSITIONS[0]).plus(new Transform3d(0.0, 0.0, CHAIN_HEIGHT_METERS, new Rotation3d())),
new Pose3d(CHAIN_POSITIONS[1]).plus(new Transform3d(0.0, 0.0, CHAIN_HEIGHT_METERS, new Rotation3d())),
new Pose3d(CHAIN_POSITIONS[2]).plus(new Transform3d(0.0, 0.0, CHAIN_HEIGHT_METERS, new Rotation3d())),
new Pose3d(CHAIN_POSITIONS[3]).plus(new Transform3d(0.0, 0.0, CHAIN_HEIGHT_METERS, new Rotation3d())),
new Pose3d(CHAIN_POSITIONS[4]).plus(new Transform3d(0.0, 0.0, CHAIN_HEIGHT_METERS, new Rotation3d())),
new Pose3d(CHAIN_POSITIONS[5]).plus(new Transform3d(0.0, 0.0, CHAIN_HEIGHT_METERS, new Rotation3d())),
};

// Speaker Positions: Blue alliance left
// @formatter:off
//
// 0 1
//
//
// @formatter:on
public static Pose2d[] SPEAKER_POSITIONS = new Pose2d[] {
public static final Pose2d[] SPEAKER_POSITIONS = new Pose2d[] {
// All points are in meters and radians
// All relative to the blue origin
// Blue Speaker
Expand All @@ -423,17 +439,11 @@ public static enum GameMode {
};

// TODO: make real constants
public static Pose2d L_POSE = new Pose2d();
public static Pose2d R_POSE = new Pose2d();
public static Pose2d M_POSE = new Pose2d();
public static final Pose2d L_POSE = new Pose2d();
public static final Pose2d R_POSE = new Pose2d();
public static final Pose2d M_POSE = new Pose2d();

public static final double CHAIN_LENGTH_METERS = Units.inchesToMeters(100);

public static enum ChainPosition {
LEFT,
RIGHT,
CENTER
}
}
public static final class NTConstants {
public static final int PIVOT_INDEX = 0;
Expand Down
89 changes: 72 additions & 17 deletions src/main/java/frc/robot/util/PoseCalculations.java
Original file line number Diff line number Diff line change
@@ -1,43 +1,98 @@
package frc.robot.util;

import java.util.Optional;

import edu.wpi.first.math.MathUtil;
import edu.wpi.first.math.Pair;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.util.Units;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.geometry.Rotation3d;
import edu.wpi.first.wpilibj.DriverStation.Alliance;
import frc.robot.util.Constants.ClimbConstants;
import frc.robot.util.Constants.FieldConstants;
import frc.robot.util.Constants.FieldConstants.ChainPosition;
import monologue.Logged;
import monologue.Annotations.Log;

public class PoseCalculations {
public class PoseCalculations implements Logged {

@Log.NT
public static ChainPosition getChainPosition(Pose2d position) {
private Pose3d chainLeft = new Pose3d();
@Log.NT
private Pose3d chainRight = new Pose3d();

public Pair<Double, Double> getChainPosition(Pose2d position) {
Pose2d closestChainPose;

double minDifference = 10000;
int closestChainIndex = 0;

for (int i = 0; i < FieldConstants.CHAIN_POSITIONS.length; i++) {
int startingIndex = FieldConstants.ALLIANCE.equals(Optional.of(Alliance.Red)) ? 3 : 0;
int endingIndex = FieldConstants.ALLIANCE.equals(Optional.of(Alliance.Red)) ? 6 : 3;

for (int i = startingIndex; i < endingIndex; i++) {
Pose2d currentChainPose = FieldConstants.CHAIN_POSITIONS[i];
double currentChainDistance = position.getTranslation().getDistance(currentChainPose.getTranslation());

minDifference = currentChainDistance < minDifference
? currentChainDistance
: minDifference;

closestChainIndex = currentChainDistance < minDifference
? i
: closestChainIndex;
if (currentChainDistance < minDifference) {
minDifference = currentChainDistance;
closestChainIndex = i;
}
}

closestChainPose = FieldConstants.CHAIN_POSITIONS[closestChainIndex];

Pose2d relativePosition = position.relativeTo(closestChainPose);

if (relativePosition.getX() < Units.metersToInches(FieldConstants.CHAIN_LENGTH_METERS / 3)) {
return ChainPosition.LEFT;
} else if (relativePosition.getX() > Units.metersToInches(FieldConstants.CHAIN_LENGTH_METERS / 3)) {
return ChainPosition.RIGHT;
if (Math.abs(relativePosition.getTranslation().getX()) > 1) {
chainLeft = new Pose3d();
chainRight = new Pose3d();
return Pair.of(0d, 0d);
}
return ChainPosition.CENTER;

double leftIntercept = getChainIntercept(relativePosition.getY() + ClimbConstants.DISTANCE_FROM_ORIGIN_METERS);
double rightIntercept = getChainIntercept(relativePosition.getY() - ClimbConstants.DISTANCE_FROM_ORIGIN_METERS);

chainLeft = new Pose3d(
0,
0,
leftIntercept - 0.6, // Convert from the chain's height to the climb's height w/ some extra space
new Rotation3d(
0,
0,
0));

chainRight = new Pose3d(
0,
0,
rightIntercept - 0.6, // Convert from the chain's height to the climb's height w/ some extra space
new Rotation3d(
0,
0,
0));

return Pair.of(
getChainIntercept(relativePosition.getY() + ClimbConstants.DISTANCE_FROM_ORIGIN_METERS),
getChainIntercept(relativePosition.getY() - ClimbConstants.DISTANCE_FROM_ORIGIN_METERS));
}

/**
* Given an intercept of the chain, return the height of the chain at that
* location.
*
* @param x The posision along the X axis of the chain
* as seen in https://www.desmos.com/calculator/84ioficbl2
* For some reason, that desmos breaks on chrome on my home computer
* please send help... i used edge to make it :(
*
* @return The height of the chain at that location
*/
public double getChainIntercept(double x) {
// The ds here turn the integers into doubles
// so that integer divion does not occur.
double calculation = 3d / 10d * Math.pow(x, 2) + 0.725;
// Clamp the output to be no lower than the lowest point of the chain,
// and no higher than the extension limit of our elevator
return MathUtil.clamp(calculation, 0.725, ClimbConstants.EXTENSION_LIMIT_METERS);
}

}

0 comments on commit 69c284e

Please sign in to comment.