Skip to content
This repository has been archived by the owner on Dec 2, 2024. It is now read-only.

Commit

Permalink
vision more like broken
Browse files Browse the repository at this point in the history
  • Loading branch information
carokhan committed Oct 17, 2024
1 parent eb4256d commit 3323539
Show file tree
Hide file tree
Showing 10 changed files with 458 additions and 12 deletions.
2 changes: 1 addition & 1 deletion simgui-ds.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,10 @@
],
"robotJoysticks": [
{
"guid": "78696e70757401000000000000000000",
"useGamepad": true
},
{
"guid": "78696e70757401000000000000000000",
"useGamepad": true
}
]
Expand Down
4 changes: 3 additions & 1 deletion simgui.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"types": {
"/AdvantageKit/RealOutputs/Climb/Mechanism2d": "Mechanism2d",
"/AdvantageKit/RealOutputs/Visualizer/FullRobot": "Mechanism2d",
"/AdvantageKit/RealOutputs/Visualizer/M_main": "Mechanism2d",
"/FMSInfo": "FMSInfo",
"/SmartDashboard/Climb Down": "Command",
"/SmartDashboard/Climb Up": "Command",
Expand All @@ -21,7 +22,8 @@
"/SmartDashboard/Shooter 60": "Command",
"/SmartDashboard/Shooter 75": "Command",
"/SmartDashboard/Shooter 90": "Command",
"/SmartDashboard/Test": "Command"
"/SmartDashboard/Test": "Command",
"/SmartDashboard/VisionSystemSim-main/Sim Field": "Field2d"
},
"windows": {
"/AdvantageKit/RealOutputs/Visualizer/FullRobot": {
Expand Down
12 changes: 6 additions & 6 deletions src/main/java/frc/robot/BuildConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ public final class BuildConstants {
public static final String MAVEN_GROUP = "";
public static final String MAVEN_NAME = "Forte-2-5";
public static final String VERSION = "unspecified";
public static final int GIT_REVISION = 83;
public static final String GIT_SHA = "cd5533efceedea228db5f5c1abfb4d489944d593";
public static final String GIT_DATE = "2024-10-16 05:10:03 EDT";
public static final String GIT_BRANCH = "main";
public static final String BUILD_DATE = "2024-10-17 07:03:41 EDT";
public static final long BUILD_UNIX_TIME = 1729163021410L;
public static final int GIT_REVISION = 84;
public static final String GIT_SHA = "eb4256d9224e4d4ebedf33266815cbb0d7c30efe";
public static final String GIT_DATE = "2024-10-17 07:04:35 EDT";
public static final String GIT_BRANCH = "vision";
public static final String BUILD_DATE = "2024-10-17 07:37:42 EDT";
public static final long BUILD_UNIX_TIME = 1729165062242L;
public static final int DIRTY = 1;

private BuildConstants() {}
Expand Down
33 changes: 33 additions & 0 deletions src/main/java/frc/robot/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,15 @@

package frc.robot;

import edu.wpi.first.apriltag.AprilTagFieldLayout;
import edu.wpi.first.apriltag.AprilTagFields;
import edu.wpi.first.math.Matrix;
import edu.wpi.first.math.VecBuilder;
import edu.wpi.first.math.geometry.Rotation3d;
import edu.wpi.first.math.geometry.Transform3d;
import edu.wpi.first.math.geometry.Translation3d;
import edu.wpi.first.math.numbers.N1;
import edu.wpi.first.math.numbers.N3;
import edu.wpi.first.math.util.Units;
import edu.wpi.first.wpilibj.simulation.SingleJointedArmSim;

Expand Down Expand Up @@ -302,4 +311,28 @@ public static class ShooterConstants {
public static class SimConstants {
public static final double loopTime = 0.02;
}

public static class VisionConstants {
public static final Transform3d leftCamToRobot =
new Transform3d(
new Translation3d(12.161481, -12.050199, 9.756915),
new Rotation3d(
Units.degreesToRadians(90),
Units.degreesToRadians(25),
Units.degreesToRadians(35)));

public static final Transform3d rightCamToRobot =
new Transform3d(
new Translation3d(12.161481, 12.050199, 9.756915),
new Rotation3d(
Units.degreesToRadians(90),
Units.degreesToRadians(25),
-Units.degreesToRadians(35)));

public static final Matrix<N3, N1> singleTagStdDev =
VecBuilder.fill(0.8, 0.8, Double.MAX_VALUE);
public static final Matrix<N3, N1> multiTagStdDev = VecBuilder.fill(0.5, 0.5, Double.MAX_VALUE);
public static final AprilTagFieldLayout aprilTagFieldLayout =
AprilTagFields.k2024Crescendo.loadAprilTagLayoutField();
}
}
12 changes: 9 additions & 3 deletions src/main/java/frc/robot/RobotContainer.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@
import edu.wpi.first.wpilibj2.command.button.CommandXboxController;
import frc.robot.Constants.DriveConstants;
import frc.robot.Constants.RobotMap;
import frc.robot.subsystems.apriltagvision.AprilTagVisionIOReal;
import frc.robot.subsystems.apriltagvision.AprilTagVisionIOReplay;
import frc.robot.subsystems.apriltagvision.AprilTagVisionIOSim;
import frc.robot.subsystems.climber.Climb;
import frc.robot.subsystems.climber.ClimbIOReplay;
import frc.robot.subsystems.climber.ClimbIOSim;
Expand Down Expand Up @@ -91,7 +94,8 @@ public RobotContainer() {
new ModuleIOReal(0),
new ModuleIOReal(1),
new ModuleIOReal(2),
new ModuleIOReal(3));
new ModuleIOReal(3),
new AprilTagVisionIOReal());
m_climber = new Climb(new ClimbIOSparkMax());
m_intake = new Intake(new IntakeIOSparkMax());
m_feeder =
Expand All @@ -111,7 +115,8 @@ public RobotContainer() {
new ModuleIOSim("FrontLeft"),
new ModuleIOSim("FrontRight"),
new ModuleIOSim("BackLeft"),
new ModuleIOSim("BackRight"));
new ModuleIOSim("BackRight"),
new AprilTagVisionIOSim());
m_climber = new Climb(new ClimbIOSim());
m_intake = new Intake(new IntakeIOSim());
m_feeder =
Expand All @@ -131,7 +136,8 @@ public RobotContainer() {
new ModuleIOReplay() {},
new ModuleIOReplay() {},
new ModuleIOReplay() {},
new ModuleIOReplay() {});
new ModuleIOReplay() {},
new AprilTagVisionIOReplay() {});
m_climber = new Climb(new ClimbIOReplay());
m_intake = new Intake(new IntakeIOReplay());
m_feeder =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package frc.robot.subsystems.apriltagvision;

import edu.wpi.first.math.Matrix;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.numbers.N1;
import edu.wpi.first.math.numbers.N3;
import java.util.List;
import org.littletonrobotics.junction.AutoLog;
import org.photonvision.EstimatedRobotPose;

public interface AprilTagVisionIO {
@AutoLog
public static class AprilTagVisionIOInputs {
public Pose3d[] visionPoses =
List.of(new Pose3d(), new Pose3d(), new Pose3d()).toArray(new Pose3d[0]);
public double[] timestamps = new double[3];
public double[] latency = new double[3];
public double[] visionStdDevs = new double[9];
}

/** Updates the set of loggable inputs. */
public abstract void updateInputs(AprilTagVisionIOInputs inputs);

/** Update the reference pose of the vision system. Currently only used in sim. */
public abstract void updatePose(Pose2d pose);

/**
* The standard deviations of the estimated poses from vision cameras, for use with {@link
* edu.wpi.first.math.estimator.SwerveDrivePoseEstimator SwerveDrivePoseEstimator}.
*
* @param estimatedPose The estimated pose to guess standard deviations for.
*/
abstract Matrix<N3, N1> getEstimationStdDevs(EstimatedRobotPose estimatedPose);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
package frc.robot.subsystems.apriltagvision;

import static java.lang.System.arraycopy;
import static org.photonvision.PhotonPoseEstimator.PoseStrategy.MULTI_TAG_PNP_ON_COPROCESSOR;

import edu.wpi.first.math.Matrix;
import edu.wpi.first.math.VecBuilder;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Pose3d;
import edu.wpi.first.math.numbers.N1;
import edu.wpi.first.math.numbers.N3;
import frc.robot.Constants.VisionConstants;
import java.util.Optional;
import org.photonvision.EstimatedRobotPose;
import org.photonvision.PhotonCamera;
import org.photonvision.PhotonPoseEstimator;

public class AprilTagVisionIOReal implements AprilTagVisionIO {

// Left Side Camera
private final PhotonCamera leftCam;
private final PhotonPoseEstimator leftPhotonPoseEstimator;

// Right Side Camera
private final PhotonCamera rightCam;
private final PhotonPoseEstimator rightPhotonPoseEstimator;

private Pose3d[] poseArray = new Pose3d[2];
private double[] timestampArray = new double[2];
private double[] visionStdArray = new double[6];
private double[] latencyArray = new double[2];
private int count = 0;

public AprilTagVisionIOReal() {
// Left Side Camera
leftCam = new PhotonCamera("left");
leftPhotonPoseEstimator =
new PhotonPoseEstimator(
VisionConstants.aprilTagFieldLayout,
MULTI_TAG_PNP_ON_COPROCESSOR,
leftCam,
VisionConstants.leftCamToRobot);

// Right Side Camera
rightCam = new PhotonCamera("right");
rightPhotonPoseEstimator =
new PhotonPoseEstimator(
VisionConstants.aprilTagFieldLayout,
MULTI_TAG_PNP_ON_COPROCESSOR,
rightCam,
VisionConstants.rightCamToRobot);
}

@Override
public void updateInputs(AprilTagVisionIOInputs inputs) {
getEstimatedPoseUpdates();
inputs.visionPoses = poseArray;
inputs.timestamps = timestampArray;
inputs.visionStdDevs = visionStdArray;
inputs.latency = latencyArray;
count += 1;
if (count % 500 == 0) {
leftCam.takeOutputSnapshot();
rightCam.takeOutputSnapshot();
}
}

public void getEstimatedPoseUpdates() {
Matrix<N3, N1> infiniteStdevs =
VecBuilder.fill(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);

Optional<EstimatedRobotPose> pose = leftPhotonPoseEstimator.update();
pose.ifPresentOrElse(
estimatedRobotPose -> {
poseArray[0] = estimatedRobotPose.estimatedPose;
timestampArray[0] = estimatedRobotPose.timestampSeconds;
Matrix<N3, N1> stdDevs = getEstimationStdDevs(estimatedRobotPose);
arraycopy(stdDevs.getData(), 0, visionStdArray, 0, 3);
latencyArray[0] = leftCam.getLatestResult().getLatencyMillis() / 1.0e3;
},
() -> {
poseArray[0] = new Pose3d();
timestampArray[0] = 0.0;
latencyArray[0] = 0.0;
});
pose = rightPhotonPoseEstimator.update();
pose.ifPresentOrElse(
estimatedRobotPose -> {
poseArray[1] = estimatedRobotPose.estimatedPose;
timestampArray[1] = estimatedRobotPose.timestampSeconds;
Matrix<N3, N1> stdDevs = getEstimationStdDevs(estimatedRobotPose);
arraycopy(stdDevs.getData(), 0, visionStdArray, 3, 3);
latencyArray[1] = leftCam.getLatestResult().getLatencyMillis() / 1.0e3;
},
() -> {
poseArray[1] = new Pose3d();
timestampArray[1] = 0.0;
latencyArray[1] = 0.0;
});
}

public Matrix<N3, N1> getEstimationStdDevs(EstimatedRobotPose estimatedPose) {
var estStdDevs = VisionConstants.singleTagStdDev;
var targets = estimatedPose.targetsUsed;
int numTags = 0;
double avgDist = 0;
for (var tgt : targets) {
var tagPose = VisionConstants.aprilTagFieldLayout.getTagPose(tgt.getFiducialId());
if (tagPose.isEmpty()) continue;
numTags++;
avgDist +=
tagPose
.get()
.toPose2d()
.minus(estimatedPose.estimatedPose.toPose2d())
.getTranslation()
.getNorm();
}

if (numTags == 0) return estStdDevs;
avgDist /= numTags;

// Decrease std devs if multiple targets are visible
if (numTags > 1 && avgDist > 5) {
estStdDevs = VecBuilder.fill(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
} else {
estStdDevs = VisionConstants.multiTagStdDev;
}
// Increase std devs based on (average) distance
if (numTags == 1 && avgDist > 4) {
estStdDevs = VecBuilder.fill(Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE);
} else {
estStdDevs = estStdDevs.times(1 + (avgDist * avgDist / 20));
}

return estStdDevs;
}

@Override
public void updatePose(Pose2d pose) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package frc.robot.subsystems.apriltagvision;

import edu.wpi.first.math.Matrix;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.numbers.N1;
import edu.wpi.first.math.numbers.N3;
import org.photonvision.EstimatedRobotPose;

public class AprilTagVisionIOReplay implements AprilTagVisionIO {

@Override
public void updateInputs(AprilTagVisionIOInputs inputs) {}

@Override
public void updatePose(Pose2d pose) {}

@Override
public Matrix<N3, N1> getEstimationStdDevs(EstimatedRobotPose estimatedPose) {
return null;
}
}
Loading

0 comments on commit 3323539

Please sign in to comment.