Merge pull request #1038 from FIRST-Tech-Challenge/20240828-111152-release-candidate
FtcRobotController v10.0
This commit is contained in:
@ -1,8 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:versionCode="54"
|
android:versionCode="55"
|
||||||
android:versionName="9.2">
|
android:versionName="10.0">
|
||||||
|
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
|
|
||||||
|
@ -99,7 +99,7 @@ public class BasicOmniOpMode_Linear extends LinearOpMode {
|
|||||||
rightFrontDrive.setDirection(DcMotor.Direction.FORWARD);
|
rightFrontDrive.setDirection(DcMotor.Direction.FORWARD);
|
||||||
rightBackDrive.setDirection(DcMotor.Direction.FORWARD);
|
rightBackDrive.setDirection(DcMotor.Direction.FORWARD);
|
||||||
|
|
||||||
// Wait for the game to start (driver presses PLAY)
|
// Wait for the game to start (driver presses START)
|
||||||
telemetry.addData("Status", "Initialized");
|
telemetry.addData("Status", "Initialized");
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
|
|
||||||
|
@ -83,14 +83,14 @@ public class BasicOpMode_Iterative extends OpMode
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code to run REPEATEDLY after the driver hits INIT, but before they hit PLAY
|
* Code to run REPEATEDLY after the driver hits INIT, but before they hit START
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void init_loop() {
|
public void init_loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code to run ONCE when the driver hits PLAY
|
* Code to run ONCE when the driver hits START
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
@ -98,7 +98,7 @@ public class BasicOpMode_Iterative extends OpMode
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code to run REPEATEDLY after the driver hits PLAY but before they hit STOP
|
* Code to run REPEATEDLY after the driver hits START but before they hit STOP
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void loop() {
|
public void loop() {
|
||||||
|
@ -76,7 +76,7 @@ public class BasicOpMode_Linear extends LinearOpMode {
|
|||||||
leftDrive.setDirection(DcMotor.Direction.REVERSE);
|
leftDrive.setDirection(DcMotor.Direction.REVERSE);
|
||||||
rightDrive.setDirection(DcMotor.Direction.FORWARD);
|
rightDrive.setDirection(DcMotor.Direction.FORWARD);
|
||||||
|
|
||||||
// Wait for the game to start (driver presses PLAY)
|
// Wait for the game to start (driver presses START)
|
||||||
waitForStart();
|
waitForStart();
|
||||||
runtime.reset();
|
runtime.reset();
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ public class ConceptAprilTag extends LinearOpMode {
|
|||||||
|
|
||||||
// Wait for the DS start button to be touched.
|
// Wait for the DS start button to be touched.
|
||||||
telemetry.addData("DS preview on/off", "3 dots, Camera Stream");
|
telemetry.addData("DS preview on/off", "3 dots, Camera Stream");
|
||||||
telemetry.addData(">", "Touch Play to start OpMode");
|
telemetry.addData(">", "Touch START to start OpMode");
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
waitForStart();
|
waitForStart();
|
||||||
|
|
||||||
|
@ -84,7 +84,7 @@ public class ConceptAprilTagEasy extends LinearOpMode {
|
|||||||
|
|
||||||
// Wait for the DS start button to be touched.
|
// Wait for the DS start button to be touched.
|
||||||
telemetry.addData("DS preview on/off", "3 dots, Camera Stream");
|
telemetry.addData("DS preview on/off", "3 dots, Camera Stream");
|
||||||
telemetry.addData(">", "Touch Play to start OpMode");
|
telemetry.addData(">", "Touch START to start OpMode");
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
waitForStart();
|
waitForStart();
|
||||||
|
|
||||||
|
@ -0,0 +1,244 @@
|
|||||||
|
/* Copyright (c) 2024 Dryw Wade. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
* are permitted (subject to the limitations in the disclaimer below) provided that
|
||||||
|
* the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
* of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
* list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
* other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of FIRST nor the names of its contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
|
||||||
|
* LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||||
|
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.firstinspires.ftc.robotcontroller.external.samples;
|
||||||
|
|
||||||
|
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
|
||||||
|
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
|
||||||
|
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
|
||||||
|
|
||||||
|
import org.firstinspires.ftc.robotcore.external.hardware.camera.BuiltinCameraDirection;
|
||||||
|
import org.firstinspires.ftc.robotcore.external.hardware.camera.WebcamName;
|
||||||
|
import org.firstinspires.ftc.robotcore.external.navigation.AngleUnit;
|
||||||
|
import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
|
||||||
|
import org.firstinspires.ftc.robotcore.external.navigation.Position;
|
||||||
|
import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles;
|
||||||
|
import org.firstinspires.ftc.vision.VisionPortal;
|
||||||
|
import org.firstinspires.ftc.vision.apriltag.AprilTagDetection;
|
||||||
|
import org.firstinspires.ftc.vision.apriltag.AprilTagProcessor;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This OpMode illustrates the basics of AprilTag based localization.
|
||||||
|
*
|
||||||
|
* For an introduction to AprilTags, see the FTC-DOCS link below:
|
||||||
|
* https://ftc-docs.firstinspires.org/en/latest/apriltag/vision_portal/apriltag_intro/apriltag-intro.html
|
||||||
|
*
|
||||||
|
* In this sample, any visible tag ID will be detected and displayed, but only tags that are included in the default
|
||||||
|
* "TagLibrary" will be used to compute the robot's location and orientation. This default TagLibrary contains
|
||||||
|
* the current Season's AprilTags and a small set of "test Tags" in the high number range.
|
||||||
|
*
|
||||||
|
* When an AprilTag in the TagLibrary is detected, the SDK provides location and orientation of the robot, relative to the field origin.
|
||||||
|
* This information is provided in the "robotPose" member of the returned "detection".
|
||||||
|
*
|
||||||
|
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
|
||||||
|
* Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list.
|
||||||
|
*/
|
||||||
|
@TeleOp(name = "Concept: AprilTag Localization", group = "Concept")
|
||||||
|
@Disabled
|
||||||
|
public class ConceptAprilTagLocalization extends LinearOpMode {
|
||||||
|
|
||||||
|
private static final boolean USE_WEBCAM = true; // true for webcam, false for phone camera
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variables to store the position and orientation of the camera on the robot. Setting these
|
||||||
|
* values requires a definition of the axes of the camera and robot:
|
||||||
|
*
|
||||||
|
* Camera axes:
|
||||||
|
* Origin location: Center of the lens
|
||||||
|
* Axes orientation: +x right, +y down, +z forward (from camera's perspective)
|
||||||
|
*
|
||||||
|
* Robot axes (this is typical, but you can define this however you want):
|
||||||
|
* Origin location: Center of the robot at field height
|
||||||
|
* Axes orientation: +x right, +y forward, +z upward
|
||||||
|
*
|
||||||
|
* Position:
|
||||||
|
* If all values are zero (no translation), that implies the camera is at the center of the
|
||||||
|
* robot. Suppose your camera is positioned 5 inches to the left, 7 inches forward, and 12
|
||||||
|
* inches above the ground - you would need to set the position to (-5, 7, 12).
|
||||||
|
*
|
||||||
|
* Orientation:
|
||||||
|
* If all values are zero (no rotation), that implies the camera is pointing straight up. In
|
||||||
|
* most cases, you'll need to set the pitch to -90 degrees (rotation about the x-axis), meaning
|
||||||
|
* the camera is horizontal. Use a yaw of 0 if the camera is pointing forwards, +90 degrees if
|
||||||
|
* it's pointing straight left, -90 degrees for straight right, etc. You can also set the roll
|
||||||
|
* to +/-90 degrees if it's vertical, or 180 degrees if it's upside-down.
|
||||||
|
*/
|
||||||
|
private Position cameraPosition = new Position(DistanceUnit.INCH,
|
||||||
|
0, 0, 0, 0);
|
||||||
|
private YawPitchRollAngles cameraOrientation = new YawPitchRollAngles(AngleUnit.DEGREES,
|
||||||
|
0, -90, 0, 0);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The variable to store our instance of the AprilTag processor.
|
||||||
|
*/
|
||||||
|
private AprilTagProcessor aprilTag;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The variable to store our instance of the vision portal.
|
||||||
|
*/
|
||||||
|
private VisionPortal visionPortal;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runOpMode() {
|
||||||
|
|
||||||
|
initAprilTag();
|
||||||
|
|
||||||
|
// Wait for the DS start button to be touched.
|
||||||
|
telemetry.addData("DS preview on/off", "3 dots, Camera Stream");
|
||||||
|
telemetry.addData(">", "Touch START to start OpMode");
|
||||||
|
telemetry.update();
|
||||||
|
waitForStart();
|
||||||
|
|
||||||
|
while (opModeIsActive()) {
|
||||||
|
|
||||||
|
telemetryAprilTag();
|
||||||
|
|
||||||
|
// Push telemetry to the Driver Station.
|
||||||
|
telemetry.update();
|
||||||
|
|
||||||
|
// Save CPU resources; can resume streaming when needed.
|
||||||
|
if (gamepad1.dpad_down) {
|
||||||
|
visionPortal.stopStreaming();
|
||||||
|
} else if (gamepad1.dpad_up) {
|
||||||
|
visionPortal.resumeStreaming();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Share the CPU.
|
||||||
|
sleep(20);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save more CPU resources when camera is no longer needed.
|
||||||
|
visionPortal.close();
|
||||||
|
|
||||||
|
} // end method runOpMode()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize the AprilTag processor.
|
||||||
|
*/
|
||||||
|
private void initAprilTag() {
|
||||||
|
|
||||||
|
// Create the AprilTag processor.
|
||||||
|
aprilTag = new AprilTagProcessor.Builder()
|
||||||
|
|
||||||
|
// The following default settings are available to un-comment and edit as needed.
|
||||||
|
//.setDrawAxes(false)
|
||||||
|
//.setDrawCubeProjection(false)
|
||||||
|
//.setDrawTagOutline(true)
|
||||||
|
//.setTagFamily(AprilTagProcessor.TagFamily.TAG_36h11)
|
||||||
|
//.setTagLibrary(AprilTagGameDatabase.getCenterStageTagLibrary())
|
||||||
|
//.setOutputUnits(DistanceUnit.INCH, AngleUnit.DEGREES)
|
||||||
|
.setCameraPose(cameraPosition, cameraOrientation)
|
||||||
|
|
||||||
|
// == CAMERA CALIBRATION ==
|
||||||
|
// If you do not manually specify calibration parameters, the SDK will attempt
|
||||||
|
// to load a predefined calibration for your camera.
|
||||||
|
//.setLensIntrinsics(578.272, 578.272, 402.145, 221.506)
|
||||||
|
// ... these parameters are fx, fy, cx, cy.
|
||||||
|
|
||||||
|
.build();
|
||||||
|
|
||||||
|
// Adjust Image Decimation to trade-off detection-range for detection-rate.
|
||||||
|
// eg: Some typical detection data using a Logitech C920 WebCam
|
||||||
|
// Decimation = 1 .. Detect 2" Tag from 10 feet away at 10 Frames per second
|
||||||
|
// Decimation = 2 .. Detect 2" Tag from 6 feet away at 22 Frames per second
|
||||||
|
// Decimation = 3 .. Detect 2" Tag from 4 feet away at 30 Frames Per Second (default)
|
||||||
|
// Decimation = 3 .. Detect 5" Tag from 10 feet away at 30 Frames Per Second (default)
|
||||||
|
// Note: Decimation can be changed on-the-fly to adapt during a match.
|
||||||
|
//aprilTag.setDecimation(3);
|
||||||
|
|
||||||
|
// Create the vision portal by using a builder.
|
||||||
|
VisionPortal.Builder builder = new VisionPortal.Builder();
|
||||||
|
|
||||||
|
// Set the camera (webcam vs. built-in RC phone camera).
|
||||||
|
if (USE_WEBCAM) {
|
||||||
|
builder.setCamera(hardwareMap.get(WebcamName.class, "Webcam 1"));
|
||||||
|
} else {
|
||||||
|
builder.setCamera(BuiltinCameraDirection.BACK);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Choose a camera resolution. Not all cameras support all resolutions.
|
||||||
|
//builder.setCameraResolution(new Size(640, 480));
|
||||||
|
|
||||||
|
// Enable the RC preview (LiveView). Set "false" to omit camera monitoring.
|
||||||
|
//builder.enableLiveView(true);
|
||||||
|
|
||||||
|
// Set the stream format; MJPEG uses less bandwidth than default YUY2.
|
||||||
|
//builder.setStreamFormat(VisionPortal.StreamFormat.YUY2);
|
||||||
|
|
||||||
|
// Choose whether or not LiveView stops if no processors are enabled.
|
||||||
|
// If set "true", monitor shows solid orange screen if no processors enabled.
|
||||||
|
// If set "false", monitor shows camera view without annotations.
|
||||||
|
//builder.setAutoStopLiveView(false);
|
||||||
|
|
||||||
|
// Set and enable the processor.
|
||||||
|
builder.addProcessor(aprilTag);
|
||||||
|
|
||||||
|
// Build the Vision Portal, using the above settings.
|
||||||
|
visionPortal = builder.build();
|
||||||
|
|
||||||
|
// Disable or re-enable the aprilTag processor at any time.
|
||||||
|
//visionPortal.setProcessorEnabled(aprilTag, true);
|
||||||
|
|
||||||
|
} // end method initAprilTag()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add telemetry about AprilTag detections.
|
||||||
|
*/
|
||||||
|
private void telemetryAprilTag() {
|
||||||
|
|
||||||
|
List<AprilTagDetection> currentDetections = aprilTag.getDetections();
|
||||||
|
telemetry.addData("# AprilTags Detected", currentDetections.size());
|
||||||
|
|
||||||
|
// Step through the list of detections and display info for each one.
|
||||||
|
for (AprilTagDetection detection : currentDetections) {
|
||||||
|
if (detection.metadata != null) {
|
||||||
|
telemetry.addLine(String.format("\n==== (ID %d) %s", detection.id, detection.metadata.name));
|
||||||
|
telemetry.addLine(String.format("XYZ %6.1f %6.1f %6.1f (inch)",
|
||||||
|
detection.robotPose.getPosition().x,
|
||||||
|
detection.robotPose.getPosition().y,
|
||||||
|
detection.robotPose.getPosition().z));
|
||||||
|
telemetry.addLine(String.format("PRY %6.1f %6.1f %6.1f (deg)",
|
||||||
|
detection.robotPose.getOrientation().getPitch(AngleUnit.DEGREES),
|
||||||
|
detection.robotPose.getOrientation().getRoll(AngleUnit.DEGREES),
|
||||||
|
detection.robotPose.getOrientation().getYaw(AngleUnit.DEGREES)));
|
||||||
|
} else {
|
||||||
|
telemetry.addLine(String.format("\n==== (ID %d) Unknown", detection.id));
|
||||||
|
telemetry.addLine(String.format("Center %6.0f %6.0f (pixels)", detection.center.x, detection.center.y));
|
||||||
|
}
|
||||||
|
} // end for() loop
|
||||||
|
|
||||||
|
// Add "key" information to telemetry
|
||||||
|
telemetry.addLine("\nkey:\nXYZ = X (Right), Y (Forward), Z (Up) dist.");
|
||||||
|
telemetry.addLine("PRY = Pitch, Roll & Yaw (XYZ Rotation)");
|
||||||
|
|
||||||
|
} // end method telemetryAprilTag()
|
||||||
|
|
||||||
|
} // end class
|
@ -98,7 +98,7 @@ public class ConceptAprilTagOptimizeExposure extends LinearOpMode
|
|||||||
|
|
||||||
// Wait for the match to begin.
|
// Wait for the match to begin.
|
||||||
telemetry.addData("Camera preview on/off", "3 dots, Camera Stream");
|
telemetry.addData("Camera preview on/off", "3 dots, Camera Stream");
|
||||||
telemetry.addData(">", "Touch Play to start OpMode");
|
telemetry.addData(">", "Touch START to start OpMode");
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
waitForStart();
|
waitForStart();
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ public class ConceptAprilTagSwitchableCameras extends LinearOpMode {
|
|||||||
|
|
||||||
// Wait for the DS start button to be touched.
|
// Wait for the DS start button to be touched.
|
||||||
telemetry.addData("DS preview on/off", "3 dots, Camera Stream");
|
telemetry.addData("DS preview on/off", "3 dots, Camera Stream");
|
||||||
telemetry.addData(">", "Touch Play to start OpMode");
|
telemetry.addData(">", "Touch START to start OpMode");
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
waitForStart();
|
waitForStart();
|
||||||
|
|
||||||
|
@ -83,7 +83,7 @@ public class ConceptExternalHardwareClass extends LinearOpMode {
|
|||||||
robot.init();
|
robot.init();
|
||||||
|
|
||||||
// Send telemetry message to signify robot waiting;
|
// Send telemetry message to signify robot waiting;
|
||||||
// Wait for the game to start (driver presses PLAY)
|
// Wait for the game to start (driver presses START)
|
||||||
waitForStart();
|
waitForStart();
|
||||||
|
|
||||||
// run until the end of the match (driver presses STOP)
|
// run until the end of the match (driver presses STOP)
|
||||||
|
@ -0,0 +1,123 @@
|
|||||||
|
package org.firstinspires.ftc.robotcontroller.external.samples;
|
||||||
|
/*
|
||||||
|
Copyright (c) 2021-24 Alan Smith
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted (subject to the limitations in the disclaimer below) provided that
|
||||||
|
the following conditions are met:
|
||||||
|
|
||||||
|
Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
other materials provided with the distribution.
|
||||||
|
|
||||||
|
Neither the name of Alan Smith nor the names of its contributors may be used to
|
||||||
|
endorse or promote products derived from this software without specific prior
|
||||||
|
written permission.
|
||||||
|
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
|
||||||
|
LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESSFOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.graphics.Color;
|
||||||
|
|
||||||
|
import com.qualcomm.hardware.sparkfun.SparkFunLEDStick;
|
||||||
|
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
|
||||||
|
import com.qualcomm.robotcore.eventloop.opmode.OpMode;
|
||||||
|
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
|
||||||
|
import com.qualcomm.robotcore.util.Range;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This OpMode illustrates how to use the SparkFun QWIIC LED Strip
|
||||||
|
*
|
||||||
|
* This is a simple way to add a strip of 10 LEDs to your robot where you can set the color of each
|
||||||
|
* LED or the whole strip. This allows for driver feedback or even just fun ways to show your team
|
||||||
|
* colors.
|
||||||
|
*
|
||||||
|
* Why?
|
||||||
|
* Because more LEDs == more fun!!
|
||||||
|
*
|
||||||
|
* This OpMode assumes that the QWIIC LED Stick is attached to an I2C interface named "back_leds" in the robot configuration.
|
||||||
|
*
|
||||||
|
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
|
||||||
|
* Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list
|
||||||
|
*
|
||||||
|
* You can buy this product here: https://www.sparkfun.com/products/18354
|
||||||
|
* Don't forget to also buy this to make it easy to connect to your Control or Expansion Hub:
|
||||||
|
* https://www.sparkfun.com/products/25596
|
||||||
|
*/
|
||||||
|
@TeleOp(name = "Concept: LED Stick", group = "Concept")
|
||||||
|
@Disabled
|
||||||
|
public class ConceptLEDStick extends OpMode {
|
||||||
|
private boolean wasUp;
|
||||||
|
private boolean wasDown;
|
||||||
|
private int brightness = 5; // this needs to be between 0 and 31
|
||||||
|
private final static double END_GAME_TIME = 120 - 30;
|
||||||
|
|
||||||
|
private SparkFunLEDStick ledStick;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
ledStick = hardwareMap.get(SparkFunLEDStick.class, "back_leds");
|
||||||
|
ledStick.setBrightness(brightness);
|
||||||
|
ledStick.setColor(Color.GREEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void start() {
|
||||||
|
resetRuntime();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loop() {
|
||||||
|
telemetry.addLine("Hold the A button to turn blue");
|
||||||
|
telemetry.addLine("Hold the B button to turn red");
|
||||||
|
telemetry.addLine("Hold the left bumper to turn off");
|
||||||
|
telemetry.addLine("Use DPAD Up/Down to change brightness");
|
||||||
|
|
||||||
|
if (getRuntime() > END_GAME_TIME) {
|
||||||
|
int[] ledColors = {Color.RED, Color.YELLOW, Color.RED, Color.YELLOW, Color.RED,
|
||||||
|
Color.YELLOW, Color.RED, Color.YELLOW, Color.RED, Color.YELLOW};
|
||||||
|
ledStick.setColors(ledColors);
|
||||||
|
} else if (gamepad1.a) {
|
||||||
|
ledStick.setColor(Color.BLUE);
|
||||||
|
} else if (gamepad1.b) {
|
||||||
|
ledStick.setColor(Color.RED);
|
||||||
|
} else if (gamepad1.left_bumper) {
|
||||||
|
ledStick.turnAllOff();
|
||||||
|
} else {
|
||||||
|
ledStick.setColor(Color.GREEN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Use DPAD up and down to change brightness
|
||||||
|
*/
|
||||||
|
int newBrightness = brightness;
|
||||||
|
if (gamepad1.dpad_up && !wasUp) {
|
||||||
|
newBrightness = brightness + 1;
|
||||||
|
} else if (gamepad1.dpad_down && !wasDown) {
|
||||||
|
newBrightness = brightness - 1;
|
||||||
|
}
|
||||||
|
if (newBrightness != brightness) {
|
||||||
|
brightness = Range.clip(newBrightness, 0, 31);
|
||||||
|
ledStick.setBrightness(brightness);
|
||||||
|
}
|
||||||
|
telemetry.addData("Brightness", brightness);
|
||||||
|
|
||||||
|
wasDown = gamepad1.dpad_down;
|
||||||
|
wasUp = gamepad1.dpad_up;
|
||||||
|
}
|
||||||
|
}
|
@ -110,7 +110,7 @@ public class ConceptMotorBulkRead extends LinearOpMode {
|
|||||||
|
|
||||||
ElapsedTime timer = new ElapsedTime();
|
ElapsedTime timer = new ElapsedTime();
|
||||||
|
|
||||||
telemetry.addData(">", "Press play to start tests");
|
telemetry.addData(">", "Press START to start tests");
|
||||||
telemetry.addData(">", "Test results will update for each access method.");
|
telemetry.addData(">", "Test results will update for each access method.");
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
waitForStart();
|
waitForStart();
|
||||||
|
@ -53,7 +53,7 @@ public class ConceptNullOp extends OpMode {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will be called repeatedly during the period between when
|
* This method will be called repeatedly during the period between when
|
||||||
* the init button is pressed and when the play button is pressed (or the
|
* the INIT button is pressed and when the START button is pressed (or the
|
||||||
* OpMode is stopped).
|
* OpMode is stopped).
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
@ -61,7 +61,7 @@ public class ConceptNullOp extends OpMode {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will be called once, when the play button is pressed.
|
* This method will be called once, when the START button is pressed.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
@ -70,7 +70,7 @@ public class ConceptNullOp extends OpMode {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method will be called repeatedly during the period between when
|
* This method will be called repeatedly during the period between when
|
||||||
* the play button is pressed and when the OpMode is stopped.
|
* the START button is pressed and when the OpMode is stopped.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void loop() {
|
public void loop() {
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2024 Alan Smith
|
||||||
|
All rights reserved.
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted (subject to the limitations in the disclaimer below) provided that
|
||||||
|
the following conditions are met:
|
||||||
|
Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
other materials provided with the distribution.
|
||||||
|
Neither the name of Alan Smith nor the names of its contributors may be used to
|
||||||
|
endorse or promote products derived from this software without specific prior
|
||||||
|
written permission.
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
|
||||||
|
LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESSFOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package org.firstinspires.ftc.robotcontroller.external.samples;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This OpMode illustrates how to use the REV Digital Indicator
|
||||||
|
*
|
||||||
|
* This is a simple way to add the REV Digital Indicator which has a red and green LED.
|
||||||
|
* (and as you may remember, red + green = yellow so when they are both on you can get yellow)
|
||||||
|
*
|
||||||
|
* Why?
|
||||||
|
* You can use this to show information to the driver. For example, green might be that you can
|
||||||
|
* pick up more game elements and red would be that you already have the possession limit.
|
||||||
|
*
|
||||||
|
* This OpMode assumes that the REV Digital Indicator is setup as 2 Digital Channels named
|
||||||
|
* front_led_green and front_led_red. (the green should be the lower of the 2 channels it is plugged
|
||||||
|
* into and the red should be the higher)
|
||||||
|
*
|
||||||
|
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
|
||||||
|
* Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list
|
||||||
|
*
|
||||||
|
* You can buy this product here: https://www.revrobotics.com/rev-31-2010/
|
||||||
|
*/
|
||||||
|
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
|
||||||
|
import com.qualcomm.robotcore.eventloop.opmode.OpMode;
|
||||||
|
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
|
||||||
|
import com.qualcomm.robotcore.hardware.LED;
|
||||||
|
|
||||||
|
@TeleOp(name = "Concept: RevLED", group = "Concept")
|
||||||
|
@Disabled
|
||||||
|
public class ConceptRevLED extends OpMode {
|
||||||
|
LED frontLED_red;
|
||||||
|
LED frontLED_green;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void init() {
|
||||||
|
frontLED_green = hardwareMap.get(LED.class, "front_led_green");
|
||||||
|
frontLED_red = hardwareMap.get(LED.class, "front_led_red");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void loop() {
|
||||||
|
if (gamepad1.a) {
|
||||||
|
frontLED_red.on();
|
||||||
|
} else {
|
||||||
|
frontLED_red.off();
|
||||||
|
}
|
||||||
|
if (gamepad1.b) {
|
||||||
|
frontLED_green.on();
|
||||||
|
} else {
|
||||||
|
frontLED_green.off();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -38,8 +38,9 @@ import com.qualcomm.robotcore.util.Range;
|
|||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This OpMode executes a basic Tank Drive Teleop for a two wheeled robot using two REV SPARKminis.
|
* This OpMode demonstrates a POV Drive system, with commented-out code for a Tank Drive system,
|
||||||
* To use this example, connect two REV SPARKminis into servo ports on the Expansion Hub. On the
|
* for a two wheeled robot using two REV SPARKminis.
|
||||||
|
* To use this example, connect two REV SPARKminis into servo ports on the Control Hub. On the
|
||||||
* robot configuration, use the drop down list under 'Servos' to select 'REV SPARKmini Controller'
|
* robot configuration, use the drop down list under 'Servos' to select 'REV SPARKmini Controller'
|
||||||
* and name them 'left_drive' and 'right_drive'.
|
* and name them 'left_drive' and 'right_drive'.
|
||||||
*
|
*
|
||||||
@ -62,8 +63,7 @@ public class ConceptRevSPARKMini extends LinearOpMode {
|
|||||||
telemetry.update();
|
telemetry.update();
|
||||||
|
|
||||||
// Initialize the hardware variables. Note that the strings used here as parameters
|
// Initialize the hardware variables. Note that the strings used here as parameters
|
||||||
// to 'get' must correspond to the names assigned during the robot configuration
|
// to 'get' must correspond to the names assigned during robot configuration.
|
||||||
// step (using the FTC Robot Controller app on the phone).
|
|
||||||
leftDrive = hardwareMap.get(DcMotorSimple.class, "left_drive");
|
leftDrive = hardwareMap.get(DcMotorSimple.class, "left_drive");
|
||||||
rightDrive = hardwareMap.get(DcMotorSimple.class, "right_drive");
|
rightDrive = hardwareMap.get(DcMotorSimple.class, "right_drive");
|
||||||
|
|
||||||
@ -72,7 +72,7 @@ public class ConceptRevSPARKMini extends LinearOpMode {
|
|||||||
leftDrive.setDirection(DcMotorSimple.Direction.FORWARD);
|
leftDrive.setDirection(DcMotorSimple.Direction.FORWARD);
|
||||||
rightDrive.setDirection(DcMotorSimple.Direction.REVERSE);
|
rightDrive.setDirection(DcMotorSimple.Direction.REVERSE);
|
||||||
|
|
||||||
// Wait for the game to start (driver presses PLAY)
|
// Wait for the game to start (driver presses START)
|
||||||
waitForStart();
|
waitForStart();
|
||||||
runtime.reset();
|
runtime.reset();
|
||||||
|
|
||||||
|
@ -100,7 +100,7 @@ public class ConceptSoundsASJava extends LinearOpMode {
|
|||||||
telemetry.addData("gold resource", goldFound ? "Found" : "NOT found\n Add gold.wav to /src/main/res/raw" );
|
telemetry.addData("gold resource", goldFound ? "Found" : "NOT found\n Add gold.wav to /src/main/res/raw" );
|
||||||
telemetry.addData("silver resource", silverFound ? "Found" : "Not found\n Add silver.wav to /src/main/res/raw" );
|
telemetry.addData("silver resource", silverFound ? "Found" : "Not found\n Add silver.wav to /src/main/res/raw" );
|
||||||
|
|
||||||
// Wait for the game to start (driver presses PLAY)
|
// Wait for the game to start (driver presses START)
|
||||||
telemetry.addData(">", "Press Start to continue");
|
telemetry.addData(">", "Press Start to continue");
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
waitForStart();
|
waitForStart();
|
||||||
|
@ -110,7 +110,7 @@ public class RobotAutoDriveByEncoder_Linear extends LinearOpMode {
|
|||||||
rightDrive.getCurrentPosition());
|
rightDrive.getCurrentPosition());
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
|
|
||||||
// Wait for the game to start (driver presses PLAY)
|
// Wait for the game to start (driver presses START)
|
||||||
waitForStart();
|
waitForStart();
|
||||||
|
|
||||||
// Step through each leg of the path,
|
// Step through each leg of the path,
|
||||||
|
@ -65,7 +65,7 @@ import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles;
|
|||||||
* Notes:
|
* Notes:
|
||||||
*
|
*
|
||||||
* All angles are referenced to the coordinate-frame that is set whenever resetHeading() is called.
|
* All angles are referenced to the coordinate-frame that is set whenever resetHeading() is called.
|
||||||
* In this sample, the heading is reset when the Start button is touched on the Driver station.
|
* In this sample, the heading is reset when the Start button is touched on the Driver Station.
|
||||||
* Note: It would be possible to reset the heading after each move, but this would accumulate steering errors.
|
* Note: It would be possible to reset the heading after each move, but this would accumulate steering errors.
|
||||||
*
|
*
|
||||||
* The angle of movement/rotation is assumed to be a standardized rotation around the robot Z axis,
|
* The angle of movement/rotation is assumed to be a standardized rotation around the robot Z axis,
|
||||||
@ -124,15 +124,15 @@ public class RobotAutoDriveByGyro_Linear extends LinearOpMode {
|
|||||||
// These constants define the desired driving/control characteristics
|
// These constants define the desired driving/control characteristics
|
||||||
// They can/should be tweaked to suit the specific robot drive train.
|
// They can/should be tweaked to suit the specific robot drive train.
|
||||||
static final double DRIVE_SPEED = 0.4; // Max driving speed for better distance accuracy.
|
static final double DRIVE_SPEED = 0.4; // Max driving speed for better distance accuracy.
|
||||||
static final double TURN_SPEED = 0.2; // Max Turn speed to limit turn rate
|
static final double TURN_SPEED = 0.2; // Max turn speed to limit turn rate.
|
||||||
static final double HEADING_THRESHOLD = 1.0 ; // How close must the heading get to the target before moving to next step.
|
static final double HEADING_THRESHOLD = 1.0 ; // How close must the heading get to the target before moving to next step.
|
||||||
// Requiring more accuracy (a smaller number) will often make the turn take longer to get into the final position.
|
// Requiring more accuracy (a smaller number) will often make the turn take longer to get into the final position.
|
||||||
// Define the Proportional control coefficient (or GAIN) for "heading control".
|
// Define the Proportional control coefficient (or GAIN) for "heading control".
|
||||||
// We define one value when Turning (larger errors), and the other is used when Driving straight (smaller errors).
|
// We define one value when Turning (larger errors), and the other is used when Driving straight (smaller errors).
|
||||||
// Increase these numbers if the heading does not corrects strongly enough (eg: a heavy robot or using tracks)
|
// Increase these numbers if the heading does not correct strongly enough (eg: a heavy robot or using tracks)
|
||||||
// Decrease these numbers if the heading does not settle on the correct value (eg: very agile robot with omni wheels)
|
// Decrease these numbers if the heading does not settle on the correct value (eg: very agile robot with omni wheels)
|
||||||
static final double P_TURN_GAIN = 0.02; // Larger is more responsive, but also less stable
|
static final double P_TURN_GAIN = 0.02; // Larger is more responsive, but also less stable.
|
||||||
static final double P_DRIVE_GAIN = 0.03; // Larger is more responsive, but also less stable
|
static final double P_DRIVE_GAIN = 0.03; // Larger is more responsive, but also less stable.
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -317,7 +317,7 @@ public class RobotAutoDriveByGyro_Linear extends LinearOpMode {
|
|||||||
* <p>
|
* <p>
|
||||||
* Move will stop once the requested time has elapsed
|
* Move will stop once the requested time has elapsed
|
||||||
* <p>
|
* <p>
|
||||||
* This function is useful for giving the robot a moment to stabilize it's heading between movements.
|
* This function is useful for giving the robot a moment to stabilize its heading between movements.
|
||||||
*
|
*
|
||||||
* @param maxTurnSpeed Maximum differential turn speed (range 0 to +1.0)
|
* @param maxTurnSpeed Maximum differential turn speed (range 0 to +1.0)
|
||||||
* @param heading Absolute Heading Angle (in Degrees) relative to last gyro reset.
|
* @param heading Absolute Heading Angle (in Degrees) relative to last gyro reset.
|
||||||
|
@ -85,10 +85,10 @@ public class RobotAutoDriveByTime_Linear extends LinearOpMode {
|
|||||||
telemetry.addData("Status", "Ready to run"); //
|
telemetry.addData("Status", "Ready to run"); //
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
|
|
||||||
// Wait for the game to start (driver presses PLAY)
|
// Wait for the game to start (driver presses START)
|
||||||
waitForStart();
|
waitForStart();
|
||||||
|
|
||||||
// Step through each leg of the path, ensuring that the Auto mode has not been stopped along the way
|
// Step through each leg of the path, ensuring that the OpMode has not been stopped along the way.
|
||||||
|
|
||||||
// Step 1: Drive forward for 3 seconds
|
// Step 1: Drive forward for 3 seconds
|
||||||
leftDrive.setPower(FORWARD_SPEED);
|
leftDrive.setPower(FORWARD_SPEED);
|
||||||
|
@ -64,7 +64,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* The code assumes a Robot Configuration with motors named: leftfront_drive and rightfront_drive, leftback_drive and rightback_drive.
|
* The code assumes a Robot Configuration with motors named: leftfront_drive and rightfront_drive, leftback_drive and rightback_drive.
|
||||||
* The motor directions must be set so a positive power goes forward on all wheels.
|
* The motor directions must be set so a positive power goes forward on all wheels.
|
||||||
* This sample assumes that the current game AprilTag Library (usually for the current season) is being loaded by default,
|
* This sample assumes that the current game AprilTag Library (usually for the current season) is being loaded by default,
|
||||||
* so you should choose to approach a valid tag ID (usually starting at 0)
|
* so you should choose to approach a valid tag ID.
|
||||||
*
|
*
|
||||||
* Under manual control, the left stick will move forward/back & left/right. The right stick will rotate the robot.
|
* Under manual control, the left stick will move forward/back & left/right. The right stick will rotate the robot.
|
||||||
* Manually drive the robot until it displays Target data on the Driver Station.
|
* Manually drive the robot until it displays Target data on the Driver Station.
|
||||||
@ -95,12 +95,12 @@ public class RobotAutoDriveToAprilTagOmni extends LinearOpMode
|
|||||||
// Set the GAIN constants to control the relationship between the measured position error, and how much power is
|
// Set the GAIN constants to control the relationship between the measured position error, and how much power is
|
||||||
// applied to the drive motors to correct the error.
|
// applied to the drive motors to correct the error.
|
||||||
// Drive = Error * Gain Make these values smaller for smoother control, or larger for a more aggressive response.
|
// Drive = Error * Gain Make these values smaller for smoother control, or larger for a more aggressive response.
|
||||||
final double SPEED_GAIN = 0.02 ; // Forward Speed Control "Gain". eg: Ramp up to 50% power at a 25 inch error. (0.50 / 25.0)
|
final double SPEED_GAIN = 0.02 ; // Forward Speed Control "Gain". e.g. Ramp up to 50% power at a 25 inch error. (0.50 / 25.0)
|
||||||
final double STRAFE_GAIN = 0.015 ; // Strafe Speed Control "Gain". eg: Ramp up to 25% power at a 25 degree Yaw error. (0.25 / 25.0)
|
final double STRAFE_GAIN = 0.015 ; // Strafe Speed Control "Gain". e.g. Ramp up to 37% power at a 25 degree Yaw error. (0.375 / 25.0)
|
||||||
final double TURN_GAIN = 0.01 ; // Turn Control "Gain". eg: Ramp up to 25% power at a 25 degree error. (0.25 / 25.0)
|
final double TURN_GAIN = 0.01 ; // Turn Control "Gain". e.g. Ramp up to 25% power at a 25 degree error. (0.25 / 25.0)
|
||||||
|
|
||||||
final double MAX_AUTO_SPEED = 0.5; // Clip the approach speed to this max value (adjust for your robot)
|
final double MAX_AUTO_SPEED = 0.5; // Clip the approach speed to this max value (adjust for your robot)
|
||||||
final double MAX_AUTO_STRAFE= 0.5; // Clip the approach speed to this max value (adjust for your robot)
|
final double MAX_AUTO_STRAFE= 0.5; // Clip the strafing speed to this max value (adjust for your robot)
|
||||||
final double MAX_AUTO_TURN = 0.3; // Clip the turn speed to this max value (adjust for your robot)
|
final double MAX_AUTO_TURN = 0.3; // Clip the turn speed to this max value (adjust for your robot)
|
||||||
|
|
||||||
private DcMotor leftFrontDrive = null; // Used to control the left front drive wheel
|
private DcMotor leftFrontDrive = null; // Used to control the left front drive wheel
|
||||||
@ -145,7 +145,7 @@ public class RobotAutoDriveToAprilTagOmni extends LinearOpMode
|
|||||||
|
|
||||||
// Wait for driver to press start
|
// Wait for driver to press start
|
||||||
telemetry.addData("Camera preview on/off", "3 dots, Camera Stream");
|
telemetry.addData("Camera preview on/off", "3 dots, Camera Stream");
|
||||||
telemetry.addData(">", "Touch Play to start OpMode");
|
telemetry.addData(">", "Touch START to start OpMode");
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
waitForStart();
|
waitForStart();
|
||||||
|
|
||||||
@ -259,7 +259,7 @@ public class RobotAutoDriveToAprilTagOmni extends LinearOpMode
|
|||||||
aprilTag = new AprilTagProcessor.Builder().build();
|
aprilTag = new AprilTagProcessor.Builder().build();
|
||||||
|
|
||||||
// Adjust Image Decimation to trade-off detection-range for detection-rate.
|
// Adjust Image Decimation to trade-off detection-range for detection-rate.
|
||||||
// eg: Some typical detection data using a Logitech C920 WebCam
|
// e.g. Some typical detection data using a Logitech C920 WebCam
|
||||||
// Decimation = 1 .. Detect 2" Tag from 10 feet away at 10 Frames per second
|
// Decimation = 1 .. Detect 2" Tag from 10 feet away at 10 Frames per second
|
||||||
// Decimation = 2 .. Detect 2" Tag from 6 feet away at 22 Frames per second
|
// Decimation = 2 .. Detect 2" Tag from 6 feet away at 22 Frames per second
|
||||||
// Decimation = 3 .. Detect 2" Tag from 4 feet away at 30 Frames Per Second
|
// Decimation = 3 .. Detect 2" Tag from 4 feet away at 30 Frames Per Second
|
||||||
|
@ -63,7 +63,7 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* The code assumes a Robot Configuration with motors named left_drive and right_drive.
|
* The code assumes a Robot Configuration with motors named left_drive and right_drive.
|
||||||
* The motor directions must be set so a positive power goes forward on both wheels;
|
* The motor directions must be set so a positive power goes forward on both wheels;
|
||||||
* This sample assumes that the default AprilTag Library (usually for the current season) is being loaded by default
|
* This sample assumes that the default AprilTag Library (usually for the current season) is being loaded by default
|
||||||
* so you should choose to approach a valid tag ID (usually starting at 0)
|
* so you should choose to approach a valid tag ID.
|
||||||
*
|
*
|
||||||
* Under manual control, the left stick will move forward/back, and the right stick will rotate the robot.
|
* Under manual control, the left stick will move forward/back, and the right stick will rotate the robot.
|
||||||
* This is called POV Joystick mode, different than Tank Drive (where each joystick controls a wheel).
|
* This is called POV Joystick mode, different than Tank Drive (where each joystick controls a wheel).
|
||||||
@ -94,8 +94,8 @@ public class RobotAutoDriveToAprilTagTank extends LinearOpMode
|
|||||||
// Set the GAIN constants to control the relationship between the measured position error, and how much power is
|
// Set the GAIN constants to control the relationship between the measured position error, and how much power is
|
||||||
// applied to the drive motors to correct the error.
|
// applied to the drive motors to correct the error.
|
||||||
// Drive = Error * Gain Make these values smaller for smoother control, or larger for a more aggressive response.
|
// Drive = Error * Gain Make these values smaller for smoother control, or larger for a more aggressive response.
|
||||||
final double SPEED_GAIN = 0.02 ; // Speed Control "Gain". eg: Ramp up to 50% power at a 25 inch error. (0.50 / 25.0)
|
final double SPEED_GAIN = 0.02 ; // Speed Control "Gain". e.g. Ramp up to 50% power at a 25 inch error. (0.50 / 25.0)
|
||||||
final double TURN_GAIN = 0.01 ; // Turn Control "Gain". eg: Ramp up to 25% power at a 25 degree error. (0.25 / 25.0)
|
final double TURN_GAIN = 0.01 ; // Turn Control "Gain". e.g. Ramp up to 25% power at a 25 degree error. (0.25 / 25.0)
|
||||||
|
|
||||||
final double MAX_AUTO_SPEED = 0.5; // Clip the approach speed to this max value (adjust for your robot)
|
final double MAX_AUTO_SPEED = 0.5; // Clip the approach speed to this max value (adjust for your robot)
|
||||||
final double MAX_AUTO_TURN = 0.25; // Clip the turn speed to this max value (adjust for your robot)
|
final double MAX_AUTO_TURN = 0.25; // Clip the turn speed to this max value (adjust for your robot)
|
||||||
@ -135,7 +135,7 @@ public class RobotAutoDriveToAprilTagTank extends LinearOpMode
|
|||||||
|
|
||||||
// Wait for the driver to press Start
|
// Wait for the driver to press Start
|
||||||
telemetry.addData("Camera preview on/off", "3 dots, Camera Stream");
|
telemetry.addData("Camera preview on/off", "3 dots, Camera Stream");
|
||||||
telemetry.addData(">", "Touch Play to start OpMode");
|
telemetry.addData(">", "Touch START to start OpMode");
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
waitForStart();
|
waitForStart();
|
||||||
|
|
||||||
@ -234,7 +234,7 @@ public class RobotAutoDriveToAprilTagTank extends LinearOpMode
|
|||||||
aprilTag = new AprilTagProcessor.Builder().build();
|
aprilTag = new AprilTagProcessor.Builder().build();
|
||||||
|
|
||||||
// Adjust Image Decimation to trade-off detection-range for detection-rate.
|
// Adjust Image Decimation to trade-off detection-range for detection-rate.
|
||||||
// eg: Some typical detection data using a Logitech C920 WebCam
|
// e.g. Some typical detection data using a Logitech C920 WebCam
|
||||||
// Decimation = 1 .. Detect 2" Tag from 10 feet away at 10 Frames per second
|
// Decimation = 1 .. Detect 2" Tag from 10 feet away at 10 Frames per second
|
||||||
// Decimation = 2 .. Detect 2" Tag from 6 feet away at 22 Frames per second
|
// Decimation = 2 .. Detect 2" Tag from 6 feet away at 22 Frames per second
|
||||||
// Decimation = 3 .. Detect 2" Tag from 4 feet away at 30 Frames Per Second
|
// Decimation = 3 .. Detect 2" Tag from 4 feet away at 30 Frames Per Second
|
||||||
|
@ -106,7 +106,7 @@ public class RobotAutoDriveToLine_Linear extends LinearOpMode {
|
|||||||
// A gain of 15 causes a Rev Color Sensor V2 to produce an Alpha value of 1.0 at about 1.5" above the floor.
|
// A gain of 15 causes a Rev Color Sensor V2 to produce an Alpha value of 1.0 at about 1.5" above the floor.
|
||||||
colorSensor.setGain(15);
|
colorSensor.setGain(15);
|
||||||
|
|
||||||
// Wait for driver to press PLAY)
|
// Wait for driver to press START)
|
||||||
// Abort this loop is started or stopped.
|
// Abort this loop is started or stopped.
|
||||||
while (opModeInInit()) {
|
while (opModeInInit()) {
|
||||||
|
|
||||||
|
@ -96,10 +96,10 @@ public class RobotTeleopPOV_Linear extends LinearOpMode {
|
|||||||
rightClaw.setPosition(MID_SERVO);
|
rightClaw.setPosition(MID_SERVO);
|
||||||
|
|
||||||
// Send telemetry message to signify robot waiting;
|
// Send telemetry message to signify robot waiting;
|
||||||
telemetry.addData(">", "Robot Ready. Press Play."); //
|
telemetry.addData(">", "Robot Ready. Press START."); //
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
|
|
||||||
// Wait for the game to start (driver presses PLAY)
|
// Wait for the game to start (driver presses START)
|
||||||
waitForStart();
|
waitForStart();
|
||||||
|
|
||||||
// run until the end of the match (driver presses STOP)
|
// run until the end of the match (driver presses STOP)
|
||||||
|
@ -94,25 +94,25 @@ public class RobotTeleopTank_Iterative extends OpMode{
|
|||||||
rightClaw.setPosition(MID_SERVO);
|
rightClaw.setPosition(MID_SERVO);
|
||||||
|
|
||||||
// Send telemetry message to signify robot waiting;
|
// Send telemetry message to signify robot waiting;
|
||||||
telemetry.addData(">", "Robot Ready. Press Play."); //
|
telemetry.addData(">", "Robot Ready. Press START."); //
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code to run REPEATEDLY after the driver hits INIT, but before they hit PLAY
|
* Code to run REPEATEDLY after the driver hits INIT, but before they hit START
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void init_loop() {
|
public void init_loop() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code to run ONCE when the driver hits PLAY
|
* Code to run ONCE when the driver hits START
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void start() {
|
public void start() {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Code to run REPEATEDLY after the driver hits PLAY but before they hit STOP
|
* Code to run REPEATEDLY after the driver hits START but before they hit STOP
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void loop() {
|
public void loop() {
|
||||||
|
@ -33,13 +33,10 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||||||
package org.firstinspires.ftc.robotcontroller.external.samples;
|
package org.firstinspires.ftc.robotcontroller.external.samples;
|
||||||
|
|
||||||
import com.qualcomm.hardware.dfrobot.HuskyLens;
|
import com.qualcomm.hardware.dfrobot.HuskyLens;
|
||||||
import com.qualcomm.hardware.rev.Rev2mDistanceSensor;
|
|
||||||
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
|
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
|
||||||
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
|
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
|
||||||
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
|
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
|
||||||
import com.qualcomm.robotcore.hardware.DistanceSensor;
|
|
||||||
|
|
||||||
import org.firstinspires.ftc.robotcore.external.navigation.DistanceUnit;
|
|
||||||
import org.firstinspires.ftc.robotcore.internal.system.Deadline;
|
import org.firstinspires.ftc.robotcore.internal.system.Deadline;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -51,6 +48,9 @@ import java.util.concurrent.TimeUnit;
|
|||||||
* detect a number of predefined objects and AprilTags in the 36h11 family, can
|
* detect a number of predefined objects and AprilTags in the 36h11 family, can
|
||||||
* recognize colors, and can be trained to detect custom objects. See this website for
|
* recognize colors, and can be trained to detect custom objects. See this website for
|
||||||
* documentation: https://wiki.dfrobot.com/HUSKYLENS_V1.0_SKU_SEN0305_SEN0336
|
* documentation: https://wiki.dfrobot.com/HUSKYLENS_V1.0_SKU_SEN0305_SEN0336
|
||||||
|
*
|
||||||
|
* For detailed instructions on how a HuskyLens is used in FTC, please see this tutorial:
|
||||||
|
* https://ftc-docs.firstinspires.org/en/latest/devices/huskylens/huskylens.html
|
||||||
*
|
*
|
||||||
* This sample illustrates how to detect AprilTags, but can be used to detect other types
|
* This sample illustrates how to detect AprilTags, but can be used to detect other types
|
||||||
* of objects by changing the algorithm. It assumes that the HuskyLens is configured with
|
* of objects by changing the algorithm. It assumes that the HuskyLens is configured with
|
||||||
@ -110,6 +110,8 @@ public class SensorHuskyLens extends LinearOpMode {
|
|||||||
* Users, should, in general, explicitly choose the algorithm they want to use
|
* Users, should, in general, explicitly choose the algorithm they want to use
|
||||||
* within the OpMode by calling selectAlgorithm() and passing it one of the values
|
* within the OpMode by calling selectAlgorithm() and passing it one of the values
|
||||||
* found in the enumeration HuskyLens.Algorithm.
|
* found in the enumeration HuskyLens.Algorithm.
|
||||||
|
*
|
||||||
|
* Other algorithm choices for FTC might be: OBJECT_RECOGNITION, COLOR_RECOGNITION or OBJECT_CLASSIFICATION.
|
||||||
*/
|
*/
|
||||||
huskyLens.selectAlgorithm(HuskyLens.Algorithm.TAG_RECOGNITION);
|
huskyLens.selectAlgorithm(HuskyLens.Algorithm.TAG_RECOGNITION);
|
||||||
|
|
||||||
@ -141,6 +143,15 @@ public class SensorHuskyLens extends LinearOpMode {
|
|||||||
telemetry.addData("Block count", blocks.length);
|
telemetry.addData("Block count", blocks.length);
|
||||||
for (int i = 0; i < blocks.length; i++) {
|
for (int i = 0; i < blocks.length; i++) {
|
||||||
telemetry.addData("Block", blocks[i].toString());
|
telemetry.addData("Block", blocks[i].toString());
|
||||||
|
/*
|
||||||
|
* Here inside the FOR loop, you could save or evaluate specific info for the currently recognized Bounding Box:
|
||||||
|
* - blocks[i].width and blocks[i].height (size of box, in pixels)
|
||||||
|
* - blocks[i].left and blocks[i].top (edges of box)
|
||||||
|
* - blocks[i].x and blocks[i].y (center location)
|
||||||
|
* - blocks[i].id (Color ID)
|
||||||
|
*
|
||||||
|
* These values have Java type int (integer).
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
|
@ -58,7 +58,7 @@ import static com.qualcomm.hardware.rev.RevHubOrientationOnRobot.xyzOrientation;
|
|||||||
* planes (X/Y, X/Z or Y/Z) OR that the Hub has only been rotated in a range of 90 degree increments.
|
* planes (X/Y, X/Z or Y/Z) OR that the Hub has only been rotated in a range of 90 degree increments.
|
||||||
*
|
*
|
||||||
* Note: if your Hub is mounted Orthogonally (on a orthogonal surface, angled at some multiple of
|
* Note: if your Hub is mounted Orthogonally (on a orthogonal surface, angled at some multiple of
|
||||||
* 90 Degrees) then you should use the simpler SensorImuOrthogonal sample in this folder.
|
* 90 Degrees) then you should use the simpler SensorIMUOrthogonal sample in this folder.
|
||||||
*
|
*
|
||||||
* But... If your Hub is mounted Non-Orthogonally, you must specify one or more rotational angles
|
* But... If your Hub is mounted Non-Orthogonally, you must specify one or more rotational angles
|
||||||
* that transform a "Default" Hub orientation into your desired orientation. That is what is
|
* that transform a "Default" Hub orientation into your desired orientation. That is what is
|
||||||
@ -94,6 +94,9 @@ public class SensorIMUNonOrthogonal extends LinearOpMode
|
|||||||
* 1) Hub laying flat on a horizontal surface, with the Printed Logo facing UP
|
* 1) Hub laying flat on a horizontal surface, with the Printed Logo facing UP
|
||||||
* 2) Rotated such that the USB ports are facing forward on the robot.
|
* 2) Rotated such that the USB ports are facing forward on the robot.
|
||||||
*
|
*
|
||||||
|
* If you are using a REV External IMU, the "Default" orientation is the same as for a REV Hub, but instead of
|
||||||
|
* the USB ports facing forward, the I2C port faces forward.
|
||||||
|
*
|
||||||
* The order that the rotations are performed matters, so this sample shows doing them in the order X, Y, then Z.
|
* The order that the rotations are performed matters, so this sample shows doing them in the order X, Y, then Z.
|
||||||
* For specifying non-orthogonal hub mounting orientations, we must temporarily use axes
|
* For specifying non-orthogonal hub mounting orientations, we must temporarily use axes
|
||||||
* defined relative to the Hub itself, instead of the usual Robot Coordinate System axes
|
* defined relative to the Hub itself, instead of the usual Robot Coordinate System axes
|
||||||
@ -124,7 +127,7 @@ public class SensorIMUNonOrthogonal extends LinearOpMode
|
|||||||
*
|
*
|
||||||
* To get the "Default" hub into this configuration you would just need a single rotation, but around a different axis.
|
* To get the "Default" hub into this configuration you would just need a single rotation, but around a different axis.
|
||||||
* 1) No rotation around the X or Y axes.
|
* 1) No rotation around the X or Y axes.
|
||||||
* 1) Rotate the Hub -30 degrees (Clockwise) around the Z axis, since a positive angle would be Counter Clockwise.
|
* 2) Rotate the Hub -30 degrees (Clockwise) around the Z axis, since a positive angle would be Counter Clockwise.
|
||||||
*
|
*
|
||||||
* So the X,Y,Z rotations would be 0,0,-30
|
* So the X,Y,Z rotations would be 0,0,-30
|
||||||
*
|
*
|
||||||
|
@ -55,7 +55,7 @@ import org.firstinspires.ftc.robotcore.external.navigation.YawPitchRollAngles;
|
|||||||
* (X/Y, X/Z or Y/Z) and that the Hub has only been rotated in a range of 90 degree increments.
|
* (X/Y, X/Z or Y/Z) and that the Hub has only been rotated in a range of 90 degree increments.
|
||||||
*
|
*
|
||||||
* Note: if your Hub is mounted on a surface angled at some non-90 Degree multiple (like 30) look at
|
* Note: if your Hub is mounted on a surface angled at some non-90 Degree multiple (like 30) look at
|
||||||
* the alternative SensorImuNonOrthogonal sample in this folder.
|
* the alternative SensorIMUNonOrthogonal sample in this folder.
|
||||||
*
|
*
|
||||||
* This "Orthogonal" requirement means that:
|
* This "Orthogonal" requirement means that:
|
||||||
*
|
*
|
||||||
@ -98,6 +98,9 @@ public class SensorIMUOrthogonal extends LinearOpMode
|
|||||||
* The first parameter specifies the direction the printed logo on the Hub is pointing.
|
* The first parameter specifies the direction the printed logo on the Hub is pointing.
|
||||||
* The second parameter specifies the direction the USB connector on the Hub is pointing.
|
* The second parameter specifies the direction the USB connector on the Hub is pointing.
|
||||||
* All directions are relative to the robot, and left/right is as-viewed from behind the robot.
|
* All directions are relative to the robot, and left/right is as-viewed from behind the robot.
|
||||||
|
*
|
||||||
|
* If you are using a REV 9-Axis IMU, you can use the Rev9AxisImuOrientationOnRobot class instead of the
|
||||||
|
* RevHubOrientationOnRobot class, which has an I2cPortFacingDirection instead of a UsbFacingDirection.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* The next two lines define Hub orientation.
|
/* The next two lines define Hub orientation.
|
||||||
|
@ -0,0 +1,159 @@
|
|||||||
|
/*
|
||||||
|
Copyright (c) 2024 Limelight Vision
|
||||||
|
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification,
|
||||||
|
are permitted (subject to the limitations in the disclaimer below) provided that
|
||||||
|
the following conditions are met:
|
||||||
|
|
||||||
|
Redistributions of source code must retain the above copyright notice, this list
|
||||||
|
of conditions and the following disclaimer.
|
||||||
|
|
||||||
|
Redistributions in binary form must reproduce the above copyright notice, this
|
||||||
|
list of conditions and the following disclaimer in the documentation and/or
|
||||||
|
other materials provided with the distribution.
|
||||||
|
|
||||||
|
Neither the name of FIRST nor the names of its contributors may be used to
|
||||||
|
endorse or promote products derived from this software without specific prior
|
||||||
|
written permission.
|
||||||
|
|
||||||
|
NO EXPRESS OR IMPLIED LICENSES TO ANY PARTY'S PATENT RIGHTS ARE GRANTED BY THIS
|
||||||
|
LICENSE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE
|
||||||
|
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||||
|
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
|
||||||
|
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package org.firstinspires.ftc.robotcontroller.external.samples;
|
||||||
|
|
||||||
|
import com.qualcomm.hardware.limelightvision.LLResult;
|
||||||
|
import com.qualcomm.hardware.limelightvision.LLResultTypes;
|
||||||
|
import com.qualcomm.hardware.limelightvision.LLStatus;
|
||||||
|
import com.qualcomm.hardware.limelightvision.Limelight3A;
|
||||||
|
import com.qualcomm.robotcore.eventloop.opmode.Disabled;
|
||||||
|
import com.qualcomm.robotcore.eventloop.opmode.LinearOpMode;
|
||||||
|
import com.qualcomm.robotcore.eventloop.opmode.TeleOp;
|
||||||
|
|
||||||
|
import org.firstinspires.ftc.robotcore.external.navigation.Pose3D;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This OpMode illustrates how to use the Limelight3A Vision Sensor.
|
||||||
|
*
|
||||||
|
* @see <a href="https://limelightvision.io/">Limelight</a>
|
||||||
|
*
|
||||||
|
* Notes on configuration:
|
||||||
|
*
|
||||||
|
* The device presents itself, when plugged into a USB port on a Control Hub as an ethernet
|
||||||
|
* interface. A DHCP server running on the Limelight automatically assigns the Control Hub an
|
||||||
|
* ip address for the new ethernet interface.
|
||||||
|
*
|
||||||
|
* Since the Limelight is plugged into a USB port, it will be listed on the top level configuration
|
||||||
|
* activity along with the Control Hub Portal and other USB devices such as webcams. Typically
|
||||||
|
* serial numbers are displayed below the device's names. In the case of the Limelight device, the
|
||||||
|
* Control Hub's assigned ip address for that ethernet interface is used as the "serial number".
|
||||||
|
*
|
||||||
|
* Tapping the Limelight's name, transitions to a new screen where the user can rename the Limelight
|
||||||
|
* and specify the Limelight's ip address. Users should take care not to confuse the ip address of
|
||||||
|
* the Limelight itself, which can be configured through the Limelight settings page via a web browser,
|
||||||
|
* and the ip address the Limelight device assigned the Control Hub and which is displayed in small text
|
||||||
|
* below the name of the Limelight on the top level configuration screen.
|
||||||
|
*/
|
||||||
|
@TeleOp(name = "Sensor: Limelight3A", group = "Sensor")
|
||||||
|
@Disabled
|
||||||
|
public class SensorLimelight3A extends LinearOpMode {
|
||||||
|
|
||||||
|
private Limelight3A limelight;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void runOpMode() throws InterruptedException
|
||||||
|
{
|
||||||
|
limelight = hardwareMap.get(Limelight3A.class, "limelight");
|
||||||
|
|
||||||
|
telemetry.setMsTransmissionInterval(11);
|
||||||
|
|
||||||
|
limelight.pipelineSwitch(0);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Starts polling for data. If you neglect to call start(), getLatestResult() will return null.
|
||||||
|
*/
|
||||||
|
limelight.start();
|
||||||
|
|
||||||
|
telemetry.addData(">", "Robot Ready. Press Play.");
|
||||||
|
telemetry.update();
|
||||||
|
waitForStart();
|
||||||
|
|
||||||
|
while (opModeIsActive()) {
|
||||||
|
LLStatus status = limelight.getStatus();
|
||||||
|
telemetry.addData("Name", "%s",
|
||||||
|
status.getName());
|
||||||
|
telemetry.addData("LL", "Temp: %.1fC, CPU: %.1f%%, FPS: %d",
|
||||||
|
status.getTemp(), status.getCpu(),(int)status.getFps());
|
||||||
|
telemetry.addData("Pipeline", "Index: %d, Type: %s",
|
||||||
|
status.getPipelineIndex(), status.getPipelineType());
|
||||||
|
|
||||||
|
LLResult result = limelight.getLatestResult();
|
||||||
|
if (result != null) {
|
||||||
|
// Access general information
|
||||||
|
Pose3D botpose = result.getBotpose();
|
||||||
|
double captureLatency = result.getCaptureLatency();
|
||||||
|
double targetingLatency = result.getTargetingLatency();
|
||||||
|
double parseLatency = result.getParseLatency();
|
||||||
|
telemetry.addData("LL Latency", captureLatency + targetingLatency);
|
||||||
|
telemetry.addData("Parse Latency", parseLatency);
|
||||||
|
telemetry.addData("PythonOutput", java.util.Arrays.toString(result.getPythonOutput()));
|
||||||
|
|
||||||
|
if (result.isValid()) {
|
||||||
|
telemetry.addData("tx", result.getTx());
|
||||||
|
telemetry.addData("txnc", result.getTxNC());
|
||||||
|
telemetry.addData("ty", result.getTy());
|
||||||
|
telemetry.addData("tync", result.getTyNC());
|
||||||
|
|
||||||
|
telemetry.addData("Botpose", botpose.toString());
|
||||||
|
|
||||||
|
// Access barcode results
|
||||||
|
List<LLResultTypes.BarcodeResult> barcodeResults = result.getBarcodeResults();
|
||||||
|
for (LLResultTypes.BarcodeResult br : barcodeResults) {
|
||||||
|
telemetry.addData("Barcode", "Data: %s", br.getData());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Access classifier results
|
||||||
|
List<LLResultTypes.ClassifierResult> classifierResults = result.getClassifierResults();
|
||||||
|
for (LLResultTypes.ClassifierResult cr : classifierResults) {
|
||||||
|
telemetry.addData("Classifier", "Class: %s, Confidence: %.2f", cr.getClassName(), cr.getConfidence());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Access detector results
|
||||||
|
List<LLResultTypes.DetectorResult> detectorResults = result.getDetectorResults();
|
||||||
|
for (LLResultTypes.DetectorResult dr : detectorResults) {
|
||||||
|
telemetry.addData("Detector", "Class: %s, Area: %.2f", dr.getClassName(), dr.getTargetArea());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Access fiducial results
|
||||||
|
List<LLResultTypes.FiducialResult> fiducialResults = result.getFiducialResults();
|
||||||
|
for (LLResultTypes.FiducialResult fr : fiducialResults) {
|
||||||
|
telemetry.addData("Fiducial", "ID: %d, Family: %s, X: %.2f, Y: %.2f", fr.getFiducialId(), fr.getFamily(),fr.getTargetXDegrees(), fr.getTargetYDegrees());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Access color results
|
||||||
|
List<LLResultTypes.ColorResult> colorResults = result.getColorResults();
|
||||||
|
for (LLResultTypes.ColorResult cr : colorResults) {
|
||||||
|
telemetry.addData("Color", "X: %.2f, Y: %.2f", cr.getTargetXDegrees(), cr.getTargetYDegrees());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
telemetry.addData("Limelight", "No data available");
|
||||||
|
}
|
||||||
|
|
||||||
|
telemetry.update();
|
||||||
|
}
|
||||||
|
limelight.stop();
|
||||||
|
}
|
||||||
|
}
|
@ -52,7 +52,7 @@ import org.firstinspires.ftc.robotcore.external.Telemetry;
|
|||||||
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
|
* Use Android Studio to Copy this Class, and Paste it into your team's code folder with a new name.
|
||||||
* Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list
|
* Remove or comment out the @Disabled line to add this OpMode to the Driver Station OpMode list
|
||||||
*
|
*
|
||||||
* See the sensor's product page: https://www.tindie.com/products/digitalchickenlabs/octoquad-8ch-quadrature-pulse-width-decoder/
|
* See the sensor's product page: https://www.tindie.com/products/35114/
|
||||||
*/
|
*/
|
||||||
@TeleOp(name = "OctoQuad Basic", group="OctoQuad")
|
@TeleOp(name = "OctoQuad Basic", group="OctoQuad")
|
||||||
@Disabled
|
@Disabled
|
||||||
@ -60,7 +60,7 @@ public class SensorOctoQuad extends LinearOpMode {
|
|||||||
|
|
||||||
// Identify which encoder OctoQuad inputs are connected to each odometry pod.
|
// Identify which encoder OctoQuad inputs are connected to each odometry pod.
|
||||||
private final int ODO_LEFT = 0; // Facing forward direction on left side of robot (Axial motion)
|
private final int ODO_LEFT = 0; // Facing forward direction on left side of robot (Axial motion)
|
||||||
private final int ODO_RIGHT = 1; // Facing forward direction on right side or robot (Axial motion )
|
private final int ODO_RIGHT = 1; // Facing forward direction on right side or robot (Axial motion)
|
||||||
private final int ODO_PERP = 2; // Facing perpendicular direction at the center of the robot (Lateral motion)
|
private final int ODO_PERP = 2; // Facing perpendicular direction at the center of the robot (Lateral motion)
|
||||||
|
|
||||||
// Declare the OctoQuad object and members to store encoder positions and velocities
|
// Declare the OctoQuad object and members to store encoder positions and velocities
|
||||||
@ -83,7 +83,7 @@ public class SensorOctoQuad extends LinearOpMode {
|
|||||||
telemetry.addData("OctoQuad Firmware Version ", octoquad.getFirmwareVersion());
|
telemetry.addData("OctoQuad Firmware Version ", octoquad.getFirmwareVersion());
|
||||||
|
|
||||||
// Reverse the count-direction of any encoder that is not what you require.
|
// Reverse the count-direction of any encoder that is not what you require.
|
||||||
// Eg: if you push the robot forward and the left encoder counts down, then reverse it so it counts up.
|
// e.g. if you push the robot forward and the left encoder counts down, then reverse it so it counts up.
|
||||||
octoquad.setSingleEncoderDirection(ODO_LEFT, OctoQuad.EncoderDirection.REVERSE);
|
octoquad.setSingleEncoderDirection(ODO_LEFT, OctoQuad.EncoderDirection.REVERSE);
|
||||||
octoquad.setSingleEncoderDirection(ODO_RIGHT, OctoQuad.EncoderDirection.FORWARD);
|
octoquad.setSingleEncoderDirection(ODO_RIGHT, OctoQuad.EncoderDirection.FORWARD);
|
||||||
octoquad.setSingleEncoderDirection(ODO_PERP, OctoQuad.EncoderDirection.FORWARD);
|
octoquad.setSingleEncoderDirection(ODO_PERP, OctoQuad.EncoderDirection.FORWARD);
|
||||||
@ -91,7 +91,7 @@ public class SensorOctoQuad extends LinearOpMode {
|
|||||||
// Any changes that are made should be saved in FLASH just in case there is a sensor power glitch.
|
// Any changes that are made should be saved in FLASH just in case there is a sensor power glitch.
|
||||||
octoquad.saveParametersToFlash();
|
octoquad.saveParametersToFlash();
|
||||||
|
|
||||||
telemetry.addLine("\nPress Play to read encoder values");
|
telemetry.addLine("\nPress START to read encoder values");
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
|
|
||||||
waitForStart();
|
waitForStart();
|
||||||
@ -100,23 +100,23 @@ public class SensorOctoQuad extends LinearOpMode {
|
|||||||
telemetry.setDisplayFormat(Telemetry.DisplayFormat.MONOSPACE);
|
telemetry.setDisplayFormat(Telemetry.DisplayFormat.MONOSPACE);
|
||||||
telemetry.setMsTransmissionInterval(50);
|
telemetry.setMsTransmissionInterval(50);
|
||||||
|
|
||||||
// Set all the encoder inputs to zero
|
// Set all the encoder inputs to zero.
|
||||||
octoquad.resetAllPositions();
|
octoquad.resetAllPositions();
|
||||||
|
|
||||||
// Loop while displaying the odometry pod positions.
|
// Loop while displaying the odometry pod positions.
|
||||||
while (opModeIsActive()) {
|
while (opModeIsActive()) {
|
||||||
telemetry.addData(">", "Press X to Reset Encoders\n");
|
telemetry.addData(">", "Press X to Reset Encoders\n");
|
||||||
|
|
||||||
// Check for X button to reset encoders
|
// Check for X button to reset encoders.
|
||||||
if (gamepad1.x) {
|
if (gamepad1.x) {
|
||||||
// Reset the position of all encoders to zero.
|
// Reset the position of all encoders to zero.
|
||||||
octoquad.resetAllPositions();
|
octoquad.resetAllPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read all the encoder data. Load into local members
|
// Read all the encoder data. Load into local members.
|
||||||
readOdometryPods();
|
readOdometryPods();
|
||||||
|
|
||||||
// Display the values
|
// Display the values.
|
||||||
telemetry.addData("Left ", "%8d counts", posLeft);
|
telemetry.addData("Left ", "%8d counts", posLeft);
|
||||||
telemetry.addData("Right", "%8d counts", posRight);
|
telemetry.addData("Right", "%8d counts", posRight);
|
||||||
telemetry.addData("Perp ", "%8d counts", posPerp);
|
telemetry.addData("Perp ", "%8d counts", posPerp);
|
||||||
@ -131,11 +131,11 @@ public class SensorOctoQuad extends LinearOpMode {
|
|||||||
// or
|
// or
|
||||||
// readAllPositions() to get all 8 encoder readings
|
// readAllPositions() to get all 8 encoder readings
|
||||||
//
|
//
|
||||||
// Since both calls take almost the same amount of time, and the actual channels may not end up being sequential,
|
// Since both calls take almost the same amount of time, and the actual channels may not end up
|
||||||
// we will read all of the encoder positions, and then pick out the ones we need.
|
// being sequential, we will read all of the encoder positions, and then pick out the ones we need.
|
||||||
int[] positions = octoquad.readAllPositions();
|
int[] positions = octoquad.readAllPositions();
|
||||||
posLeft = positions[ODO_LEFT];
|
posLeft = positions[ODO_LEFT];
|
||||||
posRight = positions[ODO_RIGHT];
|
posRight = positions[ODO_RIGHT];
|
||||||
posPerp = positions[ODO_PERP];
|
posPerp = positions[ODO_PERP];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -77,7 +77,7 @@ import java.util.List;
|
|||||||
* Note: If you prefer, you can move the two support classes from this file, and place them in their own files.
|
* Note: If you prefer, you can move the two support classes from this file, and place them in their own files.
|
||||||
* But leaving them in place is simpler for this example.
|
* But leaving them in place is simpler for this example.
|
||||||
*
|
*
|
||||||
* See the sensor's product page: https://www.tindie.com/products/digitalchickenlabs/octoquad-8ch-quadrature-pulse-width-decoder/
|
* See the sensor's product page: https://www.tindie.com/products/35114/
|
||||||
*/
|
*/
|
||||||
@TeleOp(name="OctoQuad Advanced", group="OctoQuad")
|
@TeleOp(name="OctoQuad Advanced", group="OctoQuad")
|
||||||
@Disabled
|
@Disabled
|
||||||
@ -93,7 +93,7 @@ public class SensorOctoQuadAdv extends LinearOpMode {
|
|||||||
|
|
||||||
// Display the OctoQuad firmware revision
|
// Display the OctoQuad firmware revision
|
||||||
telemetry.addLine("OctoQuad Firmware v" + octoquad.getFirmwareVersion());
|
telemetry.addLine("OctoQuad Firmware v" + octoquad.getFirmwareVersion());
|
||||||
telemetry.addLine("\nPress Play to read encoder values");
|
telemetry.addLine("\nPress START to read encoder values");
|
||||||
telemetry.update();
|
telemetry.update();
|
||||||
|
|
||||||
waitForStart();
|
waitForStart();
|
||||||
@ -275,4 +275,4 @@ class OctoSwerveModule {
|
|||||||
public void show(Telemetry telemetry) {
|
public void show(Telemetry telemetry) {
|
||||||
telemetry.addData(name, "%8.0f %7.0f %7.0f %6.0f", driveCounts, driveCountsPerSec, steerDegrees, steerDegreesPerSec);
|
telemetry.addData(name, "%8.0f %7.0f %7.0f %6.0f", driveCounts, driveCountsPerSec, steerDegrees, steerDegreesPerSec);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -446,7 +446,7 @@ public class UtilityOctoQuadConfigMenu extends LinearOpMode
|
|||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
builder.append("<font color='#119af5' face=monospace>");
|
builder.append("<font color='#119af5' face=monospace>");
|
||||||
builder.append("Navigate items.....dpad up/down\n")
|
builder.append("Navigate items.....dpad up/down\n")
|
||||||
.append("Select.............X\n")
|
.append("Select.............X or Square\n")
|
||||||
.append("Edit option........dpad left/right\n")
|
.append("Edit option........dpad left/right\n")
|
||||||
.append("Up one level.......left bumper\n");
|
.append("Up one level.......left bumper\n");
|
||||||
builder.append("</font>");
|
builder.append("</font>");
|
||||||
@ -614,7 +614,7 @@ public class UtilityOctoQuadConfigMenu extends LinearOpMode
|
|||||||
@Override
|
@Override
|
||||||
public void onClick()
|
public void onClick()
|
||||||
{
|
{
|
||||||
onRightInput();
|
//onRightInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -669,7 +669,7 @@ public class UtilityOctoQuadConfigMenu extends LinearOpMode
|
|||||||
@Override
|
@Override
|
||||||
public void onClick()
|
public void onClick()
|
||||||
{
|
{
|
||||||
onRightInput();
|
//onRightInput();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
48
README.md
48
README.md
@ -59,6 +59,54 @@ The readme.md file located in the [/TeamCode/src/main/java/org/firstinspires/ftc
|
|||||||
|
|
||||||
# Release Information
|
# Release Information
|
||||||
|
|
||||||
|
## Version 10.0 (20240828-111152)
|
||||||
|
|
||||||
|
### Breaking Changes
|
||||||
|
* Java classes and Blocks for TensorFlow Object Detection have been removed.
|
||||||
|
* `AngularVelocity.unit` which was of type `AngleUnit` has been renamed `AngularVelocity.angleUnit` of type `UnnormalizedAngleUnit`
|
||||||
|
|
||||||
|
### Enhancements
|
||||||
|
* Sample for REV Digital Indicator has been added - ConceptRevLED
|
||||||
|
* Adds support for the [Sparkfun QWIIC LED Stick](https://www.sparkfun.com/products/18354)
|
||||||
|
* To connect it directly, you need this [cable](https://www.sparkfun.com/products/25596)
|
||||||
|
* Adds ConceptLEDStick OpMode
|
||||||
|
* Adds Blocks for colors black, blue, cyan, dkgray, gray, green, ltgray, magenta, red, white, and yellow.
|
||||||
|
* Adds an "evaluate but ignore result" Block that executes the connected block and ignores the result. Allows you to call a function and ignore the return value.
|
||||||
|
* Adds I2C driver for Maxbotix Maxsonar I2CXL sonar rangefinder
|
||||||
|
* Adds Blocks for setPwmEnable, setPwmDisable, and isPwmEnabled for servos and CR servos.
|
||||||
|
* In the Blocks editor: a \n in the ExportToBlocks annotation's comment field is displayed as a line break.
|
||||||
|
* Telemetry has new method setNumDecimalPlaces
|
||||||
|
* Telemetry now formats doubles and floats (not inside objects, just by themselves)
|
||||||
|
* Adds support for the Limelight 3A.
|
||||||
|
* Adds initial support for the REV Servo Hub
|
||||||
|
* Both the Robot Controller and Driver Station need to be updated to version 10.0 in order for Servo Hubs to be
|
||||||
|
configurable as Servo Hubs. If the app on either device is outdated, the Servo Hub will show up as an Expansion Hub,
|
||||||
|
and some functionality will not work as expected. You should wait to create a configuration that includes a Servo Hub
|
||||||
|
until both the Driver Station and Robot Controller apps have been updated to version 10.0.
|
||||||
|
* Updating the Servo Hub's firmware and changing its address can only be done using the REV Hardware Client at this time
|
||||||
|
* Adds support for the REV 9-Axis IMU (REV-31-3332)
|
||||||
|
* The REV 9-Axis IMU is only supported by the [Universal IMU interface](https://ftc-docs.firstinspires.org/en/latest/programming_resources/imu/imu.html)
|
||||||
|
* Adds `Rev9AxisImuOrientationOnRobot` Java class.
|
||||||
|
* If you mentally substitute this IMU's I2C port for the Control Hub's USB ports, `RevHubOrientationOnRobot` is also compatible with this sensor
|
||||||
|
* Adds Blocks for Rev9AxisImuOrientationOnRobot, including RevHubImuOrientationOnRobot.xyzOrientation and RevHubImuOrientationOnRobot.zyxOrientation.
|
||||||
|
* Adds Blocks samples SensorRev9AxisIMUOrthogonal and SensorRev9AxisIMUNonOrthogonal.
|
||||||
|
* Improves Blocks support for RevHubImuOrientationOnRobot.
|
||||||
|
* Adds Blocks for RevHubImuOrientationOnRobot.xyzOrientation and RevHubImuOrientationOnRobot.zyxOrientation.
|
||||||
|
* Adds Blocks samples SensorHubIMUOrthogonal (replaces SensorIMU) and SensorHubIMUNonOrthogonal.
|
||||||
|
* Updates EasyOpenCV, AprilTag, OpenCV, and `libjpeg-turbo` versions
|
||||||
|
* Adds Blocks for max and min that take two numbers.
|
||||||
|
* Adds Blocks OpModes ConceptRevSPARKMini, RobotAutoDriveByEncoder, RobotAutoDriveByGyro, RobotAutoDriveByTime, RobotAutoDriveToAprilTagOmni, and RobotAutoDriveToAprilTagTank.
|
||||||
|
* Two OpModes with the same name now automatically get renamed with the name followed by a "-" and the class name allowing them to both be on the device.
|
||||||
|
* Shows the name of the active configuration on the Manage page of the Robot Controller Console
|
||||||
|
* Updated AprilTag Library for INTO THE DEEP. Notably, `getCurrentGameTagLibrary()` now returns INTO THE DEEP tags.
|
||||||
|
* Adds Blocks for Telemetry.setMsTransmissionInterval and Telemetry.getMsTransmissionInterval.
|
||||||
|
* Adds Blocks sample SensorOctoQuad.
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
* Fixes a bug where the RevBlinkinLedDriver Blocks were under Actuators in the Blocks editor toolbox. They are now Other Devices.
|
||||||
|
* Fixes a bug where `Exception`s thrown in user code after a stop was requested by the Driver Station would be silently eaten
|
||||||
|
* Fixed a bug where if you asked for `AngularVelocity` in a unit different than the device reported it in, it would normalize it between -PI and PI for radians, and -180 and 180 for degrees.
|
||||||
|
|
||||||
## Version 9.2 (20240701-085519)
|
## Version 9.2 (20240701-085519)
|
||||||
|
|
||||||
### Important Notes
|
### Important Notes
|
||||||
|
@ -25,5 +25,4 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':FtcRobotController')
|
implementation project(':FtcRobotController')
|
||||||
annotationProcessor files('lib/OpModeAnnotationProcessor.jar')
|
|
||||||
}
|
}
|
||||||
|
@ -47,10 +47,6 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
aaptOptions {
|
|
||||||
noCompress "tflite"
|
|
||||||
}
|
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
signingConfig signingConfigs.debug
|
signingConfig signingConfigs.debug
|
||||||
applicationId 'com.qualcomm.ftcrobotcontroller'
|
applicationId 'com.qualcomm.ftcrobotcontroller'
|
||||||
|
@ -4,18 +4,14 @@ repositories {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'org.firstinspires.ftc:Inspection:9.2.0'
|
implementation 'org.firstinspires.ftc:Inspection:10.0.0'
|
||||||
implementation 'org.firstinspires.ftc:Blocks:9.2.0'
|
implementation 'org.firstinspires.ftc:Blocks:10.0.0'
|
||||||
implementation 'org.firstinspires.ftc:Tfod:9.2.0'
|
implementation 'org.firstinspires.ftc:RobotCore:10.0.0'
|
||||||
implementation 'org.firstinspires.ftc:RobotCore:9.2.0'
|
implementation 'org.firstinspires.ftc:RobotServer:10.0.0'
|
||||||
implementation 'org.firstinspires.ftc:RobotServer:9.2.0'
|
implementation 'org.firstinspires.ftc:OnBotJava:10.0.0'
|
||||||
implementation 'org.firstinspires.ftc:OnBotJava:9.2.0'
|
implementation 'org.firstinspires.ftc:Hardware:10.0.0'
|
||||||
implementation 'org.firstinspires.ftc:Hardware:9.2.0'
|
implementation 'org.firstinspires.ftc:FtcCommon:10.0.0'
|
||||||
implementation 'org.firstinspires.ftc:FtcCommon:9.2.0'
|
implementation 'org.firstinspires.ftc:Vision:10.0.0'
|
||||||
implementation 'org.firstinspires.ftc:Vision:9.2.0'
|
|
||||||
implementation 'org.firstinspires.ftc:gameAssets-CenterStage:1.0.0'
|
|
||||||
implementation 'org.tensorflow:tensorflow-lite-task-vision:0.4.3'
|
|
||||||
runtimeOnly 'org.tensorflow:tensorflow-lite:2.12.0'
|
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user