We are displaying robot pose on AdvantageScope tool, and when the limelight vision camera is lined up with an aprilTag, we get the correct robot pose, but once we lose sight of the aprilTag and rotate away from it, the robot pose on AdvantageScope teleports randomly to another position.
We think that the odometry based position is not being updated correctly when we use the limelight with pose. How can we fix this issue?
Here is the vision code:
package common.Util;
import edu.wpi.first.math.VecBuilder;
import edu.wpi.first.math.estimator.SwerveDrivePoseEstimator;
import edu.wpi.first.math.geometry.Pose2d;
import edu.wpi.first.math.geometry.Rotation2d;
import edu.wpi.first.math.geometry.Translation2d;
import edu.wpi.first.wpilibj.smartdashboard.Field2d;
import edu.wpi.first.wpilibj.smartdashboard.SmartDashboard;
import frc.robot.subsystems.SwerveDrive;
public class PhoseStuff implements Runnable {
private SwerveDrive swerveDrive;
private Vision vision;
private SwerveDrivePoseEstimator poseEstimator;
private Field2d fieldSim;
public PhoseStuff(SwerveDrive swerveDrive, Vision vision) {
this.swerveDrive = swerveDrive;
this.vision = vision;
// Creates the pose estimator.
this.poseEstimator = new SwerveDrivePoseEstimator(
swerveDrive.getKin(),
swerveDrive.getGyroRotation2d(),
swerveDrive.getSwerveModulePositions(),
new Pose2d(new Translation2d(), Rotation2d.fromDegrees(0)),
VecBuilder.fill(.1, .1, .1),
VecBuilder.fill(.9, .9, .9));
this.fieldSim = new Field2d();
SmartDashboard.putData("Field", fieldSim);
}
@Override
public void run() {
tick();
}
// This is ran every tick.
public void tick() {
// double random = Math.random();
// if (random > .9){
// System.out.println("numtags: " + vision.getNumTags());
// System.out.println("distance: " + vision.getDistance());
// }
// Updates the pose estimator based on the gyro and swerve module positions.
poseEstimator.update(
swerveDrive.getGyroRotation2d(),
swerveDrive.getSwerveModulePositions());
if(Math.random() > .9){
System.out.println("Pose: " + get());
}
// Vision calculations are ran here.
visionStuff();
fieldSim.setRobotPose(get());
}
// Gets the pose estimate.
public Pose2d get() {
return poseEstimator.getEstimatedPosition();
}
// Resets the pose estimator.
public void reset(Pose2d pose) {
poseEstimator.resetPosition(
swerveDrive.getGyroRotation2d(),
swerveDrive.getSwerveModulePositions(),
pose);
fieldSim.setRobotPose(poseEstimator.getEstimatedPosition());
}
// Vision calculations are ran here.
public void visionStuff() {
Pose2d visionResult = vision.getPose();
double visionTimeStamp = vision.getTimestamp();
if ((vision.getNumTags() == 1 && vision.getDistance() < 75.00) ||
(vision.getNumTags() == 2 && vision.getDistance() < 120.00) ||
(vision.getNumTags() == 3 && vision.getDistance() < 185.00))
{
if(Math.random() > .9){
System.out.println("Pushing");
}
poseEstimator.addVisionMeasurement(visionResult, visionTimeStamp);
}
}
}