Skip to content

Commit

Permalink
Changes from today
Browse files Browse the repository at this point in the history
  • Loading branch information
JJTech0130 committed Nov 18, 2023
1 parent f42bf5f commit 12a2e7d
Show file tree
Hide file tree
Showing 4 changed files with 258 additions and 67 deletions.
Original file line number Diff line number Diff line change
@@ -1,49 +1,124 @@
package org.firstinspires.ftc.teamcode.opmode;

import android.graphics.Color;

import com.acmerobotics.dashboard.config.Config;
import com.acmerobotics.roadrunner.geometry.Pose2d;
import com.acmerobotics.roadrunner.geometry.Vector2d;
import com.qualcomm.hardware.lynx.LynxModule;
import com.qualcomm.robotcore.eventloop.opmode.Autonomous;
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
import com.qualcomm.robotcore.hardware.configuration.LynxConstants;

import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
import org.firstinspires.ftc.teamcode.drive.testbot.TestBotDrive;
import org.firstinspires.ftc.teamcode.trajectorysequence.TrajectorySequence;
import org.firstinspires.ftc.teamcode.util.Blinker;
import org.firstinspires.ftc.teamcode.vision.AprilTagCamera;
import org.firstinspires.ftc.teamcode.vision.AprilTagLocalizer;

import java.util.List;

@Autonomous
@Config
public class TestAuto extends LinearOpMode {
int[] colors = {
Color.rgb(255, 0, 0), // RED
Color.rgb(255, 128, 0), // ORANGE
Color.rgb(255, 255, 0), // YELLOW
Color.rgb(128, 255, 0), // LIME
Color.rgb(0, 255, 0), // GREEN
Color.rgb(0, 255, 128), // MINT
Color.rgb(0, 255, 255), // CYAN
Color.rgb(0, 128, 255), // BLUE
Color.rgb(0, 0, 255), // NAVY
Color.rgb(128, 0, 255), // PURPLE
Color.rgb(255, 0, 255), // PINK
Color.rgb(255, 0, 128), // HOT PINK
};

Blinker.Pattern rainbowPattern() {
Blinker.Pattern pattern = new Blinker.Pattern();
for (int color : colors) {
pattern.addStep(color, 150);
}
return pattern;
}

LynxModule controlHub(List<LynxModule> modules) {
for (LynxModule module : modules) {
if (module.getModuleAddress() == LynxConstants.CH_EMBEDDED_MODULE_ADDRESS) {
return module;
}
}
return null;
}

public static double FUDGE = 0;

@Override
public void runOpMode() throws InterruptedException {
TestBotDrive drive = new TestBotDrive(hardwareMap);

WebcamName[] webcams = new WebcamName[3];
webcams[0] = hardwareMap.get(WebcamName.class, "Webcam 1");
webcams[1] = hardwareMap.get(WebcamName.class, "Webcam 2");
webcams[2] = hardwareMap.get(WebcamName.class, "Webcam 3");
//List<LynxModule> modules = hardwareMap.getAll(LynxModule.class);
//LynxModule chub = controlHub(modules);
//Blinker blinker = new Blinker(chub);
//blinker.idle();

AprilTagCamera[] cameras = new AprilTagCamera[3];
cameras[0] = new AprilTagCamera(hardwareMap.get(WebcamName.class, "Left"), 8, Math.toRadians(70));
cameras[1] = new AprilTagCamera(hardwareMap.get(WebcamName.class, "Center"), 7, Math.toRadians(90));
cameras[2] = new AprilTagCamera(hardwareMap.get(WebcamName.class, "Right"), 8, Math.toRadians(-70));

AprilTagLocalizer aprilTag = new AprilTagLocalizer(cameras);

AprilTagLocalizer aprilTag = new AprilTagLocalizer(webcams);
Pose2d startPose = null;

Pose2d startPose = new Pose2d(-34, -62, Math.toRadians(90)); // Backup start pose
waiting:
while(opModeInInit()) {
Pose2d pose = aprilTag.estimateRobotPoseFromAprilTags(1, 10, Math.toRadians(70));
if (pose != null) {
startPose = pose;
drive.setPoseEstimate(startPose);
drive.update();
// Try each of the cameras until we get a pose estimate
for (AprilTagCamera camera : cameras) {
Pose2d pose = aprilTag.estimateRobotPoseFromAprilTags(camera);
if (pose != null) {
startPose = pose;
//blinker.displayPattern(rainbowPattern());
break waiting;
}
}
}

if (startPose == null) {
// Check one more time
for (AprilTagCamera camera : cameras) {
Pose2d pose = aprilTag.estimateRobotPoseFromAprilTags(camera);
if (pose != null) {
startPose = pose;
break;
//blinker.displayPattern(rainbowPattern())
}
}
}

if (startPose == null) {
// Give up
//startPose = new Pose2d(0, 0, 0);
throw new RuntimeException("BAD");
}

TrajectorySequence traj = null;

switch (aprilTag.whichQuadrant(startPose)) {
case RED_AUDIENCE:
// HACK: Fudge the startPose
startPose = new Pose2d(startPose.getX(), startPose.getY() - 5, startPose.getHeading());
startPose = new Pose2d(startPose.getX(), startPose.getY() + FUDGE, startPose.getHeading());
drive.setPoseEstimate(startPose);

traj = drive.trajectorySequenceBuilder(startPose)
.lineTo(new Vector2d(-34, -36))
.strafeTo(new Vector2d(48, -36))
.lineTo(new Vector2d(startPose.getX(), -24))
.splineTo(new Vector2d(0, 0), 0)
//.lineTo(new Vector2d(-34, -36))
//.strafeTo(new Vector2d(48, -36))
//.splineTo(new Vector2d(48, -35), 0)
.build();
break;
case RED_BOARD:
Expand All @@ -52,7 +127,7 @@ public void runOpMode() throws InterruptedException {
break;
case BLUE_BOARD:
// HACK: Fudge the startPose
startPose = new Pose2d(startPose.getX(), startPose.getY() + 5, startPose.getHeading());
startPose = new Pose2d(startPose.getX(), startPose.getY(), startPose.getHeading());
drive.setPoseEstimate(startPose);

traj = drive.trajectorySequenceBuilder(startPose)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
package org.firstinspires.ftc.teamcode.util;

import com.qualcomm.hardware.lynx.LynxModule;
import com.qualcomm.robotcore.hardware.Blinker.Step;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
* Control the status LED built-in to REV Control Hubs and REV Expansion Hubs
*/
public class Blinker {
private final LynxModule module;

/**
* Create a Blinker wrapper
* @param module the REV Hub to use
*/
public Blinker(LynxModule module) {
this.module = module;
}

/**
* @param pattern the pattern to display
* @see Pattern
*/
public void displayPattern(Pattern pattern) {
module.setPattern(pattern.steps);
}

/**
* Display the idle pattern
* <br/>
* <ul>
* <li>Expansion Hub</li>
* <ul>
* <li>GREEN for 5 seconds</li>
* <li>OFF for .5 seconds</li>
* <li>BLUE flashs corresponding to the ID (.5 ea. followed by .5 OFF)</li>
* </ul>
* <li>Control Hub: GREEN</li>
* </ul>
*/
public void idle() {
module.setPattern(new LynxModule.CountModuleAddressBlinkerPolicy().getIdlePattern(module));
}

/**
* Display a pattern that makes the module easily identifiable
* <br/>
* <ul>
* <li>CYAN for 150ms</li>
* <li>OFF for 75ms</li>
* <li>MAGENTA for 150ms</li>
* <li>OFF for 75ms</li>
* </ul>
*/
public void identify() {
module.setPattern(new LynxModule.BreathingBlinkerPolicy().getVisuallyIdentifyPattern(module));
}

public static class Pattern {
public static final int MAX_STEPS = 16;

private List<com.qualcomm.robotcore.hardware.Blinker.Step> steps = new ArrayList<>();

/**
* Add a step to the pattern. You can have a maximum of 16 steps.
* @param color the color to display (in Android's int color format)
* @param duration the duration in ms for this step to last
* @see android.graphics.Color
*/
public Pattern addStep(int color, int duration) {
steps.add(new Step(color, duration, TimeUnit.MILLISECONDS));
return this;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package org.firstinspires.ftc.teamcode.vision;

import com.acmerobotics.roadrunner.geometry.Pose2d;

import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;

public class AprilTagCamera {
public WebcamName webcamName;
private final double offset;
private final double angle;

public AprilTagCamera(WebcamName webcamName, double offset, double angle) {
this.webcamName = webcamName;
this.offset = offset;
this.angle = angle;
}

public Pose2d translatePose(Pose2d inputPose) {
double offsetX = offset * Math.cos(inputPose.getHeading());
double offsetY = offset * Math.sin(inputPose.getHeading());

android.util.Log.i("AprilTag Test", "Camera offset: " + offsetX + ", " + offsetY);

double robotX = inputPose.getX() - offsetX;
double robotY = inputPose.getY() - offsetY;
double robotHeading = inputPose.getHeading() - angle;

return new Pose2d(robotX, robotY, robotHeading);
}
}
Loading

0 comments on commit 12a2e7d

Please sign in to comment.