|
| 1 | +package org.firstinspires.ftc.teamcode.lib.subsystems; |
| 2 | + |
| 3 | +import com.qualcomm.hardware.sparkfun.SparkFunOTOS; |
| 4 | +import com.qualcomm.robotcore.hardware.HardwareMap; |
| 5 | + |
| 6 | +import org.firstinspires.ftc.robotcore.external.Telemetry; |
| 7 | +import org.firstinspires.ftc.robotcore.external.hardware.camera.BuiltinCameraDirection; |
| 8 | +import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName; |
| 9 | +import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit; |
| 10 | +import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit; |
| 11 | +import org.firstinspires.ftc.robotcore.external.navigation.Position; |
| 12 | +import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles; |
| 13 | +import org.firstinspires.ftc.vision.VisionPortal; |
| 14 | +import org.firstinspires.ftc.vision.apriltag.AprilTagDetection; |
| 15 | +import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor; |
| 16 | + |
| 17 | +import java.util.List; |
| 18 | + |
| 19 | +public class LocalisationSubsystem { |
| 20 | + private static final boolean USE_WEBCAM = true; |
| 21 | + private SparkFunOTOS OTOSSensor; |
| 22 | + private Telemetry telemetry; |
| 23 | + private AprilTagProcessor aprilTag; |
| 24 | + private VisionPortal visionPortal; |
| 25 | + HardwareMap hardwareMap; |
| 26 | + |
| 27 | + |
| 28 | + // CAMERA Position / YPR |
| 29 | + private Position cameraPosition = new Position(DistanceUnit.METER, |
| 30 | + 0, 0, 0, 0); |
| 31 | + |
| 32 | + // pitch was init'd as -90 in demo, but set to 0 here for now (-90 made no sense) |
| 33 | + private YawPitchRollAngles cameraOrientation = new YawPitchRollAngles(AngleUnit.DEGREES, |
| 34 | + 0, -90, 0, 0); |
| 35 | + |
| 36 | + |
| 37 | + // ROBOT X, Y and HDG |
| 38 | + public double robotX; |
| 39 | + public double robotY; |
| 40 | + public double robotH; |
| 41 | + |
| 42 | + |
| 43 | + |
| 44 | + public LocalisationSubsystem(HardwareMap hardwareMap, Telemetry telemetry) { |
| 45 | + this.telemetry = telemetry; |
| 46 | + this.hardwareMap = hardwareMap; |
| 47 | + |
| 48 | + configureAprilTag(); |
| 49 | + |
| 50 | + OTOSSensor = hardwareMap.get(SparkFunOTOS.class, "sensor_otos"); |
| 51 | + configureOTOS(); |
| 52 | + |
| 53 | + telemetry.addLine("Localisation Subsystem Configured"); |
| 54 | + telemetry.update(); |
| 55 | + } |
| 56 | + |
| 57 | + public void periodic() { |
| 58 | + List<AprilTagDetection> freshDetections = aprilTag.getFreshDetections(); |
| 59 | + |
| 60 | + if (!freshDetections.isEmpty()) { |
| 61 | + // we cannot assume that there is only one detection, but we do know the last one is the latest. therefore, by going through all of them, we can know we are up to date. |
| 62 | + for (AprilTagDetection detection : freshDetections) { |
| 63 | + // as shown by demo code - no "Obelisk" tags can be used for positioning |
| 64 | + if (!detection.metadata.name.contains("Obelisk")) { |
| 65 | + robotX = detection.robotPose.getPosition().x; |
| 66 | + robotY = detection.robotPose.getPosition().y; |
| 67 | + robotH = detection.robotPose.getOrientation().getYaw(AngleUnit.DEGREES); |
| 68 | + } |
| 69 | + } |
| 70 | + |
| 71 | + // update the OTOS's position data |
| 72 | + updateOTOS(); |
| 73 | + telemetry.addData("AprilUpdate", true); |
| 74 | + } else { |
| 75 | + // navigate off OTOS |
| 76 | + positionFromOTOS(); |
| 77 | + telemetry.addData("AprilUpdate", false); |
| 78 | + } |
| 79 | + |
| 80 | + telemetry.addData("RobotX", robotX); |
| 81 | + telemetry.addData("RobotY", robotY); |
| 82 | + telemetry.addData("RobotHDG", robotH); |
| 83 | + telemetry.update(); |
| 84 | + } |
| 85 | + |
| 86 | + private void updateOTOS() { |
| 87 | + SparkFunOTOS.Pose2D currentPosition = new SparkFunOTOS.Pose2D( |
| 88 | + robotX, |
| 89 | + robotY, |
| 90 | + robotH |
| 91 | + ); |
| 92 | + OTOSSensor.setPosition(currentPosition); |
| 93 | + } |
| 94 | + |
| 95 | + private void positionFromOTOS() { |
| 96 | + SparkFunOTOS.Pose2D currentPosition = OTOSSensor.getPosition(); |
| 97 | + robotX = currentPosition.x; |
| 98 | + robotY = currentPosition.y; |
| 99 | + robotH = currentPosition.h; |
| 100 | + } |
| 101 | + |
| 102 | + private void configureOTOS() { |
| 103 | + // UNIT CALIBRATION |
| 104 | + OTOSSensor.setLinearUnit(DistanceUnit.METER); |
| 105 | + OTOSSensor.setAngularUnit(AngleUnit.DEGREES); |
| 106 | + |
| 107 | + // OFFSET ON ROBOT -- todo: find exact values, need robot physically |
| 108 | + SparkFunOTOS.Pose2D offset = new SparkFunOTOS.Pose2D(0, 0, 0); // h is for heading, probably |
| 109 | + OTOSSensor.setOffset(offset); |
| 110 | + |
| 111 | + // SCALAR CALIBRATION -- todo: find exact values, need robot physically |
| 112 | + OTOSSensor.setLinearScalar(1.0); |
| 113 | + OTOSSensor.setAngularScalar(1.0); |
| 114 | + |
| 115 | + // CALIBRATE IMU |
| 116 | + OTOSSensor.calibrateImu(); |
| 117 | + OTOSSensor.resetTracking(); |
| 118 | + |
| 119 | + // starting position, will be updated by april tag positioning. |
| 120 | + SparkFunOTOS.Pose2D currentPosition = new SparkFunOTOS.Pose2D(0, 0, 0); |
| 121 | + OTOSSensor.setPosition(currentPosition); |
| 122 | + |
| 123 | + telemetry.addLine("OTOS Configured"); |
| 124 | + telemetry.update(); |
| 125 | + } |
| 126 | + |
| 127 | + |
| 128 | + private void configureAprilTag() { |
| 129 | + // april tag processor |
| 130 | + aprilTag = new AprilTagProcessor.Builder() |
| 131 | + .setCameraPose(cameraPosition, cameraOrientation) |
| 132 | + .build(); |
| 133 | + |
| 134 | + // vision portal |
| 135 | + VisionPortal.Builder builder = new VisionPortal.Builder(); |
| 136 | + |
| 137 | + // NOTE: USE_WEBCAM is set at top of class. idk what to set it, so it is currently true as the example code used that. |
| 138 | + if (USE_WEBCAM) { |
| 139 | + builder.setCamera(hardwareMap.get(WebcamName.class, "Webcam 1")); |
| 140 | + } else { |
| 141 | + builder.setCamera(BuiltinCameraDirection.FRONT); // used to be BACK in e.g. code |
| 142 | + } |
| 143 | + |
| 144 | + // enable the processor |
| 145 | + builder.addProcessor(aprilTag); |
| 146 | + visionPortal = builder.build(); |
| 147 | + telemetry.addLine("April Tag Process Configured"); |
| 148 | + telemetry.update(); |
| 149 | + } |
| 150 | +} |
0 commit comments